Improve DDGI probes relocation algorithm
This commit is contained in:
@@ -143,16 +143,17 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D<float4> probesState, Textur
|
||||
float4 probeState = probesState.Load(int3(GetDDGIProbeTexelCoords(data, probeIndex), 0));
|
||||
if (probeState.w == DDGI_PROBE_STATE_INACTIVE)
|
||||
continue;
|
||||
float3 probePosition = baseProbeWorldPosition + ((probeCoords - baseProbeCoords) * data.ProbesSpacing) + probeState.xyz;
|
||||
float3 probeBasePosition = baseProbeWorldPosition + ((probeCoords - baseProbeCoords) * data.ProbesSpacing);
|
||||
float3 probePosition = probeBasePosition + probeState.xyz;
|
||||
|
||||
// Calculate the distance and direction from the (biased and non-biased) shading point and the probe
|
||||
float3 worldPosToProbe = normalize(probePosition.xyz - worldPosition);
|
||||
float3 biasedPosToProbe = normalize(probePosition.xyz - biasedWorldPosition);
|
||||
float biasedPosToProbeDist = length(probePosition.xyz - biasedWorldPosition);
|
||||
float3 worldPosToProbe = normalize(probePosition - worldPosition);
|
||||
float3 biasedPosToProbe = normalize(probePosition - biasedWorldPosition);
|
||||
float biasedPosToProbeDist = length(probePosition - biasedWorldPosition);
|
||||
|
||||
// Smooth backface test
|
||||
float weight = Square(dot(worldPosToProbe, worldNormal) * 0.5f + 0.5f);
|
||||
|
||||
|
||||
// Sample distance texture
|
||||
float2 octahedralCoords = GetOctahedralCoords(-biasedPosToProbe);
|
||||
float2 uv = GetDDGIProbeUV(data, probeIndex, octahedralCoords, DDGI_PROBE_RESOLUTION_DISTANCE);
|
||||
|
||||
@@ -71,44 +71,53 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID)
|
||||
|
||||
// Load probe state and position
|
||||
float4 probeState = RWProbesState[probeDataCoords];
|
||||
float3 probePosition = GetDDGIProbeWorldPosition(DDGI, probeCoords);
|
||||
// TODO: reset probe offset for scrolled probes
|
||||
probePosition.xyz += probeState.xyz;
|
||||
float3 probeBasePosition = GetDDGIProbeWorldPosition(DDGI, probeCoords);
|
||||
float3 probePosition = probeBasePosition + probeState.xyz;
|
||||
probeState.w = DDGI_PROBE_STATE_ACTIVE;
|
||||
|
||||
// Use Global SDF to quickly get distance and direction to the scene geometry
|
||||
float sdf;
|
||||
float3 sdfNormal = normalize(SampleGlobalSDFGradient(GlobalSDF, GlobalSDFTex, probePosition.xyz, sdf));
|
||||
float threshold = GlobalSDF.CascadeVoxelSize[0] * 0.5f;
|
||||
float distanceLimit = length(DDGI.ProbesSpacing) * 1.5f + threshold;
|
||||
float distanceLimit = length(DDGI.ProbesSpacing) * 2.0f;
|
||||
float relocateLimit = length(DDGI.ProbesSpacing) * 0.6f;
|
||||
if (abs(sdf) > distanceLimit + threshold) // Probe is too far from geometry
|
||||
if (abs(sdf) > distanceLimit) // Probe is too far from geometry
|
||||
{
|
||||
// Disable it
|
||||
probeState = float4(0, 0, 0, DDGI_PROBE_STATE_INACTIVE);
|
||||
}
|
||||
else if (sdf < threshold) // Probe is inside geometry
|
||||
else
|
||||
{
|
||||
if (abs(sdf) < relocateLimit)
|
||||
if (sdf < threshold) // Probe is inside geometry
|
||||
{
|
||||
float3 offsetToAdd = sdfNormal * (sdf + threshold);
|
||||
if (distance(probeState.xyz, offsetToAdd) < relocateLimit)
|
||||
if (abs(sdf) < relocateLimit)
|
||||
{
|
||||
// Relocate it
|
||||
probeState.xyz = probeState.xyz + offsetToAdd;
|
||||
float3 offsetToAdd = sdfNormal * sdf;
|
||||
if (distance(probeState.xyz, offsetToAdd) < relocateLimit)
|
||||
{
|
||||
// Relocate it
|
||||
probeState.xyz += offsetToAdd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset relocation
|
||||
probeState.xyz = float3(0, 0, 0);
|
||||
}
|
||||
// TODO: maybe sample SDF at the relocated location and disable probe if it's still in the geometry?
|
||||
}
|
||||
else
|
||||
else if (sdf > threshold * 2.0f) // Probe is far enough any geometry
|
||||
{
|
||||
// Reset relocation
|
||||
probeState.xyz = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
// Check if probe is relocated but the base location is fine
|
||||
sdf = SampleGlobalSDF(GlobalSDF, GlobalSDFTex, probeBasePosition.xyz);
|
||||
if (sdf > threshold)
|
||||
{
|
||||
// Reset relocation
|
||||
probeState.xyz = float3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (sdf > relocateLimit) // Probe is far enough any geometry
|
||||
{
|
||||
// Reset relocation
|
||||
probeState.xyz = float3(0, 0, 0);
|
||||
}
|
||||
|
||||
RWProbesState[probeDataCoords] = probeState;
|
||||
|
||||
Reference in New Issue
Block a user