Skip to content

Commit 83a508b

Browse files
committed
Merge branch 'pkristof/sanitizePomNans' into 'main'
[REMIX-3709]: Sanitize nans in POM uvs See merge request lightspeedrtx/dxvk-remix-nv!1152
2 parents edede05 + 9d51c0c commit 83a508b

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

src/dxvk/shaders/rtx/concept/surface_material/opaque_surface_material_interaction.slangh

+19-5
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,15 @@ float4 pomGetPatchCorners(Texture2D texture, SamplerState sampler, float2 boxCen
8787
}
8888

8989
// cast a ray in tangent space. return an intersection point in tangent point (or an exit point if z > 1.0f)
90-
float3 pomTraceRay(Texture2D texture, SamplerState sampler, float3 origin, float3 direction, float2 textureGradientX, float2 textureGradientY, inout uint iterations, float neutralHeight)
90+
float3 pomTraceRay(
91+
Texture2D texture,
92+
SamplerState sampler,
93+
float3 origin,
94+
float3 direction,
95+
float2 textureGradientX,
96+
float2 textureGradientY,
97+
inout uint iterations,
98+
float neutralHeight)
9199
{
92100
// Potential future improvements for outwards rays:
93101
// 1) calculate starting height the same way the box intersection code does instead of just sampling at a pixel.
@@ -155,7 +163,7 @@ float3 pomTraceRay(Texture2D texture, SamplerState sampler, float3 origin, float
155163
// causes smooth slops to turn jagged. It may be an improvement to use that approach only when the current
156164
// pixel is the largest or smallest of all the neighbors, but that seemed too complex to be worth pursuing.
157165

158-
// Calculate the point where the ray entered this box:
166+
// Calculate the point where the ray entered this box:
159167
const float2 boxNearCorner = boxCenter - forwardHalfStep * boxSize;
160168
const float2 boxEntranceDist = (boxNearCorner - origin.xy) / direction.xy;
161169
const float3 boxEntrance = origin + max(0.0f, max(boxEntranceDist.x, boxEntranceDist.y)) * direction;
@@ -217,10 +225,12 @@ float3 pomTraceRay(Texture2D texture, SamplerState sampler, float3 origin, float
217225
}
218226

219227
// Outwards rays can go past the top of the POM surface, so limit it to there.
220-
if (curPos.z > 1) {
228+
if (curPos.z > 1)
229+
{
221230
float distToOne = (1.0f - origin.z) / direction.z;
222231
return origin + distToOne * direction;
223232
}
233+
224234
return curPos;
225235
}
226236

@@ -445,13 +455,17 @@ OpaqueSurfaceMaterialInteraction opaqueSurfaceMaterialInteractionCreate(
445455
f16vec3 viewDirTextureSpace = normalize(mul(worldToTexture, minimalRayInteraction.viewDirection));
446456
// Note: -1.f * TextureGradientX has the same x,y direction as viewDirTextureSpace, but calculating the correct z value is non-obvious.
447457
// Could potentially remove the need for the worldToTexture transform if a faster way to calculate that z value is found.
448-
458+
449459
uint iterations = 0; // unused
450-
surfaceInteraction.textureCoordinates = pomCalculateTexcoord(
460+
const vec2 pomTextureCoordinates = pomCalculateTexcoord(
451461
opaqueSurfaceMaterial,
452462
surfaceInteraction,
453463
viewDirTextureSpace,
454464
iterations).xy;
465+
466+
// WAR for REMIX-3709 - POM sometimes produces NaNs.
467+
surfaceInteraction.textureCoordinates = sanitize(pomTextureCoordinates, surfaceInteraction.textureCoordinates);
468+
455469
opaqueSurfaceMaterialInteraction.flags |= OPAQUE_SURFACE_MATERIAL_INTERACTION_FLAG_HAS_HEIGHT_TEXTURE;
456470
}
457471
#endif

src/dxvk/shaders/rtx/utility/common.slangh

+11-3
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,23 @@ bool isValidValue(vec4 value)
8282
return !(any(isnan(value)) || any(isinf(value)));
8383
}
8484

85-
float sanitize(float val, float defaultVal) {
85+
float sanitize(float val, float defaultVal)
86+
{
8687
return isValidValue(val) ? val : defaultVal;
8788
}
8889

89-
vec3 sanitize(vec3 val, vec3 defaultVal) {
90+
vec2 sanitize(vec2 val, vec2 defaultVal)
91+
{
9092
return isValidValue(val) ? val : defaultVal;
9193
}
9294

93-
vec4 sanitize(vec4 val, vec4 defaultVal) {
95+
vec3 sanitize(vec3 val, vec3 defaultVal)
96+
{
97+
return isValidValue(val) ? val : defaultVal;
98+
}
99+
100+
vec4 sanitize(vec4 val, vec4 defaultVal)
101+
{
94102
return isValidValue(val) ? val : defaultVal;
95103
}
96104

src/dxvk/shaders/rtx/utility/math.slangh

+2-2
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ f16vec4 quaternionMultiply(f16vec4 q1, f16vec4 q2, bool signBitIsParity = false)
322322
// Calculates a tangent and bitangent vector in the direction of the U and V coordinates of a triangle orthonormal to a
323323
// specified normal (this may be a triangle normal or an interpolated normal depending on the use case).
324324
// Note that the vectors this function returns may form an improper rotation when converted to a transformation due to a swap of
325-
// handedness. No gaurantees for left or right handedness are made as it depends on the triangle's UV layout.
325+
// handedness. No guarantees for left or right handedness are made as it depends on the triangle's UV layout.
326326
void genTangSpace(vec2 uvs[3],
327327
vec3 pos[3],
328328
f16vec3 normal,
@@ -358,7 +358,7 @@ void genTangSpace(vec2 uvs[3],
358358
rawTangent = (duv12[1] * dp02 - duv02[1] * dp12) * invdet;
359359
rawBitangent = (-duv12[0] * dp02 + duv02[0] * dp12) * invdet;
360360
}
361-
// rawTangent and rawBitangent are too large for fp16, but We need the non-uniform component of the scale for POM.
361+
// rawTangent and rawBitangent are too large for fp16, but we need the non-uniform component of the scale for POM.
362362
// Here, we scale both down by the length of the larger vector.
363363
float largerRawLength = sqrt(max(squareLength(rawTangent), squareLength(rawBitangent)));
364364

0 commit comments

Comments
 (0)