From 18eb1c1072eba9032efb35a3b6e1039511700548 Mon Sep 17 00:00:00 2001 From: Rudolph Bester Date: Tue, 1 Oct 2024 20:04:21 +0200 Subject: [PATCH] Fix occlusion culling by using depth instead of Euclidean distance when selecting the closest point Co-authored-by: Florent Guiocheau --- modules/raycast/raycast_occlusion_cull.cpp | 4 +++- servers/rendering/renderer_scene_occlusion_cull.h | 7 ++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 9f95307cf1c..5c23f9bb0ff 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -173,7 +173,9 @@ void RaycastOcclusionCull::RaycastHZBuffer::sort_rays(const Vector3 &p_camera_di } int k = tile_i * TILE_SIZE + tile_j; int tile_index = i * tile_grid_size.x + j; - mips[0][y * buffer_size.x + x] = camera_rays[tile_index].ray.tfar[k]; + + Vector3 ray_dir(camera_rays[tile_index].ray.dir_x[k], camera_rays[tile_index].ray.dir_y[k], camera_rays[tile_index].ray.dir_z[k]); + mips[0][y * buffer_size.x + x] = camera_rays[tile_index].ray.tfar[k] * p_camera_dir.dot(ray_dir); // Store z-depth in view space. } } } diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 690bab5c9a4..1ab50c720a7 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -71,7 +71,7 @@ public: return false; } - float min_depth = (closest_point - p_cam_position).length(); + float min_depth = -closest_point_view.z; Vector2 rect_min = Vector2(FLT_MAX, FLT_MAX); Vector2 rect_max = Vector2(FLT_MIN, FLT_MIN); @@ -82,12 +82,9 @@ public: Vector3 corner = Vector3(p_bounds[0] * c.x + p_bounds[3] * nc.x, p_bounds[1] * c.y + p_bounds[4] * nc.y, p_bounds[2] * c.z + p_bounds[5] * nc.z); Vector3 view = p_cam_inv_transform.xform(corner); - if (p_cam_projection.is_orthogonal()) { - min_depth = MIN(min_depth, -view.z); - } - Plane vp = Plane(view, 1.0); Plane projected = p_cam_projection.xform4(vp); + min_depth = MIN(min_depth, -view.z); float w = projected.d; if (w < 1.0) {