|
|
|
|
|
|
raySS = rayEndSS - rayStartSS; |
|
|
|
} |
|
|
|
|
|
|
|
// Check whether the depth of the ray is above the sampled depth |
|
|
|
// Arguments are inversed linear depth |
|
|
|
bool IsPositionAboveDepth(float invRayDepth, float2 invLinearDepth) |
|
|
|
{ |
|
|
|
// as depth is inverted, we must invert the check as well |
|
|
|
// rayZ > HiZ <=> 1/rayZ < 1/HiZ |
|
|
|
return invRayDepth > invLinearDepth.r; |
|
|
|
} |
|
|
|
|
|
|
|
// Sample the Depth buffer at a specific mip and linear depth |
|
|
|
float2 LoadDepth(float2 positionSS, int level) |
|
|
|
{ |
|
|
|
|
|
|
float CalculateHitWeight( |
|
|
|
ScreenSpaceRayHit hit, |
|
|
|
float2 startPositionSS, |
|
|
|
float2 invLinearDepth, |
|
|
|
float minLinearDepth, |
|
|
|
float settingsRayDepthSuccessBias, |
|
|
|
float settingsRayMaxScreenDistance, |
|
|
|
float settingsRayBlendScreenDistance |
|
|
|
|
|
|
float thicknessWeight = (1 + ((1 / invLinearDepth.r) - hit.linearDepth) / settingsRayDepthSuccessBias); |
|
|
|
float thicknessWeight = clamp(1 - (hit.linearDepth - minLinearDepth) / settingsRayDepthSuccessBias, 0, 1); |
|
|
|
return thicknessWeight; |
|
|
|
|
|
|
|
// Blend when the ray when the raymarched distance is too long |
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void DebugComputeHiZOutput( |
|
|
|
int iteration, |
|
|
|
float3 startPositionSS, |
|
|
|
float3 rayDirSS, |
|
|
|
int maxIterations, |
|
|
|
int maxUsedLevel, |
|
|
|
int maxMipLevel, |
|
|
|
int intersectionKind, |
|
|
|
inout ScreenSpaceRayHit hit |
|
|
|
) |
|
|
|
{ |
|
|
|
switch (_DebugLightingSubMode) |
|
|
|
{ |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC: |
|
|
|
hit.debugOutput = float3(float2(startPositionSS.xy) * _ScreenSize.zw, 0); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT: |
|
|
|
hit.debugOutput = float(iteration) / float(maxIterations); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC: |
|
|
|
hit.debugOutput = float3(rayDirSS.xy * 0.5 + 0.5, frac(0.1 / rayDirSS.z)); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL: |
|
|
|
hit.debugOutput = float(maxUsedLevel) / float(maxMipLevel); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND: |
|
|
|
hit.debugOutput = GetIndexColor(intersectionKind); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
// ------------------------------------------------- |
|
|
|
|
|
|
raySS *= 1 << mipLevel; |
|
|
|
|
|
|
|
// Offset by a texel |
|
|
|
positionSS += raySS * 1.0; |
|
|
|
//positionSS += raySS * 1.0; |
|
|
|
|
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
float3 debugIterationPositionSS = positionSS; |
|
|
|
|
|
|
|
|
|
|
float2 invLinearDepth = float2(0.0, 0.0); |
|
|
|
|
|
|
|
float minLinearDepth = 0; |
|
|
|
float minLinearDepthWithThickness = 0; |
|
|
|
float positionLinearDepth = 0; |
|
|
|
|
|
|
|
for (iteration = 0u; iteration < maxIterations; ++iteration) |
|
|
|
{ |
|
|
|
positionSS += raySS; |
|
|
|
|
|
|
|
|
|
|
minLinearDepth = 1 / invLinearDepth.r; |
|
|
|
minLinearDepthWithThickness = minLinearDepth + settingsRayDepthSuccessBias; |
|
|
|
positionLinearDepth = 1 / positionSS.z; |
|
|
|
bool isAboveDepth = positionLinearDepth < minLinearDepth; |
|
|
|
bool isAboveThickness = positionLinearDepth < minLinearDepthWithThickness; |
|
|
|
bool isBehindDepth = !isAboveThickness; |
|
|
|
bool intersectWithDepth = !isAboveDepth && isAboveThickness; |
|
|
|
|
|
|
|
debugIterationPositionSS = positionSS; |
|
|
|
debugIterationLinearDepthBufferMin = 1 / invLinearDepth.r; |
|
|
|
debugIterationLinearDepthBufferMinThickness = 1 / invLinearDepth.r + settingsRayDepthSuccessBias; |
|
|
|
debugIterationLinearDepthBufferMax = 1 / invLinearDepth.g; |
|
|
|
debugIteration = iteration; |
|
|
|
debugIterationPositionSS = positionSS; |
|
|
|
debugIterationLinearDepthBufferMin = minLinearDepth; |
|
|
|
debugIterationLinearDepthBufferMinThickness = minLinearDepthWithThickness; |
|
|
|
debugIterationLinearDepthBufferMax = 1 / invLinearDepth.g; |
|
|
|
debugIteration = iteration; |
|
|
|
if (!IsPositionAboveDepth(positionSS.z, invLinearDepth)) |
|
|
|
if (intersectWithDepth) |
|
|
|
{ |
|
|
|
hitSuccessful = true; |
|
|
|
break; |
|
|
|
|
|
|
settingsRayMaxScreenDistance, |
|
|
|
settingsRayBlendScreenDistance |
|
|
|
); |
|
|
|
|
|
|
|
switch (_DebugLightingSubMode) |
|
|
|
{ |
|
|
|
case DEBUGSCREENSPACETRACING_LINEAR_POSITION_NDC: |
|
|
|
hit.debugOutput = float3(float2(startPositionSS.xy) * _ScreenSize.zw, 0); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_LINEAR_ITERATION_COUNT: |
|
|
|
hit.debugOutput = float(iteration) / float(settingsRayMaxIterations); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_LINEAR_RAY_DIR_NDC: |
|
|
|
hit.debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z)); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_LINEAR_HIT_WEIGHT: |
|
|
|
hit.debugOutput = float3(hitWeight, hitWeight, hitWeight); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (input.debug |
|
|
|
&& _DebugScreenSpaceTracingData[0].tracingModel == -1 |
|
|
|
|
|
|
debug.endPositionSSY = hit.positionSS.y; |
|
|
|
debug.iterationCellSizeW = 1 << mipLevel; |
|
|
|
debug.iterationCellSizeH = 1 << mipLevel; |
|
|
|
debug.endHitWeight = hitWeight; |
|
|
|
|
|
|
|
_DebugScreenSpaceTracingData[0] = debug; |
|
|
|
} |
|
|
|
|
|
|
float3 positionSS = startPositionSS; |
|
|
|
float2 invLinearDepth = float2(0.0, 0.0); |
|
|
|
|
|
|
|
float positionLinearDepth = 0; |
|
|
|
float minLinearDepth = 0; |
|
|
|
float minLinearDepthWithThickness = 0; |
|
|
|
|
|
|
|
while (currentLevel >= minMipLevel) |
|
|
|
{ |
|
|
|
hitSuccessful = true; |
|
|
|
|
|
|
// Sampled as 1/Z so it interpolate properly in screen space. |
|
|
|
invLinearDepth = LoadInvDepth(positionSS.xy, currentLevel); |
|
|
|
|
|
|
|
float positionLinearDepth = 1 / positionSS.z; |
|
|
|
float minLinearDepth = 1 / invLinearDepth.r; |
|
|
|
float maxLinearDepth = minLinearDepth + settingsRayDepthSuccessBias; |
|
|
|
|
|
|
|
bool isAboveDepth = positionLinearDepth <= minLinearDepth; |
|
|
|
bool isAboveThickness = positionLinearDepth <= maxLinearDepth; |
|
|
|
bool isBehindDepth = !isAboveThickness; |
|
|
|
bool intersectWithDepth = minLinearDepth >= positionLinearDepth && isAboveThickness; |
|
|
|
positionLinearDepth = 1 / positionSS.z; |
|
|
|
minLinearDepth = 1 / invLinearDepth.r; |
|
|
|
minLinearDepthWithThickness = minLinearDepth + settingsRayDepthSuccessBias; |
|
|
|
bool isAboveDepth = positionLinearDepth < minLinearDepth; |
|
|
|
bool isAboveThickness = positionLinearDepth < minLinearDepthWithThickness; |
|
|
|
bool isBehindDepth = !isAboveThickness; |
|
|
|
bool intersectWithDepth = minLinearDepth >= positionLinearDepth && isAboveThickness; |
|
|
|
|
|
|
|
intersectionKind = HIZINTERSECTIONKIND_NONE; |
|
|
|
|
|
|
|
|
|
|
++iteration; |
|
|
|
} |
|
|
|
|
|
|
|
hit.linearDepth = 1 / positionSS.z; |
|
|
|
hit.linearDepth = positionLinearDepth; |
|
|
|
// hitWeight = CalculateHitWeight( |
|
|
|
// hit, |
|
|
|
// startPositionSS.xy, |
|
|
|
// invLinearDepth, |
|
|
|
// settingsRayDepthSuccessBias, |
|
|
|
// settingsRayMaxScreenDistance, |
|
|
|
// settingsRayBlendScreenDistance |
|
|
|
// ); |
|
|
|
|
|
|
|
invLinearDepth, |
|
|
|
minLinearDepth, |
|
|
|
|
|
|
|
DebugComputeHiZOutput( |
|
|
|
iteration, |
|
|
|
startPositionSS, |
|
|
|
raySS, |
|
|
|
settingsRayMaxIterations, |
|
|
|
debugLoopMipMaxUsedLevel, |
|
|
|
maxMipLevel, |
|
|
|
intersectionKind, |
|
|
|
hit |
|
|
|
); |
|
|
|
switch (_DebugLightingSubMode) |
|
|
|
{ |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC: |
|
|
|
hit.debugOutput = float3(float2(startPositionSS.xy) * _ScreenSize.zw, 0); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT: |
|
|
|
hit.debugOutput = float(iteration) / float(settingsRayMaxIterations); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC: |
|
|
|
hit.debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z)); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL: |
|
|
|
hit.debugOutput = float(debugLoopMipMaxUsedLevel) / float(maxMipLevel); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND: |
|
|
|
hit.debugOutput = GetIndexColor(intersectionKind); |
|
|
|
break; |
|
|
|
case DEBUGSCREENSPACETRACING_HI_ZHIT_WEIGHT: |
|
|
|
hit.debugOutput = float3(hitWeight, hitWeight, hitWeight); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (input.debug |
|
|
|
&& _DebugScreenSpaceTracingData[0].tracingModel == -1 |
|
|
|
|
|
|
debug.endLinearDepth = hit.linearDepth; |
|
|
|
debug.endPositionSSX = hit.positionSS.x; |
|
|
|
debug.endPositionSSY = hit.positionSS.y; |
|
|
|
debug.endHitWeight = hitWeight; |
|
|
|
|
|
|
|
_DebugScreenSpaceTracingData[0] = debug; |
|
|
|
} |
|
|
|