diff --git a/Source/Shaders/SSR.hlsl b/Source/Shaders/SSR.hlsl index 52fc4e7fa..2502b27be 100644 --- a/Source/Shaders/SSR.hlsl +++ b/Source/Shaders/SSR.hlsl @@ -64,6 +64,9 @@ float3 TraceScreenSpaceReflection( #endif float2 uv, GBufferSample gBuffer, Texture2D depthBuffer, float3 viewPos, float4x4 viewMatrix, float4x4 viewProjectionMatrix, float stepSize, float maxSamples = 50, bool temporal = false, float temporalTime = 0.0f, float worldAntiSelfOcclusionBias = 0.1f, float brdfBias = 0.82f, float drawDistance = 5000.0f, float roughnessThreshold = 0.4f, float edgeFade = 0.1f) { +#if SSR_USE_HZB + uncertainHit = false; +#endif #ifndef SSR_SKIP_INVALID_CHECK // Reject invalid pixels if (gBuffer.ShadingModel == SHADING_MODEL_UNLIT || gBuffer.Roughness > roughnessThreshold || gBuffer.ViewPos.z > drawDistance) @@ -73,9 +76,9 @@ float3 TraceScreenSpaceReflection( // Calculate view space normal vector float3 normalVS = mul(gBuffer.Normal, (float3x3)viewMatrix); float3 reflectVS = normalize(reflect(gBuffer.ViewPos, normalVS)); - if (gBuffer.ViewPos.z < 1.0 && reflectVS.z < 0.4) - return 0; - + if (reflectVS.z < 0.001f) + return 0; // Ray goes towards the view + // Calculate ray path in UV space (z is raw depth) float3 reflectWS = ScreenSpaceReflectionDirection(uv, gBuffer, viewPos, temporal, temporalTime, brdfBias); #if SSR_USE_HZB @@ -149,6 +152,9 @@ float3 TraceScreenSpaceReflection( // Fade on distance float distanceFade = saturate((drawDistance - gBuffer.ViewPos.z) / drawDistance); + // Fade on ray + float reflectFade = saturate(reflectVS.z * 8.0f); + // Output: xy: hitUV, z: hitMask - return float3(currOffset.xy, fadeOnBorder * roughnessFade * distanceFade); + return float3(currOffset.xy, fadeOnBorder * roughnessFade * distanceFade * reflectFade); } diff --git a/Source/ThirdParty/FidelityFX/ffx_sssr.h b/Source/ThirdParty/FidelityFX/ffx_sssr.h index 3e9eeab85..e708d2327 100644 --- a/Source/ThirdParty/FidelityFX/ffx_sssr.h +++ b/Source/ThirdParty/FidelityFX/ffx_sssr.h @@ -107,14 +107,14 @@ float3 FFX_SSSR_HierarchicalRaymarch(Texture2D depthBuffer, uint hzbMips, float FFX_SSSR_InitialAdvanceRay(origin, direction, inv_direction, current_mip_resolution, current_mip_resolution_inv, floor_offset, uv_offset, position, current_t); uint overDiffError = 0; - int i = 0; + uint i = 0; while (i < max_traversal_intersections && current_mip >= most_detailed_mip) { float2 current_mip_position = current_mip_resolution * position.xy; float surface_z = depthBuffer.Load(int3(current_mip_position, current_mip)).x; if (position.z - surface_z > depthDiffError) overDiffError++; // Count number of times we were under the depth by more than the allowed error bool skipped_tile = FFX_SSSR_AdvanceRay(origin, direction, inv_direction, current_mip_position, current_mip_resolution_inv, floor_offset, uv_offset, surface_z, position, current_t); ++i; - if (!skipped_tile || current_mip < hzbMips) // Never go too low depth resolution to avoid blocky artifacts + if (!skipped_tile || current_mip < (int)hzbMips) // Never go too low depth resolution to avoid blocky artifacts { current_mip += skipped_tile ? 1 : -1; current_mip_resolution *= skipped_tile ? 0.5 : 2;