Skip to content

Commit 59d7794

Browse files
committed
Merge branch 'pkristof/roughnessDebugView' into 'main'
Cleanly separated primary and secondary demodulation paths. Adjusted debug views See merge request lightspeedrtx/dxvk-remix-nv!2125
2 parents 13b842e + 9a991f9 commit 59d7794

9 files changed

Lines changed: 436 additions & 295 deletions

File tree

src/dxvk/rtx_render/rtx_debug_view.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ namespace dxvk {
114114
"Parameterize via:\n"
115115
"Debug Knob [0]: num texels per checker box [Default: 64]\n"
116116
"Debug Knob [1]: checkers overlay strength [Default: 0.5]"},
117-
{DEBUG_VIEW_BASE_REFLECTIVITY, "Base Reflectivity"},
118117
{DEBUG_VIEW_ROUGHNESS, "Isotropic Roughness"},
119-
{DEBUG_VIEW_PERCEPTUAL_ROUGHNESS, "Perceptual Roughness"},
118+
{DEBUG_VIEW_INDIRECT_FIRST_HIT_PERCEPTUAL_ROUGHNESS, "Indirect First Hit Perceptual Roughness"},
119+
{DEBUG_VIEW_PRIMARY_PERCEPTUAL_ROUGHNESS, "Primary Perceptual Roughness"},
120120
{DEBUG_VIEW_ANISOTROPY, "Anisotropy"},
121121
{DEBUG_VIEW_ANISOTROPIC_ROUGHNESS, "Anisotropic Roughness"},
122122
{DEBUG_VIEW_OPACITY, "Opacity"},
@@ -234,6 +234,12 @@ namespace dxvk {
234234

235235
{DEBUG_VIEW_PRIMARY_SPECULAR_ALBEDO, "Primary Specular Albedo"},
236236
{DEBUG_VIEW_SECONDARY_SPECULAR_ALBEDO, "Secondary Specular Albedo"},
237+
{DEBUG_VIEW_SECONDARY_ALBEDO, "Secondary Diffuse Albedo"},
238+
{DEBUG_VIEW_PRIMARY_BASE_REFLECTIVITY_RAW, "Primary Base Reflectivity (Raw)"},
239+
{DEBUG_VIEW_PRIMARY_BASE_REFLECTIVITY_ADJUSTED, "Primary Base Reflectivity (Adjusted)"},
240+
{DEBUG_VIEW_SECONDARY_BASE_REFLECTIVITY_RAW, "Secondary Base Reflectivity (Raw)"},
241+
{DEBUG_VIEW_SECONDARY_BASE_REFLECTIVITY_ADJUSTED, "Secondary Base Reflectivity (Adjusted)"},
242+
{DEBUG_VIEW_SECONDARY_PERCEPTUAL_ROUGHNESS, "Secondary Perceptual Roughness" },
237243

238244
{DEBUG_VIEW_NOISY_PRIMARY_DIRECT_DIFFUSE_RADIANCE, "Primary Direct Diffuse: Noisy Color"},
239245
{DEBUG_VIEW_NOISY_PRIMARY_DIRECT_DIFFUSE_HIT_T, "Primary Direct Diffuse: Noisy HitT"},
@@ -436,7 +442,7 @@ namespace dxvk {
436442
#define LIST_EXPLICIT_COMPOSITE_DEBUG_VIEWS(X) \
437443
X(CompositeDebugView::FinalRenderWithMaterialProperties, "Final Render + Material Properties", 3, \
438444
DEBUG_VIEW_POST_TONEMAP_OUTPUT, DEBUG_VIEW_ALBEDO, DEBUG_VIEW_SHADING_NORMAL, \
439-
DEBUG_VIEW_PERCEPTUAL_ROUGHNESS, DEBUG_VIEW_EMISSIVE_RADIANCE, DEBUG_VIEW_HEIGHT_MAP) \
445+
DEBUG_VIEW_PRIMARY_PERCEPTUAL_ROUGHNESS, DEBUG_VIEW_EMISSIVE_RADIANCE, DEBUG_VIEW_HEIGHT_MAP) \
440446
X(CompositeDebugView::OpaqueMaterialTextureResolutionCheckers, "Opaque Material Texture Resolution Checkers", 2, \
441447
DEBUG_VIEW_OPAQUE_RAW_ALBEDO_RESOLUTION_CHECKERS, DEBUG_VIEW_OPAQUE_NORMAL_RESOLUTION_CHECKERS, \
442448
DEBUG_VIEW_OPAQUE_ROUGHNESS_RESOLUTION_CHECKERS)

src/dxvk/shaders/rtx/algorithm/geometry_resolver.slangh

Lines changed: 68 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ void geometryResolverOutputSurface<
416416
AlphaBlendGBuffer[pixelCoordinate] = alphaBlendSurface.pack(cb.alphaBlendSurfacePackMult);
417417
}
418418

419-
geometryResolverOutputSurfaceDebugView(pixelCoordinate, virtualMotion);
419+
geometryResolverOutputSurfaceDebugView<PRIMARY_SURFACE>(pixelCoordinate, virtualMotion, polymorphicSurfaceMaterialInteraction);
420420
}
421421

422422
void geometryResolverOutputSurfaceDynamic(
@@ -525,9 +525,11 @@ void accumulateParticleBuffer(ivec2 pixelCoordinate, vec3 radiance)
525525

526526
#if GBUFFER_FEATURE_DEBUG_VIEW
527527

528-
void geometryResolverOutputSurfaceDebugView(
528+
void geometryResolverOutputSurfaceDebugView<
529+
let PRIMARY_SURFACE : bool>(
529530
uvec2 pixelCoordinate,
530-
vec3 virtualMotion)
531+
vec3 virtualMotion,
532+
PolymorphicSurfaceMaterialInteraction polymorphicSurfaceMaterialInteraction)
531533
{
532534
switch(cb.debugView)
533535
{
@@ -537,17 +539,51 @@ void geometryResolverOutputSurfaceDebugView(
537539
case DEBUG_VIEW_VIRTUAL_MOTION_VECTOR:
538540
storeInDebugView(pixelCoordinate, virtualMotion);
539541
break;
540-
case DEBUG_VIEW_NAN:
542+
case DEBUG_VIEW_SECONDARY_PERCEPTUAL_ROUGHNESS:
543+
if (!PRIMARY_SURFACE)
544+
{
545+
storeInDebugView(pixelCoordinate, SecondaryPerceptualRoughness[pixelCoordinate]);
546+
}
547+
break;
548+
case DEBUG_VIEW_SECONDARY_ALBEDO:
549+
if (!PRIMARY_SURFACE)
550+
{
551+
storeInDebugView(pixelCoordinate, SecondaryAlbedo[pixelCoordinate].xyz);
552+
}
553+
break;
554+
case DEBUG_VIEW_SECONDARY_BASE_REFLECTIVITY_RAW:
555+
if (!PRIMARY_SURFACE)
556+
{
557+
storeInDebugView(pixelCoordinate, SecondaryBaseReflectivity[pixelCoordinate].xyz);
558+
}
559+
break;
560+
case DEBUG_VIEW_NAN:
541561
{
542562
bool isValid = true;
543-
563+
544564
// DEBUG_VIEW_VIRTUAL_MOTION_VECTOR
545565
isValid &= isValidValue(virtualMotion);
546566

567+
// DEBUG_VIEW_SECONDARY_PERCEPTUAL_ROUGHNESS / DEBUG_VIEW_SECONDARY_ALBEDO
568+
if (!PRIMARY_SURFACE)
569+
{
570+
isValid &= isValidValue(SecondaryPerceptualRoughness[pixelCoordinate]);
571+
isValid &= isValidValue(SecondaryAlbedo[pixelCoordinate].xyz);
572+
// DEBUG_VIEW_SECONDARY_BASE_REFLECTIVITY_RAW
573+
isValid &= isValidValue(SecondaryBaseReflectivity[pixelCoordinate].xyz);
574+
}
575+
547576
accumulateInDebugViewAnd(pixelCoordinate, isValid);
548577
break;
549578
}
550579
}
580+
581+
// Primary-material debug views are factored into a separate helper because the unordered-decals
582+
// pass re-invokes it after blending updates the GBuffer; calling it here covers the initial write.
583+
if (PRIMARY_SURFACE)
584+
{
585+
geometryResolverOutputPrimaryMaterialDebugView(pixelCoordinate, polymorphicSurfaceMaterialInteraction);
586+
}
551587
}
552588

553589
void geometryResolverVertexOutputDebugView(
@@ -756,21 +792,6 @@ void geometryResolverVertexOutputDebugView(
756792

757793
storeInDebugView(pixelCoordinate, albedo);
758794

759-
break;
760-
case DEBUG_VIEW_BASE_REFLECTIVITY:
761-
vec3 baseReflectivity = vec3(0.0f);
762-
763-
if (materialType == surfaceMaterialTypeOpaque)
764-
{
765-
baseReflectivity = opaqueSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity;
766-
}
767-
else if (materialType == surfaceMaterialTypeTranslucent)
768-
{
769-
baseReflectivity = translucentSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity;
770-
}
771-
772-
storeInDebugView(pixelCoordinate, baseReflectivity);
773-
774795
break;
775796
case DEBUG_VIEW_ROUGHNESS:
776797
float isotropicRoughness = 0.0f;
@@ -1075,18 +1096,6 @@ void geometryResolverVertexOutputDebugView(
10751096
}
10761097
isValid &= isValidValue(albedo);
10771098

1078-
// DEBUG_VIEW_BASE_REFLECTIVITY
1079-
vec3 baseReflectivity = vec3(0.0f);
1080-
if (materialType == surfaceMaterialTypeOpaque)
1081-
{
1082-
baseReflectivity = opaqueSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity;
1083-
}
1084-
else if (materialType == surfaceMaterialTypeTranslucent)
1085-
{
1086-
baseReflectivity = translucentSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity;
1087-
}
1088-
isValid &= isValidValue(baseReflectivity);
1089-
10901099
// DEBUG_VIEW_ROUGHNESS
10911100
float isotropicRoughness = 0.0f;
10921101
if (materialType == surfaceMaterialTypeOpaque)
@@ -1334,7 +1343,12 @@ void geometryResolverOutputDebugView(uvec2 pixelCoordinate)
13341343
}
13351344
}
13361345

1337-
void geometryResolverOutputFinalPrimaryMaterialDebugView(
1346+
// Writes primary-surface debug views derived from the GBuffer-resident material data.
1347+
// May be called more than once per pixel: once after the initial primary material write in the
1348+
// geometry resolve pass, and again after unordered-decal blending updates the same GBuffer
1349+
// resources. All cases here must therefore be safe to re-run (snapshot writes that overwrite the
1350+
// previous value, or accumulators whose operation is idempotent/order-independent).
1351+
void geometryResolverOutputPrimaryMaterialDebugView(
13381352
uvec2 pixelCoordinate,
13391353
PolymorphicSurfaceMaterialInteraction polymorphicSurfaceMaterialInteraction)
13401354
{
@@ -1344,6 +1358,12 @@ void geometryResolverOutputFinalPrimaryMaterialDebugView(
13441358
{
13451359
default:
13461360
break;
1361+
case DEBUG_VIEW_PRIMARY_PERCEPTUAL_ROUGHNESS:
1362+
storeInDebugView(pixelCoordinate, PrimaryPerceptualRoughness[pixelCoordinate]);
1363+
break;
1364+
case DEBUG_VIEW_PRIMARY_BASE_REFLECTIVITY_RAW:
1365+
storeInDebugView(pixelCoordinate, PrimaryBaseReflectivity[pixelCoordinate].xyz);
1366+
break;
13471367
case DEBUG_VIEW_SHADING_NORMAL:
13481368
{
13491369
vec3 shadingNormal = vec3(0.0f);
@@ -1381,22 +1401,6 @@ void geometryResolverOutputFinalPrimaryMaterialDebugView(
13811401
storeInDebugView(pixelCoordinate, albedo);
13821402
break;
13831403
}
1384-
case DEBUG_VIEW_BASE_REFLECTIVITY:
1385-
{
1386-
vec3 baseReflectivity = vec3(0.0f);
1387-
1388-
if (materialType == surfaceMaterialTypeOpaque)
1389-
{
1390-
baseReflectivity = opaqueSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity;
1391-
}
1392-
else if (materialType == surfaceMaterialTypeTranslucent)
1393-
{
1394-
baseReflectivity = vec3(translucentSurfaceMaterialInteractionCreate(polymorphicSurfaceMaterialInteraction).baseReflectivity);
1395-
}
1396-
1397-
storeInDebugView(pixelCoordinate, baseReflectivity);
1398-
break;
1399-
}
14001404
case DEBUG_VIEW_ROUGHNESS:
14011405
{
14021406
float isotropicRoughness = 0.0f;
@@ -1511,9 +1515,11 @@ void geometryResolverOutputFinalPrimaryMaterialDebugView(
15111515

15121516
#else
15131517

1514-
void geometryResolverOutputSurfaceDebugView(
1518+
void geometryResolverOutputSurfaceDebugView<
1519+
let PRIMARY_SURFACE : bool>(
15151520
uvec2 pixelCoordinate,
1516-
vec3 virtualMotion)
1521+
vec3 virtualMotion,
1522+
PolymorphicSurfaceMaterialInteraction polymorphicSurfaceMaterialInteraction)
15171523
{
15181524
}
15191525

@@ -1996,7 +2002,7 @@ void geometryResolverVertex(
19962002

19972003
// Update NRC when a final GBuffer hit occurs.
19982004
// Note: any path termination handling is delayed to indirect pass
1999-
if (!(geometryResolverState.performPSRR || geometryResolverState.performPSTR))
2005+
if (!geometryResolverState.performedAnyPSR())
20002006
{
20012007
// Note: radiance and throughput gets reset by NRC for training paths
20022008
updateNrcOnGBufferHitTrainingAndQueryPaths(geometryResolverState.pixelCoordinate,
@@ -2038,7 +2044,7 @@ void geometryResolverVertex(
20382044
#else
20392045
true &&
20402046
#endif
2041-
(geometryResolverState.performPSRR || geometryResolverState.performPSTR);
2047+
geometryResolverState.performedAnyPSR();
20422048

20432049
if (writeFirstHitForPSRPrepare)
20442050
{
@@ -2106,7 +2112,7 @@ void geometryResolverVertex(
21062112
}
21072113
}
21082114
#if GBUFFER_FEATURE_INLINE_PSR_SAMPLING
2109-
else if (geometryResolverState.performPSRR || geometryResolverState.performPSTR)
2115+
else if (geometryResolverState.performedAnyPSR())
21102116
{
21112117
// Set the geometry flag bits that must be the same for both PSR passes, see unpackPSRData(...)
21122118

@@ -2202,7 +2208,7 @@ void geometryResolverVertex(
22022208
geometryResolverState.isViewModelSurface);
22032209
}
22042210

2205-
if (GBUFFER_FEATURE_INLINE_PSR_SAMPLING && !push.usePSRPrepare && (geometryResolverState.performPSRR || geometryResolverState.performPSTR))
2211+
if (GBUFFER_FEATURE_INLINE_PSR_SAMPLING && !push.usePSRPrepare && geometryResolverState.performedAnyPSR())
22062212
{
22072213
PrimaryAttenuation[geometryResolverState.pixelCoordinate] = colorToR11G11B10(geometryResolverState.attenuation);
22082214
}
@@ -2953,7 +2959,7 @@ void geometryResolver(ivec2 pixelCoordinate) {
29532959
bool primarySelectedIntegrationSurface;
29542960
bool secondarySurfaceMask;
29552961

2956-
if (geometryResolverState.performPSRR && geometryResolverState.performPSTR)
2962+
if (geometryResolverState.hasSecondarySurface())
29572963
{
29582964
// Note: Transmission preferred as the primary surface when both PSRR and PSTR are done at the same time.
29592965
primarySelectedIntegrationSurface = !geometryResolverState.reflectionSelectedIntegrationSurface;
@@ -3269,7 +3275,7 @@ void geometryResolverApplyUnorderedDecalsPass(ivec2 pixelCoordinate) {
32693275
}
32703276

32713277
#if GBUFFER_FEATURE_DEBUG_VIEW
3272-
geometryResolverOutputFinalPrimaryMaterialDebugView(
3278+
geometryResolverOutputPrimaryMaterialDebugView(
32733279
pixelCoordinate,
32743280
blendedPolymorphicSurfaceMaterialInteraction);
32753281
#endif
@@ -3406,7 +3412,10 @@ void geometryPSRPreparePass(ivec2 pixelCoordinate) {
34063412
SharedRadianceB[pixelCoordinate] = radiance.b;
34073413
SharedIntegrationSurfacePdf[pixelCoordinate] = selectedIntegrationSurfacePdf;
34083414

3409-
if (performPSRR && performPSTR)
3415+
geometryFlags.performPSRR = performPSRR;
3416+
geometryFlags.performPSTR = performPSTR;
3417+
3418+
if (geometryFlags.hasSecondarySurface())
34103419
{
34113420
geometryFlags.primarySelectedIntegrationSurface = !reflectionSelectedIntegrationSurface;
34123421
geometryFlags.secondarySurfaceMask = true;
@@ -3417,10 +3426,7 @@ void geometryPSRPreparePass(ivec2 pixelCoordinate) {
34173426
geometryFlags.secondarySurfaceMask = false;
34183427
}
34193428

3420-
geometryFlags.performPSRR = performPSRR;
3421-
geometryFlags.performPSTR = performPSTR;
3422-
3423-
if (!(performPSRR || performPSTR))
3429+
if (!geometryFlags.performedAnyPSR())
34243430
{
34253431
geometryResolverOutputMiss<false, false>(pixelCoordinate);
34263432
geometryFlagsWriteToGBuffer(geometryFlags, pixelCoordinate, SharedFlags);

src/dxvk/shaders/rtx/algorithm/geometry_resolver_state.slangh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ struct GeometryResolverState : IBasePayloadState
188188
return false;
189189
}
190190
#endif // defined(RAY_PIPELINE)
191+
192+
// True if any PSR (reflection or transmission) is being performed for this pixel.
193+
bool performedAnyPSR()
194+
{
195+
return performPSTR || performPSRR;
196+
}
197+
198+
// True only when BOTH PSRR and PSTR fire — one becomes the primary surface, the other becomes a distinct secondary surface.
199+
bool hasSecondarySurface()
200+
{
201+
return performPSTR && performPSRR;
202+
}
191203
}
192204

193205
struct GeometryPSRResolverState : IBasePayloadState
@@ -363,7 +375,7 @@ struct GeometryPSRResolverState : IBasePayloadState
363375
}
364376

365377
#ifdef RAY_PIPELINE
366-
bool shouldReorder(out uint coherenceHints, out uint numCoherenceHints)
378+
bool shouldReorder(out uint coherenceHints, out uint numCoherenceHints)
367379
{
368380
coherenceHints = 0;
369381
numCoherenceHints = 0;

src/dxvk/shaders/rtx/algorithm/integrator_direct.slangh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ void integratorDirectPathOutputDebugView(
517517
}
518518
break;
519519
}
520-
case DEBUG_VIEW_PERCEPTUAL_ROUGHNESS:
520+
case DEBUG_VIEW_INDIRECT_FIRST_HIT_PERCEPTUAL_ROUGHNESS:
521521
storeInDebugView(pixelCoordinate, aliasedData1.IndirectFirstHitPerceptualRoughness[pixelCoordinate]);
522522
break;
523523
case DEBUG_VIEW_INTEGRATE_INDIRECT_FIRST_RAY_THROUGHPUT:
@@ -543,7 +543,7 @@ void integratorDirectPathOutputDebugView(
543543
isValid &= isValidValue(SecondaryCombinedSpecularLobeRadianceHitDistance[pixelCoordinate]);
544544
}
545545

546-
// DEBUG_VIEW_PERCEPTUAL_ROUGHNESS
546+
// DEBUG_VIEW_INDIRECT_FIRST_HIT_PERCEPTUAL_ROUGHNESS
547547
isValid &= isValidValue(aliasedData1.IndirectFirstHitPerceptualRoughness[pixelCoordinate]);
548548

549549
// DEBUG_VIEW_INTEGRATE_INDIRECT_FIRST_RAY_THROUGHPUT

src/dxvk/shaders/rtx/pass/composite/composite.comp.slang

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,7 @@ void main(uint2 threadIndex : SV_DispatchThreadID, uint2 localIndex : SV_GroupTh
561561
// Note: Relying on the same sentinel value outputted to the linear view Z which NRD relies on, so this is safe (and lets us not have to read
562562
// in the cone radius texture which typically contains the flag we use to determine this).
563563
const bool primaryMiss = primaryLinearViewZ == cb.primaryDirectMissLinearViewZ
564-
&& !geometryFlags.performPSTR
565-
&& !geometryFlags.performPSRR; // must not be PSR
564+
&& !geometryFlags.performedAnyPSR(); // must not be PSR
566565

567566
vec4 particleLayerOutput;
568567
vec4 finalOutput = compositeResult(pixelCoordinate, geometryFlags, primaryLinearViewZ, primaryMiss, particleLayerOutput);

0 commit comments

Comments
 (0)