Increased tess depth

This commit is contained in:
Justin Marshall
2026-05-12 16:43:28 -07:00
parent 135aa685b9
commit a797428ee5
+26 -17
View File
@@ -2305,7 +2305,10 @@ cbuffer DrawCB : register(b0)
#define gUseSpecularMap gMaterialMapPad.x
#define gSpecularMapStrength gMaterialMapPad.y
#define gAlphaBlendPass gMaterialMapPad.z
#define gTessellationDisplacement max(gMaterialMapPad.w, 0.0)
// Full object-space displacement amplitude for the tessellation domain shader.
// The CPU side keeps this conservative, but clamp here too so a bad material
// strength cannot explode the mesh.
#define gTessellationDisplacement clamp(gMaterialMapPad.w, 0.0, 0.35)
Texture2D gTex0 : register(t0);
Texture2D gTex1 : register(t1);
@@ -2540,12 +2543,14 @@ float QD3D12_HeightFromNormalSample(float4 nm)
{
// Many legacy normal maps are RGB/DXT uploads with an implicitly forced
// opaque alpha channel. Treat alpha as height only when it looks like real
// authored data; otherwise derive a conservative pseudo-height from the
// normal itself. A flat normal (0.5, 0.5, 1.0) stays centered at 0.5, so
// RGB-only normal maps do not push whole surfaces outward.
// authored data; otherwise derive a stronger pseudo-height from the normal
// itself. A flat normal (0.5, 0.5, 1.0) stays centered at 0.5, while steep
// normal-map detail now gets a much larger positive lift so tessellation
// visibly pops instead of barely moving the silhouette.
bool hasAuthoredHeight = (nm.a > 0.0001 && nm.a < 0.999);
float3 decoded = nm.xyz * 2.0 - 1.0;
float slopeHeight = 0.5 + (1.0 - saturate(abs(decoded.z))) * 0.25;
float slope = 1.0 - saturate(abs(decoded.z));
float slopeHeight = 0.5 + pow(slope, 0.65) * 0.5;
float h = hasAuthoredHeight ? nm.a : slopeHeight;
return saturate(h);
}
@@ -2840,12 +2845,12 @@ float QD3D12_ComputeNormalMapTessFactor(InputPatch<VSOut, 3> patch)
float h2 = QD3D12_GetHeightFromNormalMapLOD(patch[2].uv0, 0.0);
float heightRange = max(abs(h0 - h1), max(abs(h1 - h2), abs(h2 - h0)));
// Keep the factor conservative. Most legacy normal maps are not authored as
// height maps, so aggressive tessellation creates cracks and flickering without
// adding useful detail. Height variation still nudges the factor upward.
float strength = saturate(max(gNormalMapStrength, 0.0));
float factor = 1.0 + strength + heightRange * 4.0;
return (gUseNormalMap > 0.5) ? clamp(factor, 1.0, 4.0) : 1.0;
// Give displaced normal-mapped surfaces enough subdivision to show the larger
// height push. fractional_odd will quantize these into stable odd partitions,
// so 3/5/7 are the practical quality tiers for default/strong materials.
float strength = clamp(max(gNormalMapStrength, 0.0), 0.0, 4.0);
float factor = 2.0 + strength * 1.0 + heightRange * 8.0;
return (gUseNormalMap > 0.5) ? clamp(factor, 2.0, 7.0) : 1.0;
}
HSConstOut HSMainConstants(InputPatch<VSOut, 3> patch)
@@ -2907,7 +2912,8 @@ VSOut DSMain(HSConstOut tessFactors, float3 bary : SV_DomainLocation, const Outp
float3 objNormal = QD3D12_SafeNormalize(i.objNormal, float3(0.0, 0.0, 1.0));
float height = QD3D12_GetHeightFromNormalMapLOD(i.uv0, 0.0);
float displacement = (height - 0.5) * gTessellationDisplacement;
float centeredHeight = (height - 0.5) * 2.0;
float displacement = centeredHeight * gTessellationDisplacement;
float3 displacedObjPos = i.objPos + objNormal * displacement;
float4 worldPos = mul(gModelMatrix, float4(displacedObjPos, 1.0));
@@ -8928,12 +8934,15 @@ static void QD3D12_FlushQueuedBatches()
dc->materialMapPad[0] = batch.key.useSpecularMap;
dc->materialMapPad[1] = batch.key.specularMapStrength;
dc->materialMapPad[2] = QD3D12_PipelineUsesAlphaBlend(batch.key.pipeline) ? 1.0f : 0.0f;
// Normal-map strength is a shading control, not an object-space height in
// Quake/idTech units. Use it only as a small scalar for displacement so the
// tessellation pass cannot shove surfaces through walls or the near plane.
const float tessDisplacementScale = 0.03f;
// Normal-map strength now drives a visibly stronger object-space displacement.
// Keep a hard upper bound because old RGB-only normal maps are often noisy and
// are not authored as true height maps. Default strength 1.0 gives about
// +/-0.08 object units for authored alpha-height maps and outward lift for
// RGB-only bump detail; glNormalMapStrengthf() can push it higher.
const float tessStrength = ClampValue<float>(batch.key.normalMapStrength, 0.0f, 4.0f);
const float tessDisplacementScale = 0.08f;
dc->materialMapPad[3] = QD3D12_UseNormalMapTessellationPSO(batch.key, nativeColorOnly) ?
(ClampValue<float>(batch.key.normalMapStrength, 0.0f, 4.0f) * tessDisplacementScale) : 0.0f;
ClampValue<float>(tessStrength * tessDisplacementScale, 0.0f, 0.35f) : 0.0f;
if (batch.key.useARBPrograms)
{