Improve Global Surface Atlas objects surfaces sampling
This commit is contained in:
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
Binary file not shown.
@@ -461,7 +461,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
ddgiData.Result.Constants.ProbesOriginAndSpacing[cascadeIndex] = Float4(cascade.ProbesOrigin, cascade.ProbesSpacing);
|
||||
ddgiData.Result.Constants.ProbesScrollOffsets[cascadeIndex] = Int4(cascade.ProbeScrollOffsets, 0);
|
||||
}
|
||||
ddgiData.Result.Constants.RayMaxDistance = 10000.0f; // TODO: adjust to match perf/quality ratio (make it based on Global SDF and Global Surface Atlas distance)
|
||||
ddgiData.Result.Constants.RayMaxDistance = distance;
|
||||
ddgiData.Result.Constants.ViewPos = renderContext.View.Position;
|
||||
ddgiData.Result.Constants.RaysCount = probeRaysCount;
|
||||
ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight;
|
||||
|
||||
@@ -1232,19 +1232,20 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
_dirtyObjectsBuffer.Add(actorObject);
|
||||
}
|
||||
|
||||
Matrix3x3 worldToLocalRotation;
|
||||
Matrix3x3::RotationQuaternion(object->Bounds.Transformation.Orientation.Conjugated(), worldToLocalRotation);
|
||||
Float3 worldPosition = object->Bounds.Transformation.Translation;
|
||||
Float3 worldExtents = object->Bounds.Extents * object->Bounds.Transformation.Scale;
|
||||
|
||||
// Write to objects buffer (this must match unpacking logic in HLSL)
|
||||
Matrix localToWorldBounds;
|
||||
object->Bounds.Transformation.GetWorld(localToWorldBounds);
|
||||
Matrix worldToLocalBounds;
|
||||
Matrix::Invert(localToWorldBounds, worldToLocalBounds);
|
||||
uint32 objectAddress = surfaceAtlasData.ObjectsBuffer.Data.Count() / sizeof(Float4);
|
||||
auto* objectData = surfaceAtlasData.ObjectsBuffer.WriteReserve<Float4>(GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE);
|
||||
objectData[0] = *(Float4*)&actorObjectBounds;
|
||||
objectData[1] = Float4::Zero;
|
||||
objectData[2] = Float4(worldToLocalBounds.M11, worldToLocalBounds.M12, worldToLocalBounds.M13, worldToLocalBounds.M41);
|
||||
objectData[3] = Float4(worldToLocalBounds.M21, worldToLocalBounds.M22, worldToLocalBounds.M23, worldToLocalBounds.M42);
|
||||
objectData[4] = Float4(worldToLocalBounds.M31, worldToLocalBounds.M32, worldToLocalBounds.M33, worldToLocalBounds.M43);
|
||||
objectData[5] = Float4(object->Bounds.Extents, useVisibility ? 1.0f : 0.0f);
|
||||
objectData[2] = Float4(worldToLocalRotation.M11, worldToLocalRotation.M12, worldToLocalRotation.M13, worldPosition.X);
|
||||
objectData[3] = Float4(worldToLocalRotation.M21, worldToLocalRotation.M22, worldToLocalRotation.M23, worldPosition.Y);
|
||||
objectData[4] = Float4(worldToLocalRotation.M31, worldToLocalRotation.M32, worldToLocalRotation.M33, worldPosition.Z);
|
||||
objectData[5] = Float4(worldExtents, useVisibility ? 1.0f : 0.0f);
|
||||
auto tileOffsets = reinterpret_cast<uint16*>(&objectData[1]); // xyz used for tile offsets packed into uint16
|
||||
auto objectDataSize = reinterpret_cast<uint32*>(&objectData[1].W); // w used for object size (count of Float4s for object+tiles)
|
||||
*objectDataSize = GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE;
|
||||
|
||||
@@ -414,10 +414,6 @@ void CS_UpdateProbes(uint3 GroupThreadId : SV_GroupThreadID, uint3 GroupId : SV_
|
||||
// Reduce flickering during rapid brightness changes
|
||||
//result.rgb = previous + (irradianceDelta * 0.25f);
|
||||
}
|
||||
float3 resultDelta = (1.0f - historyWeight) * irradianceDelta;
|
||||
if (Max3(result.rgb) < Max3(previous))
|
||||
resultDelta = min(max(abs(resultDelta), 1.0f / 1024.0f), abs(irradianceDelta)) * sign(resultDelta);
|
||||
//result = float4(previous + resultDelta, 1.0f);
|
||||
result = float4(lerp(result.rgb, previous.rgb, historyWeight), 1.0f);
|
||||
#else
|
||||
result = float4(lerp(result.rg, previous.rg, historyWeight), 0.0f, 1.0f);
|
||||
|
||||
@@ -23,8 +23,9 @@ struct GlobalSurfaceObject
|
||||
{
|
||||
float3 BoundsPosition;
|
||||
float BoundsRadius;
|
||||
float4x4 WorldToLocal;
|
||||
float3 Extent;
|
||||
float3x3 WorldToLocalRotation;
|
||||
float3 WorldPosition;
|
||||
float3 WorldExtents;
|
||||
bool UseVisibility;
|
||||
uint TileOffsets[6];
|
||||
uint DataSize; // count of float4s for object+tiles
|
||||
@@ -54,11 +55,11 @@ GlobalSurfaceObject LoadGlobalSurfaceAtlasObject(Buffer<float4> objects, uint ob
|
||||
GlobalSurfaceObject object = (GlobalSurfaceObject)0;
|
||||
object.BoundsPosition = vector0.xyz;
|
||||
object.BoundsRadius = vector0.w;
|
||||
object.WorldToLocal[0] = float4(vector2.xyz, 0.0f);
|
||||
object.WorldToLocal[1] = float4(vector3.xyz, 0.0f);
|
||||
object.WorldToLocal[2] = float4(vector4.xyz, 0.0f);
|
||||
object.WorldToLocal[3] = float4(vector2.w, vector3.w, vector4.w, 1.0f);
|
||||
object.Extent = vector5.xyz;
|
||||
object.WorldToLocalRotation[0] = vector2.xyz;
|
||||
object.WorldToLocalRotation[1] = vector3.xyz;
|
||||
object.WorldToLocalRotation[2] = vector4.xyz;
|
||||
object.WorldPosition = float3(vector2.w, vector3.w, vector4.w);
|
||||
object.WorldExtents = vector5.xyz;
|
||||
object.UseVisibility = vector5.w > 0.5f;
|
||||
uint vector1x = asuint(vector1.x);
|
||||
uint vector1y = asuint(vector1.y);
|
||||
@@ -198,47 +199,36 @@ float4 SampleGlobalSurfaceAtlas(const GlobalSurfaceAtlasData data, ByteAddressBu
|
||||
float4 objectBounds = LoadGlobalSurfaceAtlasObjectBounds(objects, objectAddress);
|
||||
if (distance(objectBounds.xyz, worldPosition) > objectBounds.w)
|
||||
continue;
|
||||
GlobalSurfaceObject object = LoadGlobalSurfaceAtlasObject(objects, objectAddress);
|
||||
float3 localPosition = mul(float4(worldPosition, 1), object.WorldToLocal).xyz;
|
||||
float3 localExtent = object.Extent + surfaceThreshold;
|
||||
if (any(localPosition > localExtent) || any(localPosition < -localExtent))
|
||||
continue;
|
||||
|
||||
// Remove the scale vector from the transformation matrix
|
||||
float3x3 worldToLocal = (float3x3)object.WorldToLocal;
|
||||
float scaleX = length(worldToLocal[0]);
|
||||
float scaleY = length(worldToLocal[1]);
|
||||
float scaleZ = length(worldToLocal[2]);
|
||||
float3 invScale = float3(
|
||||
scaleX > 0.00001f ? 1.0f / scaleX : 0.0f,
|
||||
scaleY > 0.00001f ? 1.0f / scaleY : 0.0f,
|
||||
scaleZ > 0.00001f ? 1.0f / scaleZ : 0.0f);
|
||||
worldToLocal[0] *= invScale.x;
|
||||
worldToLocal[1] *= invScale.y;
|
||||
worldToLocal[2] *= invScale.z;
|
||||
// Cull point vs box
|
||||
GlobalSurfaceObject object = LoadGlobalSurfaceAtlasObject(objects, objectAddress);
|
||||
float3 localPosition = mul(worldPosition - object.WorldPosition, object.WorldToLocalRotation);
|
||||
float3 localExtents = object.WorldExtents + surfaceThreshold;
|
||||
if (any(abs(localPosition) > localExtents))
|
||||
continue;
|
||||
|
||||
// Sample tiles based on the directionality
|
||||
#if GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD_ENABLED
|
||||
float3 localNormal = normalize(mul(worldNormal, worldToLocal));
|
||||
float3 localNormalSq = localNormal * localNormal;
|
||||
uint tileOffset = object.TileOffsets[localNormal.x > 0.0f ? 0 : 1];
|
||||
if (localNormalSq.x > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
tileOffset = object.TileOffsets[localNormal.y > 0.0f ? 2 : 3];
|
||||
if (localNormalSq.y > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
tileOffset = object.TileOffsets[localNormal.z > 0.0f ? 4 : 5];
|
||||
if (localNormalSq.z > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
float3 localNormal = mul(worldNormal, object.WorldToLocalRotation);
|
||||
float3 localNormalSq = localNormal * localNormal;
|
||||
uint tileOffset = object.TileOffsets[localNormal.x > 0.0f ? 0 : 1];
|
||||
if (localNormalSq.x > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
tileOffset = object.TileOffsets[localNormal.y > 0.0f ? 2 : 3];
|
||||
if (localNormalSq.y > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
tileOffset = object.TileOffsets[localNormal.z > 0.0f ? 4 : 5];
|
||||
if (localNormalSq.z > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileOffset != 0)
|
||||
{
|
||||
GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectAddress + tileOffset);
|
||||
result += SampleGlobalSurfaceAtlasTile(data, object, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold);
|
||||
}
|
||||
#else
|
||||
uint tileOffset = object.TileOffsets[0];
|
||||
if (tileOffset != 0)
|
||||
|
||||
Reference in New Issue
Block a user