//后处理CommandBuffer void BuildCommandBuffer() { afterOpaque.Clear(); //抓取深度图 if (useDepthTexture) { afterOpaque.BeginSample("Copy Depth"); afterOpaque.GetTemporaryRT(ShaderIDs.CameraDepthTex, m_Width, m_Height, 0, FilterMode.Point, RenderTextureFormat.R16); afterOpaque.CopyDepthTexture(cameraDepthTarget.depthBuffer, ShaderIDs.CameraDepthTex, RuntimeUtilities.copyDepthMat); afterOpaque.SetGlobalTexture(ShaderIDs.CameraDepthTex, ShaderIDs.CameraDepthTex); afterOpaque.ReleaseTemporaryRT(ShaderIDs.CameraDepthTex); afterOpaque.EndSample("Copy Depth"); } //抓取颜色图 if (UseColorTexture) { afterOpaque.BeginSample("Copy Color"); afterOpaque.GetTemporaryRT(ShaderIDs.CameraColorTex, m_Width, m_Height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32); afterOpaque.CopyColorTexture(cameraColorTarget.colorBuffer, ShaderIDs.CameraColorTex, RuntimeUtilities.copyColorMat); afterOpaque.SetGlobalTexture(ShaderIDs.CameraColorTex, ShaderIDs.CameraColorTex); afterOpaque.ReleaseTemporaryRT(ShaderIDs.CameraColorTex); afterOpaque.EndSample("Copy Color"); } //后处理 beforImageEffect.Clear(); uberMat = materialFactory.Get(Resource.uber); bloom.UpdateSettings(BloomIntensity, BloomThreshold, BloomDiffusion, BloomSoftKnee); bloom.Render(materialFactory, Resource.bloom, UseBloom, beforImageEffect, cameraColorTarget, uberMat, m_Width, m_Height, hdrFormat); colorGrading.Render(UseColorGrading, uberMat, LutTex2D); screenDistort.Render(UseScreenDistort, uberMat, DistortIntensity, DistortSpeedX, DistortSpeedY, DistortDensity, Resource.distortTex); //混合后处理结果 beforImageEffect.BeginSample("Uber"); if (UseToneMapping) { uberMat.EnableKeyword("ACES_TONEMAPPING"); } else { uberMat.DisableKeyword("ACES_TONEMAPPING"); } //抗锯齿 if (UseFXAA) { uberMat.SetFloat(ShaderIDs.UseFXAA, 1); fxaaMat = materialFactory.Get(Resource.fxaa); beforImageEffect.GetTemporaryRT(ShaderIDs.FXAASourceTex, m_Width, m_Height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32); beforImageEffect.BlitColorWithFullScreenTriangle(cameraColorTarget, ShaderIDs.FXAASourceTex, uberMat, 1); beforImageEffect.EndSample("Uber"); beforImageEffect.BeginSample("FXAA"); beforImageEffect.BlitColorWithFullScreenTriangle(ShaderIDs.FXAASourceTex, BuiltinRenderTextureType.CameraTarget, fxaaMat, 0); beforImageEffect.ReleaseTemporaryRT(ShaderIDs.FXAASourceTex); beforImageEffect.EndSample("FXAA"); } else { uberMat.SetFloat(ShaderIDs.UseFXAA, 0); beforImageEffect.BlitColorWithFullScreenTriangle(cameraColorTarget, BuiltinRenderTextureType.CameraTarget, uberMat, 0); beforImageEffect.EndSample("Uber"); } }
public void Render(MaterialFactory materialFactory, Shader shader, bool bloom, CommandBuffer cmd, RenderTargetIdentifier source, Material uberMat, int sourceWidth, int sourceHeight, RenderTextureFormat rtFormat) { if (intensity <= 0.01f || !bloom) { uberMat.DisableKeyword("BLOOM"); return; } bloomMat = materialFactory.Get(shader); cmd.BeginSample("Bloom"); // 从半分辨率RT开始 int tw = sourceWidth >> 1; int th = sourceHeight >> 1; // 计算迭代次数 int s = Mathf.Max(tw, th); float logs = Mathf.Log(s, 2f) + Mathf.Min(diffusion, 10f) - 10f; int logs_i = Mathf.FloorToInt(logs); int iterations = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize); float sampleScale = 0.5f + logs - logs_i; bloomMat.SetFloat(ShaderIDs.SampleScale, sampleScale); // 设置预过滤参数, 用于提取画面中高于阈值的亮度 float lthresh = Mathf.GammaToLinearSpace(threshold); float knee = lthresh * softKnee + 1e-5f; Vector4 thresholdV = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee); bloomMat.SetVector(ShaderIDs.Threshold, thresholdV); // 使用连续降采样+升采样的方式进行模糊 // 降采样, 第一次循环为预过滤pass var lastDown = source; for (int i = 0; i < iterations; i++) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; int pass = (i == 0) ? 0 : 1; cmd.GetTemporaryRT(mipDown, tw >> i, th >> i, 0, FilterMode.Bilinear, rtFormat); cmd.GetTemporaryRT(mipUp, tw >> i, th >> i, 0, FilterMode.Bilinear, rtFormat); cmd.BlitColorWithFullScreenTriangle(lastDown, mipDown, bloomMat, pass); lastDown = mipDown; } // 升采样 int lastUp = m_Pyramid[iterations - 1].down; for (int i = iterations - 2; i >= 0; i--) { int mipDown = m_Pyramid[i].down; int mipUp = m_Pyramid[i].up; cmd.SetGlobalTexture(ShaderIDs.BloomTex, mipDown); cmd.BlitColorWithFullScreenTriangle(lastUp, mipUp, bloomMat, 2); lastUp = mipUp; } // 给Uber传递bloom结果 uberMat.EnableKeyword("BLOOM"); intensity = RuntimeUtilities.Exp2(intensity / 10f) - 1f; uberMat.SetFloat(ShaderIDs.BloomIntensity, intensity); uberMat.SetFloat(ShaderIDs.SampleScale, sampleScale); cmd.SetGlobalTexture(ShaderIDs.BloomTex, lastUp); // 释放rt for (int i = 0; i < iterations; i++) { if (m_Pyramid[i].down != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].down); } if (m_Pyramid[i].up != lastUp) { cmd.ReleaseTemporaryRT(m_Pyramid[i].up); } } cmd.EndSample("Bloom"); }