|
|
|
|
|
|
return testHitPositionSS; |
|
|
|
} |
|
|
|
|
|
|
|
float CalculateHitWeight( |
|
|
|
ScreenSpaceRayHit hit, |
|
|
|
float2 startPositionSS, |
|
|
|
float invLinearDepth, |
|
|
|
float settingsRayDepthSuccessBias |
|
|
|
) |
|
|
|
{ |
|
|
|
const float maxScreenDistance = 0.3; |
|
|
|
const float blendedScreenDistance = 0.05; |
|
|
|
|
|
|
|
// Blend when the hit is near the thickness of the object |
|
|
|
float thicknessWeight = (1 + ((1 / invLinearDepth) - hit.linearDepth) / settingsRayDepthSuccessBias); |
|
|
|
|
|
|
|
// Blend when the ray when the raymarched distance is too long |
|
|
|
float2 screenDistanceNDC = abs(hit.positionSS.xy - startPositionSS) * _ScreenSize.zw; |
|
|
|
float2 screenDistanceWeights = clamp((maxScreenDistance - screenDistanceNDC) / blendedScreenDistance, 0, 1); |
|
|
|
float screenDistanceWeight = min(screenDistanceWeights.x, screenDistanceWeights.y); |
|
|
|
|
|
|
|
return thicknessWeight * screenDistanceWeight; |
|
|
|
} |
|
|
|
|
|
|
|
bool IsRaymarchingTooFar( |
|
|
|
float2 startPositionSS, |
|
|
|
float2 positionSS |
|
|
|
) |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
// ------------------------------------------------- |
|
|
|
// Debug Utilities |
|
|
|
|
|
|
uint2 bufferSize, // Texture size of screen buffers |
|
|
|
// Out |
|
|
|
out ScreenSpaceRayHit hit, |
|
|
|
out float hitWeight, |
|
|
|
out uint iteration |
|
|
|
) |
|
|
|
{ |
|
|
|
|
|
|
hitWeight = 0; |
|
|
|
int mipLevel = min(max(settingRayLevel, 0), int(_DepthPyramidScale.z)); |
|
|
|
uint maxIterations = settingsRayMaxIterations; |
|
|
|
|
|
|
|
|
|
|
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize); |
|
|
|
hit.positionSS = uint2(positionSS.xy); |
|
|
|
|
|
|
|
if (hit.linearDepth > (1 / invLinearDepth) + settingsRayDepthSuccessBias) |
|
|
|
// Detect when we go behind an object given a thickness |
|
|
|
hitWeight = CalculateHitWeight( |
|
|
|
hit, |
|
|
|
startPositionSS.xy, |
|
|
|
invLinearDepth, |
|
|
|
settingsRayDepthSuccessBias |
|
|
|
); |
|
|
|
if (hitWeight <= 0) |
|
|
|
hitSuccessful = false; |
|
|
|
|
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
uint iteration; |
|
|
|
float hitWeight; |
|
|
|
bool hitSuccessful = ScreenSpaceLinearRaymarch( |
|
|
|
inputLinear, |
|
|
|
// Settings |
|
|
|
|
|
|
bufferSize, |
|
|
|
// Out |
|
|
|
hit, |
|
|
|
hitWeight, |
|
|
|
iteration |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
float settingsRayDepthSuccessBias, // Bias to use when trying to detect whenever we raymarch behind a surface |
|
|
|
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines) |
|
|
|
// out |
|
|
|
out ScreenSpaceRayHit hit |
|
|
|
out ScreenSpaceRayHit hit, |
|
|
|
out float hitWeight |
|
|
|
) |
|
|
|
{ |
|
|
|
const float2 CROSS_OFFSET = float2(1, 1); |
|
|
|
|
|
|
hitWeight = 0; |
|
|
|
bool hitSuccessful = false; |
|
|
|
uint iteration = 0u; |
|
|
|
int minMipLevel = max(settingsRayMinLevel, 0u); |
|
|
|
|
|
|
bufferSize, |
|
|
|
// out |
|
|
|
hit, |
|
|
|
hitWeight, |
|
|
|
iteration |
|
|
|
)) |
|
|
|
return true; |
|
|
|
|
|
|
uint2 cellSize = uint2(1, 1) << currentLevel; |
|
|
|
|
|
|
|
float3 positionSS = startPositionSS; |
|
|
|
float invHiZDepth = 0; |
|
|
|
float invLinearDepth = 0; |
|
|
|
|
|
|
|
while (currentLevel >= minMipLevel) |
|
|
|
{ |
|
|
|
|
|
|
int mipLevelDelta = -1; |
|
|
|
|
|
|
|
// Sampled as 1/Z so it interpolate properly in screen space. |
|
|
|
invHiZDepth = LoadInvDepth(positionSS.xy, currentLevel); |
|
|
|
invLinearDepth = LoadInvDepth(positionSS.xy, currentLevel); |
|
|
|
if (IsPositionAboveDepth(positionSS.z, invHiZDepth)) |
|
|
|
if (IsPositionAboveDepth(positionSS.z, invLinearDepth)) |
|
|
|
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invHiZDepth); |
|
|
|
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invLinearDepth); |
|
|
|
|
|
|
|
intersectionKind = HIZINTERSECTIONKIND_DEPTH; |
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
debugLoopMipMaxUsedLevel = max(debugLoopMipMaxUsedLevel, currentLevel); |
|
|
|
debugIterationPositionSS = positionSS; |
|
|
|
debugIterationLinearDepthBuffer = 1 / invHiZDepth; |
|
|
|
debugIterationLinearDepthBuffer = 1 / invLinearDepth; |
|
|
|
debugIteration = iteration; |
|
|
|
debugIterationIntersectionKind = intersectionKind; |
|
|
|
debugIterationCellSize = cellSize; |
|
|
|
|
|
|
// Check if we are out of the buffer |
|
|
|
if (any(int2(positionSS.xy) > int2(bufferSize)) |
|
|
|
|| any(positionSS.xy < 0) |
|
|
|
) |
|
|
|
|| any(positionSS.xy < 0)) |
|
|
|
{ |
|
|
|
hitSuccessful = false; |
|
|
|
break; |
|
|
|
|
|
|
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize); |
|
|
|
hit.positionSS = uint2(positionSS.xy); |
|
|
|
|
|
|
|
if (hit.linearDepth > (1 / invHiZDepth) + settingsRayDepthSuccessBias) |
|
|
|
// Detect when we go behind an object given a thickness |
|
|
|
hitWeight = CalculateHitWeight( |
|
|
|
hit, |
|
|
|
startPositionSS.xy, |
|
|
|
invLinearDepth, |
|
|
|
settingsRayDepthSuccessBias |
|
|
|
); |
|
|
|
if (hitWeight <= 0) |
|
|
|
hitSuccessful = false; |
|
|
|
|
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
|
|
|
// ------------------------------------------------- |
|
|
|
bool MERGE_NAME(ScreenSpaceLinearRaymarch, SSRTID)( |
|
|
|
ScreenSpaceRaymarchInput input, |
|
|
|
out ScreenSpaceRayHit hit |
|
|
|
out ScreenSpaceRayHit hit, |
|
|
|
out float hitWeight |
|
|
|
) |
|
|
|
{ |
|
|
|
uint2 bufferSize = uint2(_DepthPyramidSize.xy); |
|
|
|
|
|
|
// settings |
|
|
|
SSRT_SETTING(RayLevel, SSRTID), |
|
|
|
SSRT_SETTING(RayMaxIterations, SSRTID), |
|
|
|
SSRT_SETTING(RayDepthSuccessBias, SSRTID), |
|
|
|
max(0.01, SSRT_SETTING(RayDepthSuccessBias, SSRTID)), |
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
SSRT_SETTING(DebuggedAlgorithm, SSRTID), |
|
|
|
#else |
|
|
|
|
|
|
bufferSize, |
|
|
|
// out |
|
|
|
hit, |
|
|
|
hitWeight, |
|
|
|
iteration |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
// ------------------------------------------------- |
|
|
|
bool MERGE_NAME(ScreenSpaceHiZRaymarch, SSRTID)( |
|
|
|
ScreenSpaceRaymarchInput input, |
|
|
|
out ScreenSpaceRayHit hit |
|
|
|
out ScreenSpaceRayHit hit, |
|
|
|
out float hitWeight |
|
|
|
) |
|
|
|
{ |
|
|
|
return ScreenSpaceHiZRaymarch( |
|
|
|
|
|
|
SSRT_SETTING(RayMaxLevel, SSRTID), |
|
|
|
SSRT_SETTING(RayMaxIterations, SSRTID), |
|
|
|
SSRT_SETTING(RayMaxLinearIterations, SSRTID), |
|
|
|
SSRT_SETTING(RayDepthSuccessBias, SSRTID), |
|
|
|
max(0.01, SSRT_SETTING(RayDepthSuccessBias, SSRTID)), |
|
|
|
#ifdef DEBUG_DISPLAY |
|
|
|
SSRT_SETTING(DebuggedAlgorithm, SSRTID), |
|
|
|
#else |
|
|
|
|
|
|
hit |
|
|
|
hit, |
|
|
|
hitWeight |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|