private void OnEnable() { if (materialFactory == null) { materialFactory = new MaterialFactory(); } if (bloom == null) { bloom = new Bloom(); } if (colorGrading == null) { colorGrading = new ColorGrading(); } if (screenDistort == null) { screenDistort = new ScreenDistort(); } Init(); }
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"); }