From 79ee6a973e20cd906162ce2889afd98b360a895d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 2 Jun 2024 12:06:25 +0200 Subject: [PATCH] Fix GlobalSDF for meshes intersections for negative distances inside the geometry --- Source/Shaders/GlobalSignDistanceField.shader | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/GlobalSignDistanceField.shader b/Source/Shaders/GlobalSignDistanceField.shader index 9810c53f8..0709977db 100644 --- a/Source/Shaders/GlobalSignDistanceField.shader +++ b/Source/Shaders/GlobalSignDistanceField.shader @@ -60,6 +60,14 @@ float CombineDistanceToSDF(float sdf, float distanceToSDF) return sqrt(Square(max(sdf, 0)) + Square(distanceToSDF)); } +float CombineSDF(float oldSdf, float newSdf) +{ + // Use distance closer to 0 + if (oldSdf < 0 && newSdf < 0) + return max(oldSdf, newSdf); + return min(oldSdf, newSdf); +} + #if defined(_CS_RasterizeModel) || defined(_CS_RasterizeHeightfield) RWTexture3D GlobalSDFTex : register(u0); @@ -127,7 +135,7 @@ void CS_RasterizeModel(uint3 DispatchThreadId : SV_DispatchThreadID) { ObjectRasterizeData objectData = ObjectsBuffer[Objects[i / 4][i % 4]]; float objectDistance = DistanceToModelSDF(minDistance, objectData, ObjectsTextures[i], voxelWorldPos); - minDistance = min(minDistance, objectDistance); + minDistance = CombineSDF(minDistance, objectDistance); } GlobalSDFTex[voxelCoord] = clamp(minDistance / MaxDistance, -1, 1); } @@ -177,7 +185,7 @@ void CS_RasterizeHeightfield(uint3 DispatchThreadId : SV_DispatchThreadID) float objectDistance = dot(heightfieldNormal, voxelWorldPos - heightfieldPosition); if (objectDistance < thickness) objectDistance = thickness - objectDistance; - minDistance = min(minDistance, objectDistance); + minDistance = CombineSDF(minDistance, objectDistance); } GlobalSDFTex[voxelCoord] = clamp(minDistance / MaxDistance, -1, 1); }