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); } }
// アタッチされたレンダラー(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); } }