From 211cf56619a905c8d09e8be064e2f75974c200cb Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Fri, 17 Jul 2020 08:39:50 +0200 Subject: [PATCH 01/41] Change reflection direction to match GGX --- .../ScreenSpaceReflections.compute | 36 +++++++++++++++++++ .../HDRenderPipeline.LightLoop.cs | 1 + .../RenderPipeline/HDRenderPipeline.cs | 7 ++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index cda7b28d741..e4dc9087fbe 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -35,6 +35,10 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingCommon.hlsl" + //-------------------------------------------------------------------------------------------------- // Inputs & outputs //-------------------------------------------------------------------------------------------------- @@ -151,8 +155,40 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // We start tracing from the center of the current pixel, and do so up to the far plane. float3 rayOrigin = float3(positionSS + 0.5, deviceDepth); +#if 0 // TODO: this does not match GGX. float3 R = reflect(-V, N); +#else + // Pick which subpixel we will be launching our effects from + float subPixelSample = GetBNDSequenceSample(positionSS, _RaytracingFrameIndex, 3); + int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3); + uint2 shift = HalfResIndexToCoordinateShift[subPixel]; + + //// Pixel where we will store the result of the raytracing + //uint2 outputCoord = halfResCoord * 2; + + // Pixel coordinate in full res of the pixel that we will be using for our computation + uint2 sourceCoord = positionSS + shift; + + NormalData normalData; + DecodeFromNormalBuffer(sourceCoord, normalData); + + float3x3 localToWorld = GetLocalFrame(normalData.normalWS); + + // Compute the actual roughness + float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); + + // Generate the new sample (follwing values of the sequence) + int globalSampleIndex = _RaytracingFrameIndex; + float2 Xi; + Xi.x = GetBNDSequenceSample(positionSS, globalSampleIndex, 0); + Xi.y = GetBNDSequenceSample(positionSS, globalSampleIndex, 1); + + // Importance sample the direction + float3 R = float3(0.0, 0.0, 0.0); + float NdotL, NdotH, VdotH; + SampleGGXDir(Xi, V, localToWorld, roughness, R, NdotL, NdotH, VdotH); +#endif float3 reflPosWS = positionWS + R; float3 reflPosNDC = ComputeNormalizedDeviceCoordinatesWithZ(reflPosWS, UNITY_MATRIX_VP); // Jittered diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index a0ea0620acb..f8d2b399154 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -455,6 +455,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, (RenderSSRPassData data, RenderGraphContext context) => { RenderSSR(data.parameters, + GetBlueNoiseManager(), data.depthBuffer, data.depthPyramid, data.normalBuffer, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index fc95a564c36..7ca843f38a6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4577,6 +4577,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip } static void RenderSSR( in RenderSSRParameters parameters, + BlueNoise blueNoise, RTHandle depthTexture, RTHandle depthPyramid, RTHandle normalBuffer, @@ -4618,6 +4619,8 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeBufferParam(cs, parameters.tracingKernel, HDShaderIDs._CoarseStencilBuffer, coarseStencilBuffer); cmd.SetComputeBufferParam(cs, parameters.tracingKernel, HDShaderIDs._DepthPyramidMipLevelOffsets, parameters.offsetBufferData); + blueNoise.BindDitheredRNGData1SPP(cmd); + ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); cmd.DispatchCompute(cs, parameters.tracingKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); @@ -4664,7 +4667,7 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren RTHandle clearCoatMask = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffer(2) : TextureXR.GetBlackTexture(); var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), false); - RenderSSR(parameters, m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), m_SharedRTManager.GetMotionVectorsBuffer(), m_SsrHitPointTexture, + RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), m_SharedRTManager.GetMotionVectorsBuffer(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)), clearCoatMask, previousColorPyramid, m_SsrLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); @@ -4706,7 +4709,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Evaluate the screen space reflection for the transparent pixels var previousColorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), true); - RenderSSR(parameters, m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), m_SharedRTManager.GetMotionVectorsBuffer(), + RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), m_SharedRTManager.GetMotionVectorsBuffer(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); // If color pyramid was not valid, we bind a black texture From 3c309919341eb24d3f50b9f4a628dd2b6d8fb4cc Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 6 Aug 2020 16:08:58 +0200 Subject: [PATCH 02/41] local tmp --- .../ScreenSpaceReflections.compute | 26 +++++++++++++++++-- .../RenderPipeline/HDRenderPipeline.cs | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index e4dc9087fbe..492959f73de 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -343,7 +343,7 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // recompute it using the last value of 't', which would result in an overshoot. // It also needs to be precisely at the center of the pixel to avoid artifacts. float2 hitPositionNDC = floor(rayPos.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. - _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = hitPositionNDC; + _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, t, iterCount); } // If we do not hit anything, 'rayPos.xy' provides an indication where we stopped the search. @@ -388,6 +388,27 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre return; } +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + float deviceDepth0 = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; + float deviceDepth1 = LOAD_TEXTURE2D_X(_DepthTexture, hitPositionNDC).r; +#else + float deviceDepth0 = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; + float deviceDepth1 = LOAD_TEXTURE2D_X(_CameraDepthTexture, hitPositionNDC).r; +#endif + + bool killRay0 = deviceDepth0 == UNITY_RAW_FAR_CLIP_VALUE; + bool killRay1 = deviceDepth1 == UNITY_RAW_FAR_CLIP_VALUE; + + float2 positionNDC0 = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + + float3 position0WS = ComputeWorldSpacePosition(positionNDC0, deviceDepth0, UNITY_MATRIX_I_VP); + float3 position1WS = ComputeWorldSpacePosition(hitPositionNDC, deviceDepth1, UNITY_MATRIX_I_VP); + + float linearZ0 = Linear01Depth(deviceDepth0, _ZBufferParams); + float linearZ1 = Linear01Depth(deviceDepth1, _ZBufferParams); + + float allDist = abs(linearZ0 - linearZ1); + float3 N; float perceptualRoughness; GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); @@ -408,7 +429,8 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre opacity = isPosFin ? opacity : 0; // Use premultiplied alpha. - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1) * opacity; + //allDist + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f) * opacity; } #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 7180df08a4d..9ce665eadfa 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -731,7 +731,8 @@ void InitializeRenderTextures() if (settings.supportSSR) { // m_SsrDebugTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Debug_Texture"); - m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); + //m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); + m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); } From e4cf5e6c375827dc61ea031ebad194768168ab62 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Sat, 8 Aug 2020 01:18:54 +0200 Subject: [PATCH 03/41] Temp Denoise and Inpainting --- .../ScreenSpaceReflections.compute | 134 ++++++++++++------ .../Runtime/RenderPipeline/Camera/HDCamera.cs | 29 ++++ .../Camera/HDCameraFrameHistoryType.cs | 2 + .../Runtime/RenderPipeline/HDProfileId.cs | 1 + .../HDRenderPipeline.LightLoop.cs | 10 ++ .../RenderPipeline/HDRenderPipeline.cs | 74 +++++++--- .../RenderPipeline/HDStringConstants.cs | 16 ++- 7 files changed, 196 insertions(+), 70 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 492959f73de..bc9b409b6f0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -5,8 +5,9 @@ // #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 playstation xboxone vulkan metal switch -#pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE -#pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT +#pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE +#pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT +#pragma kernel ScreenSpaceReflectionsDenoiseInpainting SSR_DENOISE_INPAINTING #pragma multi_compile _ DEPTH_SOURCE_NOT_FROM_MIP_CHAIN @@ -63,10 +64,17 @@ TEXTURE2D_X(_DepthTexture); #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); - RW_TEXTURE2D_X(float2, _SsrHitPointTexture); -#else + RW_TEXTURE2D_X(float4, _SsrHitPointTexture); +#elif defined(SSR_REPROJECT) + TEXTURE2D_X( _SsrHitPointTexture); + //RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture + TEXTURE2D_X( _PrevSSRLightingTexture); + RW_TEXTURE2D_X(float4, _SSRAccumTexture); +#else // defined(SSR_DENOISE_INPAINTING) TEXTURE2D_X( _SsrHitPointTexture); + TEXTURE2D_X( _PrevSSRLightingTexture); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture + TEXTURE2D_X( _SSRAccumTexture); #endif TEXTURE2D_X( _SsrClearCoatMaskTexture); @@ -350,7 +358,7 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, WriteDebugInfo(positionSS, float4(rayPos.xy, iterCount, hit ? 1 : 0)); } -#else // SSR_REPROJECT +#elif defined(SSR_REPROJECT) float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) { @@ -365,20 +373,39 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre uint2 positionSS = dispatchThreadId.xy; // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? - float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS).xy; + float4 srcData = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS); - if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) - { - // Miss. - return; - } + float2 hitPositionNDC = srcData.xy; + + float3 N; + float perceptualRoughness; + GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + + // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. + float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + + float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); // TODO: it's important to account for occlusion/disocclusion to avoid artifacts in motion. // This would require keeping the depth buffer from the previous frame. float2 motionVectorNDC; DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; - float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float2 curFrameUV0 = hitPositionNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + //float3 color0 = SAMPLE_TEXTURE2D_X_LOD(_PrevSSRLightingTexture, s_trilinear_clamp_sampler, curFrameUV0, mipLevel).rgb; + //float opacity0 = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; + float4 prevData = _PrevSSRLightingTexture[COORD_TEXTURE2D_X(positionSS)]; + float3 color0 = prevData.rgb; + float opacity0 = prevData.a; + + if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) + { + // Miss. + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color0, 1.0f) * opacity0; + return; + } // TODO: optimize with max(). if ((prevFrameUV.x < 0) || (prevFrameUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || @@ -388,49 +415,72 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre return; } -#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN - float deviceDepth0 = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; - float deviceDepth1 = LOAD_TEXTURE2D_X(_DepthTexture, hitPositionNDC).r; -#else - float deviceDepth0 = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; - float deviceDepth1 = LOAD_TEXTURE2D_X(_CameraDepthTexture, hitPositionNDC).r; -#endif + // Note that the color pyramid uses it's own viewport scale, since it lives on the camera. - bool killRay0 = deviceDepth0 == UNITY_RAW_FAR_CLIP_VALUE; - bool killRay1 = deviceDepth1 == UNITY_RAW_FAR_CLIP_VALUE; + float2 curFrameNDC = prevFrameNDC; + float2 curFrameUV = curFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float2 positionNDC0 = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + float3 color = SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; + float opacity = EdgeOfScreenFade(curFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; - float3 position0WS = ComputeWorldSpacePosition(positionNDC0, deviceDepth0, UNITY_MATRIX_I_VP); - float3 position1WS = ComputeWorldSpacePosition(hitPositionNDC, deviceDepth1, UNITY_MATRIX_I_VP); + //color = lerp(color, color0, 0.5f); + color = (color + color0)*0.5f; + opacity = max(opacity, opacity0); - float linearZ0 = Linear01Depth(deviceDepth0, _ZBufferParams); - float linearZ1 = Linear01Depth(deviceDepth1, _ZBufferParams); + // Disable SSR for negative, infinite and NaN history values. + uint3 intCol = asuint(color); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; - float allDist = abs(linearZ0 - linearZ1); + color = isPosFin ? color : 0; + opacity = isPosFin ? opacity : 0; + + // Use premultiplied alpha. + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f) * opacity; +} +#elif defined(SSR_DENOISE_INPAINTING) +float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) +{ + float t = Remap10(perceptualRoughness, fadeRcpLength, fadeEndTimesRcpLength); + return Smoothstep01(t); +} + +[numthreads(8, 8, 1)] +void ScreenSpaceReflectionsDenoiseInpainting(uint3 dispatchThreadId : SV_DispatchThreadID) +{ + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); + uint2 positionSS = dispatchThreadId.xy; float3 N; float perceptualRoughness; GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); - // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. - float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + float2 uv = float2(positionSS) * _RTHandleScale.xy;// _ColorPyramidUvScaleAndLimitPrevFrame.xy; - // Note that the color pyramid uses it's own viewport scale, since it lives on the camera. - float3 color = SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; - float opacity = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) - * PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + float dist = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)].z; - // Disable SSR for negative, infinite and NaN history values. - uint3 intCol = asuint(color); - bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; + float4 accum = 0; + int r = 5; + //float coef = rcp(float((2*r+1)*(2*r+1))); + float coef; + float sigma = lerp(5.0f, 5.0f, saturate(0.5f*saturate(dist/16.0f) + 0.5f*perceptualRoughness)); + float totalCoef = 0.0f; + for (int i = -r; i <= r; ++i) + { + for (int j = -r; j <= r; ++j) + { + coef = rcp(sqrt(2.0f*3.1415926538897932384626f)*sigma)*exp(-(i*i + j*j)/(2.0f*sigma*sigma)); + totalCoef += coef; + accum += coef*_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + } + } + accum /= totalCoef; - color = isPosFin ? color : 0; - opacity = isPosFin ? opacity : 0; + float4 prev = _PrevSSRLightingTexture[COORD_TEXTURE2D_X(positionSS)]; - // Use premultiplied alpha. - //allDist - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f) * opacity; -} + accum.rgb = lerp(accum.rgb, (accum.rgb + prev.rgb) * 0.5f, accum > 0.0f ? 0.0f : 1.0f); + //accum.rgb = (accum.rgb + prev.rgb) * 0.5f; + //accum.rgb = lerp(accum.rgb, (accum.rgb + prev.rgb) * 0.5f, prev.a); + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = accum; +} #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 6b6ac873486..e69e9b3d2a5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -711,6 +711,34 @@ internal void AllocateAmbientOcclusionHistoryBuffer(float scaleFactor) } } + #region Private API + // Workaround for the Allocator callback so it doesn't allocate memory because of the capture of scaleFactor. + struct ScreenSpaceAllocator + { + float scaleFactor; + + public ScreenSpaceAllocator(float scaleFactor) => this.scaleFactor = scaleFactor; + + public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSystem) + { + return rtHandleSystem.Alloc(Vector2.one * scaleFactor, TextureXR.slices, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, dimension: TextureXR.dimension, useDynamicScale: true, enableRandomWrite: true, name: string.Format("{0}_ScreenSpaceReflection history_{1}", id, frameIndex)); + } + } + #endregion + + internal void AllocateScreenSpaceHistoryBuffer(float scaleFactor) + { + if (scaleFactor != m_ScreenSpaceReflectionResolutionScale || GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection) == null) + { + ReleaseHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + + var ssrAlloc = new ScreenSpaceAllocator(scaleFactor); + AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection, ssrAlloc.Allocator, 3); + + m_ScreenSpaceReflectionResolutionScale = scaleFactor; + } + } + internal void ReleaseHistoryFrameRT(int id) { m_HistoryRTSystem.ReleaseBuffer(id); @@ -850,6 +878,7 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst int m_NumColorPyramidBuffersAllocated = 0; int m_NumVolumetricBuffersAllocated = 0; float m_AmbientOcclusionResolutionScale = 0.0f; // Factor used to track if history should be reallocated for Ambient Occlusion + float m_ScreenSpaceReflectionResolutionScale = 0.0f; // Need another factor if AO not used in the same time with SSR ViewConstants[] m_XRViewConstants; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 95c52429323..38a790aa51a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -23,6 +23,8 @@ public enum HDCameraFrameHistoryType Depth1, /// Ambient Occlusion buffer. AmbientOcclusion, + /// Screen Space Reflection buffer. + ScreenSpaceReflection, /// Ray traced ambient occlusion buffer. RaytracedAmbientOcclusion, /// Ray traced shadow history buffer. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index f6a7f5d17b2..372a99fb901 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -35,6 +35,7 @@ internal enum HDProfileId SubsurfaceScattering, SsrTracing, SsrReprojection, + SsrDenoiseInpainting, PrepareForTransparentSsr, SsgiPass, ForwardEmissive, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 65e2fd56781..295db7a9744 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -395,7 +395,9 @@ class RenderSSRPassData public TextureHandle colorPyramid; public TextureHandle stencilBuffer; public TextureHandle hitPointsTexture; + public TextureHandle ssrAccumPointTexture; public TextureHandle lightingTexture; + public TextureHandle prevLightingTexture; public TextureHandle clearCoatMask; public ComputeBufferHandle coarseStencilBuffer; //public TextureHandle debugTexture; @@ -454,6 +456,12 @@ TextureHandle RenderSSR( RenderGraph renderGraph, //passData.hitPointsTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) // { colorFormat = GraphicsFormat.ARGBFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Debug_Texture" })); + passData.ssrAccumPointTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Accum_Texture" })); + + var ssrPrevious = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection)); + passData.prevLightingTexture = builder.ReadTexture(ssrPrevious); + builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { @@ -467,7 +475,9 @@ TextureHandle RenderSSR( RenderGraph renderGraph, data.stencilBuffer, data.clearCoatMask, data.colorPyramid, + data.ssrAccumPointTexture, data.lightingTexture, + data.prevLightingTexture, data.coarseStencilBuffer, context.cmd, context.renderContext); }); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 9ce665eadfa..c75608f82cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -149,8 +149,9 @@ internal static Volume GetOrCreateDefaultVolume() IBLFilterBSDF[] m_IBLFilterArray = null; ComputeShader m_ScreenSpaceReflectionsCS { get { return defaultResources.shaders.screenSpaceReflectionsCS; } } - int m_SsrTracingKernel = -1; + int m_SsrTracingKernel = -1; int m_SsrReprojectionKernel = -1; + int m_SsrDenoiseInpaintingKernel = -1; Material m_ApplyDistortionMaterial; @@ -191,7 +192,8 @@ internal static Volume GetOrCreateDefaultVolume() // TODO: remove me, I am just a temporary debug texture. :-) // RTHandle m_SsrDebugTexture; RTHandle m_SsrHitPointTexture; - RTHandle m_SsrLightingTexture; + RTHandle m_SsrAccumPointTexture; + //RTHandle m_SsrLightingTexture; // MSAA Versions of regular textures RTHandle m_CameraColorMSAABuffer; RTHandle m_OpaqueAtmosphericScatteringMSAABuffer; // Necessary to perform dual-source (polychromatic alpha) blending which is not supported by Unity @@ -468,8 +470,9 @@ public HDRenderPipeline(HDRenderPipelineAsset asset, HDRenderPipelineAsset defau m_AmbientOcclusionSystem = new AmbientOcclusionSystem(asset, defaultResources); // Initialize various compute shader resources - m_SsrTracingKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsTracing"); + m_SsrTracingKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsTracing"); m_SsrReprojectionKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsReprojection"); + m_SsrDenoiseInpaintingKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsDenoiseInpainting"); // General material m_CameraMotionVectorsMaterial = CoreUtils.CreateEngineMaterial(defaultResources.shaders.cameraMotionVectorsPS); @@ -733,7 +736,8 @@ void InitializeRenderTextures() // m_SsrDebugTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Debug_Texture"); //m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); - m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); + m_SsrAccumPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Accum_Texture"); + //m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); } // Let's create the MSAA textures @@ -788,7 +792,7 @@ void DestroyRenderTextures() // RTHandles.Release(m_SsrDebugTexture); RTHandles.Release(m_SsrHitPointTexture); - RTHandles.Release(m_SsrLightingTexture); + //RTHandles.Release(m_SsrLightingTexture); RTHandles.Release(m_CameraColorMSAABuffer); RTHandles.Release(m_OpaqueAtmosphericScatteringMSAABuffer); @@ -1245,6 +1249,9 @@ void Resize(HDCamera hdCamera) m_DbufferManager.AllocResolutionDependentBuffers(m_MaxCameraWidth, m_MaxCameraHeight); m_SharedRTManager.AllocateCoarseStencilBuffer(m_MaxCameraWidth, m_MaxCameraHeight, hdCamera.viewCount); } + + if (hdCamera.IsSSREnabled()) + hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); } } @@ -4555,6 +4562,7 @@ struct RenderSSRParameters public ComputeShader ssrCS; public int tracingKernel; public int reprojectionKernel; + public int denoiseInpaintingKernel; public bool transparentSSR; public int width, height, viewCount; @@ -4572,6 +4580,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip parameters.ssrCS = m_ScreenSpaceReflectionsCS; parameters.tracingKernel = m_SsrTracingKernel; parameters.reprojectionKernel = m_SsrReprojectionKernel; + parameters.denoiseInpaintingKernel = m_SsrDenoiseInpaintingKernel; parameters.transparentSSR = transparentSSR; parameters.width = hdCamera.actualWidth; @@ -4613,7 +4622,9 @@ static void RenderSSR( in RenderSSRParameters parameters, RTHandle stencilBuffer, RTHandle clearCoatMask, RTHandle previousColorPyramid, + RTHandle ssrAccumPointTexture, RTHandle ssrLightingTexture, + RTHandle prevSSRLightingTexture, ComputeBuffer coarseStencilBuffer, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -4660,7 +4671,8 @@ static void RenderSSR( in RenderSSRParameters parameters, { // cmd.SetComputeTextureParam(cs, kernel, "_SsrDebugTexture", m_SsrDebugTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); @@ -4670,6 +4682,19 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.DispatchCompute(cs, parameters.reprojectionKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); } + + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrDenoiseInpainting))) + { + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); + + ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); + + cmd.DispatchCompute(cs, parameters.denoiseInpaintingKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + } } void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -4680,11 +4705,14 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren return; } + RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + var settings = hdCamera.volumeStack.GetComponent(); bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) { - RenderRayTracedReflections(hdCamera, cmd, m_SsrLightingTexture, renderContext, m_FrameCount); + RenderRayTracedReflections(hdCamera, cmd, ssrLightingTexture, renderContext, m_FrameCount); } else { @@ -4697,17 +4725,17 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)), clearCoatMask, previousColorPyramid, - m_SsrLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + m_SsrAccumPointTexture, ssrLightingTexture, prevSSRLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); - if (!hdCamera.colorPyramidHistoryIsValid) - { - cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, TextureXR.GetClearTexture()); - hdCamera.colorPyramidHistoryIsValid = true; // For the next frame... - } - } + if (!hdCamera.colorPyramidHistoryIsValid) + { + cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, TextureXR.GetClearTexture()); + hdCamera.colorPyramidHistoryIsValid = true; // For the next frame... + } + } - cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, m_SsrLightingTexture); - PushFullScreenDebugTexture(hdCamera, cmd, m_SsrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); + cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, ssrLightingTexture); + PushFullScreenDebugTexture(hdCamera, cmd, ssrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); } void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -4715,11 +4743,14 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender if (!hdCamera.IsSSREnabled(transparent: true)) return; + RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + var settings = hdCamera.volumeStack.GetComponent(); bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) { - RenderRayTracedReflections(hdCamera, cmd, m_SsrLightingTexture, renderContext, m_FrameCount, true); + RenderRayTracedReflections(hdCamera, cmd, ssrLightingTexture, renderContext, m_FrameCount, true); } else { @@ -4730,7 +4761,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.PrepareForTransparentSsr))) { // Clear the SSR lighting buffer (not sure it is required) - CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); + CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); } @@ -4739,7 +4770,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), true); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, - m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrAccumPointTexture, ssrLightingTexture, prevSSRLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); // If color pyramid was not valid, we bind a black texture if (!hdCamera.colorPyramidHistoryIsValid) @@ -4750,7 +4781,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender } // Push our texture to the debug menu - PushFullScreenDebugTexture(hdCamera, cmd, m_SsrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); + PushFullScreenDebugTexture(hdCamera, cmd, ssrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); } void RenderColorPyramid(HDCamera hdCamera, CommandBuffer cmd, bool isPreRefraction) @@ -5379,7 +5410,8 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) // and much faster than fully overwriting them from within SSR shaders. // CoreUtils.SetRenderTarget(cmd, hdCamera, m_SsrDebugTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); + RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index 1914f95ebeb..e217c586850 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -326,13 +326,15 @@ static class HDShaderIDs public static readonly int _NormalBufferTexture = Shader.PropertyToID("_NormalBufferTexture"); public static readonly int _RaytracePrepassBufferTexture = Shader.PropertyToID("_RaytracePrepassBufferTexture"); - public static readonly int _ShaderVariablesScreenSpaceReflection = Shader.PropertyToID("ShaderVariablesScreenSpaceReflection"); - public static readonly int _SsrLightingTexture = Shader.PropertyToID("_SsrLightingTexture"); - public static readonly int _SsrLightingTextureRW = Shader.PropertyToID("_SsrLightingTextureRW"); - public static readonly int _SsrHitPointTexture = Shader.PropertyToID("_SsrHitPointTexture"); - public static readonly int _SsrClearCoatMaskTexture = Shader.PropertyToID("_SsrClearCoatMaskTexture"); - public static readonly int _DepthPyramidMipLevelOffsets = Shader.PropertyToID("_DepthPyramidMipLevelOffsets"); - public static readonly int _DepthPyramidFirstMipLevelOffset = Shader.PropertyToID("_DepthPyramidFirstMipLevelOffset"); + public static readonly int _ShaderVariablesScreenSpaceReflection = Shader.PropertyToID("ShaderVariablesScreenSpaceReflection"); + public static readonly int _SsrLightingTexture = Shader.PropertyToID("_SsrLightingTexture"); + public static readonly int _SsrLightingTextureRW = Shader.PropertyToID("_SsrLightingTextureRW"); + public static readonly int _SSRAccumTexture = Shader.PropertyToID("_SSRAccumTexture"); + public static readonly int _PrevSSRLightingTexture = Shader.PropertyToID("_PrevSSRLightingTexture"); + public static readonly int _SsrHitPointTexture = Shader.PropertyToID("_SsrHitPointTexture"); + public static readonly int _SsrClearCoatMaskTexture = Shader.PropertyToID("_SsrClearCoatMaskTexture"); + public static readonly int _DepthPyramidMipLevelOffsets = Shader.PropertyToID("_DepthPyramidMipLevelOffsets"); + public static readonly int _DepthPyramidFirstMipLevelOffset = Shader.PropertyToID("_DepthPyramidFirstMipLevelOffset"); // Still used by ray tracing. From c28f92d30f241abb76796beb446f6983f6984b6c Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Sat, 22 Aug 2020 12:19:33 +0200 Subject: [PATCH 04/41] Backup remote work --- .../Runtime/Debug/DebugDisplay.cs | 4 +- .../Runtime/Lighting/LightLoop/LightLoop.cs | 2 +- .../ScreenSpaceReflections.compute | 397 ++++++++++++++++-- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 +- .../HDRenderPipeline.LightLoop.cs | 1 + .../RenderPipeline/HDRenderPipeline.cs | 24 +- 6 files changed, 396 insertions(+), 34 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 240d581cfa2..6a0ad1d1d46 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -59,6 +59,8 @@ public enum FullScreenDebugMode ScreenSpaceAmbientOcclusion, /// Display Screen Space Reflections buffer. ScreenSpaceReflections, + /// Display Screen Space Reflections buffer. + ScreenSpaceReflectionsAccum, /// Display the Transparent Screen Space Reflections buffer. TransparentScreenSpaceReflections, /// Display Contact Shadows buffer. @@ -1754,7 +1756,7 @@ internal bool DebugNeedsExposure() debugLighting == DebugLightingMode.DiffuseLighting || debugLighting == DebugLightingMode.SpecularLighting || debugLighting == DebugLightingMode.VisualizeCascade) || (data.lightingDebugSettings.overrideAlbedo || data.lightingDebugSettings.overrideNormal || data.lightingDebugSettings.overrideSmoothness || data.lightingDebugSettings.overrideSpecularColor || data.lightingDebugSettings.overrideEmissiveColor || data.lightingDebugSettings.overrideAmbientOcclusion) || (debugGBuffer == DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive) || (data.lightingDebugSettings.debugLightFilterMode != DebugLightFilterMode.None) || - (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || + (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || (debugLighting == DebugLightingMode.ProbeVolume || debugProbeVolume == ProbeVolumeDebugMode.VisualizeAtlas); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs index 425981847d7..c75e3e16f32 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs @@ -3589,7 +3589,7 @@ unsafe void UpdateShaderVariablesGlobalLightLoop(ref ShaderVariablesGlobal cb, H bool sunLightShadow = sunLightData != null && m_CurrentShadowSortedSunLightIndex >= 0; cb._DirectionalShadowIndex = sunLightShadow ? m_CurrentShadowSortedSunLightIndex : -1; cb._EnableLightLayers = hdCamera.frameSettings.IsEnabled(FrameSettingsField.LightLayers) ? 1u : 0u; - cb._EnableDecalLayers = hdCamera.frameSettings.IsEnabled(FrameSettingsField.DecalLayers) ? 1u : 0u; + cb._EnableDecalLayers = hdCamera.frameSettings.IsEnabled(FrameSettingsField.DecalLayers) ? 1u : 0u; cb._EnvLightSkyEnabled = m_SkyManager.IsLightingSkyValid(hdCamera) ? 1 : 0; const float C = (float)(1 << k_Log2NumClusters); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index bc9b409b6f0..5384203175b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -67,14 +67,14 @@ TEXTURE2D_X(_DepthTexture); RW_TEXTURE2D_X(float4, _SsrHitPointTexture); #elif defined(SSR_REPROJECT) TEXTURE2D_X( _SsrHitPointTexture); - //RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture + RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture TEXTURE2D_X( _PrevSSRLightingTexture); RW_TEXTURE2D_X(float4, _SSRAccumTexture); #else // defined(SSR_DENOISE_INPAINTING) TEXTURE2D_X( _SsrHitPointTexture); TEXTURE2D_X( _PrevSSRLightingTexture); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture - TEXTURE2D_X( _SSRAccumTexture); + RW_TEXTURE2D_X(float4, _SSRAccumTexture); #endif TEXTURE2D_X( _SsrClearCoatMaskTexture); @@ -187,7 +187,9 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); // Generate the new sample (follwing values of the sequence) - int globalSampleIndex = _RaytracingFrameIndex; + int globalSampleIndex = _FrameCount; + //round(_Time*1024.0f); + //_RaytracingFrameIndex; float2 Xi; Xi.x = GetBNDSequenceSample(positionSS, globalSampleIndex, 0); Xi.y = GetBNDSequenceSample(positionSS, globalSampleIndex, 1); @@ -196,6 +198,21 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, float3 R = float3(0.0, 0.0, 0.0); float NdotL, NdotH, VdotH; SampleGGXDir(Xi, V, localToWorld, roughness, R, NdotL, NdotH, VdotH); + + if (NdotL < 0.001f) + { + WriteDebugInfo(positionSS, -1); + return; + } + + float D = D_GGX(NdotH, roughness); + float pdf = D * NdotH / (4.0 * VdotH); + + if (pdf < 0.001f) + { + WriteDebugInfo(positionSS, -1); + return; + } #endif float3 reflPosWS = positionWS + R; @@ -351,8 +368,12 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // recompute it using the last value of 't', which would result in an overshoot. // It also needs to be precisely at the center of the pixel to avoid artifacts. float2 hitPositionNDC = floor(rayPos.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. - _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, t, iterCount); + _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, roughness*t, pdf); } + //else + //{ + // _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(-1, -1 , 32767.0f, -1); + //} // If we do not hit anything, 'rayPos.xy' provides an indication where we stopped the search. WriteDebugInfo(positionSS, float4(rayPos.xy, iterCount, hit ? 1 : 0)); @@ -382,7 +403,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. - float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); @@ -403,7 +424,8 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) { // Miss. - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color0, 1.0f) * opacity0; + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color0, 0.0f) * opacity0; + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0.0f; return; } @@ -412,6 +434,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre (prevFrameUV.y < 0) || (prevFrameUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) { // Off-screen. + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0.0f; return; } @@ -424,8 +447,9 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float opacity = EdgeOfScreenFade(curFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; //color = lerp(color, color0, 0.5f); - color = (color + color0)*0.5f; - opacity = max(opacity, opacity0); + //color = color0; + //color = (color + color0)*0.5f; + //opacity = max(opacity, opacity0); // Disable SSR for negative, infinite and NaN history values. uint3 intCol = asuint(color); @@ -435,7 +459,10 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre opacity = isPosFin ? opacity : 0; // Use premultiplied alpha. - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f) * opacity; + //if (_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].a <= 0.5f) + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f); + if (opacity > 0.0f) + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f);// *opacity; } #elif defined(SSR_DENOISE_INPAINTING) float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) @@ -444,6 +471,36 @@ float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, fl return Smoothstep01(t); } +float3 UpdateWMS(float weight, float x, float3 wms) +{ + float wsum = wms.x + weight; + float mean = wms.y; + float var = wms.z; + + wsum += weight; + + return float3( + wsum, + mean + (weight / wsum)*(x - mean), + var + weight * (x - mean) * (x - mean) + ); +} + +float ExpAvg(float x0, float x1, float alpha) +{ + return alpha * x1 + (1.0f - alpha) * x0; +} + +float3 ExpAvg(float3 x0, float3 x1, float alpha) +{ + return alpha * x1 + (1.0f - alpha) * x0; +} + +float4 ExpAvg(float4 x0, float4 x1, float alpha) +{ + return alpha * x1 + (1.0f - alpha) * x0; +} + [numthreads(8, 8, 1)] void ScreenSpaceReflectionsDenoiseInpainting(uint3 dispatchThreadId : SV_DispatchThreadID) { @@ -454,33 +511,323 @@ void ScreenSpaceReflectionsDenoiseInpainting(uint3 dispatchThreadId : SV_Dispatc float perceptualRoughness; GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? + float4 srcData = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS); + float2 hitPositionNDC = srcData.xy; + float2 motionVectorNDC; + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); + float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; + float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float2 curFrameUV0 = hitPositionNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float2 RTSize = 1.0f/_RTHandleScale.xy; + float2 uv = float2(positionSS) * _RTHandleScale.xy;// _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float dist = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)].z; + float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; + + float distCoef = hitData.z; + float pdf = hitData.w; + + float2 hitUV = hitData.xy * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + if ((hitUV.x < 0) || (hitUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || + (hitUV.y < 0) || (hitUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) + { + // Off-screen. + + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0; + return; + } - float4 accum = 0; - int r = 5; - //float coef = rcp(float((2*r+1)*(2*r+1))); - float coef; - float sigma = lerp(5.0f, 5.0f, saturate(0.5f*saturate(dist/16.0f) + 0.5f*perceptualRoughness)); - float totalCoef = 0.0f; + const int r = 1; + bool hasNeighbour = false; for (int i = -r; i <= r; ++i) { for (int j = -r; j <= r; ++j) { - coef = rcp(sqrt(2.0f*3.1415926538897932384626f)*sigma)*exp(-(i*i + j*j)/(2.0f*sigma*sigma)); - totalCoef += coef; - accum += coef*_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + if (i != 0 && j != 0) + { + float sidePDF = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS + int2(i, j))].w; + if (sidePDF > 0.0f) + { + hasNeighbour = true; + break; + } + } } + if (hasNeighbour) + break; } - accum /= totalCoef; - float4 prev = _PrevSSRLightingTexture[COORD_TEXTURE2D_X(positionSS)]; + float dx = abs(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(-1, 0))] - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(+1, 0))]) * 0.5f; + float dy = abs(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2( 0, -1))] - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2( 0, +1))]) * 0.5f; - accum.rgb = lerp(accum.rgb, (accum.rgb + prev.rgb) * 0.5f, accum > 0.0f ? 0.0f : 1.0f); - //accum.rgb = (accum.rgb + prev.rgb) * 0.5f; - //accum.rgb = lerp(accum.rgb, (accum.rgb + prev.rgb) * 0.5f, prev.a); + float lap = saturate((dx + dy) * 0.5f); - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = accum; + float4 center = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)]; + float4 centerAccum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)]; + + const float secur = 0.01f; + bool inBound = + //positionSS.x > secur * RTSize.x && positionSS.x < (1.0f - secur) * RTSize.x && positionSS.y > secur * RTSize.y && positionSS.y < (1.0f - secur) * RTSize.y; + //uv.x < 1.0f - secur && uv.x > secur && uv.y < 1.0f - secur && uv.y > secur; + //uv.x < 1.0f - secur && uv.x > secur && uv.y < 1.0f - secur && uv.y > secur; + true; + //bool isNewHit = pdf > 0.1f && uv.x < 0.75f && uv.x > 0.25f && uv.y < 0.75f && uv.y > 0.25f; + //bool isNewHit = pdf > 0.001f;//&& inBound; + //bool isNewHit = pdf > 0.00125f;//&& inBound; + bool isNewHit = pdf > 0.0f; + + //centerAccum = ExpAvg(centerAccum, float4(0.0f, 0.0f, 0.0f, 0.0f), 0.0125f); + + const float vanish = 0.75f; + const float safeAccum = 0.00f; + const float expAvgCol = 0.05f; + +#if 0 + if (isNewHit && centerAccum.w < 0.25f) + { + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb, 1.0f); + lap *= 0.0f; + } + else if (isNewHit && centerAccum.w >= 0.25f) + { + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + float4( + //ExpAvg(centerAccum.rgb, center.rgb, 0.25f), + lerp(centerAccum.rgb, center.rgb, 0.25f), + 1.0f); + //float4( + // ExpAvg(centerAccum.rgb, center.rgb, 0.95f), + // 1.0f); + lap *= 0.0f; + } + //else if (centerAccum.w > 0.1f) + //{ + // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + // float4( + // ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), expAvgCol), + // ExpAvg(centerAccum.w, 0.0f, expAvgCol)); + //} + else //if (centerAccum.w <= 0.1f) + //if (!isNewHit && hasNeighbour && centerAccum.w <= safeAccum) + { + float4 accum = 0.0f; + int smplCount = 0; + float wsum = 0.0f; + for (int i = -r; i <= r; ++i) + { + for (int j = -r; j <= r; ++j) + { + float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + //if (i != 0 && j != 0) + if (data.w > 0.0f && i != 0 && j != 0) + { + float coef = 1.0f/sqrt(dot(float2(i, j), float2(i, j))); + wsum += coef; + accum += coef*data; + ++smplCount; + } + } + } + //if (accum.w > 0.0f) + if (/*smplCount */wsum > 0) + { + //accum /= accum.w; + accum /= wsum; + //float(smplCount); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = accum * 0.95f; + //float4(accum.rgb * 0.75f, accum.w * 0.95f); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb, 1.0f); + } + //float4(accum.rgb, centerAccum.w); + //float4(accum.rgb * 0.75f, centerAccum.w * 0.75f); + //float4( + // ExpAvg(centerAccum.rgb * 0.5f, accum.rgb * 0.5f, 0.75f), + // ExpAvg(centerAccum.w * 0.5f, accum.w * 0.5f, 0.75f)); + } + //else + //{ + // lap *= 0.0f; + //} +#endif + +#if 0 + if (isNewHit && centerAccum.w <= 0.0125f) + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb, 1.0f); + else if (isNewHit && centerAccum.w > 0.0125f) + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb * (1.0f - centerAccum.w) + centerAccum.w * centerAccum.rgb, 1.0f); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + float4( + ExpAvg(center.rgb, centerAccum.rgb, 0.25f), + //ExpAvg(centerAccum.w, 0.0f, 0.25f) + ExpAvg(1.0f, centerAccum.w, 0.25f) + ); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb * (1.0f - centerAccum.w) + (centerAccum.w) * centerAccum.rgb, centerAccum.w * vanish); + else if (!isNewHit && centerAccum.w < 0.25f) + { + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + float4( + ExpAvg(center.rgb, centerAccum.rgb, 0.25f), + //ExpAvg(centerAccum.w, 0.0f, 0.25f) + ExpAvg(centerAccum.w, 0.0f, 0.45f) + ); + } + else if (hasNeighbour && inBound) + { + float3 accum = 0.0f; + float wsum = 0.0f; + int samplesCount = 0; + for (int i = -r; i <= r; ++i) + { + for (int j = -r; j <= r; ++j) + { + if (i == 0 && j == 0) + continue; + + float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + if (data.w > 0.0f && dot(data.rgb, float3(1.0f, 1.0f, 1.0f)) > 0.1f) + { + wsum += data.w; + accum += data.rgb; + ++samplesCount; + } + } + } + if (wsum > 0.0f && dot(accum.rgb, float3(1.0f, 1.0f, 1.0f)) > 0.1f) + { + accum /= wsum; + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb * (1.0f - centerAccum.w) + (centerAccum.w) * centerAccum.rgb, 1.0f); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.25f), ExpAvg(centerAccum.w, float(wsum)/((2.0f * r + 1.0f) * (2.0f * r + 1.0f)), 0.75f)); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), 0.95f*float(wsum) / float(samplesCount)); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), 0.95f * float(wsum) / float(((2.0f * r + 1.0f) * (2.0f * r + 1.0f)))); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + float4( + ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), + ExpAvg(centerAccum.w, 0.0f, 0.75f) + ); + } + } + //else + //{ + // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; + // //float4(ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), 0.95f), 1.0f); + //} +#endif + + if (true || isNewHit) + { + //float weight = pdf;// *distCoef; + //weight /= 4096.0f; + //weight = min(weight, 4096.0f); + //weight /= 4096.0f; + //pdf /= 4096.0f; + //if (pdf == 0.0f) + //{ + // weight = 1.0f; + //} + //pdf = min(pdf, 16.0f); + //float wsum = centerAccum.w + weight; + //if (wsum > 0.0f) + // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + // float4(centerAccum.rgb + (weight / wsum)*(center.rgb - centerAccum.rgb), wsum); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4( + lerp(centerAccum.rgb, center.rgb, 0.00125f), + /*lerp(centerAccum.w, pdf, 0.0125f)*/1.0f); + //centerAccum * 0.75f + 0.25f * center; + //lerp(centerAccum, center, 0.0175f); + //lerp(centerAccum, center, 0.0125f); + //ExpAvg(centerAccum, center, 1.0f - 0.0000125f); + //float4(center.rgb, 1.0f); + //float4(lerp(centerAccum.rgb, center.rgb, 0.0125f), 1.0f); + //float4( + // ExpAvg(centerAccum.rgb, center.rgb, 0.000125f), + // ExpAvg(centerAccum.w, pdf, 0.000125f)); + } + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; + /*else */if (false && centerAccum.w < 0.00125f) + { + const int r = 1; + float4 accum = 0.0f; + float wsum = 0.0f; + for (int i = -r; i <= r; ++i) + { + for (int j = -r; j <= r; ++j) + { + float4 val0 = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + float4 val1 = _SSRAccumTexture [COORD_TEXTURE2D_X(positionSS + int2(i, j))]; + //float4 val = val0 * 0.5f + 0.5f * val1; + float4 val = val1; + //if (i != 0 && j != 0 && dot(val.rgb, float3(1, 1, 1)) > 0.1f) + if (i != 0 && j != 0) + if (val.w > 0.0f) + { + wsum += 1.0f; + //Luminance(val.rgb); + //val.w; + //accum += val.w*val; + accum += val; + } + } + } + if (wsum > 0.0f) + { + accum /= wsum; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + //float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.125f), centerAccum.w); + lerp(centerAccum, accum, 0.75f); + //accum; + //float4(accum.rgb, 1.0f); + } + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb, 1.0f); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.125f), 1.0f); + } + //else //if (false) + //if (false) + { + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), 0.05f); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + //lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), saturate(10000000000000.0f*length(motionVectorNDC))); + lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), 0.1f); + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = + // //float4(ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), 0.25f), 1.0f); + // ExpAvg(centerAccum, float4(0.0f, 0.0f, 0.0f, 0.0f), 0.125f); + } + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; + + float3 output = 0.0f; + int rad = 32; + float tot = 0.0f; + for (int x = -rad; x <= rad; ++x) + { + for (int y = -rad; y <= rad; ++y) + { + float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(x, y))]; + //if (data.w > 0.0f) + //if (x != 0 && y != 0) + { + //float sigma = lerp(0.125f, 16.0f, saturate(data.w/128.f)); + float sigma = lerp(0.125f, 128.0f, saturate(distCoef)); + float sigma2 = sigma * sigma; + float coef = rcp(sigma2 * 2.0f * 3.1415926535897932354626f) * exp2(-(float(x * x + y * y) / (2.0f * sigma2))); + tot += coef; + output += coef * data; + } + } + } + output = output / tot; + + //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(sqrt(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].x).xxx, 1.0f); + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].www, 1.0f); + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(distCoef.xxx, 1.0f); + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(motionVectorNDC.rg, 0.0f, 1.0f); + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(output.xyz, 1.0f); + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].www, 1.0f); + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)]; + + //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0*float4(1.0f, 1.0f, 1.0f, 1.0f); } + #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index e69e9b3d2a5..f028ef0e2b4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -733,7 +733,7 @@ internal void AllocateScreenSpaceHistoryBuffer(float scaleFactor) ReleaseHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); var ssrAlloc = new ScreenSpaceAllocator(scaleFactor); - AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection, ssrAlloc.Allocator, 3); + AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection, ssrAlloc.Allocator, 2); m_ScreenSpaceReflectionResolutionScale = scaleFactor; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 295db7a9744..64e191546c9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -493,6 +493,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, } PushFullScreenDebugTexture(renderGraph, result, transparent ? FullScreenDebugMode.TransparentScreenSpaceReflections : FullScreenDebugMode.ScreenSpaceReflections); + //PushFullScreenDebugTexture(renderGraph, result, FullScreenDebugMode.ScreenSpaceReflectionsAccum); return result; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index c75608f82cd..131c21d4663 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -731,7 +731,7 @@ void InitializeRenderTextures() m_LowResTransparentBuffer = RTHandles.Alloc(Vector2.one * 0.5f, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "Low res transparent"); } - if (settings.supportSSR) + if (settings.supportSSR && (m_SsrHitPointTexture == null || m_SsrAccumPointTexture == null)) { // m_SsrDebugTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Debug_Texture"); //m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); @@ -4672,8 +4672,11 @@ static void RenderSSR( in RenderSSRParameters parameters, // cmd.SetComputeTextureParam(cs, kernel, "_SsrDebugTexture", m_SsrDebugTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); + if (prevSSRLightingTexture != null) + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); + if (ssrLightingTexture != null) + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); @@ -4687,9 +4690,12 @@ static void RenderSSR( in RenderSSRParameters parameters, { cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + if (ssrLightingTexture != null) + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); + if (prevSSRLightingTexture != null) + cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); @@ -4734,8 +4740,11 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren } } - cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, ssrLightingTexture); + + if (ssrLightingTexture != null) + cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, ssrLightingTexture); PushFullScreenDebugTexture(hdCamera, cmd, ssrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); + PushFullScreenDebugTexture(hdCamera, cmd, m_SsrAccumPointTexture, FullScreenDebugMode.ScreenSpaceReflectionsAccum); } void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -5411,7 +5420,10 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) // CoreUtils.SetRenderTarget(cmd, hdCamera, m_SsrDebugTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); + if (ssrLightingTexture != null) + { + CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); + } } } From 72933cedbb2bfb6131b39f4769c6a5d5d061a5a9 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 17 Sep 2020 17:09:55 +0200 Subject: [PATCH 05/41] Remove blur step --- .../HDScreenSpaceReflectionEditor.cs | 4 + .../Runtime/Debug/DebugDisplay.cs | 6 +- .../Runtime/Debug/DebugDisplay.cs.hlsl | 51 +- .../Runtime/Debug/DebugFullScreen.shader | 6 +- .../ScreenSpaceReflection.cs | 5 + .../ScreenSpaceReflections.compute | 946 +++++++++--------- .../ShaderVariablesScreenSpaceReflection.cs | 2 +- ...aderVariablesScreenSpaceReflection.cs.hlsl | 2 +- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 14 - .../Camera/HDCameraFrameHistoryType.cs | 2 - .../Runtime/RenderPipeline/HDProfileId.cs | 2 +- .../HDRenderPipeline.LightLoop.cs | 7 +- .../RenderPipeline/HDRenderPipeline.cs | 116 ++- .../RenderPipeline/HDStringConstants.cs | 2 +- 14 files changed, 600 insertions(+), 565 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index 1a1d9457be6..877e4726eab 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -20,6 +20,7 @@ class HDScreenSpaceReflectionEditor : VolumeComponentWithQualityEditor SerializedDataParameter m_ScreenFadeDistance; SerializedDataParameter m_RayMaxIterations; SerializedDataParameter m_DepthBufferThickness; + SerializedDataParameter m_AccumulationFactor; // Ray Tracing SerializedDataParameter m_LayerMask; @@ -54,6 +55,7 @@ public override void OnEnable() m_DepthBufferThickness = Unpack(o.Find(x => x.depthBufferThickness)); m_RayMaxIterations = Unpack(o.Find(x => x.rayMaxIterations)); m_ScreenFadeDistance = Unpack(o.Find(x => x.screenFadeDistance)); + m_AccumulationFactor = Unpack(o.Find(x => x.accumulationFactor)); // Generic ray tracing m_LayerMask = Unpack(o.Find(x => x.layerMask)); @@ -78,6 +80,7 @@ public override void OnEnable() static public readonly GUIContent k_MinimumSmoothnessText = EditorGUIUtility.TrTextContent("Minimum Smoothness", "Controls the smoothness value at which HDRP activates SSR and the smoothness-controlled fade out stops."); static public readonly GUIContent k_SmoothnessFadeStartText = EditorGUIUtility.TrTextContent("Smoothness Fade Start", "Controls the smoothness value at which the smoothness-controlled fade out starts. The fade is in the range [Min Smoothness, Smoothness Fade Start]."); static public readonly GUIContent k_ScreenFaceDistanceText = EditorGUIUtility.TrTextContent("Screen Edge Fade Distance", "Controls the distance at which HDRP fades out SSR near the edge of the screen."); + static public readonly GUIContent k_AccumulationFactorText = EditorGUIUtility.TrTextContent("Accumulation Factor", "Controls Controls the amount of accumulation (0 no accumulation, 1 just accumulate)."); static public readonly GUIContent k_DepthBufferThicknessText = EditorGUIUtility.TrTextContent("Object Thickness", "Controls the typical thickness of objects the reflection rays may pass behind."); static public readonly GUIContent k_RayMaxIterationsText = EditorGUIUtility.TrTextContent("Max Ray Steps", "Sets the maximum number of steps HDRP uses for raytracing. Affects both correctness and performance."); static public readonly GUIContent k_RayLengthText = EditorGUIUtility.TrTextContent("Ray Length", "Controls the length of reflection rays."); @@ -207,6 +210,7 @@ public override void OnInspectorGUI() PropertyField(m_RayMaxIterations, k_RayMaxIterationsText); m_RayMaxIterations.value.intValue = Mathf.Max(0, m_RayMaxIterations.value.intValue); GUI.enabled = true; + PropertyField(m_AccumulationFactor, k_AccumulationFactorText); } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 5b2641388ca..0fcee7f8c07 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -60,7 +60,11 @@ public enum FullScreenDebugMode /// Display Screen Space Reflections buffer. ScreenSpaceReflections, /// Display Screen Space Reflections buffer. + ScreenSpaceReflectionsPrev, + /// Display Screen Space Reflections buffer. ScreenSpaceReflectionsAccum, + /// Display Screen Space Information buffer. + ScreenSpaceReflectionsInfo, /// Display the Transparent Screen Space Reflections buffer. TransparentScreenSpaceReflections, /// Display Contact Shadows buffer. @@ -1773,7 +1777,7 @@ internal bool DebugNeedsExposure() debugLighting == DebugLightingMode.DiffuseLighting || debugLighting == DebugLightingMode.SpecularLighting || debugLighting == DebugLightingMode.VisualizeCascade) || (data.lightingDebugSettings.overrideAlbedo || data.lightingDebugSettings.overrideNormal || data.lightingDebugSettings.overrideSmoothness || data.lightingDebugSettings.overrideSpecularColor || data.lightingDebugSettings.overrideEmissiveColor || data.lightingDebugSettings.overrideAmbientOcclusion) || (debugGBuffer == DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive) || (data.lightingDebugSettings.debugLightFilterMode != DebugLightFilterMode.None) || - (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || + (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsPrev || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsInfo || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || (debugLighting == DebugLightingMode.ProbeVolume || debugProbeVolume == ProbeVolumeDebugMode.VisualizeAtlas); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl index f27b672a72a..2955b1dc2d7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl @@ -11,30 +11,33 @@ #define FULLSCREENDEBUGMODE_MIN_LIGHTING_FULL_SCREEN_DEBUG (1) #define FULLSCREENDEBUGMODE_SCREEN_SPACE_AMBIENT_OCCLUSION (2) #define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS (3) -#define FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS (4) -#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS (5) -#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS_FADE (6) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_SHADOWS (7) -#define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (8) -#define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (9) -#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (10) -#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (11) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (12) -#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (13) -#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (14) -#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (15) -#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (16) -#define FULLSCREENDEBUGMODE_MOTION_VECTORS (17) -#define FULLSCREENDEBUGMODE_NAN_TRACKER (18) -#define FULLSCREENDEBUGMODE_COLOR_LOG (19) -#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (20) -#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (21) -#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (22) -#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (23) -#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (24) -#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (25) -#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (26) -#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (27) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV (4) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM (5) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_INFO (6) +#define FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS (7) +#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS (8) +#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS_FADE (9) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_SHADOWS (10) +#define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (11) +#define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (12) +#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (13) +#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (14) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (15) +#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (16) +#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (17) +#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (18) +#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (19) +#define FULLSCREENDEBUGMODE_MOTION_VECTORS (20) +#define FULLSCREENDEBUGMODE_NAN_TRACKER (21) +#define FULLSCREENDEBUGMODE_COLOR_LOG (22) +#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (23) +#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (24) +#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (25) +#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (26) +#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (27) +#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (28) +#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (29) +#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (30) // Generated from UnityEngine.Rendering.HighDefinition.ShaderVariablesDebugDisplay // PackingRules = Exact diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader index 7770faec9de..367621a1cc5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader @@ -303,7 +303,11 @@ Shader "Hidden/HDRP/DebugFullScreen" return float4(fade.xxx, 0.0); } - if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS || _FullScreenDebugMode == FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS) + if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS || + _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV || + _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM || + _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_INFO || + _FullScreenDebugMode == FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS) { float4 color = SAMPLE_TEXTURE2D_X(_DebugFullScreenTexture, s_point_clamp_sampler, input.texcoord) * GetCurrentExposureMultiplier(); return float4(color.rgb, 1.0f); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs index eebc3628114..b111d38cf87 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs @@ -77,6 +77,11 @@ public float smoothnessFadeStart /// public ClampedFloatParameter screenFadeDistance = new ClampedFloatParameter(0.1f, 0.0f, 1.0f); + /// + /// Controls the amount of accumulation (0 no accumulation, 1 just accumulate) + /// + public ClampedFloatParameter accumulationFactor = new ClampedFloatParameter(0.125f, 0.0f, 1.0f); + /// /// Layer mask used to include the objects for screen space reflection. /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 5384203175b..688892de9bd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -1,4 +1,4 @@ -//-------------------------------------------------------------------------------------------------- + // Definitions //-------------------------------------------------------------------------------------------------- @@ -7,7 +7,7 @@ #pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE #pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT -#pragma kernel ScreenSpaceReflectionsDenoiseInpainting SSR_DENOISE_INPAINTING +#pragma kernel ScreenSpaceReflectionsAccumulate SSR_ACCUMULATE #pragma multi_compile _ DEPTH_SOURCE_NOT_FROM_MIP_CHAIN @@ -15,7 +15,10 @@ // #define DEBUG #define SSR_TRACE_BEHIND_OBJECTS #define SSR_TRACE_TOWARDS_EYE -#define SSR_TRACE_EPS 0.00024414 // 2^-12, should be good up to 4K +#define SAMPLES_VNDF +#define SSR_TRACE_EPS 0.00024414 // 2^-12, should be good up to 4K +#define MIN_GGX_ROUGHNESS 0.00001f +#define MAX_GGX_ROUGHNESS 0.99999f //-------------------------------------------------------------------------------------------------- // Included headers @@ -28,7 +31,6 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Builtin/BuiltinData.hlsl" - #ifdef DEBUG_DISPLAY #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Debug.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" @@ -39,6 +41,10 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingCommon.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/PreIntegratedFGD/PreIntegratedFGD.cs.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl" + +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/TemporalAntialiasing.hlsl" //-------------------------------------------------------------------------------------------------- // Inputs & outputs @@ -65,16 +71,16 @@ TEXTURE2D_X(_DepthTexture); #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); RW_TEXTURE2D_X(float4, _SsrHitPointTexture); + RW_TEXTURE2D_X(float4, _SSRInfoTexture); #elif defined(SSR_REPROJECT) TEXTURE2D_X( _SsrHitPointTexture); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture - TEXTURE2D_X( _PrevSSRLightingTexture); RW_TEXTURE2D_X(float4, _SSRAccumTexture); -#else // defined(SSR_DENOISE_INPAINTING) +#else //if defined(SSR_ACCUMULATE) TEXTURE2D_X( _SsrHitPointTexture); - TEXTURE2D_X( _PrevSSRLightingTexture); - RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture - RW_TEXTURE2D_X(float4, _SSRAccumTexture); + RW_TEXTURE2D_X(float4, _SsrPrevLightingTexture); + RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); + TEXTURE2D_X( _SSRAccumTexture); #endif TEXTURE2D_X( _SsrClearCoatMaskTexture); @@ -82,9 +88,290 @@ TEXTURE2D_X(_DepthTexture); StructuredBuffer _CoarseStencilBuffer; //-------------------------------------------------------------------------------------------------- -// Implementation +// Helpers //-------------------------------------------------------------------------------------------------- +// Adapted from: "Sampling the GGX Distribution of Visible Normals", by E. Heitz +// http://jcgt.org/published/0007/04/01/paper.pdf +void SampleGGXVisibleNormal(float2 u, + float3 V, + float3x3 localToWorld, + float roughness, + out float3 localV, + out float3 localH, + out float VdotH) +{ + localV = mul(V, transpose(localToWorld)); + + // Construct an orthonormal basis around the stretched view direction + float3x3 viewToLocal; + viewToLocal[2] = normalize(float3(roughness * localV.x, roughness * localV.y, localV.z)); + viewToLocal[0] = (viewToLocal[2].z < 0.9999) ? normalize(cross(float3(0, 0, 1), viewToLocal[2])) : float3(1, 0, 0); + viewToLocal[1] = cross(viewToLocal[2], viewToLocal[0]); + + // Compute a sample point with polar coordinates (r, phi) + float r = sqrt(u.x); + float phi = 2.0 * PI * u.y; + float t1 = r * cos(phi); + float t2 = r * sin(phi); + float s = 0.5 * (1.0 + viewToLocal[2].z); + t2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2; + + // Reproject onto hemisphere + localH = t1 * viewToLocal[0] + t2 * viewToLocal[1] + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * viewToLocal[2]; + + // Transform the normal back to the ellipsoid configuration + localH = normalize(float3(roughness * localH.x, roughness * localH.y, max(0.0, localH.z))); + + VdotH = saturate(dot(localV, localH)); +} + +float Lambda_GGX(float roughness, + float3 V) +{ + return 0.5 * (sqrt(1.0 + (Sq(roughness * V.x) + Sq(roughness * V.y)) / Sq(V.z)) - 1.0); +} + +bool SampleGGX(float roughness_, + float3x3 localToWorld, + float3 V, + float fresnel0, + float2 inputSample, + out float3 outgoingDir, + out float value, + out float pdf, + out float fresnel) +{ + float roughness = clamp(roughness_, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); + + float VdotH; + float3 localV, localH; + SampleGGXVisibleNormal(inputSample, V, localToWorld, roughness, localV, localH, VdotH); + + // Compute the reflection direction + float3 localL = 2.0 * VdotH * localH - localV; + outgoingDir = mul(localL, localToWorld); + + //if (localL.z < 0.001 || !IsAbove(mtlData, outgoingDir)) + if (localL.z < 0.001) + return false; + + //float pdfNoGV = D_AnisoGGX(roughnessX, roughnessY, localH) / (4.0 * localV.z); + //float pdfNoGV = D_AnisoGGX(roughness, roughness, localH) / (4.0 * localV.z); + float pdfNoGV = D_GGX(localH.z, roughness); + //float lambdaVPlusOne = Lambda_AnisoGGX(roughnessX, roughnessY, localV) + 1.0; + float lambdaVPlusOne = Lambda_GGX(roughness, localV) + 1.0; + pdf = pdfNoGV / lambdaVPlusOne; + + //float lambdaL = Lambda_AnisoGGX(roughnessX, roughnessY, localL); + float lambdaL = Lambda_GGX(roughness, localL); + fresnel = F_Schlick(fresnel0, VdotH); + value = fresnel * pdfNoGV / (lambdaVPlusOne + lambdaL); + + if (pdf < 0.001) + return false; + + return true; +} + +float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) +{ + float t = Remap10(perceptualRoughness, fadeRcpLength, fadeEndTimesRcpLength); + return Smoothstep01(t); +} + +void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerceptualRoughness, out float3 positionWS, out float pdf, out float weight, out float3 N, out float3 L, out float3 V, out float dist, out float NdotL, out float NdotH, out float VdotH, out float NdotV) +{ + float2 uv = float2(positionSS) * _RTHandleScale.xy; + + float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; + dist = hitData.z; + hitPositionNDC = hitData.xy; + + int globalSampleIndex = _FrameCount; + float2 Xi; + Xi.x = GetBNDSequenceSample(positionSS, globalSampleIndex, 0); + Xi.y = GetBNDSequenceSample(positionSS, globalSampleIndex, 1); + + // Pick which subpixel we will be launching our effects from + float subPixelSample = GetBNDSequenceSample(positionSS, globalSampleIndex, 3); + int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3); + uint2 shift = HalfResIndexToCoordinateShift[subPixel]; + + uint2 sourceCoord = positionSS + shift; + + NormalData normalData; + DecodeFromNormalBuffer(sourceCoord, normalData); + + srcPerceptualRoughness = normalData.perceptualRoughness; + + float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); + float3x3 localToWorld = GetLocalFrame(normalData.normalWS); + + Xi.x = lerp(Xi.x, 0.0f, srcPerceptualRoughness * 0.7f); + +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + float deviceDepth = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; +#else + float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; +#endif + + float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + positionWS = ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP); + V = GetWorldSpaceNormalizeViewDir(positionWS); + + N = normalData.normalWS; + +#ifdef SAMPLES_VNDF + float value; + float fresnel; + + SampleGGX(roughness, + localToWorld, + V, + 1.0f, // F0 + Xi, + L, + value, + pdf, + fresnel); + + weight = fresnel * value / pdf; + + NdotV = dot(normalData.normalWS, V); + NdotL = dot(normalData.normalWS, L); + float3 H = normalize(V + L); + NdotH = dot(normalData.normalWS, H); + VdotH = dot(V, H); +#else + SampleGGXDir(Xi, V, localToWorld, roughness, L, NdotL, NdotH, VdotH); + + NdotV = dot(normalData.normalWS, V); + float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); + float fresnel = F_Schlick(1.0f, VdotH); + float D = D_GGX(NdotH, roughness); + + pdf = D * NdotH / (4.0 * VdotH); + weight = fresnel * D * Vg * NdotL / pdf; +#endif +} + +float2 GetHitNDC(float2 positionNDC) +{ + // TODO: it's important to account for occlusion/disocclusion to avoid artifacts in motion. + // This would require keeping the depth buffer from the previous frame. + float2 motionVectorNDC; + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); + float2 prevFrameNDC = positionNDC - motionVectorNDC; + return prevFrameNDC; +} + +float2 GetHitUV(float2 positionNDC) +{ + return GetHitNDC(positionNDC) * _ColorPyramidUvScaleAndLimitPrevFrame.xy; +} + +float3 GetWorldSpacePosition(uint2 positionSS) +{ + float2 uv = float2(positionSS) * _RTHandleScale.xy; + +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + float deviceDepth = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; +#else + float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; +#endif + + //float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + float2 positionNDC = positionSS;// *_ScreenSize.zw + (0.5 * _ScreenSize.zw); + + return ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP/*UNITY_MATRIX_PREV_I_VP*/); +} + +float2 GetWorldSpacePoint(uint2 positionSS, out float3 positionSrcWS, out float3 positionDstWS) +{ + positionSrcWS = GetWorldSpacePosition(positionSS); + + float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; + uint2 positionDstSS = (hitData.xy - (0.5 * _ScreenSize.zw)) / _ScreenSize.zw; + //uint2 positionDstSS = hitData.xy; + + positionDstWS = GetWorldSpacePosition(positionDstSS); + + return hitData.xy; +} + +float GetTraceDistance(uint2 positionSS) +{ + float3 positionSrcWS; + float3 positionDstWS; + GetWorldSpacePoint(positionSS, positionSrcWS, positionDstWS); + + return length(positionDstWS - positionSrcWS); +} + +float3 GetVectorSample(uint2 positionSS) +{ + float3 positionSrcWS; + float3 positionDstWS; + GetWorldSpacePoint(positionSS, positionSrcWS, positionDstWS); + + return normalize(positionDstWS - positionSrcWS); +} + +float3 GetHitColorFromUV(float2 prevFrameUV, float perceptualRoughness, out float opacity, int mipLevel = 0) +{ + float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + opacity = EdgeOfScreenFade(prevFrameUV / _ColorPyramidUvScaleAndLimitPrevFrame.xy, _SsrEdgeFadeRcpLength) * tmpCoef; + return SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; +} + +float3 GetHitColor(float2 hitPositionNDC, float perceptualRoughness, out float opacity, int mipLevel = 0) +{ + float2 prevFrameNDC = GetHitNDC(hitPositionNDC); + float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + opacity = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; + return SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; +} + +float2 GetSampleInfo(uint2 positionSS, out float3 color, out float localBRDF, out float localPDF, out float opacity) +{ + float3 positionSrcWS; + float3 positionDstWS; + float2 hitData = GetWorldSpacePoint(positionSS, positionSrcWS, positionDstWS); + + float3 V = GetWorldSpaceNormalizeViewDir(positionSrcWS); + float3 L = normalize(positionDstWS - positionSrcWS); + float3 H = normalize(V + L); + + NormalData normalData; + DecodeFromNormalBuffer(positionSS, normalData); + + float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); + + roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); + + float NdotV = dot(normalData.normalWS, V); + float NdotL = dot(normalData.normalWS, L); + float VdotH = dot(V, H); + float NdotH = dot(normalData.normalWS, H); + float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); + float fresnel = F_Schlick(1.0f, VdotH); + float D = D_GGX(NdotH, roughness); + + float lambdaVPlusOne = Lambda_GGX(roughness, V) + 1.0; + localPDF = D / lambdaVPlusOne; + + float lambdaL = Lambda_GGX(roughness, L); + fresnel = F_Schlick(1.0f, VdotH); + localBRDF = fresnel * D / (lambdaVPlusOne + lambdaL); + + color = GetHitColor(hitData.xy, normalData.perceptualRoughness, opacity, 0); + + return hitData; +} + void GetNormalAndPerceptualRoughness(uint2 positionSS, out float3 normalWS, out float perceptualRoughness) { // Load normal and perceptualRoughness. @@ -102,6 +389,10 @@ void WriteDebugInfo(uint2 positionSS, float4 value) #endif } +//-------------------------------------------------------------------------------------------------- +// Implementation +//-------------------------------------------------------------------------------------------------- + #ifdef SSR_TRACE [numthreads(8, 8, 1)] @@ -131,7 +422,8 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, return; } - float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. + NormalData normalData; + DecodeFromNormalBuffer(positionSS, normalData); #ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN float deviceDepth = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; @@ -139,21 +431,29 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; #endif - bool killRay = deviceDepth == UNITY_RAW_FAR_CLIP_VALUE; - - float3 positionWS = ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP); // Jittered - float3 V = GetWorldSpaceNormalizeViewDir(positionWS); - - float3 N; + float pdf, weight; + float dist; + float NdotL, NdotH, VdotH, NdotV; + float3 R, V, N; + float3 positionWS; + //float2 hitUV; + float2 hitPositionNDC; float perceptualRoughness; - GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + GetHitInfos(positionSS, hitPositionNDC, perceptualRoughness, positionWS, pdf, weight, N, R, V, dist, NdotL, NdotH, VdotH, NdotV); + + if (NdotL < 0.001f || pdf < 0.001f) + { + WriteDebugInfo(positionSS, -1); + return; + } float3 camPosWS = GetCurrentViewPosition(); // Apply normal bias with the magnitude dependent on the distance from the camera. // Unfortunately, we only have access to the shading normal, which is less than ideal... - positionWS = camPosWS + (positionWS - camPosWS) * (1 - 0.001 * rcp(max(dot(N, V), FLT_EPS))); - deviceDepth = ComputeNormalizedDeviceCoordinatesWithZ(positionWS, UNITY_MATRIX_VP).z; + positionWS = camPosWS + (positionWS - camPosWS) * (1 - 0.001 * rcp(max(dot(N, V), FLT_EPS))); + /*float*/ deviceDepth = ComputeNormalizedDeviceCoordinatesWithZ(positionWS, UNITY_MATRIX_VP).z; + bool killRay = deviceDepth == UNITY_RAW_FAR_CLIP_VALUE; // Ref. #1: Michal Drobot - Quadtree Displacement Mapping with Height Blending. // Ref. #2: Yasin Uludag - Hi-Z Screen-Space Cone-Traced Reflections. @@ -163,58 +463,6 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // We start tracing from the center of the current pixel, and do so up to the far plane. float3 rayOrigin = float3(positionSS + 0.5, deviceDepth); -#if 0 - // TODO: this does not match GGX. - float3 R = reflect(-V, N); -#else - // Pick which subpixel we will be launching our effects from - float subPixelSample = GetBNDSequenceSample(positionSS, _RaytracingFrameIndex, 3); - int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3); - uint2 shift = HalfResIndexToCoordinateShift[subPixel]; - - //// Pixel where we will store the result of the raytracing - //uint2 outputCoord = halfResCoord * 2; - - // Pixel coordinate in full res of the pixel that we will be using for our computation - uint2 sourceCoord = positionSS + shift; - - NormalData normalData; - DecodeFromNormalBuffer(sourceCoord, normalData); - - float3x3 localToWorld = GetLocalFrame(normalData.normalWS); - - // Compute the actual roughness - float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); - - // Generate the new sample (follwing values of the sequence) - int globalSampleIndex = _FrameCount; - //round(_Time*1024.0f); - //_RaytracingFrameIndex; - float2 Xi; - Xi.x = GetBNDSequenceSample(positionSS, globalSampleIndex, 0); - Xi.y = GetBNDSequenceSample(positionSS, globalSampleIndex, 1); - - // Importance sample the direction - float3 R = float3(0.0, 0.0, 0.0); - float NdotL, NdotH, VdotH; - SampleGGXDir(Xi, V, localToWorld, roughness, R, NdotL, NdotH, VdotH); - - if (NdotL < 0.001f) - { - WriteDebugInfo(positionSS, -1); - return; - } - - float D = D_GGX(NdotH, roughness); - float pdf = D * NdotH / (4.0 * VdotH); - - if (pdf < 0.001f) - { - WriteDebugInfo(positionSS, -1); - return; - } -#endif - float3 reflPosWS = positionWS + R; float3 reflPosNDC = ComputeNormalizedDeviceCoordinatesWithZ(reflPosWS, UNITY_MATRIX_VP); // Jittered float3 reflPosSS = float3(reflPosNDC.xy * _ScreenSize.xy, reflPosNDC.z); @@ -368,12 +616,10 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // recompute it using the last value of 't', which would result in an overshoot. // It also needs to be precisely at the center of the pixel to avoid artifacts. float2 hitPositionNDC = floor(rayPos.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. - _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, roughness*t, pdf); + _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, t, weight); + float3 res = _SSRInfoTexture[COORD_TEXTURE2D_X(positionSS)].rgb; + _SSRInfoTexture[COORD_TEXTURE2D_X(positionSS)] = float4(res, NdotV); } - //else - //{ - // _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(-1, -1 , 32767.0f, -1); - //} // If we do not hit anything, 'rayPos.xy' provides an indication where we stopped the search. WriteDebugInfo(positionSS, float4(rayPos.xy, iterCount, hit ? 1 : 0)); @@ -381,453 +627,229 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, #elif defined(SSR_REPROJECT) -float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) -{ - float t = Remap10(perceptualRoughness, fadeRcpLength, fadeEndTimesRcpLength); - return Smoothstep01(t); -} - [numthreads(8, 8, 1)] void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThreadID) { UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); - uint2 positionSS = dispatchThreadId.xy; - - // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? - float4 srcData = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS); - - float2 hitPositionNDC = srcData.xy; + uint2 positionSS0 = dispatchThreadId.xy; float3 N; - float perceptualRoughness; - GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + float perceptualRoughness0; + GetNormalAndPerceptualRoughness(positionSS0, N, perceptualRoughness0); - // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. - float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + // Compute the actual roughness + float roughness0 = PerceptualRoughnessToRoughness(perceptualRoughness0); - float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + roughness0 = clamp(roughness0, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); - // TODO: it's important to account for occlusion/disocclusion to avoid artifacts in motion. - // This would require keeping the depth buffer from the previous frame. + // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? + float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS0).xy; float2 motionVectorNDC; DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float2 curFrameUV0 = hitPositionNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - //float3 color0 = SAMPLE_TEXTURE2D_X_LOD(_PrevSSRLightingTexture, s_trilinear_clamp_sampler, curFrameUV0, mipLevel).rgb; - //float opacity0 = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; - float4 prevData = _PrevSSRLightingTexture[COORD_TEXTURE2D_X(positionSS)]; - float3 color0 = prevData.rgb; - float opacity0 = prevData.a; + float depthOrigin = LoadCameraDepth(positionSS0.xy); + PositionInputs posInputOrigin = GetPositionInput(positionSS0.xy, _ScreenSize.zw, depthOrigin, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(8, 8)); + float3 originWS = posInputOrigin.positionWS + _WorldSpaceCameraPos; - if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) + float2 RTSize = 1.0f / _RTHandleScale.xy; + + float2 uv = float2(positionSS0) * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float pdf0, weight0; + float dist0; + float NdotL0, NdotH0, VdotH0, NdotV0; + float3 R0, V0, N0; + float3 positionWS0; + float perceptualRoughness; + GetHitInfos(positionSS0, hitPositionNDC, perceptualRoughness, positionWS0, pdf0, weight0, N0, R0, V0, dist0, NdotL0, NdotH0, VdotH0, NdotV0); + + float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; + + float opacity = 1.0f; + + if (NdotL0 < 0.001f || pdf0 < 0.001f) { - // Miss. - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color0, 0.0f) * opacity0; - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0.0f; return; } - - // TODO: optimize with max(). - if ((prevFrameUV.x < 0) || (prevFrameUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || - (prevFrameUV.y < 0) || (prevFrameUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) + float2 hitUV0 = hitPositionNDC.xy * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + if ((hitUV0.x < 0) || (hitUV0.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || + (hitUV0.y < 0) || (hitUV0.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) { // Off-screen. - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0.0f; + return; + } + if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) + { + // Miss. return; } - // Note that the color pyramid uses it's own viewport scale, since it lives on the camera. - - float2 curFrameNDC = prevFrameNDC; - float2 curFrameUV = curFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - - float3 color = SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; - float opacity = EdgeOfScreenFade(curFrameNDC, _SsrEdgeFadeRcpLength) * tmpCoef; - - //color = lerp(color, color0, 0.5f); - //color = color0; - //color = (color + color0)*0.5f; - //opacity = max(opacity, opacity0); - - // Disable SSR for negative, infinite and NaN history values. - uint3 intCol = asuint(color); - bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; - - color = isPosFin ? color : 0; - opacity = isPosFin ? opacity : 0; + float3 color = 0.0f; + opacity = 0.0f; - // Use premultiplied alpha. - //if (_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].a <= 0.5f) - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f); - if (opacity > 0.0f) - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(color, 1.0f);// *opacity; -} -#elif defined(SSR_DENOISE_INPAINTING) -float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, float fadeEndTimesRcpLength) -{ - float t = Remap10(perceptualRoughness, fadeRcpLength, fadeEndTimesRcpLength); - return Smoothstep01(t); -} + const int radius = 1; + int samplesCount = 0; + float4 outputs = 0.0f; + float wAll = 0.0f; + for (int y = -radius; y <= radius; ++y) + { + for (int x = -radius; x <= radius; ++x) + { + uint2 positionSS = uint2(int2(positionSS0) + int2(x, y)); + + float3 color; + float localBRDF; + float localPDF; + float opacity; + float2 hitData = GetSampleInfo(positionSS, color, localBRDF, localPDF, opacity); + if (max(hitData.x, hitData.y) != 0.0f && opacity > 0.0f) + { + //// Note that the color pyramid uses it's own viewport scale, since it lives on the camera. + // Disable SSR for negative, infinite and NaN history values. + uint3 intCol = asuint(color); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; -float3 UpdateWMS(float weight, float x, float3 wms) -{ - float wsum = wms.x + weight; - float mean = wms.y; - float var = wms.z; + float2 prevFrameUV = hitData * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - wsum += weight; + float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + opacity = EdgeOfScreenFade(prevFrameUV / _ColorPyramidUvScaleAndLimitPrevFrame.xy, _SsrEdgeFadeRcpLength) *tmpCoef; - return float3( - wsum, - mean + (weight / wsum)*(x - mean), - var + weight * (x - mean) * (x - mean) - ); -} + color = isPosFin ? color : 0; + opacity = isPosFin ? opacity : 0; -float ExpAvg(float x0, float x1, float alpha) -{ - return alpha * x1 + (1.0f - alpha) * x0; -} + float weight = localBRDF / localPDF; + outputs += weight * float4(color, opacity); + wAll += weight; + } + } + } -float3 ExpAvg(float3 x0, float3 x1, float alpha) -{ - return alpha * x1 + (1.0f - alpha) * x0; + if (wAll > 0.0f) + { + //float2 coordLUT = Remap01ToHalfTexelCoord(float2(sqrt(NdotV0), roughness0), FGDTEXTURE_RESOLUTION); + //float E = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD_GGXDisneyDiffuse, s_linear_clamp_sampler, coordLUT, 0).y; + //float E0 = (1.0 - E) / E; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = outputs / wAll; + } } -float4 ExpAvg(float4 x0, float4 x1, float alpha) -{ - return alpha * x1 + (1.0f - alpha) * x0; -} +#elif defined(SSR_ACCUMULATE) [numthreads(8, 8, 1)] -void ScreenSpaceReflectionsDenoiseInpainting(uint3 dispatchThreadId : SV_DispatchThreadID) +void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThreadID) { UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); uint2 positionSS = dispatchThreadId.xy; float3 N; - float perceptualRoughness; - GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + float perceptualRoughness0; + GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness0); - // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? - float4 srcData = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS); - float2 hitPositionNDC = srcData.xy; - float2 motionVectorNDC; - DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); - float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; - float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - - float2 curFrameUV0 = hitPositionNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + // Compute the actual roughness + float roughness = PerceptualRoughnessToRoughness(perceptualRoughness0); + roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); - float2 RTSize = 1.0f/_RTHandleScale.xy; + float4 data0 = _SSRAccumTexture[COORD_TEXTURE2D_X(int2(positionSS))]; - float2 uv = float2(positionSS) * _RTHandleScale.xy;// _ColorPyramidUvScaleAndLimitPrevFrame.xy; + float3 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS).xyz; - float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; + // Compute the radius of the projected solid angle + float dist = GetTraceDistance(positionSS); + float radiusWS = 2.0f * dist * tan(clamp(perceptualRoughness0 * 1.5707963267948966192313216916398f, 0.00125f, 1.5707963267948966192313216916398f - 0.00125f)); - float distCoef = hitData.z; - float pdf = hitData.w; + // Approximate the footprint based on the hit normal + float2 hitSS = (hitPositionNDC.xy - (0.5 * _ColorPyramidUvScaleAndLimitPrevFrame.zw)) / _ColorPyramidUvScaleAndLimitPrevFrame.zw; - float2 hitUV = hitData.xy * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - if ((hitUV.x < 0) || (hitUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || - (hitUV.y < 0) || (hitUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) - { - // Off-screen. + NormalData hitNormalData; + DecodeFromNormalBuffer(hitSS, hitNormalData); + float3 hitN = hitNormalData.normalWS; - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0; - return; - } + float3 hitPositionWS = GetWorldSpacePosition(hitSS); + float3 V = GetWorldSpaceNormalizeViewDir(hitPositionWS); - const int r = 1; - bool hasNeighbour = false; - for (int i = -r; i <= r; ++i) - { - for (int j = -r; j <= r; ++j) - { - if (i != 0 && j != 0) - { - float sidePDF = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS + int2(i, j))].w; - if (sidePDF > 0.0f) - { - hasNeighbour = true; - break; - } - } - } - if (hasNeighbour) - break; - } + float3x3 hitLocalToWorld = GetLocalFrame(hitN); - float dx = abs(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(-1, 0))] - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(+1, 0))]) * 0.5f; - float dy = abs(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2( 0, -1))] - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2( 0, +1))]) * 0.5f; + //float3 radPoint = hitPositionWS + hitLocalToWorld._11_21_31 * radiusWS; + float3 radPoint = hitPositionWS + hitLocalToWorld._11_12_13 * radiusWS; - float lap = saturate((dx + dy) * 0.5f); + // Convert to screen space radius + float4 hitCS0 = ComputeClipSpacePosition(hitPositionWS, UNITY_MATRIX_VP); + float4 hitCS1 = ComputeClipSpacePosition(radPoint, UNITY_MATRIX_VP); - float4 center = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)]; - float4 centerAccum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)]; + hitCS0 *= rcp(hitCS0.w); + hitCS0.xy = hitCS0.xy * 0.5 + 0.5; + hitCS1 *= rcp(hitCS1.w); + hitCS1.xy = hitCS1.xy * 0.5 + 0.5; - const float secur = 0.01f; - bool inBound = - //positionSS.x > secur * RTSize.x && positionSS.x < (1.0f - secur) * RTSize.x && positionSS.y > secur * RTSize.y && positionSS.y < (1.0f - secur) * RTSize.y; - //uv.x < 1.0f - secur && uv.x > secur && uv.y < 1.0f - secur && uv.y > secur; - //uv.x < 1.0f - secur && uv.x > secur && uv.y < 1.0f - secur && uv.y > secur; - true; - //bool isNewHit = pdf > 0.1f && uv.x < 0.75f && uv.x > 0.25f && uv.y < 0.75f && uv.y > 0.25f; - //bool isNewHit = pdf > 0.001f;//&& inBound; - //bool isNewHit = pdf > 0.00125f;//&& inBound; - bool isNewHit = pdf > 0.0f; + float radiusSS = length(hitCS0.xy - hitCS1.xy); - //centerAccum = ExpAvg(centerAccum, float4(0.0f, 0.0f, 0.0f, 0.0f), 0.0125f); +#define Const0 0.2206356001526516f // Log(2)/pi +#define RcpConst0 4.532360141827193f // 1/Const0 == pi/Log(2) +#define Epsilon 0.000125f - const float vanish = 0.75f; - const float safeAccum = 0.00f; - const float expAvgCol = 0.05f; + const float sigma = lerp(0.125f, 64.0f, saturate(radiusSS)); + const float invSigma = rcp(sigma); -#if 0 - if (isNewHit && centerAccum.w < 0.25f) - { - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb, 1.0f); - lap *= 0.0f; - } - else if (isNewHit && centerAccum.w >= 0.25f) - { - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - float4( - //ExpAvg(centerAccum.rgb, center.rgb, 0.25f), - lerp(centerAccum.rgb, center.rgb, 0.25f), - 1.0f); - //float4( - // ExpAvg(centerAccum.rgb, center.rgb, 0.95f), - // 1.0f); - lap *= 0.0f; - } - //else if (centerAccum.w > 0.1f) - //{ - // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - // float4( - // ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), expAvgCol), - // ExpAvg(centerAccum.w, 0.0f, expAvgCol)); - //} - else //if (centerAccum.w <= 0.1f) - //if (!isNewHit && hasNeighbour && centerAccum.w <= safeAccum) + const int rad = round(clamp(radiusSS, 0.0f, 16.0f)); + float tot = 0.0f; + float4 output = 0.0f; + for (int x = -rad; x <= rad; ++x) { - float4 accum = 0.0f; - int smplCount = 0; - float wsum = 0.0f; - for (int i = -r; i <= r; ++i) - { - for (int j = -r; j <= r; ++j) - { - float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; - //if (i != 0 && j != 0) - if (data.w > 0.0f && i != 0 && j != 0) - { - float coef = 1.0f/sqrt(dot(float2(i, j), float2(i, j))); - wsum += coef; - accum += coef*data; - ++smplCount; - } - } - } - //if (accum.w > 0.0f) - if (/*smplCount */wsum > 0) + for (int y = -rad; y <= rad; ++y) { - //accum /= accum.w; - accum /= wsum; - //float(smplCount); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = accum * 0.95f; - //float4(accum.rgb * 0.75f, accum.w * 0.95f); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb, 1.0f); - } - //float4(accum.rgb, centerAccum.w); - //float4(accum.rgb * 0.75f, centerAccum.w * 0.75f); - //float4( - // ExpAvg(centerAccum.rgb * 0.5f, accum.rgb * 0.5f, 0.75f), - // ExpAvg(centerAccum.w * 0.5f, accum.w * 0.5f, 0.75f)); - } - //else - //{ - // lap *= 0.0f; - //} -#endif + float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; + float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; + //float sigma = lerp(0.125f, 16.0f, saturate(data.w/128.f)); + //float sigma = lerp(0.125f, 32.0f, saturate(var)); + //float sigma = lerp(0.125f, 32.0f, saturate(dist)); + //if (dot(data.rgb, float3(1, 1, 1) > 0.0f)) + //if (data.w > 0.0f) + uint3 intCol = asuint(data.rgb); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; -#if 0 - if (isNewHit && centerAccum.w <= 0.0125f) - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb, 1.0f); - else if (isNewHit && centerAccum.w > 0.0125f) - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb * (1.0f - centerAccum.w) + centerAccum.w * centerAccum.rgb, 1.0f); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - float4( - ExpAvg(center.rgb, centerAccum.rgb, 0.25f), - //ExpAvg(centerAccum.w, 0.0f, 0.25f) - ExpAvg(1.0f, centerAccum.w, 0.25f) - ); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(center.rgb * (1.0f - centerAccum.w) + (centerAccum.w) * centerAccum.rgb, centerAccum.w * vanish); - else if (!isNewHit && centerAccum.w < 0.25f) - { - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - float4( - ExpAvg(center.rgb, centerAccum.rgb, 0.25f), - //ExpAvg(centerAccum.w, 0.0f, 0.25f) - ExpAvg(centerAccum.w, 0.0f, 0.45f) - ); - } - else if (hasNeighbour && inBound) - { - float3 accum = 0.0f; - float wsum = 0.0f; - int samplesCount = 0; - for (int i = -r; i <= r; ++i) - { - for (int j = -r; j <= r; ++j) - { - if (i == 0 && j == 0) - continue; - - float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; - if (data.w > 0.0f && dot(data.rgb, float3(1.0f, 1.0f, 1.0f)) > 0.1f) - { - wsum += data.w; - accum += data.rgb; - ++samplesCount; - } - } - } - if (wsum > 0.0f && dot(accum.rgb, float3(1.0f, 1.0f, 1.0f)) > 0.1f) - { - accum /= wsum; - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb * (1.0f - centerAccum.w) + (centerAccum.w) * centerAccum.rgb, 1.0f); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.25f), ExpAvg(centerAccum.w, float(wsum)/((2.0f * r + 1.0f) * (2.0f * r + 1.0f)), 0.75f)); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), 0.95f*float(wsum) / float(samplesCount)); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), 0.95f * float(wsum) / float(((2.0f * r + 1.0f) * (2.0f * r + 1.0f)))); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - float4( - ExpAvg(centerAccum.rgb, accum.rgb, 0.75f), - ExpAvg(centerAccum.w, 0.0f, 0.75f) - ); - } - } - //else - //{ - // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; - // //float4(ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), 0.95f), 1.0f); - //} -#endif + data = isPosFin ? data : 0; + float opacity = isPosFin ? data.w : 0; - if (true || isNewHit) - { - //float weight = pdf;// *distCoef; - //weight /= 4096.0f; - //weight = min(weight, 4096.0f); - //weight /= 4096.0f; - //pdf /= 4096.0f; - //if (pdf == 0.0f) - //{ - // weight = 1.0f; - //} - //pdf = min(pdf, 16.0f); - //float wsum = centerAccum.w + weight; - //if (wsum > 0.0f) - // _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - // float4(centerAccum.rgb + (weight / wsum)*(center.rgb - centerAccum.rgb), wsum); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4( - lerp(centerAccum.rgb, center.rgb, 0.00125f), - /*lerp(centerAccum.w, pdf, 0.0125f)*/1.0f); - //centerAccum * 0.75f + 0.25f * center; - //lerp(centerAccum, center, 0.0175f); - //lerp(centerAccum, center, 0.0125f); - //ExpAvg(centerAccum, center, 1.0f - 0.0000125f); - //float4(center.rgb, 1.0f); - //float4(lerp(centerAccum.rgb, center.rgb, 0.0125f), 1.0f); - //float4( - // ExpAvg(centerAccum.rgb, center.rgb, 0.000125f), - // ExpAvg(centerAccum.w, pdf, 0.000125f)); - } - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; - /*else */if (false && centerAccum.w < 0.00125f) - { - const int r = 1; - float4 accum = 0.0f; - float wsum = 0.0f; - for (int i = -r; i <= r; ++i) - { - for (int j = -r; j <= r; ++j) - { - float4 val0 = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS + int2(i, j))]; - float4 val1 = _SSRAccumTexture [COORD_TEXTURE2D_X(positionSS + int2(i, j))]; - //float4 val = val0 * 0.5f + 0.5f * val1; - float4 val = val1; - //if (i != 0 && j != 0 && dot(val.rgb, float3(1, 1, 1)) > 0.1f) - if (i != 0 && j != 0) - if (val.w > 0.0f) - { - wsum += 1.0f; - //Luminance(val.rgb); - //val.w; - //accum += val.w*val; - accum += val; - } - } - } - if (wsum > 0.0f) - { - accum /= wsum; - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - //float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.125f), centerAccum.w); - lerp(centerAccum, accum, 0.75f); - //accum; - //float4(accum.rgb, 1.0f); + float coef = invSigma * Const0 * exp2( -(x * x + y * y) * invSigma); + + tot += coef; + output += coef * data; } - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(accum.rgb, 1.0f); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = float4(ExpAvg(centerAccum.rgb, accum.rgb, 0.125f), 1.0f); - } - //else //if (false) - //if (false) - { - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), 0.05f); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - //lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), saturate(10000000000000.0f*length(motionVectorNDC))); - lerp(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], float4(0.0f, 0.0f, 0.0f, 0.0f), 0.1f); - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = - // //float4(ExpAvg(centerAccum.rgb, float3(0.0f, 0.0f, 0.0f), 0.25f), 1.0f); - // ExpAvg(centerAccum, float4(0.0f, 0.0f, 0.0f, 0.0f), 0.125f); } - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; - float3 output = 0.0f; - int rad = 32; - float tot = 0.0f; - for (int x = -rad; x <= rad; ++x) + if (tot > 0.0f) { - for (int y = -rad; y <= rad; ++y) - { - float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS + int2(x, y))]; - //if (data.w > 0.0f) - //if (x != 0 && y != 0) - { - //float sigma = lerp(0.125f, 16.0f, saturate(data.w/128.f)); - float sigma = lerp(0.125f, 128.0f, saturate(distCoef)); - float sigma2 = sigma * sigma; - float coef = rcp(sigma2 * 2.0f * 3.1415926535897932354626f) * exp2(-(float(x * x + y * y) / (2.0f * sigma2))); - tot += coef; - output += coef * data; - } - } + output = output / tot; + float2 motionVectorNDC; + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC.xy, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorNDC); + //motionVectorNDC *= _ColorPyramidUvScaleAndLimitPrevFrame.xy; + float speedDst = length(motionVectorNDC); + + float2 motionVectorCenterNDC; + float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorCenterNDC); + //motionVectorCenterNDC *= _ColorPyramidUvScaleAndLimitPrevFrame.xy; + float speedSrc = length(motionVectorCenterNDC); + float speed = (speedDst + speedDst); + //speed = speed > 0.0f ? saturate(1.0f) : 0.0f; + + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = + lerp( + _SsrPrevLightingTexture[COORD_TEXTURE2D_X(positionSS)], + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], + //output, + //1.0f - saturate(speed)); + //1.0f); + //0.125f); + //lerp(speed, 1.0f, _SsrAccumulationAmount)); + lerp(_SsrAccumulationAmount, 1.0f, saturate(speed))); + //_SsrAccumulationAmount*speed); } - output = output / tot; - - //_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = 0.0f; - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(sqrt(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].x).xxx, 1.0f); - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].www, 1.0f); - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(distCoef.xxx, 1.0f); - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(motionVectorNDC.rg, 0.0f, 1.0f); - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(output.xyz, 1.0f); - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = float4(_SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)].www, 1.0f); - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)]; - - //_SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = 0*float4(1.0f, 1.0f, 1.0f, 1.0f); } #endif + +#undef MIN_GGX_ROUGHNESS +#undef MAX_GGX_ROUGHNESS diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs index d0be0791579..0ed5a611b0b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs @@ -18,6 +18,6 @@ unsafe struct ShaderVariablesScreenSpaceReflection public int _SsrDepthPyramidMaxMip; public int _SsrColorPyramidMaxMip; public int _SsrReflectsSky; - public float _ScreenSpaceReflectionPad0; + public float _SsrAccumulationAmount; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs.hlsl index c9eb01809ca..770a0ab1865 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ShaderVariablesScreenSpaceReflection.cs.hlsl @@ -19,7 +19,7 @@ CBUFFER_START(ShaderVariablesScreenSpaceReflection) int _SsrDepthPyramidMaxMip; int _SsrColorPyramidMaxMip; int _SsrReflectsSky; - float _ScreenSpaceReflectionPad0; + float _SsrAccumulationAmount; CBUFFER_END diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index f028ef0e2b4..d58707c40d5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -726,19 +726,6 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst } #endregion - internal void AllocateScreenSpaceHistoryBuffer(float scaleFactor) - { - if (scaleFactor != m_ScreenSpaceReflectionResolutionScale || GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection) == null) - { - ReleaseHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - - var ssrAlloc = new ScreenSpaceAllocator(scaleFactor); - AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection, ssrAlloc.Allocator, 2); - - m_ScreenSpaceReflectionResolutionScale = scaleFactor; - } - } - internal void ReleaseHistoryFrameRT(int id) { m_HistoryRTSystem.ReleaseBuffer(id); @@ -878,7 +865,6 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst int m_NumColorPyramidBuffersAllocated = 0; int m_NumVolumetricBuffersAllocated = 0; float m_AmbientOcclusionResolutionScale = 0.0f; // Factor used to track if history should be reallocated for Ambient Occlusion - float m_ScreenSpaceReflectionResolutionScale = 0.0f; // Need another factor if AO not used in the same time with SSR ViewConstants[] m_XRViewConstants; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 38a790aa51a..95c52429323 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -23,8 +23,6 @@ public enum HDCameraFrameHistoryType Depth1, /// Ambient Occlusion buffer. AmbientOcclusion, - /// Screen Space Reflection buffer. - ScreenSpaceReflection, /// Ray traced ambient occlusion buffer. RaytracedAmbientOcclusion, /// Ray traced shadow history buffer. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index 7143a72d034..78fdb666435 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -36,7 +36,7 @@ internal enum HDProfileId SubsurfaceScattering, SsrTracing, SsrReprojection, - SsrDenoiseInpainting, + SsrAccumulate, PrepareForTransparentSsr, // SSGI diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index d337ab443cd..29f8cac277d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -459,15 +459,12 @@ TextureHandle RenderSSR( RenderGraph renderGraph, { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Hit_Point_Texture" }); passData.lightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" })); - //passData.hitPointsTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - // { colorFormat = GraphicsFormat.ARGBFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Debug_Texture" })); + passData.prevLightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Prev_Lighting_Texture" })); passData.ssrAccumPointTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Accum_Texture" })); - var ssrPrevious = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection)); - passData.prevLightingTexture = builder.ReadTexture(ssrPrevious); - builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index dfb93b60950..3c73a2119bd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -151,7 +151,7 @@ internal static Volume GetOrCreateDefaultVolume() ComputeShader m_ScreenSpaceReflectionsCS { get { return defaultResources.shaders.screenSpaceReflectionsCS; } } int m_SsrTracingKernel = -1; int m_SsrReprojectionKernel = -1; - int m_SsrDenoiseInpaintingKernel = -1; + int m_SsrAccumulateKernel = -1; Material m_ApplyDistortionMaterial; @@ -193,7 +193,8 @@ internal static Volume GetOrCreateDefaultVolume() // RTHandle m_SsrDebugTexture; RTHandle m_SsrHitPointTexture; RTHandle m_SsrAccumPointTexture; - //RTHandle m_SsrLightingTexture; + RTHandle m_SsrLightingTexture; + RTHandle m_SsrPrevLightingTexture; // MSAA Versions of regular textures RTHandle m_CameraColorMSAABuffer; RTHandle m_OpaqueAtmosphericScatteringMSAABuffer; // Necessary to perform dual-source (polychromatic alpha) blending which is not supported by Unity @@ -471,7 +472,7 @@ public HDRenderPipeline(HDRenderPipelineAsset asset, HDRenderPipelineAsset defau // Initialize various compute shader resources m_SsrTracingKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsTracing"); m_SsrReprojectionKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsReprojection"); - m_SsrDenoiseInpaintingKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsDenoiseInpainting"); + m_SsrAccumulateKernel = m_ScreenSpaceReflectionsCS.FindKernel("ScreenSpaceReflectionsAccumulate"); // General material m_CameraMotionVectorsMaterial = CoreUtils.CreateEngineMaterial(defaultResources.shaders.cameraMotionVectorsPS); @@ -730,13 +731,12 @@ void InitializeRenderTextures() m_LowResTransparentBuffer = RTHandles.Alloc(Vector2.one * 0.5f, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "Low res transparent"); } - if (settings.supportSSR && (m_SsrHitPointTexture == null || m_SsrAccumPointTexture == null)) + if (settings.supportSSR) { - // m_SsrDebugTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Debug_Texture"); - //m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); m_SsrAccumPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Accum_Texture"); - //m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); + m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); + m_SsrPrevLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Prev_Lighting_Texture"); } // Let's create the MSAA textures @@ -791,7 +791,9 @@ void DestroyRenderTextures() // RTHandles.Release(m_SsrDebugTexture); RTHandles.Release(m_SsrHitPointTexture); - //RTHandles.Release(m_SsrLightingTexture); + RTHandles.Release(m_SsrAccumPointTexture); + RTHandles.Release(m_SsrLightingTexture); + RTHandles.Release(m_SsrPrevLightingTexture); RTHandles.Release(m_CameraColorMSAABuffer); RTHandles.Release(m_OpaqueAtmosphericScatteringMSAABuffer); @@ -1245,8 +1247,8 @@ void Resize(HDCamera hdCamera) m_SharedRTManager.AllocateCoarseStencilBuffer(m_MaxCameraWidth, m_MaxCameraHeight, hdCamera.viewCount); } - if (hdCamera.IsSSREnabled()) - hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); + //if (hdCamera.IsSSREnabled()) + // hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); } } @@ -2231,7 +2233,6 @@ ref _cullingResults UnityEngine.Rendering.RenderPipeline.EndFrameRendering(renderContext, cameras); } - void PropagateScreenSpaceShadowData() { // For every unique light that has been registered, update the previous transform @@ -2824,7 +2825,7 @@ void Callback(CommandBuffer c, HDCamera cam) } // We push the motion vector debug texture here as transparent object can overwrite the motion vector texture content. - if(m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors) + if (m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors) PushFullScreenDebugTexture(hdCamera, cmd, m_SharedRTManager.GetMotionVectorsBuffer(), FullScreenDebugMode.MotionVectors); // Second resolve the color buffer for finishing the frame @@ -4561,7 +4562,7 @@ struct RenderSSRParameters public ComputeShader ssrCS; public int tracingKernel; public int reprojectionKernel; - public int denoiseInpaintingKernel; + public int accumulateKernel; public bool transparentSSR; public int width, height, viewCount; @@ -4579,7 +4580,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip parameters.ssrCS = m_ScreenSpaceReflectionsCS; parameters.tracingKernel = m_SsrTracingKernel; parameters.reprojectionKernel = m_SsrReprojectionKernel; - parameters.denoiseInpaintingKernel = m_SsrDenoiseInpaintingKernel; + parameters.accumulateKernel = m_SsrAccumulateKernel; parameters.transparentSSR = transparentSSR; parameters.width = hdCamera.actualWidth; @@ -4605,6 +4606,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip cb._ColorPyramidUvScaleAndLimitPrevFrame = HDUtils.ComputeViewportScaleAndLimit(hdCamera.historyRTHandleProperties.previousViewportSize, hdCamera.historyRTHandleProperties.previousRenderTargetSize); cb._SsrColorPyramidMaxMip = hdCamera.colorPyramidHistoryMipCount - 1; cb._SsrDepthPyramidMaxMip = depthPyramid.mipLevelCount - 1; + cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -12.0f, volumeSettings.accumulationFactor.value)); parameters.offsetBufferData = depthPyramid.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); @@ -4668,37 +4670,45 @@ static void RenderSSR( in RenderSSRParameters parameters, using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrReprojection))) { - // cmd.SetComputeTextureParam(cs, kernel, "_SsrDebugTexture", m_SsrDebugTexture); + if (parameters.transparentSSR) + { + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", true); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._DepthTexture, depthTexture); + } + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraDepthTexture, depthPyramid); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); - if (prevSSRLightingTexture != null) - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); - if (ssrLightingTexture != null) - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); cmd.DispatchCompute(cs, parameters.reprojectionKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); } - using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrDenoiseInpainting))) + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrAccumulate))) { - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); - if (ssrLightingTexture != null) - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); - if (prevSSRLightingTexture != null) - cmd.SetComputeTextureParam(cs, parameters.denoiseInpaintingKernel, HDShaderIDs._PrevSSRLightingTexture, prevSSRLightingTexture); + if (parameters.transparentSSR) + { + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", true); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._DepthTexture, depthTexture); + } + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraDepthTexture, depthPyramid); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrPrevLightingTexture, prevSSRLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); - cmd.DispatchCompute(cs, parameters.denoiseInpaintingKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + cmd.DispatchCompute(cs, parameters.accumulateKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); } } @@ -4710,14 +4720,11 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren return; } - RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - var settings = hdCamera.volumeStack.GetComponent(); bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) { - RenderRayTracedReflections(hdCamera, cmd, ssrLightingTexture, renderContext, m_FrameCount); + RenderRayTracedReflections(hdCamera, cmd, m_SsrLightingTexture, renderContext, m_FrameCount); } else { @@ -4730,7 +4737,7 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)), clearCoatMask, previousColorPyramid, - m_SsrAccumPointTexture, ssrLightingTexture, prevSSRLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + m_SsrAccumPointTexture, m_SsrLightingTexture, m_SsrPrevLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); if (!hdCamera.colorPyramidHistoryIsValid) { @@ -4739,10 +4746,10 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren } } - - if (ssrLightingTexture != null) - cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, ssrLightingTexture); - PushFullScreenDebugTexture(hdCamera, cmd, ssrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); + //if (ssrLightingTexture != null) + cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, m_SsrLightingTexture); + PushFullScreenDebugTexture(hdCamera, cmd, m_SsrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); + PushFullScreenDebugTexture(hdCamera, cmd, m_SsrPrevLightingTexture, FullScreenDebugMode.ScreenSpaceReflectionsPrev); PushFullScreenDebugTexture(hdCamera, cmd, m_SsrAccumPointTexture, FullScreenDebugMode.ScreenSpaceReflectionsAccum); } @@ -4751,25 +4758,27 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender if (!hdCamera.IsSSREnabled(transparent: true)) return; - RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + //RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + //RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); var settings = hdCamera.volumeStack.GetComponent(); bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) { - RenderRayTracedReflections(hdCamera, cmd, ssrLightingTexture, renderContext, m_FrameCount, true); + RenderRayTracedReflections(hdCamera, cmd, /*ssrLightingTexture*/m_SsrLightingTexture, renderContext, m_FrameCount, true); } else { BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd); + //hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); + // Before doing anything, we need to clear the target buffers and rebuild the depth pyramid for tracing // NOTE: This is probably something we can avoid if we read from the depth buffer and traced on the pyramid without the transparent objects using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.PrepareForTransparentSsr))) { // Clear the SSR lighting buffer (not sure it is required) - CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); + CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); } @@ -4778,7 +4787,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), true); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, - m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrAccumPointTexture, ssrLightingTexture, prevSSRLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrAccumPointTexture, /*ssrLightingTexture*/m_SsrLightingTexture, m_SsrPrevLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); // If color pyramid was not valid, we bind a black texture if (!hdCamera.colorPyramidHistoryIsValid) @@ -4789,7 +4798,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender } // Push our texture to the debug menu - PushFullScreenDebugTexture(hdCamera, cmd, ssrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); + PushFullScreenDebugTexture(hdCamera, cmd, /*ssrLightingTexture*/m_SsrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); } void RenderColorPyramid(HDCamera hdCamera, CommandBuffer cmd, bool isPreRefraction) @@ -5160,7 +5169,6 @@ static void ResolveColorPickerDebug(in DebugParameters parameters, HDUtils.DrawFullScreen(cmd, parameters.colorPickerMaterial, output); } - static void RenderExposureDebug(in DebugParameters parameters, RTHandle inputColorBuffer, RTHandle postprocessedColorBuffer, @@ -5418,15 +5426,19 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ClearSsrBuffers))) { + //RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + // In practice, these textures are sparse (mostly black). Therefore, clearing them is fast (due to CMASK), // and much faster than fully overwriting them from within SSR shaders. // CoreUtils.SetRenderTarget(cmd, hdCamera, m_SsrDebugTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - if (ssrLightingTexture != null) - { - CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); - } + //if (ssrLightingTexture != null) + // CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); + //CoreUtils.Swap(ref m_SsrLightingTexture, ref m_SsrPrevLightingTexture); + //CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); + cmd.CopyTexture(m_SsrLightingTexture, m_SsrPrevLightingTexture); + CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.None); + CoreUtils.SetRenderTarget(cmd, m_SsrAccumPointTexture, ClearFlag.Color, Color.clear); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index c21fb461ec7..f68625e36e5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -328,9 +328,9 @@ static class HDShaderIDs public static readonly int _ShaderVariablesScreenSpaceReflection = Shader.PropertyToID("ShaderVariablesScreenSpaceReflection"); public static readonly int _SsrLightingTexture = Shader.PropertyToID("_SsrLightingTexture"); + public static readonly int _SsrPrevLightingTexture = Shader.PropertyToID("_SsrPrevLightingTexture"); public static readonly int _SsrLightingTextureRW = Shader.PropertyToID("_SsrLightingTextureRW"); public static readonly int _SSRAccumTexture = Shader.PropertyToID("_SSRAccumTexture"); - public static readonly int _PrevSSRLightingTexture = Shader.PropertyToID("_PrevSSRLightingTexture"); public static readonly int _SsrHitPointTexture = Shader.PropertyToID("_SsrHitPointTexture"); public static readonly int _SsrClearCoatMaskTexture = Shader.PropertyToID("_SsrClearCoatMaskTexture"); public static readonly int _DepthPyramidMipLevelOffsets = Shader.PropertyToID("_DepthPyramidMipLevelOffsets"); From 8f0c4a016ed686a1d173353eaa577286d7a1e1cd Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 17 Sep 2020 17:17:26 +0200 Subject: [PATCH 06/41] Add doc --- .../Documentation~/Override-Screen-Space-Reflection.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md index dcba2e1b61b..4656fdd6e62 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md @@ -31,4 +31,5 @@ HDRP uses the [Volume](Volumes.md) framework to calculate SSR, so to enable and | **Object Thickness** | Use the slider to control the thickness of the GameObjects on screen. Because the SSR algorithm can not distinguish thin GameObjects from thick ones, this property helps trace rays behind GameObjects. The algorithm applies this property to every GameObject uniformly. | | **Min Smoothness** | Use the slider to set the minimum amount of surface smoothness at which HDRP performs SSR tracing. Lower values result in HDRP performing SSR tracing for less smooth GameObjects. | | **Smoothness Fade Start** | Use the slider to set the smoothness value at which SSR reflections begin to fade out. Lower values result in HDRP fading out SSR reflections for less smooth GameObjects | -| **Reflect Sky** | Indicates whether HDRP should use SSR to handle sky reflection. If you disable this property, pixels that reflect the sky use the next level of the [reflection hierarchy](Reflection-in-HDRP.md#ReflectionHierarchy).
**Note**: SSR uses the depth buffer to calculate reflection and HDRP does not add transparent GameObjects to the depth buffer. If you enable this property, transparent GameObject that appear over the sky in the color buffer can cause visual artifacts and incorrect looking reflection. This is a common limitation for SSR techniques. | \ No newline at end of file +| **Reflect Sky** | Indicates whether HDRP should use SSR to handle sky reflection. If you disable this property, pixels that reflect the sky use the next level of the [reflection hierarchy](Reflection-in-HDRP.md#ReflectionHierarchy).
**Note**: SSR uses the depth buffer to calculate reflection and HDRP does not add transparent GameObjects to the depth buffer. If you enable this property, transparent GameObject that appear over the sky in the color buffer can cause visual artifacts and incorrect looking reflection. This is a common limitation for SSR techniques. | +| **Accumulation Factor** | Use the slider to control the speed of converge. 0 mean no accumulation, on the result of the current frame is used. 1 mean accumulation is very slowly which is useful for fixed image. Use carefuly to find a balance between convergence and ghosting. More rough image need accumulation to image converged. | \ No newline at end of file From 2b39f2fcb8c4872c72ba3b9c628d6a910c9b6f29 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 17 Sep 2020 17:42:37 +0200 Subject: [PATCH 07/41] ChangeLog + small fix --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 1 + .../ScreenSpaceLighting/ScreenSpaceReflections.compute | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index c3ae54de7f0..74d1611e11d 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added option for 11-11-10 format for cube reflection probes. - Added an optional check in the HDRP DXR Wizard to verify 64 bits target architecture - Added option to display timing stats in the debug menu as an average over 1 second. +- Added new algorithm for SSR with temporal accumulation ### Fixed - Fixed several issues with physically-based DoF (TAA ghosting of the CoC buffer, smooth layer transitions, etc) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 66825ae9ffa..a49c8bcdfe4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -71,7 +71,6 @@ TEXTURE2D_X(_DepthTexture); #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); RW_TEXTURE2D_X(float4, _SsrHitPointTexture); - RW_TEXTURE2D_X(float4, _SSRInfoTexture); #elif defined(SSR_REPROJECT) TEXTURE2D_X( _SsrHitPointTexture); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture @@ -624,8 +623,6 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // It also needs to be precisely at the center of the pixel to avoid artifacts. float2 hitPositionNDC = floor(rayPos.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, t, weight); - float3 res = _SSRInfoTexture[COORD_TEXTURE2D_X(positionSS)].rgb; - _SSRInfoTexture[COORD_TEXTURE2D_X(positionSS)] = float4(res, NdotV); } // If we do not hit anything, 'rayPos.xy' provides an indication where we stopped the search. From fd0b761db3f9bf1af292e9276b932f15e7648109 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 17 Sep 2020 18:33:08 +0200 Subject: [PATCH 08/41] Speed dependend convergence --- .../ScreenSpaceLighting/ScreenSpaceReflections.compute | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index a49c8bcdfe4..9b38e6f7ca6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -837,19 +837,13 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread //motionVectorCenterNDC *= _ColorPyramidUvScaleAndLimitPrevFrame.xy; float speedSrc = length(motionVectorCenterNDC); float speed = (speedDst + speedDst); - //speed = speed > 0.0f ? saturate(1.0f) : 0.0f; + speed = speed > 0.0f ? 1.0f : 0.0f; _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = lerp( _SsrPrevLightingTexture[COORD_TEXTURE2D_X(positionSS)], _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], - //output, - //1.0f - saturate(speed)); - //1.0f); - //0.125f); - //lerp(speed, 1.0f, _SsrAccumulationAmount)); - lerp(_SsrAccumulationAmount, 1.0f, saturate(speed))); - //_SsrAccumulationAmount*speed); + lerp(_SsrAccumulationAmount, 1.0f, speed)); } } From 8d1f573060e3f1636280b0f594955d349e4e5b46 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 17 Sep 2020 18:38:50 +0200 Subject: [PATCH 09/41] Clean code --- .../Runtime/Debug/DebugDisplay.cs | 10 ++++------ .../Runtime/Debug/DebugFullScreen.shader | 1 - .../RenderPipeline/HDRenderPipeline.LightLoop.cs | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 818989904d0..1c5f822b95a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -57,14 +57,12 @@ public enum FullScreenDebugMode MinLightingFullScreenDebug, /// Display Screen Space Ambient Occlusion buffer. ScreenSpaceAmbientOcclusion, - /// Display Screen Space Reflections buffer. + /// Display Screen Space Reflections buffer used for lighting. ScreenSpaceReflections, - /// Display Screen Space Reflections buffer. + /// Display Screen Space Reflections buffer of the previous frame accumulated. ScreenSpaceReflectionsPrev, - /// Display Screen Space Reflections buffer. + /// Display Screen Space Reflections buffer of the current frame hit. ScreenSpaceReflectionsAccum, - /// Display Screen Space Information buffer. - ScreenSpaceReflectionsInfo, /// Display the Transparent Screen Space Reflections buffer. TransparentScreenSpaceReflections, /// Display Contact Shadows buffer. @@ -1881,7 +1879,7 @@ internal bool DebugNeedsExposure() debugLighting == DebugLightingMode.DiffuseLighting || debugLighting == DebugLightingMode.SpecularLighting || debugLighting == DebugLightingMode.VisualizeCascade) || (data.lightingDebugSettings.overrideAlbedo || data.lightingDebugSettings.overrideNormal || data.lightingDebugSettings.overrideSmoothness || data.lightingDebugSettings.overrideSpecularColor || data.lightingDebugSettings.overrideEmissiveColor || data.lightingDebugSettings.overrideAmbientOcclusion) || (debugGBuffer == DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive) || (data.lightingDebugSettings.debugLightFilterMode != DebugLightFilterMode.None) || - (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsPrev || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsInfo || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || + (data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsPrev || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination || (debugLighting == DebugLightingMode.ProbeVolume || debugProbeVolume == ProbeVolumeDebugMode.VisualizeAtlas); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader index 367621a1cc5..d8fe4f841f3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader @@ -306,7 +306,6 @@ Shader "Hidden/HDRP/DebugFullScreen" if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS || _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV || _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM || - _FullScreenDebugMode == FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_INFO || _FullScreenDebugMode == FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS) { float4 color = SAMPLE_TEXTURE2D_X(_DebugFullScreenTexture, s_point_clamp_sampler, input.texcoord) * GetCurrentExposureMultiplier(); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 41f890ee2f0..ede6f866801 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -502,7 +502,6 @@ TextureHandle RenderSSR( RenderGraph renderGraph, } PushFullScreenDebugTexture(renderGraph, result, transparent ? FullScreenDebugMode.TransparentScreenSpaceReflections : FullScreenDebugMode.ScreenSpaceReflections); - //PushFullScreenDebugTexture(renderGraph, result, FullScreenDebugMode.ScreenSpaceReflectionsAccum); return result; } From ffa19bfe7389e642c3cf38f85fae5a90ad4e079e Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 21 Sep 2020 22:24:22 +0200 Subject: [PATCH 10/41] Fix multicamera + SSR --- .../ScreenSpaceReflections.compute | 3 +- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 26 +++++++++ .../Camera/HDCameraFrameHistoryType.cs | 2 + .../HDRenderPipeline.LightLoop.cs | 7 ++- .../RenderPipeline/HDRenderPipeline.cs | 58 +++++++++++-------- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 9b38e6f7ca6..27f30c7a434 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -79,7 +79,7 @@ TEXTURE2D_X(_DepthTexture); TEXTURE2D_X( _SsrHitPointTexture); RW_TEXTURE2D_X(float4, _SsrPrevLightingTexture); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); - TEXTURE2D_X( _SSRAccumTexture); + RW_TEXTURE2D_X(float4, _SSRAccumTexture); #endif TEXTURE2D_X( _SsrClearCoatMaskTexture); @@ -844,6 +844,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread _SsrPrevLightingTexture[COORD_TEXTURE2D_X(positionSS)], _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], lerp(_SsrAccumulationAmount, 1.0f, speed)); + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)]; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index cb9254b7965..39e919d239e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -765,6 +765,19 @@ internal void AllocateAmbientOcclusionHistoryBuffer(float scaleFactor) } } + public void AllocateScreenSpaceAccumulationHistoryBuffer(float scaleFactor) + { + if (scaleFactor != m_ScreenSpaceAccumulationResolutionScale|| GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation) == null) + { + ReleaseHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + + var ssrAlloc = new ScreenSpaceAccumulationAllocator(scaleFactor); + AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation, ssrAlloc.Allocator, 2); + + m_ScreenSpaceAccumulationResolutionScale = scaleFactor; + } + } + #region Private API // Workaround for the Allocator callback so it doesn't allocate memory because of the capture of scaleFactor. struct ScreenSpaceAllocator @@ -910,6 +923,18 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst } } + struct ScreenSpaceAccumulationAllocator + { + float scaleFactor; + + public ScreenSpaceAccumulationAllocator(float scaleFactor) => this.scaleFactor = scaleFactor; + + public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSystem) + { + return rtHandleSystem.Alloc(Vector2.one * scaleFactor, TextureXR.slices, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, dimension: TextureXR.dimension, useDynamicScale: true, enableRandomWrite: true, name: string.Format("{0}_SSR_Accum Packed history_{1}", id, frameIndex)); + } + } + static Dictionary<(Camera, int), HDCamera> s_Cameras = new Dictionary<(Camera, int), HDCamera>(); static List<(Camera, int)> s_Cleanup = new List<(Camera, int)>(); // Recycled to reduce GC pressure @@ -918,6 +943,7 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst int m_NumColorPyramidBuffersAllocated = 0; int m_NumVolumetricBuffersAllocated = 0; float m_AmbientOcclusionResolutionScale = 0.0f; // Factor used to track if history should be reallocated for Ambient Occlusion + float m_ScreenSpaceAccumulationResolutionScale = 0.0f; // Use another scale if AO & SSR don't have the same resolution ViewConstants[] m_XRViewConstants; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 95c52429323..340bb3cbcac 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -23,6 +23,8 @@ public enum HDCameraFrameHistoryType Depth1, /// Ambient Occlusion buffer. AmbientOcclusion, + /// Screen Space Reflection Accumulation. + ScreenSpaceReflectionAccumulation, /// Ray traced ambient occlusion buffer. RaytracedAmbientOcclusion, /// Ray traced shadow history buffer. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index ede6f866801..271db7939c3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -466,15 +466,16 @@ TextureHandle RenderSSR( RenderGraph renderGraph, passData.lightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" })); passData.prevLightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Prev_Lighting_Texture" })); + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Prev_Lighting_Texture" })); - passData.ssrAccumPointTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Accum_Texture" })); + //passData.ssrAccumPointTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) + // { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Accum_Texture" })); builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { RenderSSR(data.parameters, + hdCamera, GetBlueNoiseManager(), data.depthBuffer, data.depthPyramid, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index d21833b5f54..6f22ad48d4d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -194,9 +194,9 @@ internal static Volume GetOrCreateDefaultVolume() // TODO: remove me, I am just a temporary debug texture. :-) // RTHandle m_SsrDebugTexture; RTHandle m_SsrHitPointTexture; - RTHandle m_SsrAccumPointTexture; + //RTHandle m_SsrCurrentTexture; RTHandle m_SsrLightingTexture; - RTHandle m_SsrPrevLightingTexture; + //RTHandle m_SsrPrevLightingTexture; // MSAA Versions of regular textures RTHandle m_CameraColorMSAABuffer; RTHandle m_OpaqueAtmosphericScatteringMSAABuffer; // Necessary to perform dual-source (polychromatic alpha) blending which is not supported by Unity @@ -746,9 +746,9 @@ void InitializeRenderTextures() if (settings.supportSSR) { m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); - m_SsrAccumPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Accum_Texture"); + //m_SsrCurrentTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Accum_Texture"); m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); - m_SsrPrevLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Prev_Lighting_Texture"); + //m_SsrPrevLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Prev_Lighting_Texture"); } // Let's create the MSAA textures @@ -803,9 +803,9 @@ void DestroyRenderTextures() // RTHandles.Release(m_SsrDebugTexture); RTHandles.Release(m_SsrHitPointTexture); - RTHandles.Release(m_SsrAccumPointTexture); + //RTHandles.Release(m_SsrCurrentTexture); RTHandles.Release(m_SsrLightingTexture); - RTHandles.Release(m_SsrPrevLightingTexture); + //RTHandles.Release(m_SsrPrevLightingTexture); RTHandles.Release(m_CameraColorMSAABuffer); RTHandles.Release(m_OpaqueAtmosphericScatteringMSAABuffer); @@ -4650,6 +4650,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip } static void RenderSSR( in RenderSSRParameters parameters, + HDCamera camera, BlueNoise blueNoise, RTHandle depthTexture, RTHandle depthPyramid, @@ -4659,9 +4660,9 @@ static void RenderSSR( in RenderSSRParameters parameters, RTHandle stencilBuffer, RTHandle clearCoatMask, RTHandle previousColorPyramid, - RTHandle ssrAccumPointTexture, + RTHandle ssrAccum, RTHandle ssrLightingTexture, - RTHandle prevSSRLightingTexture, + RTHandle ssrAccumPrev, ComputeBuffer coarseStencilBuffer, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -4715,7 +4716,7 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); @@ -4736,9 +4737,9 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccumPointTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrPrevLightingTexture, prevSSRLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrPrevLightingTexture, ssrAccumPrev); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); @@ -4764,6 +4765,11 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren } else { + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f + + RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + var previousColorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); // Evaluate the clear coat mask texture based on the lit shader mode @@ -4771,22 +4777,22 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), false); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); - RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, + RenderSSR(parameters, hdCamera, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)), clearCoatMask, previousColorPyramid, - m_SsrAccumPointTexture, m_SsrLightingTexture, m_SsrPrevLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + ssrAccumulation, m_SsrLightingTexture, ssrAccumulationPrev, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); if (!hdCamera.colorPyramidHistoryIsValid) { cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, TextureXR.GetClearTexture()); hdCamera.colorPyramidHistoryIsValid = true; // For the next frame... } + + PushFullScreenDebugTexture(hdCamera, cmd, ssrAccumulation, FullScreenDebugMode.ScreenSpaceReflectionsAccum); + PushFullScreenDebugTexture(hdCamera, cmd, ssrAccumulationPrev, FullScreenDebugMode.ScreenSpaceReflectionsPrev); } - //if (ssrLightingTexture != null) cmd.SetGlobalTexture(HDShaderIDs._SsrLightingTexture, m_SsrLightingTexture); PushFullScreenDebugTexture(hdCamera, cmd, m_SsrLightingTexture, FullScreenDebugMode.ScreenSpaceReflections); - PushFullScreenDebugTexture(hdCamera, cmd, m_SsrPrevLightingTexture, FullScreenDebugMode.ScreenSpaceReflectionsPrev); - PushFullScreenDebugTexture(hdCamera, cmd, m_SsrAccumPointTexture, FullScreenDebugMode.ScreenSpaceReflectionsAccum); } void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext) @@ -4794,9 +4800,6 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender if (!hdCamera.IsSSREnabled(transparent: true)) return; - //RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - //RTHandle prevSSRLightingTexture = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); - var settings = hdCamera.volumeStack.GetComponent(); bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) @@ -4810,7 +4813,10 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // re-enabled in the shader. BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd, resolveOnly: true); - //hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f + + RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); // Before doing anything, we need to clear the target buffers and rebuild the depth pyramid for tracing // NOTE: This is probably something we can avoid if we read from the depth buffer and traced on the pyramid without the transparent objects @@ -4825,8 +4831,8 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender var previousColorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), true); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); - RenderSSR(parameters, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, - m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrAccumPointTexture, /*ssrLightingTexture*/m_SsrLightingTexture, m_SsrPrevLightingTexture, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + RenderSSR(parameters, hdCamera, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, + m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, ssrAccumulation, /*ssrLightingTexture*/m_SsrLightingTexture, ssrAccumulationPrev, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); // If color pyramid was not valid, we bind a black texture if (!hdCamera.colorPyramidHistoryIsValid) @@ -5467,7 +5473,9 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ClearSsrBuffers))) { - //RTHandle ssrLightingTexture = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflection); + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); + + RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); // In practice, these textures are sparse (mostly black). Therefore, clearing them is fast (due to CMASK), // and much faster than fully overwriting them from within SSR shaders. @@ -5477,9 +5485,9 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) // CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); //CoreUtils.Swap(ref m_SsrLightingTexture, ref m_SsrPrevLightingTexture); //CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); - cmd.CopyTexture(m_SsrLightingTexture, m_SsrPrevLightingTexture); + //cmd.CopyTexture(m_SsrLightingTexture, m_SsrPrevLightingTexture); CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.None); - CoreUtils.SetRenderTarget(cmd, m_SsrAccumPointTexture, ClearFlag.Color, Color.clear); + CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); } } From 4203364608550053a683be19896e096192ba4ca2 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 22 Sep 2020 20:53:30 +0200 Subject: [PATCH 11/41] Cleanup --- .../ScreenSpaceReflections.compute | 65 +++++-------------- .../HDRenderPipeline.LightLoop.cs | 23 +++---- .../RenderPipeline/HDRenderPipeline.cs | 13 +--- .../RenderPipeline/HDStringConstants.cs | 2 +- 4 files changed, 29 insertions(+), 74 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 27f30c7a434..776bfc1426c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -77,7 +77,7 @@ TEXTURE2D_X(_DepthTexture); RW_TEXTURE2D_X(float4, _SSRAccumTexture); #else //if defined(SSR_ACCUMULATE) TEXTURE2D_X( _SsrHitPointTexture); - RW_TEXTURE2D_X(float4, _SsrPrevLightingTexture); + RW_TEXTURE2D_X(float4, _SsrAccumPrev); RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); RW_TEXTURE2D_X(float4, _SSRAccumTexture); #endif @@ -151,18 +151,13 @@ bool SampleGGX(float roughness_, float3 localL = 2.0 * VdotH * localH - localV; outgoingDir = mul(localL, localToWorld); - //if (localL.z < 0.001 || !IsAbove(mtlData, outgoingDir)) if (localL.z < 0.001) return false; - //float pdfNoGV = D_AnisoGGX(roughnessX, roughnessY, localH) / (4.0 * localV.z); - //float pdfNoGV = D_AnisoGGX(roughness, roughness, localH) / (4.0 * localV.z); float pdfNoGV = D_GGX(localH.z, roughness); - //float lambdaVPlusOne = Lambda_AnisoGGX(roughnessX, roughnessY, localV) + 1.0; float lambdaVPlusOne = Lambda_GGX(roughness, localV) + 1.0; pdf = pdfNoGV / lambdaVPlusOne; - //float lambdaL = Lambda_AnisoGGX(roughnessX, roughnessY, localL); float lambdaL = Lambda_GGX(roughness, localL); fresnel = F_Schlick(fresnel0, VdotH); value = fresnel * pdfNoGV / (lambdaVPlusOne + lambdaL); @@ -280,10 +275,9 @@ float3 GetWorldSpacePosition(uint2 positionSS) float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; #endif - //float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); - float2 positionNDC = positionSS;// *_ScreenSize.zw + (0.5 * _ScreenSize.zw); + float2 positionNDC = positionSS *_ScreenSize.zw + (0.5 * _ScreenSize.zw); - return ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP/*UNITY_MATRIX_PREV_I_VP*/); + return ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP); } float2 GetWorldSpacePoint(uint2 positionSS, out float3 positionSrcWS, out float3 positionDstWS) @@ -292,7 +286,6 @@ float2 GetWorldSpacePoint(uint2 positionSS, out float3 positionSrcWS, out float3 float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; uint2 positionDstSS = (hitData.xy - (0.5 * _ScreenSize.zw)) / _ScreenSize.zw; - //uint2 positionDstSS = hitData.xy; positionDstWS = GetWorldSpacePosition(positionDstSS); @@ -638,13 +631,12 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre uint2 positionSS0 = dispatchThreadId.xy; float3 N; - float perceptualRoughness0; - GetNormalAndPerceptualRoughness(positionSS0, N, perceptualRoughness0); + float perceptualRoughness; + GetNormalAndPerceptualRoughness(positionSS0, N, perceptualRoughness); // Compute the actual roughness - float roughness0 = PerceptualRoughnessToRoughness(perceptualRoughness0); - - roughness0 = clamp(roughness0, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); + float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS0).xy; @@ -661,29 +653,10 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float2 uv = float2(positionSS0) * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float pdf0, weight0; - float dist0; - float NdotL0, NdotH0, VdotH0, NdotV0; - float3 R0, V0, N0; - float3 positionWS0; - float perceptualRoughness; - GetHitInfos(positionSS0, hitPositionNDC, perceptualRoughness, positionWS0, pdf0, weight0, N0, R0, V0, dist0, NdotL0, NdotH0, VdotH0, NdotV0); - float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; float opacity = 1.0f; - if (NdotL0 < 0.001f || pdf0 < 0.001f) - { - return; - } - float2 hitUV0 = hitPositionNDC.xy * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - if ((hitUV0.x < 0) || (hitUV0.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || - (hitUV0.y < 0) || (hitUV0.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) - { - // Off-screen. - return; - } if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) { // Miss. @@ -732,9 +705,6 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre if (wAll > 0.0f) { - //float2 coordLUT = Remap01ToHalfTexelCoord(float2(sqrt(NdotV0), roughness0), FGDTEXTURE_RESOLUTION); - //float E = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD_GGXDisneyDiffuse, s_linear_clamp_sampler, coordLUT, 0).y; - //float E0 = (1.0 - E) / E; _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = outputs / wAll; } } @@ -805,11 +775,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread { float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; - //float sigma = lerp(0.125f, 16.0f, saturate(data.w/128.f)); - //float sigma = lerp(0.125f, 32.0f, saturate(var)); - //float sigma = lerp(0.125f, 32.0f, saturate(dist)); - //if (dot(data.rgb, float3(1, 1, 1) > 0.0f)) - //if (data.w > 0.0f) + uint3 intCol = asuint(data.rgb); bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; @@ -828,23 +794,22 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread output = output / tot; float2 motionVectorNDC; DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC.xy, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorNDC); - //motionVectorNDC *= _ColorPyramidUvScaleAndLimitPrevFrame.xy; float speedDst = length(motionVectorNDC); float2 motionVectorCenterNDC; float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorCenterNDC); - //motionVectorCenterNDC *= _ColorPyramidUvScaleAndLimitPrevFrame.xy; float speedSrc = length(motionVectorCenterNDC); float speed = (speedDst + speedDst); speed = speed > 0.0f ? 1.0f : 0.0f; - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = - lerp( - _SsrPrevLightingTexture[COORD_TEXTURE2D_X(positionSS)], - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], - lerp(_SsrAccumulationAmount, 1.0f, speed)); - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)]; + float4 result = lerp( + _SsrAccumPrev[COORD_TEXTURE2D_X(positionSS)], + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], + lerp(_SsrAccumulationAmount, 1.0f, speed)); + + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 271db7939c3..ce889df72a9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -398,9 +398,9 @@ class RenderSSRPassData public TextureHandle colorPyramid; public TextureHandle stencilBuffer; public TextureHandle hitPointsTexture; - public TextureHandle ssrAccumPointTexture; + public TextureHandle ssrAccum; public TextureHandle lightingTexture; - public TextureHandle prevLightingTexture; + public TextureHandle ssrAccumPrev; public TextureHandle clearCoatMask; public ComputeBufferHandle coarseStencilBuffer; //public TextureHandle debugTexture; @@ -444,6 +444,11 @@ TextureHandle RenderSSR( RenderGraph renderGraph, var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f + + var ssrAccum = renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation)); + var ssrAccumPrev = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation)); + passData.parameters = PrepareSSRParameters(hdCamera, m_DepthBufferMipChainInfo, transparent); passData.depthBuffer = builder.ReadTexture(prepassOutput.depthBuffer); passData.depthPyramid = builder.ReadTexture(prepassOutput.depthPyramidTexture); @@ -463,13 +468,9 @@ TextureHandle RenderSSR( RenderGraph renderGraph, // and much faster than fully overwriting them from within SSR shaders. passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Hit_Point_Texture" }); - passData.lightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" })); - passData.prevLightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Prev_Lighting_Texture" })); - - //passData.ssrAccumPointTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - // { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Accum_Texture" })); + passData.lightingTexture = builder.WriteTexture(ssrAccum); + passData.ssrAccum = builder.WriteTexture(ssrAccum); + passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => @@ -485,9 +486,9 @@ TextureHandle RenderSSR( RenderGraph renderGraph, data.stencilBuffer, data.clearCoatMask, data.colorPyramid, - data.ssrAccumPointTexture, + data.ssrAccum, data.lightingTexture, - data.prevLightingTexture, + data.ssrAccumPrev, data.coarseStencilBuffer, context.cmd, context.renderContext); }); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 6f22ad48d4d..5fd3a340fd0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -194,9 +194,7 @@ internal static Volume GetOrCreateDefaultVolume() // TODO: remove me, I am just a temporary debug texture. :-) // RTHandle m_SsrDebugTexture; RTHandle m_SsrHitPointTexture; - //RTHandle m_SsrCurrentTexture; RTHandle m_SsrLightingTexture; - //RTHandle m_SsrPrevLightingTexture; // MSAA Versions of regular textures RTHandle m_CameraColorMSAABuffer; RTHandle m_OpaqueAtmosphericScatteringMSAABuffer; // Necessary to perform dual-source (polychromatic alpha) blending which is not supported by Unity @@ -746,9 +744,7 @@ void InitializeRenderTextures() if (settings.supportSSR) { m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); - //m_SsrCurrentTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Accum_Texture"); m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); - //m_SsrPrevLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Prev_Lighting_Texture"); } // Let's create the MSAA textures @@ -803,9 +799,7 @@ void DestroyRenderTextures() // RTHandles.Release(m_SsrDebugTexture); RTHandles.Release(m_SsrHitPointTexture); - //RTHandles.Release(m_SsrCurrentTexture); RTHandles.Release(m_SsrLightingTexture); - //RTHandles.Release(m_SsrPrevLightingTexture); RTHandles.Release(m_CameraColorMSAABuffer); RTHandles.Release(m_OpaqueAtmosphericScatteringMSAABuffer); @@ -4739,7 +4733,7 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrPrevLightingTexture, ssrAccumPrev); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrAccumPrev, ssrAccumPrev); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); @@ -5481,11 +5475,6 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) // and much faster than fully overwriting them from within SSR shaders. // CoreUtils.SetRenderTarget(cmd, hdCamera, m_SsrDebugTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - //if (ssrLightingTexture != null) - // CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); - //CoreUtils.Swap(ref m_SsrLightingTexture, ref m_SsrPrevLightingTexture); - //CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); - //cmd.CopyTexture(m_SsrLightingTexture, m_SsrPrevLightingTexture); CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.None); CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index 40bb01ade06..3c26b6b3c44 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -328,7 +328,7 @@ static class HDShaderIDs public static readonly int _ShaderVariablesScreenSpaceReflection = Shader.PropertyToID("ShaderVariablesScreenSpaceReflection"); public static readonly int _SsrLightingTexture = Shader.PropertyToID("_SsrLightingTexture"); - public static readonly int _SsrPrevLightingTexture = Shader.PropertyToID("_SsrPrevLightingTexture"); + public static readonly int _SsrAccumPrev = Shader.PropertyToID("_SsrAccumPrev"); public static readonly int _SsrLightingTextureRW = Shader.PropertyToID("_SsrLightingTextureRW"); public static readonly int _SSRAccumTexture = Shader.PropertyToID("_SSRAccumTexture"); public static readonly int _SsrHitPointTexture = Shader.PropertyToID("_SsrHitPointTexture"); From 9629f427c24e610c92052e38a3770abfb52c0271 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Wed, 23 Sep 2020 13:57:46 +0200 Subject: [PATCH 12/41] Saturate local & target velocity --- .../Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 776bfc1426c..7327b36e91b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -800,7 +800,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorCenterNDC); float speedSrc = length(motionVectorCenterNDC); - float speed = (speedDst + speedDst); + float speed = saturate((speedDst + speedDst) * 0.5f); speed = speed > 0.0f ? 1.0f : 0.0f; float4 result = lerp( From 8102ea77e751f138dff1e93bdb7d0e1a7fea0747 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 29 Sep 2020 14:48:25 +0200 Subject: [PATCH 13/41] Fix RenderGraph --- .../Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs | 5 +++-- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index ce889df72a9..0c6cc00e75e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -254,7 +254,7 @@ TextureHandle CreateDiffuseLightingBuffer(RenderGraph renderGraph, bool msaa) return renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = !msaa, bindTextureMS = msaa, enableMSAA = msaa, clearBuffer = true, clearColor = Color.clear, name = msaa ? "CameraSSSDiffuseLightingMSAA" : "CameraSSSDiffuseLighting" }); - } + } class DeferredLightingPassData { @@ -469,7 +469,8 @@ TextureHandle RenderSSR( RenderGraph renderGraph, passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Hit_Point_Texture" }); passData.lightingTexture = builder.WriteTexture(ssrAccum); - passData.ssrAccum = builder.WriteTexture(ssrAccum); + passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); builder.SetRenderFunc( diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 6e67b842fba..1d9737b2c51 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4683,7 +4683,10 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip cb._ColorPyramidUvScaleAndLimitPrevFrame = HDUtils.ComputeViewportScaleAndLimit(hdCamera.historyRTHandleProperties.previousViewportSize, hdCamera.historyRTHandleProperties.previousRenderTargetSize); cb._SsrColorPyramidMaxMip = hdCamera.colorPyramidHistoryMipCount - 1; cb._SsrDepthPyramidMaxMip = depthPyramid.mipLevelCount - 1; - cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -12.0f, volumeSettings.accumulationFactor.value)); + if (hdCamera.isFirstFrame || hdCamera.cameraFrameCount <= 2) + cb._SsrAccumulationAmount = 1.0f; + else + cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -12.0f, volumeSettings.accumulationFactor.value)); parameters.offsetBufferData = depthPyramid.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); From 184efb89bf18af23c4915555c476a2100f9626f5 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 5 Oct 2020 11:38:08 +0200 Subject: [PATCH 14/41] Code cleaning + comments --- .../ScreenSpaceReflections.compute | 118 ++++-------------- 1 file changed, 25 insertions(+), 93 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 7327b36e91b..e8a7dfef8c2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -182,27 +182,19 @@ void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerce dist = hitData.z; hitPositionNDC = hitData.xy; - int globalSampleIndex = _FrameCount; float2 Xi; - Xi.x = GetBNDSequenceSample(positionSS, globalSampleIndex, 0); - Xi.y = GetBNDSequenceSample(positionSS, globalSampleIndex, 1); - - // Pick which subpixel we will be launching our effects from - float subPixelSample = GetBNDSequenceSample(positionSS, globalSampleIndex, 3); - int subPixel = clamp((int)(subPixelSample * 4.0), 0, 3); - uint2 shift = HalfResIndexToCoordinateShift[subPixel]; - - uint2 sourceCoord = positionSS + shift; + Xi.x = GetBNDSequenceSample(positionSS, _FrameCount, 0); + Xi.y = GetBNDSequenceSample(positionSS, _FrameCount, 1); NormalData normalData; - DecodeFromNormalBuffer(sourceCoord, normalData); + DecodeFromNormalBuffer(positionSS, normalData); srcPerceptualRoughness = normalData.perceptualRoughness; float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); float3x3 localToWorld = GetLocalFrame(normalData.normalWS); - Xi.x = lerp(Xi.x, 0.0f, srcPerceptualRoughness * 0.7f); + Xi.x = lerp(Xi.x, 0.0f, srcPerceptualRoughness * 0.7f); // 0.7 is an arbitrary bias to reduce noise for high roughness #ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN float deviceDepth = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; @@ -301,15 +293,6 @@ float GetTraceDistance(uint2 positionSS) return length(positionDstWS - positionSrcWS); } -float3 GetVectorSample(uint2 positionSS) -{ - float3 positionSrcWS; - float3 positionDstWS; - GetWorldSpacePoint(positionSS, positionSrcWS, positionDstWS); - - return normalize(positionDstWS - positionSrcWS); -} - float3 GetHitColorFromUV(float2 prevFrameUV, float perceptualRoughness, out float opacity, int mipLevel = 0) { float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); @@ -451,7 +434,7 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // Apply normal bias with the magnitude dependent on the distance from the camera. // Unfortunately, we only have access to the shading normal, which is less than ideal... positionWS = camPosWS + (positionWS - camPosWS) * (1 - 0.001 * rcp(max(dot(N, V), FLT_EPS))); - /*float*/ deviceDepth = ComputeNormalizedDeviceCoordinatesWithZ(positionWS, UNITY_MATRIX_VP).z; + deviceDepth = ComputeNormalizedDeviceCoordinatesWithZ(positionWS, UNITY_MATRIX_VP).z; bool killRay = deviceDepth == UNITY_RAW_FAR_CLIP_VALUE; // Ref. #1: Michal Drobot - Quadtree Displacement Mapping with Height Blending. @@ -628,7 +611,8 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThreadID) { UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); - uint2 positionSS0 = dispatchThreadId.xy; + + const uint2 positionSS0 = dispatchThreadId.xy; float3 N; float perceptualRoughness; @@ -666,13 +650,14 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float3 color = 0.0f; opacity = 0.0f; - const int radius = 1; +#define BLOCK_SAMPLE_RADIUS 1 int samplesCount = 0; float4 outputs = 0.0f; float wAll = 0.0f; - for (int y = -radius; y <= radius; ++y) + // TODO: check by Unroll, or sample cross only instead of 3x3 block + for (int y = -BLOCK_SAMPLE_RADIUS; y <= BLOCK_SAMPLE_RADIUS; ++y) { - for (int x = -radius; x <= radius; ++x) + for (int x = -BLOCK_SAMPLE_RADIUS; x <= BLOCK_SAMPLE_RADIUS; ++x) { uint2 positionSS = uint2(int2(positionSS0) + int2(x, y)); @@ -702,6 +687,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre } } } +#undef BLOCK_SAMPLE_RADIUS if (wAll > 0.0f) { @@ -740,77 +726,23 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread DecodeFromNormalBuffer(hitSS, hitNormalData); float3 hitN = hitNormalData.normalWS; - float3 hitPositionWS = GetWorldSpacePosition(hitSS); - float3 V = GetWorldSpaceNormalizeViewDir(hitPositionWS); - - float3x3 hitLocalToWorld = GetLocalFrame(hitN); - - //float3 radPoint = hitPositionWS + hitLocalToWorld._11_21_31 * radiusWS; - float3 radPoint = hitPositionWS + hitLocalToWorld._11_12_13 * radiusWS; - - // Convert to screen space radius - float4 hitCS0 = ComputeClipSpacePosition(hitPositionWS, UNITY_MATRIX_VP); - float4 hitCS1 = ComputeClipSpacePosition(radPoint, UNITY_MATRIX_VP); + float4 original = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)]; + float4 previous = _SsrAccumPrev[COORD_TEXTURE2D_X(positionSS)]; - hitCS0 *= rcp(hitCS0.w); - hitCS0.xy = hitCS0.xy * 0.5 + 0.5; - hitCS1 *= rcp(hitCS1.w); - hitCS1.xy = hitCS1.xy * 0.5 + 0.5; - - float radiusSS = length(hitCS0.xy - hitCS1.xy); - -#define Const0 0.2206356001526516f // Log(2)/pi -#define RcpConst0 4.532360141827193f // 1/Const0 == pi/Log(2) -#define Epsilon 0.000125f - - const float sigma = lerp(0.125f, 64.0f, saturate(radiusSS)); - const float invSigma = rcp(sigma); - - const int rad = round(clamp(radiusSS, 0.0f, 16.0f)); - float tot = 0.0f; - float4 output = 0.0f; - for (int x = -rad; x <= rad; ++x) - { - for (int y = -rad; y <= rad; ++y) - { - float4 data = _SSRAccumTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; - float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(int2(positionSS) + int2(x, y))]; - - uint3 intCol = asuint(data.rgb); - bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; + float2 motionVectorNDC; + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC.xy, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorNDC); + float speedDst = length(motionVectorNDC); - data = isPosFin ? data : 0; - float opacity = isPosFin ? data.w : 0; + float2 motionVectorCenterNDC; + float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorCenterNDC); + float speedSrc = length(motionVectorCenterNDC); + float speed = saturate((speedDst + speedDst) * 128.0f); // 128 is arbitrary - float coef = invSigma * Const0 * exp2( -(x * x + y * y) * invSigma); + float4 result = lerp(previous, original, lerp(_SsrAccumulationAmount, 1.0f, speed)); - tot += coef; - output += coef * data; - } - } - - if (tot > 0.0f) - { - output = output / tot; - float2 motionVectorNDC; - DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC.xy, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorNDC); - float speedDst = length(motionVectorNDC); - - float2 motionVectorCenterNDC; - float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); - DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(positionNDC, 1.0f - 0.5f * _ScreenSize.zw)* _RTHandleScale.xy, 0), motionVectorCenterNDC); - float speedSrc = length(motionVectorCenterNDC); - float speed = saturate((speedDst + speedDst) * 0.5f); - speed = speed > 0.0f ? 1.0f : 0.0f; - - float4 result = lerp( - _SsrAccumPrev[COORD_TEXTURE2D_X(positionSS)], - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)], - lerp(_SsrAccumulationAmount, 1.0f, speed)); - - _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; - } + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; } #endif From 1060cf862d21094bc1992a800a61e042f7a21e03 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 5 Oct 2020 13:21:15 +0200 Subject: [PATCH 15/41] Fix feedback --- .../ScreenSpaceReflections.compute | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index e8a7dfef8c2..3a9cd91aabd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -134,12 +134,10 @@ float Lambda_GGX(float roughness, bool SampleGGX(float roughness_, float3x3 localToWorld, float3 V, - float fresnel0, float2 inputSample, out float3 outgoingDir, out float value, - out float pdf, - out float fresnel) + out float pdf) { float roughness = clamp(roughness_, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); @@ -159,8 +157,7 @@ bool SampleGGX(float roughness_, pdf = pdfNoGV / lambdaVPlusOne; float lambdaL = Lambda_GGX(roughness, localL); - fresnel = F_Schlick(fresnel0, VdotH); - value = fresnel * pdfNoGV / (lambdaVPlusOne + lambdaL); + value = pdfNoGV / (lambdaVPlusOne + lambdaL); if (pdf < 0.001) return false; @@ -210,19 +207,16 @@ void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerce #ifdef SAMPLES_VNDF float value; - float fresnel; SampleGGX(roughness, localToWorld, V, - 1.0f, // F0 Xi, L, value, - pdf, - fresnel); + pdf); - weight = fresnel * value / pdf; + weight = value / pdf; NdotV = dot(normalData.normalWS, V); NdotL = dot(normalData.normalWS, L); @@ -234,11 +228,10 @@ void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerce NdotV = dot(normalData.normalWS, V); float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); - float fresnel = F_Schlick(1.0f, VdotH); float D = D_GGX(NdotH, roughness); pdf = D * NdotH / (4.0 * VdotH); - weight = fresnel * D * Vg * NdotL / pdf; + weight = D * Vg * NdotL / pdf; #endif } @@ -332,15 +325,13 @@ float2 GetSampleInfo(uint2 positionSS, out float3 color, out float localBRDF, ou float VdotH = dot(V, H); float NdotH = dot(normalData.normalWS, H); float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); - float fresnel = F_Schlick(1.0f, VdotH); float D = D_GGX(NdotH, roughness); float lambdaVPlusOne = Lambda_GGX(roughness, V) + 1.0; localPDF = D / lambdaVPlusOne; float lambdaL = Lambda_GGX(roughness, L); - fresnel = F_Schlick(1.0f, VdotH); - localBRDF = fresnel * D / (lambdaVPlusOne + lambdaL); + localBRDF = D / (lambdaVPlusOne + lambdaL); color = GetHitColor(hitData.xy, normalData.perceptualRoughness, opacity, 0); @@ -418,7 +409,6 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, float NdotL, NdotH, VdotH, NdotV; float3 R, V, N; float3 positionWS; - //float2 hitUV; float2 hitPositionNDC; float perceptualRoughness; GetHitInfos(positionSS, hitPositionNDC, perceptualRoughness, positionWS, pdf, weight, N, R, V, dist, NdotL, NdotH, VdotH, NdotV); @@ -717,7 +707,6 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread // Compute the radius of the projected solid angle float dist = GetTraceDistance(positionSS); - float radiusWS = 2.0f * dist * tan(clamp(perceptualRoughness0 * 1.5707963267948966192313216916398f, 0.00125f, 1.5707963267948966192313216916398f - 0.00125f)); // Approximate the footprint based on the hit normal float2 hitSS = (hitPositionNDC.xy - (0.5 * _ColorPyramidUvScaleAndLimitPrevFrame.zw)) / _ColorPyramidUvScaleAndLimitPrevFrame.zw; From 2367f44045daacdef24560653bde91ddc9f22099 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 6 Oct 2020 12:07:27 +0200 Subject: [PATCH 16/41] Support previous & new algorithm --- .../ScreenSpaceReflection.cs | 30 ++++ .../ScreenSpaceReflections.compute | 129 +++++++++++------- .../RenderPipeline/HDRenderPipeline.cs | 69 +++++++--- 3 files changed, 158 insertions(+), 70 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs index b111d38cf87..666b389cec1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs @@ -1,8 +1,35 @@ using System; +using System.Diagnostics; using UnityEngine.Serialization; namespace UnityEngine.Rendering.HighDefinition { + /// + /// Screen Space Reflection Algorithm + /// + public enum ScreenSpaceReflectionAlgorithm + { + /// Legacy SSR approximation. + Approximation, + /// Screen Space Reflection, Physically Based with Accumulation through multiple frame. + PBRAccumulation + } + + /// + /// Screen Space Reflection Algorithm Type volume parameter. + /// + [Serializable, DebuggerDisplay(k_DebuggerDisplay)] + public sealed class SSRAlgoParameter : VolumeParameter + { + /// + /// Screen Space Reflection Algorithm Type volume parameter constructor. + /// + /// SSR Algo Type parameter. + /// Initial override state. + public SSRAlgoParameter(ScreenSpaceReflectionAlgorithm value, bool overrideState = false) + : base(value, overrideState) { } + } + /// /// A volume component that holds settings for screen space reflection and ray traced reflections. /// @@ -25,6 +52,9 @@ bool UsesRayTracing() [Tooltip("Enable Screen Space Reflections.")] public BoolParameter enabled = new BoolParameter(true); + /// Screen Space Reflections Algorithm used. + public SSRAlgoParameter ssrAlgo = new SSRAlgoParameter(ScreenSpaceReflectionAlgorithm.Approximation); + /// /// Enable ray traced reflections. /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 3a9cd91aabd..41c5f58d9cc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -5,17 +5,20 @@ // #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 playstation xboxone vulkan metal switch -#pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE -#pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT -#pragma kernel ScreenSpaceReflectionsAccumulate SSR_ACCUMULATE +#pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE +#pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT +#pragma kernel ScreenSpaceReflectionsAccumulate SSR_ACCUMULATE #pragma multi_compile _ DEPTH_SOURCE_NOT_FROM_MIP_CHAIN +#pragma multi_compile _ SSR_APPROX // Tweak parameters. // #define DEBUG #define SSR_TRACE_BEHIND_OBJECTS #define SSR_TRACE_TOWARDS_EYE -#define SAMPLES_VNDF +#ifndef SSR_APPROX + #define SAMPLES_VNDF +#endif #define SSR_TRACE_EPS 0.00024414 // 2^-12, should be good up to 4K #define MIN_GGX_ROUGHNESS 0.00001f #define MAX_GGX_ROUGHNESS 0.99999f @@ -70,10 +73,9 @@ TEXTURE2D_X(_DepthTexture); #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); - RW_TEXTURE2D_X(float4, _SsrHitPointTexture); + RW_TEXTURE2D_X(float2, _SsrHitPointTexture); #elif defined(SSR_REPROJECT) TEXTURE2D_X( _SsrHitPointTexture); - RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); // ShaderVariablesScreenSpaceLighting.hlsl already pulls in a non-RW _SsrLightingTexture RW_TEXTURE2D_X(float4, _SSRAccumTexture); #else //if defined(SSR_ACCUMULATE) TEXTURE2D_X( _SsrHitPointTexture); @@ -120,7 +122,7 @@ void SampleGGXVisibleNormal(float2 u, localH = t1 * viewToLocal[0] + t2 * viewToLocal[1] + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * viewToLocal[2]; // Transform the normal back to the ellipsoid configuration - localH = normalize(float3(roughness * localH.x, roughness * localH.y, max(0.0, localH.z))); + localH = normalize(float3(roughness * localH.xy, max(0.0, localH.z))); VdotH = saturate(dot(localV, localH)); } @@ -131,13 +133,12 @@ float Lambda_GGX(float roughness, return 0.5 * (sqrt(1.0 + (Sq(roughness * V.x) + Sq(roughness * V.y)) / Sq(V.z)) - 1.0); } -bool SampleGGX(float roughness_, - float3x3 localToWorld, - float3 V, - float2 inputSample, - out float3 outgoingDir, - out float value, - out float pdf) +bool SampleGGX_VNDF(float roughness_, + float3x3 localToWorld, + float3 V, + float2 inputSample, + out float3 outgoingDir, + out float weight) { float roughness = clamp(roughness_, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); @@ -154,12 +155,12 @@ bool SampleGGX(float roughness_, float pdfNoGV = D_GGX(localH.z, roughness); float lambdaVPlusOne = Lambda_GGX(roughness, localV) + 1.0; - pdf = pdfNoGV / lambdaVPlusOne; float lambdaL = Lambda_GGX(roughness, localL); - value = pdfNoGV / (lambdaVPlusOne + lambdaL); - if (pdf < 0.001) + weight = 1.0f + lambdaL / lambdaVPlusOne; + + if (weight < 0.001) return false; return true; @@ -171,13 +172,11 @@ float PerceptualRoughnessFade(float perceptualRoughness, float fadeRcpLength, fl return Smoothstep01(t); } -void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerceptualRoughness, out float3 positionWS, out float pdf, out float weight, out float3 N, out float3 L, out float3 V, out float dist, out float NdotL, out float NdotH, out float VdotH, out float NdotV) +void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerceptualRoughness, out float3 positionWS, out float weight, out float3 N, out float3 L, out float3 V, out float NdotL, out float NdotH, out float VdotH, out float NdotV) { float2 uv = float2(positionSS) * _RTHandleScale.xy; - float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; - dist = hitData.z; - hitPositionNDC = hitData.xy; + hitPositionNDC = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)].xy; float2 Xi; Xi.x = GetBNDSequenceSample(positionSS, _FrameCount, 0); @@ -208,15 +207,12 @@ void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerce #ifdef SAMPLES_VNDF float value; - SampleGGX(roughness, + SampleGGX_VNDF(roughness, localToWorld, V, Xi, L, - value, - pdf); - - weight = value / pdf; + weight); NdotV = dot(normalData.normalWS, V); NdotL = dot(normalData.normalWS, L); @@ -228,10 +224,8 @@ void GetHitInfos(uint2 positionSS, out float2 hitPositionNDC, out float srcPerce NdotV = dot(normalData.normalWS, V); float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); - float D = D_GGX(NdotH, roughness); - pdf = D * NdotH / (4.0 * VdotH); - weight = D * Vg * NdotL / pdf; + weight = 4.0f * NdotL * VdotH * Vg / NdotH; #endif } @@ -269,7 +263,7 @@ float2 GetWorldSpacePoint(uint2 positionSS, out float3 positionSrcWS, out float3 { positionSrcWS = GetWorldSpacePosition(positionSS); - float4 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)]; + float2 hitData = _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)].xy; uint2 positionDstSS = (hitData.xy - (0.5 * _ScreenSize.zw)) / _ScreenSize.zw; positionDstWS = GetWorldSpacePosition(positionDstSS); @@ -303,7 +297,7 @@ float3 GetHitColor(float2 hitPositionNDC, float perceptualRoughness, out float o return SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; } -float2 GetSampleInfo(uint2 positionSS, out float3 color, out float localBRDF, out float localPDF, out float opacity) +float2 GetSampleInfo(uint2 positionSS, out float3 color, out float weight, out float opacity) { float3 positionSrcWS; float3 positionDstWS; @@ -325,13 +319,14 @@ float2 GetSampleInfo(uint2 positionSS, out float3 color, out float localBRDF, ou float VdotH = dot(V, H); float NdotH = dot(normalData.normalWS, H); float Vg = V_SmithJointGGX(NdotL, NdotV, roughness); - float D = D_GGX(NdotH, roughness); + + float jac = 4.0 * NdotV; float lambdaVPlusOne = Lambda_GGX(roughness, V) + 1.0; - localPDF = D / lambdaVPlusOne; float lambdaL = Lambda_GGX(roughness, L); - localBRDF = D / (lambdaVPlusOne + lambdaL); + + weight = 1.0f + lambdaL / lambdaVPlusOne; color = GetHitColor(hitData.xy, normalData.perceptualRoughness, opacity, 0); @@ -404,20 +399,31 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; #endif - float pdf, weight; - float dist; +#ifdef SSR_APPROX + float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. + float3 positionWS = ComputeWorldSpacePosition(positionNDC, deviceDepth, UNITY_MATRIX_I_VP); // Jittered + float3 V = GetWorldSpaceNormalizeViewDir(positionWS); + + float3 N; + float perceptualRoughness; + GetNormalAndPerceptualRoughness(positionSS, N, perceptualRoughness); + + float3 R = reflect(-V, N); +#else + float weight; float NdotL, NdotH, VdotH, NdotV; float3 R, V, N; float3 positionWS; float2 hitPositionNDC; float perceptualRoughness; - GetHitInfos(positionSS, hitPositionNDC, perceptualRoughness, positionWS, pdf, weight, N, R, V, dist, NdotL, NdotH, VdotH, NdotV); + GetHitInfos(positionSS, hitPositionNDC, perceptualRoughness, positionWS, weight, N, R, V, NdotL, NdotH, VdotH, NdotV); - if (NdotL < 0.001f || pdf < 0.001f) + if (NdotL < 0.001f || weight < 0.001f) { WriteDebugInfo(positionSS, -1); return; } +#endif float3 camPosWS = GetCurrentViewPosition(); @@ -588,7 +594,7 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, // recompute it using the last value of 't', which would result in an overshoot. // It also needs to be precisely at the center of the pixel to avoid artifacts. float2 hitPositionNDC = floor(rayPos.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. - _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = float4(hitPositionNDC, t, weight); + _SsrHitPointTexture[COORD_TEXTURE2D_X(positionSS)] = hitPositionNDC.xy; } // If we do not hit anything, 'rayPos.xy' provides an indication where we stopped the search. @@ -624,21 +630,43 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float3 originWS = posInputOrigin.positionWS + _WorldSpaceCameraPos; float2 RTSize = 1.0f / _RTHandleScale.xy; - float2 uv = float2(positionSS0) * _ColorPyramidUvScaleAndLimitPrevFrame.xy; float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; - float opacity = 1.0f; - if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) - { + { // Miss. return; } + if ((prevFrameUV.x < 0) || (prevFrameUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || + (prevFrameUV.y < 0) || (prevFrameUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) + { + // Off-Screen. + return; + } + +#ifdef SSR_APPROX + + // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. + float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + + float3 color = SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; + float opacity = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) + * PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); + + // Disable SSR for negative, infinite and NaN history values. + uint3 intCol = asuint(color); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; + + color = isPosFin ? color : 0; + opacity = isPosFin ? opacity : 0; + + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = float4(color, 1) * opacity; +#else float3 color = 0.0f; - opacity = 0.0f; + float opacity = 0.0f; #define BLOCK_SAMPLE_RADIUS 1 int samplesCount = 0; @@ -652,10 +680,9 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre uint2 positionSS = uint2(int2(positionSS0) + int2(x, y)); float3 color; - float localBRDF; - float localPDF; float opacity; - float2 hitData = GetSampleInfo(positionSS, color, localBRDF, localPDF, opacity); + float weight; + float2 hitData = GetSampleInfo(positionSS, color, weight, opacity); if (max(hitData.x, hitData.y) != 0.0f && opacity > 0.0f) { //// Note that the color pyramid uses it's own viewport scale, since it lives on the camera. @@ -671,7 +698,6 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre color = isPosFin ? color : 0; opacity = isPosFin ? opacity : 0; - float weight = localBRDF / localPDF; outputs += weight * float4(color, opacity); wAll += weight; } @@ -683,6 +709,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre { _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = outputs / wAll; } +#endif } #elif defined(SSR_ACCUMULATE) @@ -703,7 +730,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float4 data0 = _SSRAccumTexture[COORD_TEXTURE2D_X(int2(positionSS))]; - float3 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS).xyz; + float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS).xy; // Compute the radius of the projected solid angle float dist = GetTraceDistance(positionSS); @@ -728,7 +755,9 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float speedSrc = length(motionVectorCenterNDC); float speed = saturate((speedDst + speedDst) * 128.0f); // 128 is arbitrary - float4 result = lerp(previous, original, lerp(_SsrAccumulationAmount, 1.0f, speed)); + float coefExpAvg = lerp(_SsrAccumulationAmount, 1.0f, speed); + + float4 result = lerp(previous, original, lerp(1.0f, coefExpAvg, saturate(_FrameCount - 2.0f))); _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 1d9737b2c51..06b14e432fb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4641,6 +4641,7 @@ struct RenderSSRParameters public int reprojectionKernel; public int accumulateKernel; public bool transparentSSR; + public bool usePBRAlgo; public int width, height, viewCount; @@ -4659,6 +4660,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip parameters.reprojectionKernel = m_SsrReprojectionKernel; parameters.accumulateKernel = m_SsrAccumulateKernel; parameters.transparentSSR = transparentSSR; + parameters.usePBRAlgo = volumeSettings.ssrAlgo.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation; parameters.width = hdCamera.actualWidth; parameters.height = hdCamera.actualHeight; @@ -4713,6 +4715,13 @@ static void RenderSSR( in RenderSSRParameters parameters, { var cs = parameters.ssrCS; + bool usePBRAlgo = parameters.usePBRAlgo; + + if (!usePBRAlgo) + { + CoreUtils.SetKeyword(cmd, "SSR_APPROX", true); + } + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrTracing))) { // cmd.SetComputeTextureParam(cs, kernel, "_SsrDebugTexture", m_SsrDebugTexture); @@ -4760,8 +4769,10 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); - cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + if (usePBRAlgo) + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); + else + cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SSRAccumTexture, ssrLightingTexture); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.reprojectionKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); @@ -4770,26 +4781,34 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.DispatchCompute(cs, parameters.reprojectionKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); } - using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrAccumulate))) + if (usePBRAlgo) { - if (parameters.transparentSSR) + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrAccumulate))) { - CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", true); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._DepthTexture, depthTexture); + if (parameters.transparentSSR) + { + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", true); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._DepthTexture, depthTexture); + } + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraDepthTexture, depthPyramid); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrAccumPrev, ssrAccumPrev); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); + cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); + + ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); + + cmd.DispatchCompute(cs, parameters.accumulateKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); } - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraDepthTexture, depthPyramid); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._NormalBufferTexture, normalBuffer); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._ColorPyramidTexture, previousColorPyramid); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SSRAccumTexture, ssrAccum); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrLightingTextureRW, ssrLightingTexture); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrAccumPrev, ssrAccumPrev); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); - cmd.SetComputeTextureParam(cs, parameters.accumulateKernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorsBuffer); - - ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); + } - cmd.DispatchCompute(cs, parameters.accumulateKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + if (!usePBRAlgo) + { + CoreUtils.SetKeyword(cmd, "SSR_APPROX", false); } } @@ -4819,6 +4838,11 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren // Evaluate the clear coat mask texture based on the lit shader mode RTHandle clearCoatMask = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffer(2) : TextureXR.GetBlackTexture(); + if (settings.ssrAlgo == ScreenSpaceReflectionAlgorithm.Approximation) + { + CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); + } + var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), false); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, hdCamera, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, @@ -4848,7 +4872,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender bool usesRaytracedReflections = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value; if (usesRaytracedReflections) { - RenderRayTracedReflections(hdCamera, cmd, /*ssrLightingTexture*/m_SsrLightingTexture, renderContext, m_FrameCount, true); + RenderRayTracedReflections(hdCamera, cmd, m_SsrLightingTexture, renderContext, m_FrameCount, true); } else { @@ -4869,6 +4893,11 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Clear the SSR lighting buffer (not sure it is required) CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); + if (settings.ssrAlgo == ScreenSpaceReflectionAlgorithm.Approximation) + { + CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); + //CoreUtils.SetRenderTarget(cmd, ssrAccumulationPrev, ClearFlag.Color, Color.clear); + } } // Evaluate the screen space reflection for the transparent pixels @@ -4887,7 +4916,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender } // Push our texture to the debug menu - PushFullScreenDebugTexture(hdCamera, cmd, /*ssrLightingTexture*/m_SsrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); + PushFullScreenDebugTexture(hdCamera, cmd, m_SsrLightingTexture, FullScreenDebugMode.TransparentScreenSpaceReflections); } void RenderColorPyramid(HDCamera hdCamera, CommandBuffer cmd, bool isPreRefraction) From 356d97b7309969964da41bf43425bcf8c4372d44 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 6 Oct 2020 12:08:56 +0200 Subject: [PATCH 17/41] missing file: support both algorithm --- .../Lighting/Reflection/HDScreenSpaceReflectionEditor.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index 877e4726eab..90d4a751f2b 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -9,6 +9,7 @@ namespace UnityEditor.Rendering.HighDefinition class HDScreenSpaceReflectionEditor : VolumeComponentWithQualityEditor { SerializedDataParameter m_Enable; + SerializedDataParameter m_SSRAlgo; SerializedDataParameter m_RayTracing; // Shared data @@ -44,6 +45,7 @@ public override void OnEnable() var o = new PropertyFetcher(serializedObject); m_Enable = Unpack(o.Find(x => x.enabled)); + m_SSRAlgo = Unpack(o.Find(x => x.ssrAlgo)); m_RayTracing = Unpack(o.Find(x => x.rayTracing)); // Shared data @@ -74,6 +76,7 @@ public override void OnEnable() m_BounceCount = Unpack(o.Find(x => x.bounceCount)); } + static public readonly GUIContent k_Algo = EditorGUIUtility.TrTextContent("Algorithm", "The screen space reflection algorithm used."); static public readonly GUIContent k_RayTracingText = EditorGUIUtility.TrTextContent("Ray Tracing (Preview)", "Enable ray traced reflections."); static public readonly GUIContent k_ReflectSkyText = EditorGUIUtility.TrTextContent("Reflect Sky", "When enabled, SSR handles sky reflection."); static public readonly GUIContent k_LayerMaskText = EditorGUIUtility.TrTextContent("Layer Mask", "Layer mask used to include the objects for screen space reflection."); @@ -195,6 +198,8 @@ public override void OnInspectorGUI() } else { + PropertyField(m_SSRAlgo, k_Algo); + // Shared Data PropertyField(m_MinSmoothness, k_MinimumSmoothnessText); PropertyField(m_SmoothnessFadeStart, k_SmoothnessFadeStartText); From 3cd285700f384ca81a793da05aa526b761b73960 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 6 Oct 2020 12:23:35 +0200 Subject: [PATCH 18/41] fix for default RenderGraph --- .../Lighting/Reflection/HDScreenSpaceReflectionEditor.cs | 1 - .../Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs | 1 - .../Runtime/RenderPipeline/HDRenderPipeline.cs | 6 +----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index 2054b740d6c..d377c40d297 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -218,7 +218,6 @@ public override void OnInspectorGUI() EditorGUI.indentLevel--; } PropertyField(m_AccumulationFactor, k_AccumulationFactorText); - PropertyField(m_AccumulationFactor, k_AccumulationFactorText); } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 0c6cc00e75e..c2999cf9d1b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -435,7 +435,6 @@ TextureHandle RenderSSR( RenderGraph renderGraph, // However if the generated HTile will be used for something else but SSR, this should be made NOT resolve only and // re-enabled in the shader. BuildCoarseStencilAndResolveIfNeeded(renderGraph, hdCamera, resolveOnly: true, ref prepassOutput); - } using (var builder = renderGraph.AddRenderPass("Render SSR", out var passData)) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 6514b910dd4..5d65ba25cfc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4776,6 +4776,7 @@ static void RenderSSR( in RenderSSRParameters parameters, if (!usePBRAlgo) { CoreUtils.SetKeyword(cmd, "SSR_APPROX", true); + CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); } using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrTracing))) @@ -4894,11 +4895,6 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren // Evaluate the clear coat mask texture based on the lit shader mode RTHandle clearCoatMask = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffer(2) : TextureXR.GetBlackTexture(); - if (settings.ssrAlgo == ScreenSpaceReflectionAlgorithm.Approximation) - { - CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); - } - var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), false); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, hdCamera, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, m_SsrHitPointTexture, From 75217b53f9109f5c2d4d47794cd22f92bf3439e5 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 6 Oct 2020 12:25:23 +0200 Subject: [PATCH 19/41] Simplify UI --- .../Lighting/Reflection/HDScreenSpaceReflectionEditor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index d377c40d297..b354be7ae47 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -217,7 +217,8 @@ public override void OnInspectorGUI() m_RayMaxIterations.value.intValue = Mathf.Max(0, m_RayMaxIterations.value.intValue); EditorGUI.indentLevel--; } - PropertyField(m_AccumulationFactor, k_AccumulationFactorText); + if (m_SSRAlgo.value.intValue == (int)ScreenSpaceReflectionAlgorithm.PBRAccumulation) + PropertyField(m_AccumulationFactor, k_AccumulationFactorText); } } } From 8bc18eef78acc56b1bd58b2ab821e0d627e1e241 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 6 Oct 2020 12:31:20 +0200 Subject: [PATCH 20/41] Remap parameters for more userfriendly parametrization --- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 5d65ba25cfc..757c91ed5cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4744,7 +4744,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip if (hdCamera.isFirstFrame || hdCamera.cameraFrameCount <= 2) cb._SsrAccumulationAmount = 1.0f; else - cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -12.0f, volumeSettings.accumulationFactor.value)); + cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -6.0f, volumeSettings.accumulationFactor.value)); parameters.offsetBufferData = depthPyramid.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); From a089aa0a47d714ebd11d3b4165b29e4a8d1f2e0f Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Wed, 7 Oct 2020 06:05:32 +0200 Subject: [PATCH 21/41] fix doc missing --- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 39e919d239e..d6e01a82a44 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -765,7 +765,7 @@ internal void AllocateAmbientOcclusionHistoryBuffer(float scaleFactor) } } - public void AllocateScreenSpaceAccumulationHistoryBuffer(float scaleFactor) + internal void AllocateScreenSpaceAccumulationHistoryBuffer(float scaleFactor) { if (scaleFactor != m_ScreenSpaceAccumulationResolutionScale|| GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation) == null) { From 602323da8b2cc80a47917f328eaed66da75a7bac Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 8 Oct 2020 13:56:29 +0200 Subject: [PATCH 22/41] Clean up --- .../ScreenSpaceReflections.compute | 24 ++++++++++--------- .../HDRenderPipeline.LightLoop.cs | 3 ++- .../RenderPipeline/HDRenderPipeline.cs | 8 ++----- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 41c5f58d9cc..d326a67a2b1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -618,28 +618,27 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); - // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS0).xy; - float2 motionVectorNDC; - DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); - float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; - float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float depthOrigin = LoadCameraDepth(positionSS0.xy); PositionInputs posInputOrigin = GetPositionInput(positionSS0.xy, _ScreenSize.zw, depthOrigin, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(8, 8)); float3 originWS = posInputOrigin.positionWS + _WorldSpaceCameraPos; - float2 RTSize = 1.0f / _RTHandleScale.xy; - float2 uv = float2(positionSS0) * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - - float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; - if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) { // Miss. return; } + // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? + float2 motionVectorNDC; + DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); + float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; + float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + float2 RTSize = 1.0f / _RTHandleScale.xy; + float2 uv = float2(positionSS0)* _ColorPyramidUvScaleAndLimitPrevFrame.xy; + + // TODO: optimize with max(). if ((prevFrameUV.x < 0) || (prevFrameUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || (prevFrameUV.y < 0) || (prevFrameUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) { @@ -652,6 +651,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); + // Note that the color pyramid uses it's own viewport scale, since it lives on the camera. float3 color = SAMPLE_TEXTURE2D_X_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, prevFrameUV, mipLevel).rgb; float opacity = EdgeOfScreenFade(prevFrameNDC, _SsrEdgeFadeRcpLength) * PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); @@ -668,6 +668,8 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float3 color = 0.0f; float opacity = 0.0f; + float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; + #define BLOCK_SAMPLE_RADIUS 1 int samplesCount = 0; float4 outputs = 0.0f; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 7790cc29355..90cd2862d42 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -467,9 +467,10 @@ TextureHandle RenderSSR( RenderGraph renderGraph, // and much faster than fully overwriting them from within SSR shaders. passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Hit_Point_Texture" }); + // { colorFormat = GraphicsFormat.ARGBFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Debug_Texture" })); passData.lightingTexture = builder.WriteTexture(ssrAccum); passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); builder.SetRenderFunc( diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index a2cdaf2a433..2cc459d8147 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -748,7 +748,7 @@ void InitializeRenderTextures() if (settings.supportSSR) { - m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); + m_SsrHitPointTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16_UNorm, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Hit_Point_Texture"); m_SsrLightingTexture = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, name: "SSR_Lighting_Texture"); } @@ -1305,9 +1305,6 @@ void Resize(HDCamera hdCamera) m_SharedRTManager.AllocateFullScreenDebugBuffer(m_MaxCameraWidth, m_MaxCameraHeight, m_MaxViewCount); m_SharedRTManager.AllocateCoarseStencilBuffer(m_MaxCameraWidth, m_MaxCameraHeight, m_MaxViewCount); } - - //if (hdCamera.IsSSREnabled()) - // hdCamera.AllocateScreenSpaceHistoryBuffer(1.0f); } } @@ -4946,7 +4943,6 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender if (settings.ssrAlgo == ScreenSpaceReflectionAlgorithm.Approximation) { CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); - //CoreUtils.SetRenderTarget(cmd, ssrAccumulationPrev, ClearFlag.Color, Color.clear); } } @@ -4955,7 +4951,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), true); var motionVectors = m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors ? m_SharedRTManager.GetMotionVectorsBuffer() : TextureXR.GetBlackTexture(); RenderSSR(parameters, hdCamera, GetBlueNoiseManager(), m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SharedRTManager.GetNormalBuffer(), motionVectors, - m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, ssrAccumulation, /*ssrLightingTexture*/m_SsrLightingTexture, ssrAccumulationPrev, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); + m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, ssrAccumulation, m_SsrLightingTexture, ssrAccumulationPrev, m_SharedRTManager.GetCoarseStencilBuffer(), cmd, renderContext); // If color pyramid was not valid, we bind a black texture if (!hdCamera.colorPyramidHistoryIsValid) From 0a220e979aa0888fb914d281849c4dd895afbf4d Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 12 Oct 2020 07:17:34 +0200 Subject: [PATCH 23/41] New rendergraph fix --- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 +- .../HDRenderPipeline.LightLoop.cs | 22 ++++++++++++++++--- .../RenderPipeline/HDRenderPipeline.cs | 6 +++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index d6e01a82a44..a37e09f337e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -767,7 +767,7 @@ internal void AllocateAmbientOcclusionHistoryBuffer(float scaleFactor) internal void AllocateScreenSpaceAccumulationHistoryBuffer(float scaleFactor) { - if (scaleFactor != m_ScreenSpaceAccumulationResolutionScale|| GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation) == null) + if (scaleFactor != m_ScreenSpaceAccumulationResolutionScale || GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation) == null) { ReleaseHistoryFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 6c9f4d67bc1..257c9e8549f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -466,11 +466,21 @@ TextureHandle RenderSSR( RenderGraph renderGraph, // In practice, these textures are sparse (mostly black). Therefore, clearing them is fast (due to CMASK), // and much faster than fully overwriting them from within SSR shaders. passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Hit_Point_Texture" }); + { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Hit_Point_Texture_Trans" : "SSR_Hit_Point_Texture" }); // { colorFormat = GraphicsFormat.ARGBFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Debug_Texture" })); - passData.lightingTexture = builder.WriteTexture(ssrAccum); + //passData.lightingTexture = builder.WriteTexture(ssrAccum); + ////passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + //// { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); + //passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + //{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); + //passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); + + //passData.lightingTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + //{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Lighting_Texture_Trans" : "SSR_Lighting_Texture" }); passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); + //passData.ssrAccum = builder.WriteTexture(ssrAccum); + passData.lightingTexture = builder.WriteTexture(ssrAccum); passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); builder.SetRenderFunc( @@ -495,6 +505,12 @@ TextureHandle RenderSSR( RenderGraph renderGraph, }); result = passData.lightingTexture; + + if (!transparent) + { + PushFullScreenDebugTexture(renderGraph, ssrAccum, FullScreenDebugMode.ScreenSpaceReflectionsAccum); + PushFullScreenDebugTexture(renderGraph, ssrAccumPrev, FullScreenDebugMode.ScreenSpaceReflectionsPrev); + } } if (!hdCamera.colorPyramidHistoryIsValid) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 2cc459d8147..40afe951b09 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4831,6 +4831,9 @@ static void RenderSSR( in RenderSSRParameters parameters, ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); cmd.DispatchCompute(cs, parameters.reprojectionKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + + if (parameters.transparentSSR) + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", false); } if (usePBRAlgo) @@ -4855,6 +4858,9 @@ static void RenderSSR( in RenderSSRParameters parameters, ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); cmd.DispatchCompute(cs, parameters.accumulateKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + + if (parameters.transparentSSR) + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", false); } } From 453afcc85a99f3e7d8c4d9386e9184da74ca568b Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 12 Oct 2020 13:02:33 +0200 Subject: [PATCH 24/41] temp --- .../ScreenSpaceReflections.compute | 8 +++++--- .../RenderPipeline/HDRenderPipeline.LightLoop.cs | 2 -- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 13 ++++--------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index d326a67a2b1..242644e5a4e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -663,7 +663,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre color = isPosFin ? color : 0; opacity = isPosFin ? opacity : 0; - _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = float4(color, 1) * opacity; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = float4(color, 1.0f) * opacity; #else float3 color = 0.0f; float opacity = 0.0f; @@ -700,7 +700,9 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre color = isPosFin ? color : 0; opacity = isPosFin ? opacity : 0; - outputs += weight * float4(color, opacity); + weight *= opacity; + + outputs += weight * float4(color, 1.0f); wAll += weight; } } @@ -759,7 +761,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float coefExpAvg = lerp(_SsrAccumulationAmount, 1.0f, speed); - float4 result = lerp(previous, original, lerp(1.0f, coefExpAvg, saturate(_FrameCount - 2.0f))); + float4 result = lerp(previous, original, lerp(1.0f, coefExpAvg, saturate(_FrameCount - 1.0f))); _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 257c9e8549f..133d465b8bc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -443,8 +443,6 @@ TextureHandle RenderSSR( RenderGraph renderGraph, var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); - hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f - var ssrAccum = renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation)); var ssrAccumPrev = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation)); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 40afe951b09..c45c1cc14f2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -1821,8 +1821,6 @@ void AddVisibleProbeVisibleIndexIfUpdateIsRequired(HDProbe probe, int visibleInI if (m_FrameCount > 1 && visibility > 0.0f) probe.SetIsRendered(m_FrameCount); - - if (!renderRequestIndicesWhereTheProbeIsVisible.TryGetValue(probe, out var visibleInIndices)) { visibleInIndices = ListPool<(int index, float weight)>.Get(); @@ -4739,7 +4737,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip if (hdCamera.isFirstFrame || hdCamera.cameraFrameCount <= 2) cb._SsrAccumulationAmount = 1.0f; else - cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -6.0f, volumeSettings.accumulationFactor.value)); + cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -7.0f, volumeSettings.accumulationFactor.value)); parameters.offsetBufferData = depthPyramid.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); @@ -4747,7 +4745,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip } static void RenderSSR( in RenderSSRParameters parameters, - HDCamera camera, + HDCamera hdCamera, BlueNoise blueNoise, RTHandle depthTexture, RTHandle depthPyramid, @@ -4765,9 +4763,10 @@ static void RenderSSR( in RenderSSRParameters parameters, ScriptableRenderContext renderContext) { var cs = parameters.ssrCS; - bool usePBRAlgo = parameters.usePBRAlgo; + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f + if (!usePBRAlgo) { CoreUtils.SetKeyword(cmd, "SSR_APPROX", true); @@ -4886,8 +4885,6 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren } else { - hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f - RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); @@ -4934,8 +4931,6 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // re-enabled in the shader. BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd, resolveOnly: true); - hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f - RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); From 7ed5ed7cc6fe6824006b784e5337a751f4a29a2e Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 13 Oct 2020 14:13:09 +0200 Subject: [PATCH 25/41] Fix alloc issues RenderGraphs --- .../RenderPipeline/HDRenderPipeline.LightLoop.cs | 14 +++----------- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 6 ++++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 133d465b8bc..409761d76b9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -441,6 +441,8 @@ TextureHandle RenderSSR( RenderGraph renderGraph, { builder.EnableAsyncCompute(hdCamera.frameSettings.SSRRunsAsync()); + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); + var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); var ssrAccum = renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation)); @@ -465,19 +467,9 @@ TextureHandle RenderSSR( RenderGraph renderGraph, // and much faster than fully overwriting them from within SSR shaders. passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Hit_Point_Texture_Trans" : "SSR_Hit_Point_Texture" }); - // { colorFormat = GraphicsFormat.ARGBFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Debug_Texture" })); - //passData.lightingTexture = builder.WriteTexture(ssrAccum); - ////passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - //// { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); - //passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - //{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); - //passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); - - //passData.lightingTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - //{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Lighting_Texture_Trans" : "SSR_Lighting_Texture" }); + passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); - //passData.ssrAccum = builder.WriteTexture(ssrAccum); passData.lightingTexture = builder.WriteTexture(ssrAccum); passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 2db7dec9fbf..1d0f3f1c1a7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4765,8 +4765,6 @@ static void RenderSSR( in RenderSSRParameters parameters, var cs = parameters.ssrCS; bool usePBRAlgo = parameters.usePBRAlgo; - hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); // SSR is computed on fullscreen == 1.0f - if (!usePBRAlgo) { CoreUtils.SetKeyword(cmd, "SSR_APPROX", true); @@ -4885,6 +4883,8 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren } else { + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); + RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); @@ -4931,6 +4931,8 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // re-enabled in the shader. BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd, resolveOnly: true); + hdCamera.AllocateScreenSpaceAccumulationHistoryBuffer(1.0f); + RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); From 6ec73fcdbd147c9272063fd025ab4e8d7a48e6c2 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 13 Oct 2020 14:18:01 +0200 Subject: [PATCH 26/41] Update default values --- .../Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs index 539ad497a3b..1a8276ffb3b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs @@ -110,7 +110,7 @@ public float smoothnessFadeStart /// /// Controls the amount of accumulation (0 no accumulation, 1 just accumulate) /// - public ClampedFloatParameter accumulationFactor = new ClampedFloatParameter(0.125f, 0.0f, 1.0f); + public ClampedFloatParameter accumulationFactor = new ClampedFloatParameter(0.75f, 0.0f, 1.0f); /// /// Layer mask used to include the objects for screen space reflection. From e7ccb8b1fa207435ff27dc16d3185afde03c4d3a Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 13 Oct 2020 15:52:25 +0200 Subject: [PATCH 27/41] Add NaN killer --- .../ScreenSpaceReflections.compute | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 242644e5a4e..551d71adae1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -711,6 +711,12 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre if (wAll > 0.0f) { + uint3 intCol = asuint(outputs.rgb); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; + + outputs.rgb = isPosFin ? outputs.rgb : 0; + wAll = isPosFin ? wAll : 0; + _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = outputs / wAll; } #endif @@ -763,6 +769,12 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float4 result = lerp(previous, original, lerp(1.0f, coefExpAvg, saturate(_FrameCount - 1.0f))); + uint3 intCol = asuint(result.rgb); + bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; + + result.rgb = isPosFin ? result.rgb : 0; + result.w = isPosFin ? result.w : 0; + _SsrLightingTextureRW[COORD_TEXTURE2D_X(positionSS)] = result; _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS)] = result; } From 104896d6b0034079b1dc77c0c9e787d21ae4c267 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Thu, 15 Oct 2020 00:36:49 +0200 Subject: [PATCH 28/41] New strategy for 'first frame' reset --- .../HDScreenSpaceReflectionEditor.cs | 9 +++--- .../ScreenSpaceReflection.cs | 2 +- .../ScreenSpaceReflections.compute | 2 +- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 ++ .../RenderPipeline/HDRenderPipeline.cs | 28 +++++++++++++------ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index b354be7ae47..f050260e72b 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -9,7 +9,7 @@ namespace UnityEditor.Rendering.HighDefinition class HDScreenSpaceReflectionEditor : VolumeComponentWithQualityEditor { SerializedDataParameter m_Enable; - SerializedDataParameter m_SSRAlgo; + SerializedDataParameter m_UsedAlgorithm; SerializedDataParameter m_RayTracing; // Shared data @@ -45,7 +45,7 @@ public override void OnEnable() var o = new PropertyFetcher(serializedObject); m_Enable = Unpack(o.Find(x => x.enabled)); - m_SSRAlgo = Unpack(o.Find(x => x.ssrAlgo)); + m_UsedAlgorithm = Unpack(o.Find(x => x.usedAlgorithm)); m_RayTracing = Unpack(o.Find(x => x.rayTracing)); // Shared data @@ -113,7 +113,6 @@ void RayTracingQualityModeGUI() } } - void RayTracingPerformanceModeGUI() { base.OnInspectorGUI(); @@ -197,7 +196,7 @@ public override void OnInspectorGUI() } else { - PropertyField(m_SSRAlgo, k_Algo); + PropertyField(m_UsedAlgorithm, k_Algo); // Shared Data PropertyField(m_MinSmoothness, k_MinimumSmoothnessText); @@ -217,7 +216,7 @@ public override void OnInspectorGUI() m_RayMaxIterations.value.intValue = Mathf.Max(0, m_RayMaxIterations.value.intValue); EditorGUI.indentLevel--; } - if (m_SSRAlgo.value.intValue == (int)ScreenSpaceReflectionAlgorithm.PBRAccumulation) + if (m_UsedAlgorithm.value.intValue == (int)ScreenSpaceReflectionAlgorithm.PBRAccumulation) PropertyField(m_AccumulationFactor, k_AccumulationFactorText); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs index 1a8276ffb3b..a747dd7fa2d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflection.cs @@ -53,7 +53,7 @@ bool UsesRayTracing() public BoolParameter enabled = new BoolParameter(true); /// Screen Space Reflections Algorithm used. - public SSRAlgoParameter ssrAlgo = new SSRAlgoParameter(ScreenSpaceReflectionAlgorithm.Approximation); + public SSRAlgoParameter usedAlgorithm = new SSRAlgoParameter(ScreenSpaceReflectionAlgorithm.Approximation); /// /// Enable ray traced reflections. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 551d71adae1..55b6619bcbb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -767,7 +767,7 @@ void ScreenSpaceReflectionsAccumulate(uint3 dispatchThreadId : SV_DispatchThread float coefExpAvg = lerp(_SsrAccumulationAmount, 1.0f, speed); - float4 result = lerp(previous, original, lerp(1.0f, coefExpAvg, saturate(_FrameCount - 1.0f))); + float4 result = lerp(previous, original, coefExpAvg); uint3 intCol = asuint(result.rgb); bool isPosFin = Max3(intCol.r, intCol.g, intCol.b) < 0x7F800000; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index a37e09f337e..b6d6d88a825 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -944,6 +944,8 @@ public RTHandle Allocator(string id, int frameIndex, RTHandleSystem rtHandleSyst int m_NumVolumetricBuffersAllocated = 0; float m_AmbientOcclusionResolutionScale = 0.0f; // Factor used to track if history should be reallocated for Ambient Occlusion float m_ScreenSpaceAccumulationResolutionScale = 0.0f; // Use another scale if AO & SSR don't have the same resolution + public ScreenSpaceReflectionAlgorithm + currentSSRAlgorithm = ScreenSpaceReflectionAlgorithm.Approximation; // Store current algorithm which help to know if we trigger to reset history SSR Buffers ViewConstants[] m_XRViewConstants; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 1d0f3f1c1a7..87b6a761f23 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2638,7 +2638,6 @@ void Callback(CommandBuffer c, HDCamera cam) RenderCameraMotionVectors(cullingResults, hdCamera, renderContext, cmd); } - if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MotionVectors)) cmd.SetGlobalTexture(HDShaderIDs._CameraMotionVectorsTexture, m_SharedRTManager.GetMotionVectorsBuffer()); else @@ -2662,7 +2661,6 @@ void Callback(CommandBuffer c, HDCamera cam) hdCamera.volumeStack.GetComponent().enable.value && hdCamera.camera.cameraType != CameraType.Preview) { - // We only request the light cluster if we are gonna use it for debug mode if (FullScreenDebugMode.LightCluster == m_CurrentDebugDisplaySettings.data.fullScreenDebugMode && GetRayTracingClusterState()) { @@ -2674,7 +2672,6 @@ void Callback(CommandBuffer c, HDCamera cam) } else { - // When debug is enabled we need to clear otherwise we may see non-shadows areas with stale values. if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.ContactShadows) && m_CurrentDebugDisplaySettings.data.fullScreenDebugMode == FullScreenDebugMode.ContactShadows) { @@ -2687,7 +2684,7 @@ void Callback(CommandBuffer c, HDCamera cam) if (hdCamera.IsSSREnabled()) BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd, resolveOnly: true); - hdCamera.xr.StopSinglePass(cmd); + hdCamera.xr.StopSinglePass(cmd); var buildLightListTask = new HDGPUAsyncTask("Build light list", ComputeQueueType.Background); // It is important that this task is in the same queue as the build light list due to dependency it has on it. If really need to move it, put an extra fence to make sure buildLightListTask has finished. @@ -2722,7 +2719,7 @@ void Callback(CommandBuffer c, HDGPUAsyncTaskParams a) haveAsyncTaskWithShadows = true; - void Callback(CommandBuffer c, HDGPUAsyncTaskParams a) + void Callback(CommandBuffer c, HDGPUAsyncTaskParams a) => RenderSSR(a.hdCamera, c, a.renderContext); } @@ -2738,7 +2735,7 @@ void Callback(CommandBuffer c, HDGPUAsyncTaskParams a) void AsyncSSAODispatch(CommandBuffer c, HDGPUAsyncTaskParams a) => m_AmbientOcclusionSystem.Dispatch(c, a.hdCamera, depthTexture, normalBuffer, motionVectors, a.frameCount); } - + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RenderShadowMaps))) { // This call overwrites camera properties passed to the shader system. @@ -2838,7 +2835,6 @@ void Callback(CommandBuffer c, HDCamera cam) SetContactShadowsTexture(hdCamera, m_ContactShadowBuffer, cmd); - if (hdCamera.frameSettings.SSRRunsAsync()) { SSRTask.End(cmd, hdCamera); @@ -4709,7 +4705,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip parameters.reprojectionKernel = m_SsrReprojectionKernel; parameters.accumulateKernel = m_SsrAccumulateKernel; parameters.transparentSSR = transparentSSR; - parameters.usePBRAlgo = volumeSettings.ssrAlgo.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation; + parameters.usePBRAlgo = volumeSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation; parameters.width = hdCamera.actualWidth; parameters.height = hdCamera.actualHeight; @@ -4943,7 +4939,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Clear the SSR lighting buffer (not sure it is required) CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - if (settings.ssrAlgo == ScreenSpaceReflectionAlgorithm.Approximation) + if (settings.usedAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) { CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); } @@ -5625,12 +5621,26 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) RTHandle ssrAccumulation = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + ScreenSpaceReflection ssrSettings = hdCamera.volumeStack.GetComponent(); + + bool ssrNeedReset = false; + if (ssrSettings.usedAlgorithm == ScreenSpaceReflectionAlgorithm.PBRAccumulation && + hdCamera.currentSSRAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) + ssrNeedReset = true; + + hdCamera.currentSSRAlgorithm = ssrSettings.usedAlgorithm.value; + // In practice, these textures are sparse (mostly black). Therefore, clearing them is fast (due to CMASK), // and much faster than fully overwriting them from within SSR shaders. // CoreUtils.SetRenderTarget(cmd, hdCamera, m_SsrDebugTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.None); CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); + if (ssrNeedReset || hdCamera.isFirstFrame) + { + RTHandle ssrAccumulationPrev = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ScreenSpaceReflectionAccumulation); + CoreUtils.SetRenderTarget(cmd, ssrAccumulationPrev, ClearFlag.Color, Color.clear); + } } } From 08e146bcf6c7bc23d4aeca3fd78400e19a2adbe5 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Fri, 16 Oct 2020 15:54:21 +0200 Subject: [PATCH 29/41] Update doc with clearer explaination --- .../Documentation~/Override-Screen-Space-Reflection.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md index 608794106dd..1522db2a701 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Screen-Space-Reflection.md @@ -26,14 +26,14 @@ HDRP uses the [Volume](Volumes.md) framework to calculate SSR, so to enable and | **Property** | **Description** | | ----------------------------- | ------------------------------------------------------------ | -| **Algorithm** | Unity provide two algorithm 'Approximation' and 'PBR Accumulation'. 'Approximation' is the regular one which try to have fast and less precise, 'PBR Accumulation' provide a more precise SSR by accumulating through multiple frames (controlable with 'Accumulation Factor'). | +| **Algorithm** | Unity provide two algorithm 'Approximation' and 'PBR Accumulation'. 'Approximation' is the regular one which try to have fast and less precise, 'PBR Accumulation' provide a more precise SSR by accumulating through multiple frames (controlable with 'Accumulation Factor'). | | **Screen Edge Fade Distance** | Use the slider to control the distance at which HDRP fades out screen space reflections when the destination of the ray is near the boundaries of the screen. Increase this value to increase the distance from the screen edge at which HDRP fades out screen space reflections for a ray destination. | | **Max Number of Ray Steps** | Sets the maximum number of iterations that the algorithm can execute before it stops trying to find an intersection with a Mesh. For example, if you set the number of iterations to 1000 and the algorithm only needs 10 to find an intersection, the algorithm terminates after 10 iterations. If you set this value too low, the algorithm may terminate too early and abruptly stop reflections. | | **Object Thickness** | Use the slider to control the thickness of the GameObjects on screen. Because the SSR algorithm can not distinguish thin GameObjects from thick ones, this property helps trace rays behind GameObjects. The algorithm applies this property to every GameObject uniformly. | | **Min Smoothness** | Use the slider to set the minimum amount of surface smoothness at which HDRP performs SSR tracing. Lower values result in HDRP performing SSR tracing for less smooth GameObjects. | | **Smoothness Fade Start** | Use the slider to set the smoothness value at which SSR reflections begin to fade out. Lower values result in HDRP fading out SSR reflections for less smooth GameObjects | | **Reflect Sky** | Indicates whether HDRP should use SSR to handle sky reflection. If you disable this property, pixels that reflect the sky use the next level of the [reflection hierarchy](Reflection-in-HDRP.md#ReflectionHierarchy).
**Note**: SSR uses the depth buffer to calculate reflection and HDRP does not add transparent GameObjects to the depth buffer. If you enable this property, transparent GameObject that appear over the sky in the color buffer can cause visual artifacts and incorrect looking reflection. This is a common limitation for SSR techniques. | -| **Accumulation Factor** | Use the slider to control the speed of converge. 0 mean no accumulation, on the result of the current frame is used. 1 mean accumulation is very slowly which is useful for fixed image. Use carefuly to find a balance between convergence and ghosting. More rough image need accumulation to image converged. | +| **Accumulation Factor** | Use the slider to control the speed of converge. 0 means no accumulation. 1 means accumulation is very slow which is useful for fixed image. Use carefuly to find a balance between convergence and ghosting. The more rough the reflection surfaces is, the more accumulation it will need to have a converged image without noise. | ## Limitations From b20e96df59764c9ef2d31f091b28a2b36554c6e0 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Sun, 18 Oct 2020 22:06:38 +0200 Subject: [PATCH 30/41] Perf improvement --- .../ScreenSpaceReflections.compute | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 55b6619bcbb..32dc1a19d09 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -619,7 +619,12 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS0).xy; - float depthOrigin = LoadCameraDepth(positionSS0.xy); +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + float depthOrigin = LOAD_TEXTURE2D_X(_DepthTexture, positionSS0.xy).r; +#else + float depthOrigin = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS0.xy).r; +#endif + PositionInputs posInputOrigin = GetPositionInput(positionSS0.xy, _ScreenSize.zw, depthOrigin, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(8, 8)); float3 originWS = posInputOrigin.positionWS + _WorldSpaceCameraPos; @@ -674,11 +679,14 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre int samplesCount = 0; float4 outputs = 0.0f; float wAll = 0.0f; - // TODO: check by Unroll, or sample cross only instead of 3x3 block for (int y = -BLOCK_SAMPLE_RADIUS; y <= BLOCK_SAMPLE_RADIUS; ++y) { for (int x = -BLOCK_SAMPLE_RADIUS; x <= BLOCK_SAMPLE_RADIUS; ++x) { + UNITY_FLATTEN + if (abs(x) == abs(y) && abs(x) == 1) + continue; + uint2 positionSS = uint2(int2(positionSS0) + int2(x, y)); float3 color; From 6ccacada00886ffa7c5e0628a6e70510b59b3ad1 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 19 Oct 2020 08:47:18 +0200 Subject: [PATCH 31/41] Move code --- .../ScreenSpaceReflections.compute | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 32dc1a19d09..9fb8570f13d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -619,6 +619,13 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre roughness = clamp(roughness, MIN_GGX_ROUGHNESS, MAX_GGX_ROUGHNESS); float2 hitPositionNDC = LOAD_TEXTURE2D_X(_SsrHitPointTexture, positionSS0).xy; + + if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) + { + // Miss. + return; + } + #ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN float depthOrigin = LOAD_TEXTURE2D_X(_DepthTexture, positionSS0.xy).r; #else @@ -628,21 +635,12 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre PositionInputs posInputOrigin = GetPositionInput(positionSS0.xy, _ScreenSize.zw, depthOrigin, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, uint2(8, 8)); float3 originWS = posInputOrigin.positionWS + _WorldSpaceCameraPos; - if (max(hitPositionNDC.x, hitPositionNDC.y) == 0) - { - // Miss. - return; - } - // TODO: this texture is sparse (mostly black). Can we avoid reading every texel? How about using Hi-S? float2 motionVectorNDC; DecodeMotionVector(SAMPLE_TEXTURE2D_X_LOD(_CameraMotionVectorsTexture, s_linear_clamp_sampler, min(hitPositionNDC, 1.0f - 0.5f * _ScreenSize.zw) * _RTHandleScale.xy, 0), motionVectorNDC); float2 prevFrameNDC = hitPositionNDC - motionVectorNDC; float2 prevFrameUV = prevFrameNDC * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float2 RTSize = 1.0f / _RTHandleScale.xy; - float2 uv = float2(positionSS0)* _ColorPyramidUvScaleAndLimitPrevFrame.xy; - // TODO: optimize with max(). if ((prevFrameUV.x < 0) || (prevFrameUV.x > _ColorPyramidUvScaleAndLimitPrevFrame.z) || (prevFrameUV.y < 0) || (prevFrameUV.y > _ColorPyramidUvScaleAndLimitPrevFrame.w)) @@ -652,7 +650,6 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre } #ifdef SSR_APPROX - // TODO: filtering is quite awful. Needs to be non-Gaussian, bilateral and anisotropic. float mipLevel = lerp(0, _SsrColorPyramidMaxMip, perceptualRoughness); @@ -683,7 +680,6 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre { for (int x = -BLOCK_SAMPLE_RADIUS; x <= BLOCK_SAMPLE_RADIUS; ++x) { - UNITY_FLATTEN if (abs(x) == abs(y) && abs(x) == 1) continue; From 4aa7511915a9b3c95dc2173f5ff992f044345955 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Mon, 19 Oct 2020 18:33:28 +0200 Subject: [PATCH 32/41] Fix GCAlloc issues --- .../Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs | 9 +++++++-- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 409761d76b9..55d133e7b66 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -403,6 +403,8 @@ class RenderSSRPassData public TextureHandle ssrAccumPrev; public TextureHandle clearCoatMask; public ComputeBufferHandle coarseStencilBuffer; + public BlueNoise blueNoise; + public HDCamera hdCamera; //public TextureHandle debugTexture; } @@ -473,12 +475,15 @@ TextureHandle RenderSSR( RenderGraph renderGraph, passData.lightingTexture = builder.WriteTexture(ssrAccum); passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); + passData.hdCamera = hdCamera; + passData.blueNoise = GetBlueNoiseManager(); + builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { RenderSSR(data.parameters, - hdCamera, - GetBlueNoiseManager(), + data.hdCamera, + data.blueNoise, data.depthBuffer, data.depthPyramid, data.normalBuffer, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 0803690de12..fa2025038c7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4964,7 +4964,7 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Clear the SSR lighting buffer (not sure it is required) CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - if (settings.usedAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) + if (settings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.Approximation) { CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); } @@ -5649,7 +5649,7 @@ void ClearBuffers(HDCamera hdCamera, CommandBuffer cmd) ScreenSpaceReflection ssrSettings = hdCamera.volumeStack.GetComponent(); bool ssrNeedReset = false; - if (ssrSettings.usedAlgorithm == ScreenSpaceReflectionAlgorithm.PBRAccumulation && + if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation && hdCamera.currentSSRAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) ssrNeedReset = true; From a1aa2071dc5077dd018efcab2e7ad6f10f2db5cc Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 20 Oct 2020 00:08:15 +0200 Subject: [PATCH 33/41] Fix SSR & Transparent, both pipe RenderGraph & non-RenderGraph --- .../HDRenderPipeline.LightLoop.cs | 50 ++++++++++++++++--- .../RenderPipeline/HDRenderPipeline.cs | 4 -- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 55d133e7b66..23b8150cc4b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -465,22 +465,53 @@ TextureHandle RenderSSR( RenderGraph renderGraph, else passData.motionVectorsBuffer = builder.ReadTexture(renderGraph.defaultResources.blackTextureXR); + passData.hdCamera = hdCamera; + passData.blueNoise = GetBlueNoiseManager(); + + ScreenSpaceReflection ssrVolumeSettings = hdCamera.volumeStack.GetComponent(); + // In practice, these textures are sparse (mostly black). Therefore, clearing them is fast (due to CMASK), // and much faster than fully overwriting them from within SSR shaders. passData.hitPointsTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Hit_Point_Texture_Trans" : "SSR_Hit_Point_Texture" }); + { colorFormat = GraphicsFormat.R16G16_UNorm, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = transparent ? "SSR_Hit_Point_Texture_Trans" : "SSR_Hit_Point_Texture" }); - passData.ssrAccum = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + if (ssrVolumeSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation) + { + passData.ssrAccum = builder.WriteTexture(ssrAccum); + passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); + passData.lightingTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" }); - passData.lightingTexture = builder.WriteTexture(ssrAccum); - passData.ssrAccumPrev = builder.WriteTexture(ssrAccumPrev); - - passData.hdCamera = hdCamera; - passData.blueNoise = GetBlueNoiseManager(); + } + else + { + passData.lightingTexture = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.clear, enableRandomWrite = true, name = "SSR_Lighting_Texture" })); + } builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { + ScreenSpaceReflection ssrSettings = data.hdCamera.volumeStack.GetComponent(); + + if (!data.parameters.transparentSSR) + { + bool ssrNeedReset = false; + if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation && + data.hdCamera.currentSSRAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) + ssrNeedReset = true; + + data.hdCamera.currentSSRAlgorithm = ssrSettings.usedAlgorithm.value; + + if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation) + { + CoreUtils.SetRenderTarget(context.cmd, data.ssrAccum, ClearFlag.Color, Color.clear); + if (ssrNeedReset || data.hdCamera.isFirstFrame) + { + CoreUtils.SetRenderTarget(context.cmd, data.ssrAccumPrev, ClearFlag.Color, Color.clear); + } + } + } + RenderSSR(data.parameters, data.hdCamera, data.blueNoise, @@ -499,7 +530,10 @@ TextureHandle RenderSSR( RenderGraph renderGraph, context.cmd, context.renderContext); }); - result = passData.lightingTexture; + if (ssrVolumeSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation) + result = passData.ssrAccum; + else + result = passData.lightingTexture; if (!transparent) { diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index fa2025038c7..75538d43621 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4964,10 +4964,6 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Clear the SSR lighting buffer (not sure it is required) CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - if (settings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.Approximation) - { - CoreUtils.SetRenderTarget(cmd, ssrAccumulation, ClearFlag.Color, Color.clear); - } } // Evaluate the screen space reflection for the transparent pixels From 08a24b68dafd1f028d03171cdb2e4e03ea23c93d Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Tue, 20 Oct 2020 17:58:33 +0200 Subject: [PATCH 34/41] Add what's new --- .../Documentation~/Images/HDRP-SSRImprovement.png | 3 +++ .../Documentation~/whats-new-10-0.md | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 com.unity.render-pipelines.high-definition/Documentation~/Images/HDRP-SSRImprovement.png diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Images/HDRP-SSRImprovement.png b/com.unity.render-pipelines.high-definition/Documentation~/Images/HDRP-SSRImprovement.png new file mode 100644 index 00000000000..18c00a07e33 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Documentation~/Images/HDRP-SSRImprovement.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62caf65f55dc28df7eb71470f257e5af5ca1c3174cb96f6700761c389cc45ab7 +size 739508 diff --git a/com.unity.render-pipelines.high-definition/Documentation~/whats-new-10-0.md b/com.unity.render-pipelines.high-definition/Documentation~/whats-new-10-0.md index 22401435653..5fb3657bf28 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/whats-new-10-0.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/whats-new-10-0.md @@ -199,6 +199,12 @@ This version of HDRP introduces a new injection point for custom post-processing HDRP, being a high-end modern renderer, contains a lot of compute shader passes. Up until now, to define variations of some compute shaders, HDRP had to manually declare new kernels for each variation. From this version, every compute shader in HDRP uses Unity's multi-compile API which makes maintenance easier, but more importantly allows HDRP to strip shaders that you do not need to improve compilation times. +### Screen Space Reflection + +![](Images/HDRP-SSRImprovement.png) + +HDRP improves the Screen Space Reflection by providing a new implementation 'PBR Accumulation' + ### Planar reflection probe filtering ![](Images/PlanarReflectionFiltering-Feature.png) From dd67a28bd8ec4dbf7dfefbcaa9c942878c8f1764 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Wed, 21 Oct 2020 12:02:13 +0200 Subject: [PATCH 35/41] Regenerate shader includes --- .../Runtime/Lighting/LightLoop/LightLoop.cs.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs.hlsl index dc8f41cf636..4c4eeacfcfc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs.hlsl @@ -136,7 +136,7 @@ float3 GetCenter(SFiniteLightBound value) { return value.center; } -float2 GetScaleXY(SFiniteLightBound value) +float GetScaleXY(SFiniteLightBound value) { return value.scaleXY; } From c2ae5d5a32d9cfdd2d18e4f863237ed9f1c93b00 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Fri, 23 Oct 2020 11:37:35 +0200 Subject: [PATCH 36/41] Fix API Test --- .../HDScreenSpaceReflectionEditor.cs | 4 +- .../Runtime/Debug/DebugDisplay.cs | 11 ++-- .../Runtime/Debug/DebugDisplay.cs.hlsl | 56 +++++++++---------- .../ScreenSpaceReflections.compute | 9 +-- .../Camera/HDCameraFrameHistoryType.cs | 7 ++- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs index f050260e72b..847738a1695 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs @@ -203,7 +203,9 @@ public override void OnInspectorGUI() PropertyField(m_SmoothnessFadeStart, k_SmoothnessFadeStartText); PropertyField(m_ReflectSky, k_ReflectSkyText); m_SmoothnessFadeStart.value.floatValue = Mathf.Max(m_MinSmoothness.value.floatValue, m_SmoothnessFadeStart.value.floatValue); - PropertyField(m_ScreenFadeDistance, k_ScreenFaceDistanceText); + + if (m_UsedAlgorithm.value.intValue != (int)ScreenSpaceReflectionAlgorithm.PBRAccumulation) + PropertyField(m_ScreenFadeDistance, k_ScreenFaceDistanceText); PropertyField(m_DepthBufferThickness, k_DepthBufferThicknessText); m_DepthBufferThickness.value.floatValue = Mathf.Clamp(m_DepthBufferThickness.value.floatValue, 0.001f, 1.0f); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 80c3cbc58c8..9068e65dc45 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -59,10 +59,6 @@ public enum FullScreenDebugMode ScreenSpaceAmbientOcclusion, /// Display Screen Space Reflections buffer used for lighting. ScreenSpaceReflections, - /// Display Screen Space Reflections buffer of the previous frame accumulated. - ScreenSpaceReflectionsPrev, - /// Display Screen Space Reflections buffer of the current frame hit. - ScreenSpaceReflectionsAccum, /// Display the Transparent Screen Space Reflections buffer. TransparentScreenSpaceReflections, /// Display Contact Shadows buffer. @@ -120,7 +116,12 @@ public enum FullScreenDebugMode /// Display specular Color validation mode. ValidateSpecularColor, /// Maximum Full Screen Material debug mode value (used internally). - MaxMaterialFullScreenDebug + MaxMaterialFullScreenDebug, + // TODO: Move before count for 11.0 + /// Display Screen Space Reflections buffer of the previous frame accumulated. + ScreenSpaceReflectionsPrev, + /// Display Screen Space Reflections buffer of the current frame hit. + ScreenSpaceReflectionsAccum } /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl index 05bae86ab6d..8e3563cf69e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl @@ -11,34 +11,34 @@ #define FULLSCREENDEBUGMODE_MIN_LIGHTING_FULL_SCREEN_DEBUG (1) #define FULLSCREENDEBUGMODE_SCREEN_SPACE_AMBIENT_OCCLUSION (2) #define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS (3) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV (4) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM (5) -#define FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS (6) -#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS (7) -#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS_FADE (8) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_SHADOWS (9) -#define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (10) -#define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (11) -#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (12) -#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (13) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (14) -#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (15) -#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (16) -#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (17) -#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (18) -#define FULLSCREENDEBUGMODE_MOTION_VECTORS (19) -#define FULLSCREENDEBUGMODE_NAN_TRACKER (20) -#define FULLSCREENDEBUGMODE_COLOR_LOG (21) -#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (22) -#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (23) -#define FULLSCREENDEBUGMODE_QUAD_OVERDRAW (24) -#define FULLSCREENDEBUGMODE_VERTEX_DENSITY (25) -#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (26) -#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (27) -#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (28) -#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (29) -#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (30) -#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (31) +#define FULLSCREENDEBUGMODE_TRANSPARENT_SCREEN_SPACE_REFLECTIONS (4) +#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS (5) +#define FULLSCREENDEBUGMODE_CONTACT_SHADOWS_FADE (6) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_SHADOWS (7) +#define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (8) +#define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (9) +#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (10) +#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (11) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (12) +#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (13) +#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (14) +#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (15) +#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (16) +#define FULLSCREENDEBUGMODE_MOTION_VECTORS (17) +#define FULLSCREENDEBUGMODE_NAN_TRACKER (18) +#define FULLSCREENDEBUGMODE_COLOR_LOG (19) +#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (20) +#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (21) +#define FULLSCREENDEBUGMODE_QUAD_OVERDRAW (22) +#define FULLSCREENDEBUGMODE_VERTEX_DENSITY (23) +#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (24) +#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (25) +#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (26) +#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (27) +#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (28) +#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (29) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV (30) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM (31) // Generated from UnityEngine.Rendering.HighDefinition.ShaderVariablesDebugDisplay // PackingRules = Exact diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 9fb8570f13d..16efce74407 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -668,7 +668,6 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)] = float4(color, 1.0f) * opacity; #else float3 color = 0.0f; - float opacity = 0.0f; float4 accum = _SSRAccumTexture[COORD_TEXTURE2D_X(positionSS0)]; @@ -698,13 +697,7 @@ void ScreenSpaceReflectionsReprojection(uint3 dispatchThreadId : SV_DispatchThre float2 prevFrameUV = hitData * _ColorPyramidUvScaleAndLimitPrevFrame.xy; - float tmpCoef = PerceptualRoughnessFade(perceptualRoughness, _SsrRoughnessFadeRcpLength, _SsrRoughnessFadeEndTimesRcpLength); - opacity = EdgeOfScreenFade(prevFrameUV / _ColorPyramidUvScaleAndLimitPrevFrame.xy, _SsrEdgeFadeRcpLength) *tmpCoef; - - color = isPosFin ? color : 0; - opacity = isPosFin ? opacity : 0; - - weight *= opacity; + color = isPosFin ? color : 0; outputs += weight * float4(color, 1.0f); wAll += weight; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 340bb3cbcac..7c9b4b4703d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -23,8 +23,6 @@ public enum HDCameraFrameHistoryType Depth1, /// Ambient Occlusion buffer. AmbientOcclusion, - /// Screen Space Reflection Accumulation. - ScreenSpaceReflectionAccumulation, /// Ray traced ambient occlusion buffer. RaytracedAmbientOcclusion, /// Ray traced shadow history buffer. @@ -46,6 +44,9 @@ public enum HDCameraFrameHistoryType /// Temporal antialiasing history after DoF. TemporalAntialiasingPostDoF, /// Number of history buffers. - Count + Count, // TODO: Obsolete + // TODO: Move before count for 11.0 + /// Screen Space Reflection Accumulation. + ScreenSpaceReflectionAccumulation } } From 87f8666f70319383483f38dd747bfc574fc1cb65 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 24 Oct 2020 13:22:24 +0200 Subject: [PATCH 37/41] Fix name RayTracingCommon.hlsl --- .../Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 16efce74407..d5ff83d685d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -43,7 +43,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingCommon.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/PreIntegratedFGD/PreIntegratedFGD.cs.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl" From c22c1287de163818c210f63a9c4c55aa52a26b87 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Sat, 24 Oct 2020 13:44:27 +0200 Subject: [PATCH 38/41] Typo simplification --- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index f326390b367..af75c843ff7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4767,7 +4767,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip if (hdCamera.isFirstFrame || hdCamera.cameraFrameCount <= 2) cb._SsrAccumulationAmount = 1.0f; else - cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(-0.0f, -7.0f, volumeSettings.accumulationFactor.value)); + cb._SsrAccumulationAmount = Mathf.Pow(2, Mathf.Lerp(0.0f, -7.0f, volumeSettings.accumulationFactor.value)); parameters.offsetBufferData = depthPyramid.GetOffsetBufferData(m_DepthPyramidMipLevelOffsetsBuffer); From 5be50111c3c8cc67193916dd078a14e905f00893 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 24 Oct 2020 18:12:44 +0200 Subject: [PATCH 39/41] Update VertMesh.hlsl --- .../Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl | 2 -- 1 file changed, 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl index 1d066989fdf..1b5723c23da 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl @@ -1,5 +1,3 @@ -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/FullScreenDebug.hlsl" struct VaryingsToPS { From a6d20a859cab9ea413bd20170f05ab2f5d31efff Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 24 Oct 2020 18:13:14 +0200 Subject: [PATCH 40/41] Update VertMesh.hlsl --- .../Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl index 1b5723c23da..624e5f02dbb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl @@ -1,4 +1,3 @@ - struct VaryingsToPS { VaryingsMeshToPS vmesh; From 5b913e63b1fa9cd81196edd2d15cf05a7716b472 Mon Sep 17 00:00:00 2001 From: Soufiane KHIAT Date: Sun, 25 Oct 2020 22:55:09 +0100 Subject: [PATCH 41/41] Fix parity RG & Non-RG --- .../HDRenderPipeline.LightLoop.cs | 21 ------------------ .../RenderPipeline/HDRenderPipeline.cs | 22 ++++++++++++++++++- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 23b8150cc4b..b44c4391829 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -491,27 +491,6 @@ TextureHandle RenderSSR( RenderGraph renderGraph, builder.SetRenderFunc( (RenderSSRPassData data, RenderGraphContext context) => { - ScreenSpaceReflection ssrSettings = data.hdCamera.volumeStack.GetComponent(); - - if (!data.parameters.transparentSSR) - { - bool ssrNeedReset = false; - if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation && - data.hdCamera.currentSSRAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) - ssrNeedReset = true; - - data.hdCamera.currentSSRAlgorithm = ssrSettings.usedAlgorithm.value; - - if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation) - { - CoreUtils.SetRenderTarget(context.cmd, data.ssrAccum, ClearFlag.Color, Color.clear); - if (ssrNeedReset || data.hdCamera.isFirstFrame) - { - CoreUtils.SetRenderTarget(context.cmd, data.ssrAccumPrev, ClearFlag.Color, Color.clear); - } - } - } - RenderSSR(data.parameters, data.hdCamera, data.blueNoise, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index d9446780d0e..47a899847e0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -4798,10 +4798,30 @@ static void RenderSSR( in RenderSSRParameters parameters, var cs = parameters.ssrCS; bool usePBRAlgo = parameters.usePBRAlgo; + ScreenSpaceReflection ssrSettings = hdCamera.volumeStack.GetComponent(); + + if (!parameters.transparentSSR) + { + bool ssrNeedReset = false; + if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation && + hdCamera.currentSSRAlgorithm == ScreenSpaceReflectionAlgorithm.Approximation) + ssrNeedReset = true; + + hdCamera.currentSSRAlgorithm = ssrSettings.usedAlgorithm.value; + + if (ssrSettings.usedAlgorithm.value == ScreenSpaceReflectionAlgorithm.PBRAccumulation) + { + CoreUtils.SetRenderTarget(cmd, ssrAccum, ClearFlag.Color, Color.clear); + if (ssrNeedReset || hdCamera.isFirstFrame) + { + CoreUtils.SetRenderTarget(cmd, ssrAccumPrev, ClearFlag.Color, Color.clear); + } + } + } + if (!usePBRAlgo) { CoreUtils.SetKeyword(cmd, "SSR_APPROX", true); - CoreUtils.SetRenderTarget(cmd, ssrLightingTexture, ClearFlag.Color, Color.clear); } using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrTracing)))