示例#1
0
        private void OnDisable()
        {
            ReleaseComputeResources();

            if (m_FilmicDepthOfFieldMaterial != null)
            {
                DestroyImmediate(m_FilmicDepthOfFieldMaterial);
            }

            if (m_TextureBokehMaterial != null)
            {
                DestroyImmediate(m_TextureBokehMaterial);
            }

            if (m_MedianFilterMaterial != null)
            {
                DestroyImmediate(m_MedianFilterMaterial);
            }

            m_FilmicDepthOfFieldMaterial = null;
            m_TextureBokehMaterial       = null;
            m_MedianFilterMaterial       = null;

            m_RTU.ReleaseAllTemporaryRenderTextures();
        }
示例#2
0
        private void OnDisable()
        {
            if (m_Material != null)
            {
                DestroyImmediate(m_Material);
            }

            m_Material = null;
            m_RTU.ReleaseAllTemporaryRenderTextures();
        }
示例#3
0
        public void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if (material == null)
            {
                Graphics.Blit(source, destination);
                return;
            }
            if (m_HasInformationFromPreviousFrame)
            {
                m_HasInformationFromPreviousFrame = (m_PreviousDepthBuffer != null) &&
                                                    (source.width == m_PreviousDepthBuffer.width) &&
                                                    (source.height == m_PreviousDepthBuffer.height);
            }
            bool doTemporalFilterThisFrame = m_HasInformationFromPreviousFrame && settings.advancedSettings.temporalFilterStrength > 0.0;

            m_HasInformationFromPreviousFrame = false;

            // Not using deferred shading? Just blit source to destination.
            if (Camera.current.actualRenderingPath != RenderingPath.DeferredShading)
            {
                Graphics.Blit(source, destination);
                return;
            }

            var rtW = source.width;
            var rtH = source.height;

            // RGB: Normals, A: Roughness.
            // Has the nice benefit of allowing us to control the filtering mode as well.
            RenderTexture bilateralKeyTexture = m_RTU.GetTemporaryRenderTexture(rtW, rtH, 0, RenderTextureFormat.ARGB32);

            bilateralKeyTexture.filterMode = FilterMode.Point;
            Graphics.Blit(source, bilateralKeyTexture, material, (int)PassIndex.BilateralKeyPack);
            material.SetTexture("_NormalAndRoughnessTexture", bilateralKeyTexture);

            float sWidth  = source.width;
            float sHeight = source.height;

            Vector2 sourceToTempUV = new Vector2(sWidth / rtW, sHeight / rtH);

            int downsampleAmount = (settings.advancedSettings.resolution == SSRResolution.FullResolution) ? 1 : 2;

            rtW = rtW / downsampleAmount;
            rtH = rtH / downsampleAmount;

            material.SetVector("_SourceToTempUV", new Vector4(sourceToTempUV.x, sourceToTempUV.y, 1.0f / sourceToTempUV.x, 1.0f / sourceToTempUV.y));


            Matrix4x4 P        = GetComponent <Camera>().projectionMatrix;
            Vector4   projInfo = new Vector4
                                     ((-2.0f / (sWidth * P[0])),
                                     (-2.0f / (sHeight * P[5])),
                                     ((1.0f - P[2]) / P[0]),
                                     ((1.0f + P[6]) / P[5]));

            /** The height in pixels of a 1m object if viewed from 1m away. */
            float pixelsPerMeterAtOneMeter = sWidth / (-2.0f * (float)(Math.Tan(GetComponent <Camera>().fieldOfView / 180.0 * Math.PI * 0.5)));

            material.SetFloat("_PixelsPerMeterAtOneMeter", pixelsPerMeterAtOneMeter);


            float sx = sWidth / 2.0f;
            float sy = sHeight / 2.0f;

            Matrix4x4 warpToScreenSpaceMatrix = new Matrix4x4();

            warpToScreenSpaceMatrix.SetRow(0, new Vector4(sx, 0.0f, 0.0f, sx));
            warpToScreenSpaceMatrix.SetRow(1, new Vector4(0.0f, sy, 0.0f, sy));
            warpToScreenSpaceMatrix.SetRow(2, new Vector4(0.0f, 0.0f, 1.0f, 0.0f));
            warpToScreenSpaceMatrix.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));

            Matrix4x4 projectToPixelMatrix = warpToScreenSpaceMatrix * P;

            material.SetVector("_ScreenSize", new Vector2(sWidth, sHeight));
            material.SetVector("_ReflectionBufferSize", new Vector2(rtW, rtH));
            Vector2 invScreenSize = new Vector2((float)(1.0 / sWidth), (float)(1.0 / sHeight));

            Matrix4x4 worldToCameraMatrix = GetComponent <Camera>().worldToCameraMatrix;
            Matrix4x4 cameraToWorldMatrix = GetComponent <Camera>().worldToCameraMatrix.inverse;

            material.SetVector("_InvScreenSize", invScreenSize);
            material.SetVector("_ProjInfo", projInfo); // used for unprojection
            material.SetMatrix("_ProjectToPixelMatrix", projectToPixelMatrix);
            material.SetMatrix("_WorldToCameraMatrix", worldToCameraMatrix);
            material.SetMatrix("_CameraToWorldMatrix", cameraToWorldMatrix);
            material.SetInt("_EnableRefine", settings.advancedSettings.reduceBanding ? 1 : 0);
            material.SetInt("_AdditiveReflection", settings.basicSettings.additiveReflection ? 1 : 0);
            material.SetInt("_ImproveCorners", settings.advancedSettings.improveCorners ? 1 : 0);
            material.SetFloat("_ScreenEdgeFading", settings.basicSettings.screenEdgeFading);
            material.SetFloat("_MipBias", mipBias);
            material.SetInt("_UseOcclusion", useOcclusion ? 1 : 0);
            material.SetInt("_BilateralUpsampling", settings.advancedSettings.bilateralUpsample ? 1 : 0);
            material.SetInt("_FallbackToSky", fallbackToSky ? 1 : 0);
            material.SetInt("_TreatBackfaceHitAsMiss", settings.advancedSettings.treatBackfaceHitAsMiss ? 1 : 0);
            material.SetInt("_AllowBackwardsRays", settings.advancedSettings.allowBackwardsRays ? 1 : 0);
            material.SetInt("_TraceEverywhere", settings.advancedSettings.traceEverywhere ? 1 : 0);

            float z_f = GetComponent <Camera>().farClipPlane;
            float z_n = GetComponent <Camera>().nearClipPlane;

            Vector3 cameraClipInfo = (float.IsPositiveInfinity(z_f)) ?
                                     new Vector3(z_n, -1.0f, 1.0f) :
                                     new Vector3(z_n * z_f, z_n - z_f, z_f);

            material.SetVector("_CameraClipInfo", cameraClipInfo);
            material.SetFloat("_MaxRayTraceDistance", settings.basicSettings.maxDistance);
            material.SetFloat("_FadeDistance", settings.basicSettings.fadeDistance);
            material.SetFloat("_LayerThickness", settings.reflectionSettings.widthModifier);

            const int maxMip = 5;

            RenderTexture[]     reflectionBuffers;
            RenderTextureFormat intermediateFormat = settings.basicSettings.enableHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;

            reflectionBuffers = new RenderTexture[maxMip];
            for (int i = 0; i < maxMip; ++i)
            {
                if (fullResolutionFiltering)
                {
                    reflectionBuffers[i] = m_RTU.GetTemporaryRenderTexture(rtW, rtH, 0, intermediateFormat);
                }
                else
                {
                    reflectionBuffers[i] = m_RTU.GetTemporaryRenderTexture(rtW >> i, rtH >> i, 0, intermediateFormat);
                }
                // We explicitly interpolate during bilateral upsampling.
                reflectionBuffers[i].filterMode = settings.advancedSettings.bilateralUpsample ? FilterMode.Point : FilterMode.Bilinear;
            }

            material.SetInt("_EnableSSR", 1);
            material.SetInt("_DebugMode", (int)settings.debugSettings.debugMode);

            material.SetInt("_TraceBehindObjects", settings.advancedSettings.traceBehindObjects ? 1 : 0);

            material.SetInt("_MaxSteps", settings.reflectionSettings.maxSteps);

            RenderTexture rayHitTexture = m_RTU.GetTemporaryRenderTexture(rtW, rtH);

            // We have 5 passes for different step sizes
            int tracePass = Mathf.Clamp(settings.reflectionSettings.rayStepSize, 0, 4);

            Graphics.Blit(source, rayHitTexture, material, tracePass);

            material.SetTexture("_HitPointTexture", rayHitTexture);
            // Resolve the hitpoints into the mirror reflection buffer
            Graphics.Blit(source, reflectionBuffers[0], material, (int)PassIndex.HitPointToReflections);

            material.SetTexture("_ReflectionTexture0", reflectionBuffers[0]);
            material.SetInt("_FullResolutionFiltering", fullResolutionFiltering ? 1 : 0);

            material.SetFloat("_MaxRoughness", 1.0f - settings.reflectionSettings.smoothFallbackThreshold);
            material.SetFloat("_RoughnessFalloffRange", settings.reflectionSettings.smoothFallbackDistance);

            material.SetFloat("_SSRMultiplier", settings.basicSettings.reflectionMultiplier);

            RenderTexture[] edgeTextures = new RenderTexture[maxMip];
            if (settings.advancedSettings.bilateralUpsample && useEdgeDetector)
            {
                edgeTextures[0] = m_RTU.GetTemporaryRenderTexture(rtW, rtH);
                Graphics.Blit(source, edgeTextures[0], material, (int)PassIndex.EdgeGeneration);
                for (int i = 1; i < maxMip; ++i)
                {
                    edgeTextures[i] = m_RTU.GetTemporaryRenderTexture(rtW >> i, rtH >> i);
                    material.SetInt("_LastMip", i - 1);
                    Graphics.Blit(edgeTextures[i - 1], edgeTextures[i], material, (int)PassIndex.MinMipGeneration);
                }
            }

            if (settings.advancedSettings.highQualitySharpReflections)
            {
                RenderTexture filteredReflections = m_RTU.GetTemporaryRenderTexture(reflectionBuffers[0].width, reflectionBuffers[0].height, 0, reflectionBuffers[0].format);
                filteredReflections.filterMode  = reflectionBuffers[0].filterMode;
                reflectionBuffers[0].filterMode = FilterMode.Bilinear;
                Graphics.Blit(reflectionBuffers[0], filteredReflections, material, (int)PassIndex.PoissonBlur);

                // Replace the unfiltered buffer with the newly filtered one.
                m_RTU.ReleaseTemporaryRenderTexture(reflectionBuffers[0]);
                reflectionBuffers[0] = filteredReflections;
                material.SetTexture("_ReflectionTexture0", reflectionBuffers[0]);
            }

            // Generate the blurred low-resolution buffers
            for (int i = 1; i < maxMip; ++i)
            {
                RenderTexture inputTex = reflectionBuffers[i - 1];

                RenderTexture hBlur;
                if (fullResolutionFiltering)
                {
                    hBlur = m_RTU.GetTemporaryRenderTexture(rtW, rtH, 0, intermediateFormat);
                }
                else
                {
                    int lowMip = i;
                    hBlur = m_RTU.GetTemporaryRenderTexture(rtW >> lowMip, rtH >> (i - 1), 0, intermediateFormat);
                }
                for (int j = 0; j < (fullResolutionFiltering ? (i * i) : 1); ++j)
                {
                    // Currently we blur at the resolution of the previous mip level, we could save bandwidth by blurring directly to the lower resolution.
                    material.SetVector("_Axis", new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
                    material.SetFloat("_CurrentMipLevel", i - 1.0f);

                    Graphics.Blit(inputTex, hBlur, material, (int)PassIndex.Blur);

                    material.SetVector("_Axis", new Vector4(0.0f, 1.0f, 0.0f, 0.0f));

                    inputTex = reflectionBuffers[i];
                    Graphics.Blit(hBlur, inputTex, material, (int)PassIndex.Blur);
                }

                material.SetTexture("_ReflectionTexture" + i, reflectionBuffers[i]);

                m_RTU.ReleaseTemporaryRenderTexture(hBlur);
            }


            if (settings.advancedSettings.bilateralUpsample && useEdgeDetector)
            {
                for (int i = 0; i < maxMip; ++i)
                {
                    material.SetTexture("_EdgeTexture" + i, edgeTextures[i]);
                }
            }
            material.SetInt("_UseEdgeDetector", useEdgeDetector ? 1 : 0);

            RenderTexture averageRayDistanceBuffer = m_RTU.GetTemporaryRenderTexture(source.width, source.height, 0, RenderTextureFormat.RHalf);

            if (computeAverageRayDistance)
            {
                Graphics.Blit(source, averageRayDistanceBuffer, material, (int)PassIndex.AverageRayDistanceGeneration);
            }
            material.SetInt("_UseAverageRayDistance", computeAverageRayDistance ? 1 : 0);
            material.SetTexture("_AverageRayDistanceBuffer", averageRayDistanceBuffer);
            bool          resolveDiffersFromTraceRes = (settings.advancedSettings.resolution == SSRResolution.HalfTraceFullResolve);
            RenderTexture finalReflectionBuffer      = m_RTU.GetTemporaryRenderTexture(resolveDiffersFromTraceRes ? source.width : rtW, resolveDiffersFromTraceRes ? source.height : rtH, 0, intermediateFormat);

            material.SetFloat("_FresnelFade", settings.reflectionSettings.fresnelFade);
            material.SetFloat("_FresnelFadePower", settings.reflectionSettings.fresnelFadePower);
            material.SetFloat("_DistanceBlur", settings.reflectionSettings.distanceBlur);
            material.SetInt("_HalfResolution", (settings.advancedSettings.resolution != SSRResolution.FullResolution) ? 1 : 0);
            material.SetInt("_HighlightSuppression", settings.advancedSettings.highlightSuppression ? 1 : 0);
            Graphics.Blit(reflectionBuffers[0], finalReflectionBuffer, material, (int)PassIndex.CompositeSSR);
            material.SetTexture("_FinalReflectionTexture", finalReflectionBuffer);


            RenderTexture temporallyFilteredBuffer = m_RTU.GetTemporaryRenderTexture(resolveDiffersFromTraceRes ? source.width : rtW, resolveDiffersFromTraceRes ? source.height : rtH, 0, intermediateFormat);

            if (doTemporalFilterThisFrame)
            {
                material.SetInt("_UseTemporalConfidence", settings.advancedSettings.useTemporalConfidence ? 1 : 0);
                material.SetFloat("_TemporalAlpha", settings.advancedSettings.temporalFilterStrength);
                material.SetMatrix("_CurrentCameraToPreviousCamera", m_PreviousWorldToCameraMatrix * cameraToWorldMatrix);
                material.SetTexture("_PreviousReflectionTexture", m_PreviousReflectionBuffer);
                material.SetTexture("_PreviousCSZBuffer", m_PreviousDepthBuffer);
                Graphics.Blit(source, temporallyFilteredBuffer, material, (int)PassIndex.TemporalFilter);

                material.SetTexture("_FinalReflectionTexture", temporallyFilteredBuffer);
            }

            if (settings.advancedSettings.temporalFilterStrength > 0.0)
            {
                m_PreviousWorldToCameraMatrix = worldToCameraMatrix;
                PreparePreviousBuffers(source.width, source.height);
                Graphics.Blit(source, m_PreviousDepthBuffer, material, (int)PassIndex.BlitDepthAsCSZ);
                Graphics.Blit(rayHitTexture, m_PreviousHitBuffer);
                Graphics.Blit(doTemporalFilterThisFrame ? temporallyFilteredBuffer : finalReflectionBuffer, m_PreviousReflectionBuffer);

                m_HasInformationFromPreviousFrame = true;
            }


            Graphics.Blit(source, destination, material, (int)PassIndex.CompositeFinal);

            m_RTU.ReleaseAllTemporaryRenderTextures();
        }