private void DoDepthOfField(RenderTexture source, RenderTexture destination)
        {
            float radiusAdjustement = source.height / 720f;

            float textureBokehScale     = radiusAdjustement;
            float textureBokehMaxRadius = textureBokehScale * 30f;

            float nearBlurRadius = 40 * radiusAdjustement;
            float maxBlurRadius  = nearBlurRadius;

            maxBlurRadius *= 1.2f;
            if (maxBlurRadius < 0.5f)
            {
                Graphics.Blit(source, destination);
                return;
            }

            // Quarter resolution
            int rtW           = source.width / 2;
            int rtH           = source.height / 2;
            var blurrinessCoe = new Vector4(nearBlurRadius * 0.5f, nearBlurRadius * 0.5f, 0f, 0f);
            var colorAndCoc   = m_RTU.GetTemporaryRenderTexture(rtW, rtH);
            var colorAndCoc2  = m_RTU.GetTemporaryRenderTexture(rtW, rtH);

            // Downsample to Color + COC buffer
            Vector4 cocParam;
            Vector4 cocCoe;

            ComputeCocParameters(out cocParam, out cocCoe);
            filmicDepthOfFieldMaterial.SetVector(m_BlurParams, cocParam);
            filmicDepthOfFieldMaterial.SetVector(m_BlurCoe, cocCoe);
            Graphics.Blit(source, colorAndCoc2, filmicDepthOfFieldMaterial, (int)Passes.CaptureCocExplicit);
            var src = colorAndCoc2;
            var dst = colorAndCoc;

            // Collect texture bokeh candidates and replace with a darker pixel
            if (shouldPerformBokeh)
            {
                // Blur a bit so we can do a frequency check
                var blurred = m_RTU.GetTemporaryRenderTexture(rtW, rtH);
                Graphics.Blit(src, blurred, filmicDepthOfFieldMaterial, (int)Passes.BoxBlur);
                filmicDepthOfFieldMaterial.SetVector(m_Offsets, new Vector4(0f, 1.5f, 0f, 1.5f));
                Graphics.Blit(blurred, dst, filmicDepthOfFieldMaterial, (int)Passes.BlurAlphaWeighted);
                filmicDepthOfFieldMaterial.SetVector(m_Offsets, new Vector4(1.5f, 0f, 0f, 1.5f));
                Graphics.Blit(dst, blurred, filmicDepthOfFieldMaterial, (int)Passes.BlurAlphaWeighted);

                // Collect texture bokeh candidates and replace with a darker pixel
                textureBokehMaterial.SetTexture(m_BlurredColor, blurred);
                textureBokehMaterial.SetFloat(m_SpawnHeuristic, bokehTexture.spawnHeuristic);
                textureBokehMaterial.SetVector(m_BokehParams, new Vector4(bokehTexture.scale * textureBokehScale, bokehTexture.intensity, bokehTexture.threshold, textureBokehMaxRadius));
                Graphics.SetRandomWriteTarget(1, computeBufferPoints);
                Graphics.Blit(src, dst, textureBokehMaterial, (int)BokehTexturesPasses.Collect);
                Graphics.ClearRandomWriteTargets();
                SwapRenderTexture(ref src, ref dst);
                m_RTU.ReleaseTemporaryRenderTexture(blurred);
            }

            filmicDepthOfFieldMaterial.SetVector(m_BlurParams, cocParam);
            filmicDepthOfFieldMaterial.SetVector(m_BlurCoe, blurrinessCoe);

            // Dilate near blur factor
            RenderTexture blurredFgCoc = null;

            var blurredFgCoc2 = m_RTU.GetTemporaryRenderTexture(rtW, rtH, 0, RenderTextureFormat.RGHalf);

            blurredFgCoc = m_RTU.GetTemporaryRenderTexture(rtW, rtH, 0, RenderTextureFormat.RGHalf);
            filmicDepthOfFieldMaterial.SetVector(m_Offsets, new Vector4(0f, nearBlurRadius * 0.75f, 0f, 0f));
            Graphics.Blit(src, blurredFgCoc2, filmicDepthOfFieldMaterial, (int)Passes.DilateFgCocFromColor);
            filmicDepthOfFieldMaterial.SetVector(m_Offsets, new Vector4(nearBlurRadius * 0.75f, 0f, 0f, 0f));
            Graphics.Blit(blurredFgCoc2, blurredFgCoc, filmicDepthOfFieldMaterial, (int)Passes.DilateFgCoc);
            m_RTU.ReleaseTemporaryRenderTexture(blurredFgCoc2);
            blurredFgCoc.filterMode = FilterMode.Point;

            Graphics.Blit(src, dst, filmicDepthOfFieldMaterial, (int)Passes.CocPrefilter);
            SwapRenderTexture(ref src, ref dst);

            DoHexagonalBlur(blurredFgCoc, ref src, ref dst, maxBlurRadius);



            // Smooth result

            Graphics.Blit(src, dst, medianFilterMaterial, (int)MedianPasses.Median3X3);
            SwapRenderTexture(ref src, ref dst);
            // Merge to full resolution (with boost) + upsampling (linear or bicubic)
            filmicDepthOfFieldMaterial.SetVector(m_BlurCoe, blurrinessCoe);
            filmicDepthOfFieldMaterial.SetVector(m_Convolved_TexelSize, new Vector4(src.width, src.height, 1f / src.width, 1f / src.height));
            filmicDepthOfFieldMaterial.SetTexture(m_SecondTex, src);
            int mergePass = (int)Passes.MergeExplicit;

            // Apply texture bokeh
            if (shouldPerformBokeh)
            {
                var tmp = m_RTU.GetTemporaryRenderTexture(source.height, source.width, 0, source.format);
                Graphics.Blit(source, tmp, filmicDepthOfFieldMaterial, mergePass);

                Graphics.SetRenderTarget(tmp);
                ComputeBuffer.CopyCount(computeBufferPoints, computeBufferDrawArgs, 0);
                textureBokehMaterial.SetBuffer(pointBuffer, computeBufferPoints);
                textureBokehMaterial.SetTexture(m_MainTex, bokehTexture.texture);
                textureBokehMaterial.SetVector(m_Screen, new Vector3(1f / (1f * source.width), 1f / (1f * source.height), textureBokehMaxRadius));
                textureBokehMaterial.SetPass((int)BokehTexturesPasses.Apply);
                Graphics.DrawProceduralIndirect(MeshTopology.Points, computeBufferDrawArgs, 0);
                Graphics.Blit(tmp, destination); // Hackaround for DX11 flipfun (OPTIMIZEME)
            }
            else
            {
                Graphics.Blit(source, destination, filmicDepthOfFieldMaterial, mergePass);
            }
        }
Beispiel #2
0
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (!this.enabled)
        {
            Graphics.Blit(source, destination);
            return;
        }

        material.shaderKeywords = null;

        if (this.enabled)
        {
            material.SetColor("_VignetteColor", this.color);

            if (this.blur > 0f)
            {
                // Downscale + gaussian blur (2 passes)
                int w   = source.width / 2;
                int h   = source.height / 2;
                var rt1 = m_RTU.GetTemporaryRenderTexture(w, h, 0, source.format);
                var rt2 = m_RTU.GetTemporaryRenderTexture(w, h, 0, source.format);

                material.SetVector("_BlurPass", new Vector2(1f / w, 0f));
                Graphics.Blit(source, rt1, material, (int)Pass.BlurPrePass);

                material.SetVector("_BlurPass", new Vector2(0f, 1f / h));
                Graphics.Blit(rt1, rt2, material, (int)Pass.BlurPrePass);

                material.SetVector("_BlurPass", new Vector2(1f / w, 0f));
                Graphics.Blit(rt2, rt1, material, (int)Pass.BlurPrePass);
                material.SetVector("_BlurPass", new Vector2(0f, 1f / h));
                Graphics.Blit(rt1, rt2, material, (int)Pass.BlurPrePass);

                material.SetTexture("_BlurTex", rt2);
                material.SetFloat("_VignetteBlur", this.blur * 3f);
                material.EnableKeyword("VIGNETTE_BLUR");
            }

            if (this.desaturate > 0f)
            {
                material.EnableKeyword("VIGNETTE_DESAT");
                material.SetFloat("_VignetteDesat", 1f - this.desaturate);
            }

            material.SetVector("_VignetteCenter", this.center);

            if (Mathf.Approximately(this.roundness, 1f))
            {
                material.EnableKeyword("VIGNETTE_CLASSIC");
                material.SetVector("_VignetteSettings", new Vector2(this.intensity, this.smoothness));
            }
            else
            {
                material.EnableKeyword("VIGNETTE_FILMIC");
                float roundness = (1f - this.roundness) * 6f + this.roundness;
                material.SetVector("_VignetteSettings", new Vector3(this.intensity, this.smoothness, roundness));
            }
        }

        Graphics.Blit(source, destination, material, 1);

        m_RTU.ReleaseAllTemporaryRenderTextures();
    }