From 85b134b7be0411fcda366ee0ce6a969cdc978b7d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 4 Nov 2025 13:27:21 +0100 Subject: [PATCH] Add improved Global SDF quality and precision of rasterization --- Content/Editor/Primitives/Cube.flax | 4 ++-- Source/Engine/Tools/ModelTool/ModelTool.cpp | 2 ++ Source/Shaders/SDF.shader | 2 ++ Source/Shaders/ThirdParty/TressFX/TressFXSDF.hlsl | 8 ++++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Content/Editor/Primitives/Cube.flax b/Content/Editor/Primitives/Cube.flax index 6328a7bbc..b12f75e05 100644 --- a/Content/Editor/Primitives/Cube.flax +++ b/Content/Editor/Primitives/Cube.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5a18bf58e0b93c8bba9459fd77a92898f0fae373b58d3acbcb9e36f66c89cd7 -size 23537 +oid sha256:8e8d210a74ae373793eaee1ddab1372a6a50a000c489f97b2258a09cd93cc2d0 +size 5031 diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 0ae1e0639..78a3fe515 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -366,9 +366,11 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, const ModelData* modelData, return true; ModelBase::SDFData sdf; sdf.WorldUnitsPerVoxel = METERS_TO_UNITS(0.1f) / Math::Max(resolutionScale, 0.0001f); // 1 voxel per 10 centimeters +#if 0 const float boundsMargin = sdf.WorldUnitsPerVoxel * 0.5f; // Add half-texel margin around the mesh bounds.Minimum -= boundsMargin; bounds.Maximum += boundsMargin; +#endif const Float3 size = bounds.GetSize(); Int3 resolution(Float3::Ceil(Float3::Clamp(size / sdf.WorldUnitsPerVoxel, 4, 256))); Float3 uvwToLocalMul = size; diff --git a/Source/Shaders/SDF.shader b/Source/Shaders/SDF.shader index ba2626ff9..2239e2dbe 100644 --- a/Source/Shaders/SDF.shader +++ b/Source/Shaders/SDF.shader @@ -142,8 +142,10 @@ void CS_RasterizeTriangle(uint3 DispatchThreadId : SV_DispatchThreadID) int voxelIndex = GetVoxelIndex(voxelCoord); float3 voxelPos = GetVoxelPos(voxelCoord); float distance = SignedDistancePointToTriangle(voxelPos, v0, v1, v2); +#if 0 if (distance < -10.0f) // TODO: find a better way to reject negative distance from degenerate triangles that break SDF shape distance = abs(distance); +#endif InterlockedMin(SDF[voxelIndex], FloatFlip3(distance)); } } diff --git a/Source/Shaders/ThirdParty/TressFX/TressFXSDF.hlsl b/Source/Shaders/ThirdParty/TressFX/TressFXSDF.hlsl index 13c28f16d..7128ba9ca 100644 --- a/Source/Shaders/ThirdParty/TressFX/TressFXSDF.hlsl +++ b/Source/Shaders/ThirdParty/TressFX/TressFXSDF.hlsl @@ -52,6 +52,14 @@ uint IFloatFlip3(uint f2) float DistancePointToEdge(float3 p, float3 x0, float3 x1, out float3 n) { + // Hack to swap to ensure the order is correct (.x only for simplicity) + if (x0.x > x1.x) + { + float3 temp = x0; + x0 = x1; + x1 = temp; + } + float3 x10 = x1 - x0; float t = dot(x1 - p, x10) / dot(x10, x10);