Fix SSR artifacts when ray goes towards the screen
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
4
Source/ThirdParty/FidelityFX/ffx_sssr.h
vendored
4
Source/ThirdParty/FidelityFX/ffx_sssr.h
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user