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(); }
private void OnDisable() { if (m_Material != null) { DestroyImmediate(m_Material); } m_Material = null; m_RTU.ReleaseAllTemporaryRenderTextures(); }
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(); }