Exemplo n.º 1
0
        private void OnWillRenderObject()
        {
            var cam = Camera.current;

            if (!_cameras.ContainsKey(cam))
            {
                //現在レンダリングしているカメラにCommandBufferがない場合
                var cmdInfo = new CmdBufferInfo();
                cmdInfo.pass        = CameraEvent.BeforeGBuffer;
                cmdInfo.buffer      = new CommandBuffer();
                cmdInfo.buffer.name = "** SSFR Command Buffer **";
                cam.AddCommandBuffer(cmdInfo.pass, cmdInfo.buffer);
                _cameras.Add(cam, cmdInfo);
            }
            else
            {
                var buf = _cameras[cam].buffer;
                buf.Clear();
                //render particle----------------
                #region RenderDepth_Block
                int depthBufferId = Shader.PropertyToID("-DepthBuffer_SSFR");
                buf.GetTemporaryRT(depthBufferId, -1, -1, 24, FilterMode.Point, RenderTextureFormat.RFloat);

                buf.SetRenderTarget
                (
                    new RenderTargetIdentifier(depthBufferId),      // デプス
                    new RenderTargetIdentifier(depthBufferId)       // デプス書き込み用
                );
                buf.ClearRenderTarget(true, true, Color.clear);

                _depthMat.SetBuffer("particles", buffer);
                _depthMat.SetFloat("particleSize", particleSize);
                buf.DrawProcedural(Matrix4x4.identity, _depthMat, 0, MeshTopology.Points, particleNum);
                #endregion

                #region Blur_Block

                /*
                 * string TempDepthStr = "_TempDepthbufferId";
                 * var tempDepthBufferId = Shader.PropertyToID(TempDepthStr);
                 * //blur
                 * _blurMat.SetFloat("_FilterRadius", _blurFilterRadius);
                 * _blurMat.SetFloat("_BlurScale", _blurScale);
                 * _blurMat.SetFloat("_BlurDepthFallOff", _blurDepthFallOff);
                 * buf.SetGlobalVector("_BlurDir", new Vector2(0.0f, 1.0f));
                 * buf.Blit(depthBufferId, tempDepthBufferId, _blurMat);
                 * buf.SetGlobalVector("_BlurDir", new Vector2(1.0f, 0.0f));
                 * buf.Blit(tempDepthBufferId, depthBufferId, _blurMat);
                 */


                var tempDepthBufferId = Shader.PropertyToID("_TempDepthBufferId");
                buf.GetTemporaryRT(tempDepthBufferId, -1, -1, 0, FilterMode.Trilinear, RenderTextureFormat.RFloat);

                // ブラーエフェクトのプロパティをセット
                _blurMat.SetFloat("_FilterRadius", _blurFilterRadius);
                _blurMat.SetFloat("_BlurScale", _blurScale);
                _blurMat.SetFloat("_BlurDepthFallOff", _blurDepthFallOff);

                // 水平方向のブラーを実行
                buf.SetGlobalVector("_BlurDir", new Vector2(0.0f, 1.0f));
                buf.Blit(depthBufferId, tempDepthBufferId, _blurMat);

                // 垂直方向のブラーを実行
                buf.SetGlobalVector("_BlurDir", new Vector2(1.0f, 0.0f));
                buf.Blit(tempDepthBufferId, depthBufferId, _blurMat);


                #endregion

                #region calcNormal

                //int normalBufferId = Shader.PropertyToID("_NormalBuffer");
                //buf.GetTemporaryRT(normalBufferId, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGBFloat);
                //buf.SetRenderTarget(normalBufferId);
                //buf.ClearRenderTarget(false, true, Color.clear);
                //var view = cam.worldToCameraMatrix;
                //_calcNormalMat.SetMatrix("_ViewMatrix", view);
                //buf.SetGlobalTexture("_DepthBuffer", depthBufferId);
                //buf.Blit(null, normalBufferId, _calcNormalMat);

                int normalBufferId = Shader.PropertyToID("_NormalBuffer");
                buf.GetTemporaryRT(normalBufferId, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGBFloat);
                // 法線バッファをレンダーターゲットにセット
                buf.SetRenderTarget(normalBufferId);
                // クリア
                buf.ClearRenderTarget(false, true, Color.clear);
                // ビュー変換マトリックスをセット
                var view = cam.worldToCameraMatrix;
                _calcNormalMat.SetMatrix("_ViewMatrix", view);
                // デプスバッファをシェーダにセット
                buf.SetGlobalTexture("_DepthBuffer", depthBufferId);
                // デプスから法線をスクリーンスペースで計算
                buf.Blit(null, normalBufferId, _calcNormalMat);

                #endregion
                //write gbuffer------------------
                _renderGBufferMat.SetColor("_Diffuse", _diffuse);
                _renderGBufferMat.SetColor("_Specular", new Vector4(_specular.r, _specular.g, _specular.b, 1.0f - _roughness));
                _renderGBufferMat.SetColor("_Emission", _emission);
                buf.SetGlobalTexture("_DepthBuffer", depthBufferId);
                buf.SetGlobalTexture("_NormalBuffer", normalBufferId);
                buf.SetRenderTarget
                (
                    new RenderTargetIdentifier[4]
                {
                    BuiltinRenderTextureType.GBuffer0,     // Diffuse
                    BuiltinRenderTextureType.GBuffer1,     // Specular + Roughness
                    BuiltinRenderTextureType.GBuffer2,     // World Normal
                    BuiltinRenderTextureType.GBuffer3      // Emission
                },
                    BuiltinRenderTextureType.CameraTarget  // Depth
                );

                buf.DrawMesh(quad, Matrix4x4.identity, _renderGBufferMat);
                buf.ReleaseTemporaryRT(depthBufferId);
                buf.ReleaseTemporaryRT(tempDepthBufferId);
                buf.ReleaseTemporaryRT(normalBufferId);
            }
        }
Exemplo n.º 2
0
        // アタッチされたレンダラー(MeshRenderer)がカメラに映っているときに呼び出される
        void OnWillRenderObject()
        {
            // 自身がアクティブでなければ解放処理をして、以降は何もしない
            var act = gameObject.activeInHierarchy && enabled;

            if (!act)
            {
                CleanUp();
                return;
            }
            // 現在レンダリング処理をしているカメラがなければ、以降は何もしない
            var cam = Camera.current;

            if (!cam)
            {
                return;
            }

            // 現在レンダリング処理をしているカメラに、CommandBufferがアタッチされていなければ
            if (!_cameras.ContainsKey(cam))
            {
                // CommandBufferの情報作成
                var buf = new CmdBufferInfo();
                buf.pass   = CameraEvent.BeforeGBuffer;
                buf.buffer = new CommandBuffer()
                {
                    name = "Screen Space Fluid Renderer"
                };
                // G-Bufferが生成される前のカメラのレンダリングパイプライン上のパスに、
                // 作成したCommandBufferを追加
                cam.AddCommandBuffer(buf.pass, buf.buffer);

                // CommandBufferを追加したカメラを管理するリストにカメラを追加
                _cameras.Add(cam, buf);
            }
            // CommandBuffer がアタッチされているならば
            else
            {
                // コマンドバッファを取得
                var buf = _cameras[cam].buffer;
                // コマンドバッファをクリア
                buf.Clear();

                // -----------------------------------------------------------------------------
                // 1. パーティクルをポイントスプライトとして描画し、深度とカラーのデータを得る
                // -----------------------------------------------------------------------------
                // デプスバッファのシェーダプロパティIDを取得
                int depthBufferId = Shader.PropertyToID("_DepthBuffer");
                // 一時的なRenderTextureを取得
                buf.GetTemporaryRT(depthBufferId, -1, -1, 24, FilterMode.Point, RenderTextureFormat.RFloat);

                // カラーバッファとデプスバッファをレンダーターゲットに指定
                buf.SetRenderTarget
                (
                    new RenderTargetIdentifier(depthBufferId),  // デプス
                    new RenderTargetIdentifier(depthBufferId)   // デプス書き込み用
                );
                // カラーバッファとデプスバッファをクリア
                buf.ClearRenderTarget(true, true, Color.clear);

                // パーティクルのサイズをセット
                _renderParticleDepthMaterial.SetFloat("_ParticleSize", _particleSize);
                // パーティクルのデータ(ComputeBuffer)をセット
                _renderParticleDepthMaterial.SetBuffer("_ParticleDataBuffer", _simScript.GetParticlesBuffer());

                // パーティクルをポイントスプライトとして描画
                buf.DrawProcedural
                (
                    Matrix4x4.identity,
                    _renderParticleDepthMaterial,
                    0,
                    MeshTopology.Points,
                    _simScript.GetParticleNum()
                );

                // -----------------------------------------------------------------------------
                // 2. デプスバッファにブラーをかける
                // -----------------------------------------------------------------------------
                // ブラーエフェクト計算に一時的に使用するバッファの作成
                var tempDepthBufferId = Shader.PropertyToID("_TempDepthBufferId");
                buf.GetTemporaryRT(tempDepthBufferId, -1, -1, 0, FilterMode.Trilinear, RenderTextureFormat.RFloat);
                // ブラーエフェクトのプロパティをセット
                _bilateralFilterBlurMaterial.SetFloat("_FilterRadius", _blurFilterRadius);
                _bilateralFilterBlurMaterial.SetFloat("_BlurScale", _blurScale);
                _bilateralFilterBlurMaterial.SetFloat("_BlurDepthFallOff", _blurDepthFallOff);
                // 水平方向のブラーを実行
                buf.SetGlobalVector("_BlurDir", new Vector2(1.0f, 0.0f));
                buf.Blit(depthBufferId, tempDepthBufferId, _bilateralFilterBlurMaterial);
                // 垂直方向のブラーを実行
                buf.SetGlobalVector("_BlurDir", new Vector2(0.0f, 1.0f));
                buf.Blit(tempDepthBufferId, depthBufferId, _bilateralFilterBlurMaterial);

                // -----------------------------------------------------------------------------
                // 3. デプスバッファから法線バッファを計算
                // -----------------------------------------------------------------------------
                // 法線バッファの作成
                int normalBufferId = Shader.PropertyToID("_NormalBuffer");
                buf.GetTemporaryRT(normalBufferId, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGBFloat);
                // 法線バッファをレンダーターゲットにセット
                buf.SetRenderTarget(normalBufferId);
                // クリア
                buf.ClearRenderTarget(false, true, Color.clear);
                // ビュー変換マトリックスをセット
                var view = cam.worldToCameraMatrix;
                _calcNormalMaterial.SetMatrix("_ViewMatrix", view);
                // デプスバッファをシェーダにセット
                buf.SetGlobalTexture("_DepthBuffer", depthBufferId);
                // デプスから法線をスクリーンスペースで計算
                buf.Blit(null, normalBufferId, _calcNormalMaterial);

                // -----------------------------------------------------------------------------
                // 4. 計算結果を G-Buffer に書き込みパーティクルを描画
                // -----------------------------------------------------------------------------
                buf.SetGlobalTexture("_NormalBuffer", normalBufferId); // 法線バッファをセット
                buf.SetGlobalTexture("_DepthBuffer", depthBufferId);   // デプスバッファをセット

                // プロパティをセット
                _renderGBufferMaterial.SetColor("_Diffuse", _diffuse);
                _renderGBufferMaterial.SetColor("_Specular", new Vector4(_specular.r, _specular.g, _specular.b, 1.0f - _roughness));
                _renderGBufferMaterial.SetColor("_Emission", _emission);

                // G-Buffer を レンダーターゲットにセット
                buf.SetRenderTarget
                (
                    new RenderTargetIdentifier[4]
                {
                    BuiltinRenderTextureType.GBuffer0,     // Diffuse
                    BuiltinRenderTextureType.GBuffer1,     // Specular + Roughness
                    BuiltinRenderTextureType.GBuffer2,     // World Normal
                    BuiltinRenderTextureType.GBuffer3      // Emission
                },
                    BuiltinRenderTextureType.CameraTarget  // Depth
                );
                // G-Bufferに書き込み
                buf.DrawMesh(quad, Matrix4x4.identity, _renderGBufferMaterial);

                // -----------------------------------------------------------------------------
                // 一時的に作成したRenderTextureを解放
                buf.ReleaseTemporaryRT(depthBufferId);
                buf.ReleaseTemporaryRT(tempDepthBufferId);
                buf.ReleaseTemporaryRT(normalBufferId);
            }
        }