public override void Render()

in unity/Assets/PostProcessingV2/Runtime/Effects/ScreenSpaceReflections.cs [115:232]


        public override void Render(PostProcessRenderContext context)
        {
            var cmd = context.command;
            cmd.BeginSample("Screen-space Reflections");

            // Get quality settings
            if (settings.preset.value != ScreenSpaceReflectionPreset.Custom)
            {
                int id = (int)settings.preset.value;
                settings.maximumIterationCount.value = m_Presets[id].maximumIterationCount;
                settings.thickness.value = m_Presets[id].thickness;
                settings.resolution.value = m_Presets[id].downsampling;
            }

            settings.maximumMarchDistance.value = Mathf.Max(0f, settings.maximumMarchDistance.value);

            // Square POT target
            int size = Mathf.ClosestPowerOfTwo(Mathf.Min(context.width, context.height));

            if (settings.resolution.value == ScreenSpaceReflectionResolution.Downsampled)
                size >>= 1;
            else if (settings.resolution.value == ScreenSpaceReflectionResolution.Supersampled)
                size <<= 1;

            // The gaussian pyramid compute works in blocks of 8x8 so make sure the last lod has a
            // minimum size of 8x8
            const int kMaxLods = 12;
            int lodCount = Mathf.FloorToInt(Mathf.Log(size, 2f) - 3f);
            lodCount = Mathf.Min(lodCount, kMaxLods);

            CheckRT(ref m_Resolve, size, size, context.sourceFormat, FilterMode.Trilinear, true);

            var noiseTex = context.resources.blueNoise256[0];
            var sheet = context.propertySheets.Get(context.resources.shaders.screenSpaceReflections);
            sheet.properties.SetTexture(ShaderIDs.Noise, noiseTex);

            var screenSpaceProjectionMatrix = new Matrix4x4();
            screenSpaceProjectionMatrix.SetRow(0, new Vector4(size * 0.5f, 0f, 0f, size * 0.5f));
            screenSpaceProjectionMatrix.SetRow(1, new Vector4(0f, size * 0.5f, 0f, size * 0.5f));
            screenSpaceProjectionMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
            screenSpaceProjectionMatrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f));

            var projectionMatrix = GL.GetGPUProjectionMatrix(context.camera.projectionMatrix, false);
            screenSpaceProjectionMatrix *= projectionMatrix;

            sheet.properties.SetMatrix(ShaderIDs.ViewMatrix, context.camera.worldToCameraMatrix);
            sheet.properties.SetMatrix(ShaderIDs.InverseViewMatrix, context.camera.worldToCameraMatrix.inverse);
            sheet.properties.SetMatrix(ShaderIDs.InverseProjectionMatrix, projectionMatrix.inverse);
            sheet.properties.SetMatrix(ShaderIDs.ScreenSpaceProjectionMatrix, screenSpaceProjectionMatrix);
            sheet.properties.SetVector(ShaderIDs.Params, new Vector4((float)settings.vignette.value, settings.distanceFade.value, settings.maximumMarchDistance.value, lodCount));
            sheet.properties.SetVector(ShaderIDs.Params2, new Vector4((float)context.width / (float)context.height, (float)size / (float)noiseTex.width, settings.thickness.value, settings.maximumIterationCount.value));

            cmd.GetTemporaryRT(ShaderIDs.Test, size, size, 0, FilterMode.Point, context.sourceFormat);
            cmd.BlitFullscreenTriangle(context.source, ShaderIDs.Test, sheet, (int)Pass.Test);

            if (context.isSceneView)
            {
                cmd.BlitFullscreenTriangle(context.source, m_Resolve, sheet, (int)Pass.Resolve);
            }
            else
            {
                CheckRT(ref m_History, size, size, context.sourceFormat, FilterMode.Bilinear, false);

                if (m_ResetHistory)
                {
                    context.command.BlitFullscreenTriangle(context.source, m_History);
                    m_ResetHistory = false;
                }

                cmd.GetTemporaryRT(ShaderIDs.SSRResolveTemp, size, size, 0, FilterMode.Bilinear, context.sourceFormat);
                cmd.BlitFullscreenTriangle(context.source, ShaderIDs.SSRResolveTemp, sheet, (int)Pass.Resolve);

                sheet.properties.SetTexture(ShaderIDs.History, m_History);
                cmd.BlitFullscreenTriangle(ShaderIDs.SSRResolveTemp, m_Resolve, sheet, (int)Pass.Reproject);

                cmd.CopyTexture(m_Resolve, 0, 0, m_History, 0, 0);

                cmd.ReleaseTemporaryRT(ShaderIDs.SSRResolveTemp);
            }

            cmd.ReleaseTemporaryRT(ShaderIDs.Test);

            // Pre-cache mipmaps ids
            if (m_MipIDs == null || m_MipIDs.Length == 0)
            {
                m_MipIDs = new int[kMaxLods];

                for (int i = 0; i < kMaxLods; i++)
                    m_MipIDs[i] = Shader.PropertyToID("_SSRGaussianMip" + i);
            }

            var compute = context.resources.computeShaders.gaussianDownsample;
            int kernel = compute.FindKernel("KMain");

            var last = new RenderTargetIdentifier(m_Resolve);

            for (int i = 0; i < lodCount; i++)
            {
                size >>= 1;
                Assert.IsTrue(size > 0);

                cmd.GetTemporaryRT(m_MipIDs[i], size, size, 0, FilterMode.Bilinear, context.sourceFormat, RenderTextureReadWrite.Default, 1, true);
                cmd.SetComputeTextureParam(compute, kernel, "_Source", last);
                cmd.SetComputeTextureParam(compute, kernel, "_Result", m_MipIDs[i]);
                cmd.SetComputeVectorParam(compute, "_Size", new Vector4(size, size, 1f / size, 1f / size));
                cmd.DispatchCompute(compute, kernel, size / 8, size / 8, 1);
                cmd.CopyTexture(m_MipIDs[i], 0, 0, m_Resolve, 0, i + 1);

                last = m_MipIDs[i];
            }

            for (int i = 0; i < lodCount; i++)
                cmd.ReleaseTemporaryRT(m_MipIDs[i]);

            sheet.properties.SetTexture(ShaderIDs.Resolve, m_Resolve);
            cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, (int)Pass.Composite);
            cmd.EndSample("Screen-space Reflections");
        }