diff --git a/src/dxvk/rtx_render/rtx_restir_gi_rayquery.h b/src/dxvk/rtx_render/rtx_restir_gi_rayquery.h index 24cd5e662..6b08ef2e5 100644 --- a/src/dxvk/rtx_render/rtx_restir_gi_rayquery.h +++ b/src/dxvk/rtx_render/rtx_restir_gi_rayquery.h @@ -119,7 +119,7 @@ namespace dxvk { RTX_OPTION("rtx.restirGI", float, fireflyThreshold, 50.f, "Clamps specular input to suppress boiling."); RTX_OPTION("rtx.restirGI", float, roughnessClamp, 0.01f, "Clamps minimum roughness a sample's importance is evaluated."); RTX_OPTION("rtx.restirGI", bool, validateLightingChange, true, "Remove samples when direct light has changed."); - RTX_OPTION("rtx.restirGI", bool, validateVisibilityChange, false, "Remove samples when visibility has changed. This feature is automatically disabled when virtual sample is enabled."); + RTX_OPTION_ENV("rtx.restirGI", bool, validateVisibilityChange, false, "DXVK_RESTIR_GI_VISIBILITY_VALIDATION", "Remove samples when visibility has changed. This feature is automatically disabled when virtual sample is enabled."); RTX_OPTION_ENV("rtx.restirGI", float, lightingValidationThreshold, 0.5, "DXVK_RESTIR_GI_SAMPLE_VALIDATION_THRESHOLD", "Invalidate a sample when pixel change ratio is above this value."); RTX_OPTION("rtx.restirGI", float, visibilityValidationRange, 0.05, "Check actual hit distance of a shadow ray, invalidate a sample if hit length is longer than one plus this portion, compared to the distance from the surface to the sample."); }; diff --git a/src/dxvk/shaders/rtx/algorithm/visibility.slangh b/src/dxvk/shaders/rtx/algorithm/visibility.slangh index 5c43576c1..597e0c3c8 100644 --- a/src/dxvk/shaders/rtx/algorithm/visibility.slangh +++ b/src/dxvk/shaders/rtx/algorithm/visibility.slangh @@ -317,10 +317,17 @@ VisibilityResult traceVisibilityRay( f16vec3 surfaceAttenuation = handleVisibilityVertex(visibilityRay, rayHitInfo, visibilityMode, usePreviousTLAS); + f16vec3 prevAttenuation = result.attenuation; result.attenuation *= surfaceAttenuation; + // Find an opaque hit if ((float16_t(1) - calcBt709Luminance(result.attenuation)) >= cb.resolveOpaquenessThreshold) { + // If opaque hit is not considered in the attenuation term, need to recover previous attenuation. + if(!clearOpaqueHitAttenuation) + { + result.attenuation = prevAttenuation; + } rayQuery.CommitNonOpaqueTriangleHit(); break; }