diff --git a/Content/Shaders/GI/DDGI.flax b/Content/Shaders/GI/DDGI.flax index 3f0e3b153..29c746d3b 100644 --- a/Content/Shaders/GI/DDGI.flax +++ b/Content/Shaders/GI/DDGI.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5a7f8297f6ce999229521399607d277c63a350dadff2d48fd009b892f48d286 -size 18558 +oid sha256:cd93974da1fcb3fad04406e385cb2988f171ef2378017adb9971ac36e5d7b5de +size 18757 diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index 2aaf8f74d..3017a6c8a 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -143,16 +143,17 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D 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); diff --git a/Source/Shaders/GI/DDGI.shader b/Source/Shaders/GI/DDGI.shader index cd1ed41d8..6cfb7fa0d 100644 --- a/Source/Shaders/GI/DDGI.shader +++ b/Source/Shaders/GI/DDGI.shader @@ -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;