Improve abdbd1ee64 to better handle cascade transitions

This commit is contained in:
Wojtek Figat
2024-06-05 13:43:34 +02:00
parent 0620310f4f
commit c26649a0a8

View File

@@ -215,35 +215,37 @@ GlobalSDFHit RayTraceGlobalSDF(const GlobalSDFData data, Texture3D<float> tex, T
hit.HitTime = -1.0f; hit.HitTime = -1.0f;
float chunkSizeDistance = (float)GLOBAL_SDF_RASTERIZE_CHUNK_SIZE / data.Resolution; // Size of the chunk in SDF distance (0-1) float chunkSizeDistance = (float)GLOBAL_SDF_RASTERIZE_CHUNK_SIZE / data.Resolution; // Size of the chunk in SDF distance (0-1)
float chunkMarginDistance = (float)GLOBAL_SDF_RASTERIZE_CHUNK_MARGIN / data.Resolution; // Size of the chunk margin in SDF distance (0-1) float chunkMarginDistance = (float)GLOBAL_SDF_RASTERIZE_CHUNK_MARGIN / data.Resolution; // Size of the chunk margin in SDF distance (0-1)
float nextIntersectionStart = 0.0f; float nextIntersectionStart = trace.MinDistance;
float traceMaxDistance = min(trace.MaxDistance, data.CascadePosDistance[3].w * 2); float traceMaxDistance = min(trace.MaxDistance, data.CascadePosDistance[3].w * 2);
float3 traceEndPosition = trace.WorldPosition + trace.WorldDirection * traceMaxDistance; float3 traceEndPosition = trace.WorldPosition + trace.WorldDirection * traceMaxDistance;
LOOP
for (uint cascade = 0; cascade < data.CascadesCount && hit.HitTime < 0.0f; cascade++) for (uint cascade = 0; cascade < data.CascadesCount && hit.HitTime < 0.0f; cascade++)
{ {
float4 cascadePosDistance = data.CascadePosDistance[cascade]; float4 cascadePosDistance = data.CascadePosDistance[cascade];
float voxelSize = data.CascadeVoxelSize[cascade]; float voxelSize = data.CascadeVoxelSize[cascade];
float voxelExtent = voxelSize * 0.5f; float voxelExtent = voxelSize * 0.5f;
float3 worldPosition = trace.WorldPosition + trace.WorldDirection * max(voxelSize * cascadeTraceStartBias, trace.MinDistance); float3 worldPosition = trace.WorldPosition;
// Skip until cascade that contains the start location
if (any(abs(worldPosition - cascadePosDistance.xyz) > cascadePosDistance.w))
continue;
// Hit the cascade bounds to find the intersection points // Hit the cascade bounds to find the intersection points
float traceStartBias = voxelSize * cascadeTraceStartBias;
float2 intersections = LineHitBox(worldPosition, traceEndPosition, cascadePosDistance.xyz - cascadePosDistance.www, cascadePosDistance.xyz + cascadePosDistance.www); float2 intersections = LineHitBox(worldPosition, traceEndPosition, cascadePosDistance.xyz - cascadePosDistance.www, cascadePosDistance.xyz + cascadePosDistance.www);
intersections.xy *= traceMaxDistance; intersections.xy *= traceMaxDistance;
intersections.x = max(intersections.x, traceStartBias);
intersections.x = max(intersections.x, nextIntersectionStart); intersections.x = max(intersections.x, nextIntersectionStart);
if (intersections.x >= intersections.y) if (intersections.x < intersections.y)
{ {
// Skip the current cascade if the ray starts outside it // Skip the current cascade tracing on the next cascade
continue; nextIntersectionStart = max(nextIntersectionStart, intersections.y - voxelSize);
}
// Skip the current cascade tracing on the next cascade (if we're tracing from inside SDF volume)
if (intersections.x <= 0.0f)
nextIntersectionStart = intersections.y;
// Walk over the cascade SDF // Walk over the cascade SDF
uint step = 0; uint step = 0;
float stepTime = intersections.x; float stepTime = intersections.x;
LOOP LOOP
for (; step < 250 && stepTime < intersections.y; step++) for (; step < 250 && stepTime < intersections.y && hit.HitTime < 0.0f; step++)
{ {
float3 stepPosition = worldPosition + trace.WorldDirection * stepTime; float3 stepPosition = worldPosition + trace.WorldDirection * stepTime;
@@ -287,7 +289,6 @@ GlobalSDFHit RayTraceGlobalSDF(const GlobalSDFData data, Texture3D<float> tex, T
float zn = tex.SampleLevel(SamplerLinearClamp, float3(textureUV.x, textureUV.y, textureUV.z - texelOffset), 0).x; float zn = tex.SampleLevel(SamplerLinearClamp, float3(textureUV.x, textureUV.y, textureUV.z - texelOffset), 0).x;
hit.HitNormal = normalize(float3(xp - xn, yp - yn, zp - zn)); hit.HitNormal = normalize(float3(xp - xn, yp - yn, zp - zn));
} }
break;
} }
// Move forward // Move forward
@@ -295,6 +296,7 @@ GlobalSDFHit RayTraceGlobalSDF(const GlobalSDFData data, Texture3D<float> tex, T
} }
hit.StepsCount += step; hit.StepsCount += step;
} }
}
return hit; return hit;
} }