From a5229022b0e500ac86560e585081f45293e587d2 Mon Sep 17 00:00:00 2001 From: skal Date: Fri, 6 Feb 2026 09:53:52 +0100 Subject: fix(shaders): Correct plane distance scaling for non-uniform transforms When a plane has non-uniform scaling (e.g., floor with scale 20,0.01,20), transforming points to local space distorts SDF distances. For a horizontal plane with Y-scale of 0.01, distances become 100x too large in local space. Fix: Multiply plane distances by the scale factor along the normal direction (Y component for horizontal planes). This corrects shadow calculations while maintaining the large floor area needed for visualization. Reverted incorrect uniform scale fix (c23f3b9) that made floor too small. --- assets/final/shaders/render/scene_query_bvh.wgsl | 11 ++++++++--- assets/final/shaders/render/scene_query_linear.wgsl | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'assets/final') diff --git a/assets/final/shaders/render/scene_query_bvh.wgsl b/assets/final/shaders/render/scene_query_bvh.wgsl index 61efe49..f70a389 100644 --- a/assets/final/shaders/render/scene_query_bvh.wgsl +++ b/assets/final/shaders/render/scene_query_bvh.wgsl @@ -45,10 +45,15 @@ fn map_scene(p: vec3, skip_idx: u32) -> f32 { // IMPORTANT: Plane (type 4.0) and Mesh (type 5.0) should not be scaled by 's'. // The 's' factor is meant for unit primitives (sphere, box, torus) that are // scaled by the model matrix. Meshes already have correct local-space extents. - if (obj.params.x != 4.0 && obj.params.x != 5.0) { // Not plane, not mesh - d = min(d, get_dist(q, obj.params) * s); - } else { + // For planes with non-uniform scaling, we need to correct the distance by the + // scale along the normal direction (Y for horizontal planes). + if (obj.params.x == 4.0) { // Plane + let plane_scale = length(obj.model[1].xyz); // Y scale for horizontal plane + d = min(d, get_dist(q, obj.params) * plane_scale); + } else if (obj.params.x == 5.0) { // Mesh d = min(d, get_dist(q, obj.params)); + } else { // Unit primitives + d = min(d, get_dist(q, obj.params) * s); } } else { // Internal if (stack_ptr < 31) { diff --git a/assets/final/shaders/render/scene_query_linear.wgsl b/assets/final/shaders/render/scene_query_linear.wgsl index ab3845a..881a939 100644 --- a/assets/final/shaders/render/scene_query_linear.wgsl +++ b/assets/final/shaders/render/scene_query_linear.wgsl @@ -45,10 +45,15 @@ fn map_scene(p: vec3, skip_idx: u32) -> f32 { // IMPORTANT: Plane (type 4.0) and Mesh (type 5.0) should not be scaled by 's'. // The 's' factor is meant for unit primitives (sphere, box, torus) that are // scaled by the model matrix. Meshes already have correct local-space extents. - if (obj.params.x != 4.0 && obj.params.x != 5.0) { // Not plane, not mesh - d = min(d, get_dist(q, obj.params) * s); - } else { + // For planes with non-uniform scaling, we need to correct the distance by the + // scale along the normal direction (Y for horizontal planes). + if (obj.params.x == 4.0) { // Plane + let plane_scale = length(obj.model[1].xyz); // Y scale for horizontal plane + d = min(d, get_dist(q, obj.params) * plane_scale); + } else if (obj.params.x == 5.0) { // Mesh d = min(d, get_dist(q, obj.params)); + } else { // Unit primitives + d = min(d, get_dist(q, obj.params) * s); } } else { // Internal if (stack_ptr < 31) { -- cgit v1.2.3