Fix DDGI probes scrolling to properly handle bigger scroll deltas
This commit is contained in:
@@ -67,14 +67,12 @@ public:
|
|||||||
Float3 ProbesOrigin;
|
Float3 ProbesOrigin;
|
||||||
float ProbesSpacing = 0.0f;
|
float ProbesSpacing = 0.0f;
|
||||||
Int3 ProbeScrollOffsets;
|
Int3 ProbeScrollOffsets;
|
||||||
Int3 ProbeScrollDirections;
|
|
||||||
Int3 ProbeScrollClears;
|
Int3 ProbeScrollClears;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
ProbesOrigin = Float3::Zero;
|
ProbesOrigin = Float3::Zero;
|
||||||
ProbeScrollOffsets = Int3::Zero;
|
ProbeScrollOffsets = Int3::Zero;
|
||||||
ProbeScrollDirections = Int3::Zero;
|
|
||||||
ProbeScrollClears = Int3::Zero;
|
ProbeScrollClears = Int3::Zero;
|
||||||
}
|
}
|
||||||
} Cascades[4];
|
} Cascades[4];
|
||||||
@@ -400,6 +398,7 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
|||||||
const uint64 cascadeFrequencies[] = { 2, 3, 5, 7 };
|
const uint64 cascadeFrequencies[] = { 2, 3, 5, 7 };
|
||||||
//const uint64 cascadeFrequencies[] = { 1, 2, 3, 5 };
|
//const uint64 cascadeFrequencies[] = { 1, 2, 3, 5 };
|
||||||
//const uint64 cascadeFrequencies[] = { 1, 1, 1, 1 };
|
//const uint64 cascadeFrequencies[] = { 1, 1, 1, 1 };
|
||||||
|
//const uint64 cascadeFrequencies[] = { 10, 10, 10, 10 };
|
||||||
bool cascadeSkipUpdate[4];
|
bool cascadeSkipUpdate[4];
|
||||||
for (int32 cascadeIndex = 0; cascadeIndex < cascadesCount; cascadeIndex++)
|
for (int32 cascadeIndex = 0; cascadeIndex < cascadesCount; cascadeIndex++)
|
||||||
{
|
{
|
||||||
@@ -413,16 +412,6 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
|||||||
continue;
|
continue;
|
||||||
auto& cascade = ddgiData.Cascades[cascadeIndex];
|
auto& cascade = ddgiData.Cascades[cascadeIndex];
|
||||||
|
|
||||||
// Reset the volume origin and scroll offsets for each axis once it overflows
|
|
||||||
for (int32 axis = 0; axis < 3; axis++)
|
|
||||||
{
|
|
||||||
if (cascade.ProbeScrollOffsets.Raw[axis] != 0 && (cascade.ProbeScrollOffsets.Raw[axis] % ddgiData.ProbeCounts.Raw[axis] == 0))
|
|
||||||
{
|
|
||||||
cascade.ProbesOrigin.Raw[axis] += (float)ddgiData.ProbeCounts.Raw[axis] * cascade.ProbesSpacing * (float)cascade.ProbeScrollDirections.Raw[axis];
|
|
||||||
cascade.ProbeScrollOffsets.Raw[axis] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the count of grid cells between the view origin and the scroll anchor
|
// Calculate the count of grid cells between the view origin and the scroll anchor
|
||||||
const Float3 volumeOrigin = cascade.ProbesOrigin + Float3(cascade.ProbeScrollOffsets) * cascade.ProbesSpacing;
|
const Float3 volumeOrigin = cascade.ProbesOrigin + Float3(cascade.ProbeScrollOffsets) * cascade.ProbesSpacing;
|
||||||
const Float3 translation = viewOrigins[cascadeIndex] - volumeOrigin;
|
const Float3 translation = viewOrigins[cascadeIndex] - volumeOrigin;
|
||||||
@@ -432,7 +421,24 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
|||||||
const int32 scroll = value >= 0.0f ? (int32)Math::Floor(value) : (int32)Math::Ceil(value);
|
const int32 scroll = value >= 0.0f ? (int32)Math::Floor(value) : (int32)Math::Ceil(value);
|
||||||
cascade.ProbeScrollOffsets.Raw[axis] += scroll;
|
cascade.ProbeScrollOffsets.Raw[axis] += scroll;
|
||||||
cascade.ProbeScrollClears.Raw[axis] = scroll;
|
cascade.ProbeScrollClears.Raw[axis] = scroll;
|
||||||
cascade.ProbeScrollDirections.Raw[axis] = translation.Raw[axis] >= 0.0f ? 1 : -1;
|
}
|
||||||
|
|
||||||
|
// Shift the volume origin based on scroll offsets for each axis once it overflows
|
||||||
|
for (int32 axis = 0; axis < 3; axis++)
|
||||||
|
{
|
||||||
|
// different volume scroll that preserves the scroll offset delta relative to the probe count
|
||||||
|
const int32 probeCount = ddgiData.ProbeCounts.Raw[axis];
|
||||||
|
int32& scrollOffset = cascade.ProbeScrollOffsets.Raw[axis];
|
||||||
|
while (scrollOffset >= probeCount)
|
||||||
|
{
|
||||||
|
cascade.ProbesOrigin.Raw[axis] += cascade.ProbesSpacing * probeCount;
|
||||||
|
scrollOffset -= probeCount;
|
||||||
|
}
|
||||||
|
while (scrollOffset <= -probeCount)
|
||||||
|
{
|
||||||
|
cascade.ProbesOrigin.Raw[axis] -= cascade.ProbesSpacing * probeCount;
|
||||||
|
scrollOffset += probeCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ uint2 GetDDGIProbeTexelCoords(DDGIData data, uint cascadeIndex, uint probeIndex)
|
|||||||
uint GetDDGIScrollingProbeIndex(DDGIData data, uint cascadeIndex, uint3 probeCoords)
|
uint GetDDGIScrollingProbeIndex(DDGIData data, uint cascadeIndex, uint3 probeCoords)
|
||||||
{
|
{
|
||||||
// Probes are scrolled on edges to stabilize GI when camera moves
|
// Probes are scrolled on edges to stabilize GI when camera moves
|
||||||
return GetDDGIProbeIndex(data, (probeCoords + data.ProbesCounts + data.ProbesScrollOffsets[cascadeIndex].xyz) % data.ProbesCounts);
|
int3 probeCoordsOffset = (int3)data.ProbesCounts + data.ProbesScrollOffsets[cascadeIndex].xyz;
|
||||||
|
return GetDDGIProbeIndex(data, (probeCoords + (uint3)probeCoordsOffset) % data.ProbesCounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 GetDDGIProbeWorldPosition(DDGIData data, uint cascadeIndex, uint3 probeCoords)
|
float3 GetDDGIProbeWorldPosition(DDGIData data, uint cascadeIndex, uint3 probeCoords)
|
||||||
@@ -86,7 +87,8 @@ float3 GetDDGIProbeWorldPosition(DDGIData data, uint cascadeIndex, uint3 probeCo
|
|||||||
float probesSpacing = data.ProbesOriginAndSpacing[cascadeIndex].w;
|
float probesSpacing = data.ProbesOriginAndSpacing[cascadeIndex].w;
|
||||||
float3 probePosition = probeCoords * probesSpacing;
|
float3 probePosition = probeCoords * probesSpacing;
|
||||||
float3 probeGridOffset = (probesSpacing * (data.ProbesCounts - 1)) * 0.5f;
|
float3 probeGridOffset = (probesSpacing * (data.ProbesCounts - 1)) * 0.5f;
|
||||||
return probesOrigin + probePosition - probeGridOffset + (data.ProbesScrollOffsets[cascadeIndex].xyz * probesSpacing);
|
float3 probeScrollOffset = data.ProbesScrollOffsets[cascadeIndex].xyz * probesSpacing;
|
||||||
|
return probesOrigin + probePosition - probeGridOffset + probeScrollOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads probe probe data (encoded)
|
// Loads probe probe data (encoded)
|
||||||
|
|||||||
@@ -111,11 +111,28 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if probe was scrolled
|
||||||
|
int3 probeScrollClears = ProbeScrollClears[CascadeIndex].xyz;
|
||||||
|
bool wasScrolled = false;
|
||||||
|
UNROLL
|
||||||
|
for (uint planeIndex = 0; planeIndex < 3; planeIndex++)
|
||||||
|
{
|
||||||
|
int probeCount = (int)DDGI.ProbesCounts[planeIndex];
|
||||||
|
int newCoord = (int)probeCoords[planeIndex] + probeScrollClears[planeIndex];
|
||||||
|
if (newCoord < 0 || newCoord >= probeCount)
|
||||||
|
wasScrolled = true;
|
||||||
|
newCoord = (int)probeCoords[planeIndex] - probeScrollClears[planeIndex];
|
||||||
|
if (newCoord < 0 || newCoord >= probeCount)
|
||||||
|
wasScrolled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Load probe state and position
|
// Load probe state and position
|
||||||
float4 probeData = RWProbesData[probeDataCoords];
|
float4 probeData = RWProbesData[probeDataCoords];
|
||||||
uint probeState = DecodeDDGIProbeState(probeData);
|
uint probeState = DecodeDDGIProbeState(probeData);
|
||||||
uint probeStateOld = probeState;
|
uint probeStateOld = probeState;
|
||||||
float3 probeOffset = probeData.xyz * probesSpacing; // Probe offset is [-1;1] within probes spacing
|
float3 probeOffset = probeData.xyz * probesSpacing; // Probe offset is [-1;1] within probes spacing
|
||||||
|
if (wasScrolled || probeState == DDGI_PROBE_STATE_INACTIVE)
|
||||||
|
probeOffset = float3(0, 0, 0); // Clear offset for a new probe
|
||||||
float3 probeOffsetOld = probeOffset;
|
float3 probeOffsetOld = probeOffset;
|
||||||
float3 probePosition = probeBasePosition + probeOffset;
|
float3 probePosition = probeBasePosition + probeOffset;
|
||||||
|
|
||||||
@@ -207,18 +224,6 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if probe was scrolled
|
|
||||||
int3 probeScrollClears = ProbeScrollClears[CascadeIndex].xyz;
|
|
||||||
bool wasScrolled = false;
|
|
||||||
UNROLL
|
|
||||||
for (uint planeIndex = 0; planeIndex < 3; planeIndex++)
|
|
||||||
{
|
|
||||||
int probeCount = (int)DDGI.ProbesCounts[planeIndex];
|
|
||||||
int newCord = (int)probeCoords[planeIndex] + probeScrollClears[planeIndex];
|
|
||||||
if (newCord < 0 || newCord >= probeCount)
|
|
||||||
wasScrolled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If probe was in a different location or was activated now then mark it as activated
|
// If probe was in a different location or was activated now then mark it as activated
|
||||||
bool wasActivated = probeStateOld == DDGI_PROBE_STATE_INACTIVE;
|
bool wasActivated = probeStateOld == DDGI_PROBE_STATE_INACTIVE;
|
||||||
bool wasRelocated = distance(probeOffset, probeOffsetOld) > 2.0f;
|
bool wasRelocated = distance(probeOffset, probeOffsetOld) > 2.0f;
|
||||||
@@ -468,8 +473,9 @@ void CS_UpdateProbes(uint3 GroupThreadId : SV_GroupThreadID, uint3 GroupId : SV_
|
|||||||
|
|
||||||
// Blend current value with the previous probe data
|
// Blend current value with the previous probe data
|
||||||
float historyWeight = DDGI.ProbeHistoryWeight;
|
float historyWeight = DDGI.ProbeHistoryWeight;
|
||||||
|
//historyWeight = 1.0f;
|
||||||
//historyWeight = 0.0f;
|
//historyWeight = 0.0f;
|
||||||
if (ResetBlend || wasActivated || dot(previous, previous) == 0)
|
if (ResetBlend || wasActivated)
|
||||||
historyWeight = 0.0f;
|
historyWeight = 0.0f;
|
||||||
#if DDGI_PROBE_UPDATE_MODE == 0
|
#if DDGI_PROBE_UPDATE_MODE == 0
|
||||||
result *= DDGI.IndirectLightingIntensity;
|
result *= DDGI.IndirectLightingIntensity;
|
||||||
|
|||||||
Reference in New Issue
Block a user