Skip to content

Commit

Permalink
Merge pull request #23 from rodolphito/meshlet-orthographic
Browse files Browse the repository at this point in the history
Fix occlusion culling in orthographic views
  • Loading branch information
JMS55 authored Jan 19, 2024
2 parents d0789ae + 4dcc424 commit 2a5c800
Showing 1 changed file with 34 additions and 19 deletions.
53 changes: 34 additions & 19 deletions crates/bevy_pbr/src/meshlet/cull_meshlets.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {
let aabb = project_view_space_sphere_to_screen_space_aabb(bounding_sphere_center_view_space, bounding_sphere_radius);

let depth_pyramid_size_mip_0 = vec2<f32>(textureDimensions(depth_pyramid, 0));
let width = (aabb.z - aabb.x) * depth_pyramid_size_mip_0.x;
let height = (aabb.w - aabb.y) * depth_pyramid_size_mip_0.y;
// we halve the size because the first depth mip resampling pass cut the full screen resolution into a power of two conservatively
let width = (aabb.z - aabb.x) * 0.5 * depth_pyramid_size_mip_0.x;
let height = (aabb.w - aabb.y) * 0.5 * depth_pyramid_size_mip_0.y;
let depth_level = max(0, i32(ceil(log2(max(width, height))))); // TODO: Naga doesn't like this being a u32
let depth_pyramid_size = vec2<f32>(textureDimensions(depth_pyramid, depth_level));
let aabb_top_left = vec2<u32>(aabb.xy * depth_pyramid_size);
Expand All @@ -63,9 +64,15 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {
let depth_quad_c = textureLoad(depth_pyramid, aabb_top_left + vec2(0u, 1u), depth_level).x;
let depth_quad_d = textureLoad(depth_pyramid, aabb_top_left + vec2(1u, 1u), depth_level).x;
let occluder_depth = min(min(depth_quad_a, depth_quad_b), min(depth_quad_c, depth_quad_d));

let sphere_depth = -view.projection[3][2] / (bounding_sphere_center_view_space.z + bounding_sphere_radius);
meshlet_visible &= sphere_depth >= occluder_depth;
if view.projection[3][3] == 1.0 {
// Orthographic
let sphere_depth = view.projection[3][2] + (bounding_sphere_center_view_space.z + bounding_sphere_radius) * view.projection[2][2];
meshlet_visible &= sphere_depth >= occluder_depth;
} else {
// Perspective
let sphere_depth = -view.projection[3][2] / (bounding_sphere_center_view_space.z + bounding_sphere_radius);
meshlet_visible &= sphere_depth >= occluder_depth;
}
}
#endif

Expand All @@ -76,23 +83,31 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {

// https://zeux.io/2023/01/12/approximate-projected-bounds
fn project_view_space_sphere_to_screen_space_aabb(cp: vec3<f32>, r: f32) -> vec4<f32> {
let c = vec3(cp.xy, -cp.z);
// No need to clip near plane because frustum culling already checked that
let inv_width = view.projection[0][0] * 0.5;
let inv_height = view.projection[1][1] * 0.5;
if view.projection[3][3] == 1.0 {
// Orthographic
let min_x = cp.x - r;
let max_x = cp.x + r;

let cr = c * r;
let czr2 = c.z * c.z - r * r;
let min_y = cp.y - r;
let max_y = cp.y + r;

let vx = sqrt(c.x * c.x + czr2);
let min_x = (vx * c.x - cr.z) / (vx * c.z + cr.x);
let max_x = (vx * c.x + cr.z) / (vx * c.z - cr.x);
return vec4(min_x * inv_width, 1.0 - max_y * inv_height, max_x * inv_width, 1.0 - min_y * inv_height);
} else {
// Perspective
let c = vec3(cp.xy, -cp.z);
let cr = c * r;
let czr2 = c.z * c.z - r * r;

let vy = sqrt(c.y * c.y + czr2);
let min_y = (vy * c.y - cr.z) / (vy * c.z + cr.y);
let max_y = (vy * c.y + cr.z) / (vy * c.z - cr.y);
let vx = sqrt(c.x * c.x + czr2);
let min_x = (vx * c.x - cr.z) / (vx * c.z + cr.x);
let max_x = (vx * c.x + cr.z) / (vx * c.z - cr.x);

let p00 = view.projection[0][0];
let p11 = view.projection[1][1];
let vy = sqrt(c.y * c.y + czr2);
let min_y = (vy * c.y - cr.z) / (vy * c.z + cr.y);
let max_y = (vy * c.y + cr.z) / (vy * c.z - cr.y);

var aabb = vec4(min_x * p00, min_y * p11, max_x * p00, max_y * p11);
return aabb.xwzy * vec4(0.5, -0.5, 0.5, -0.5) + vec4(0.5);
return vec4(min_x * inv_width, -max_y * inv_height, max_x * inv_width, -min_y * inv_height) + vec4(0.5);
}
}

0 comments on commit 2a5c800

Please sign in to comment.