@@ -52,8 +52,9 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {
52
52
let aabb = project_view_space_sphere_to_screen_space_aabb (bounding_sphere_center_view_space , bounding_sphere_radius );
53
53
54
54
let depth_pyramid_size_mip_0 = vec2 <f32 >(textureDimensions (depth_pyramid , 0 ));
55
- let width = (aabb . z - aabb . x) * depth_pyramid_size_mip_0 . x;
56
- let height = (aabb . w - aabb . y) * depth_pyramid_size_mip_0 . y;
55
+ // we halve the size because the first depth mip resampling pass cut the full screen resolution into a power of two conservatively
56
+ let width = (aabb . z - aabb . x) * 0.5 * depth_pyramid_size_mip_0 . x;
57
+ let height = (aabb . w - aabb . y) * 0.5 * depth_pyramid_size_mip_0 . y;
57
58
let depth_level = max (0 , i32 (ceil (log2 (max (width , height ))))); // TODO: Naga doesn't like this being a u32
58
59
let depth_pyramid_size = vec2 <f32 >(textureDimensions (depth_pyramid , depth_level ));
59
60
let aabb_top_left = vec2 <u32 >(aabb . xy * depth_pyramid_size );
@@ -63,9 +64,15 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {
63
64
let depth_quad_c = textureLoad (depth_pyramid , aabb_top_left + vec2 (0u , 1u ), depth_level ). x;
64
65
let depth_quad_d = textureLoad (depth_pyramid , aabb_top_left + vec2 (1u , 1u ), depth_level ). x;
65
66
let occluder_depth = min (min (depth_quad_a , depth_quad_b ), min (depth_quad_c , depth_quad_d ));
66
-
67
- let sphere_depth = - view . projection[3 ][2 ] / (bounding_sphere_center_view_space . z + bounding_sphere_radius );
68
- meshlet_visible &= sphere_depth >= occluder_depth ;
67
+ if view . projection[3 ][3 ] == 1.0 {
68
+ // Orthographic
69
+ let sphere_depth = view . projection[3 ][2 ] + (bounding_sphere_center_view_space . z + bounding_sphere_radius ) * view . projection[2 ][2 ];
70
+ meshlet_visible &= sphere_depth >= occluder_depth ;
71
+ } else {
72
+ // Perspective
73
+ let sphere_depth = - view . projection[3 ][2 ] / (bounding_sphere_center_view_space . z + bounding_sphere_radius );
74
+ meshlet_visible &= sphere_depth >= occluder_depth ;
75
+ }
69
76
}
70
77
#endif
71
78
@@ -76,23 +83,31 @@ fn cull_meshlets(@builtin(global_invocation_id) thread_id: vec3<u32>) {
76
83
77
84
// https://zeux.io/2023/01/12/approximate-projected-bounds
78
85
fn project_view_space_sphere_to_screen_space_aabb (cp : vec3 <f32 >, r : f32 ) -> vec4 <f32 > {
79
- let c = vec3 (cp . xy, - cp . z);
80
- // No need to clip near plane because frustum culling already checked that
86
+ let inv_width = view . projection[0 ][0 ] * 0.5 ;
87
+ let inv_height = view . projection[1 ][1 ] * 0.5 ;
88
+ if view . projection[3 ][3 ] == 1.0 {
89
+ // Orthographic
90
+ let min_x = cp . x - r ;
91
+ let max_x = cp . x + r ;
81
92
82
- let cr = c * r ;
83
- let czr2 = c . z * c . z - r * r ;
93
+ let min_y = cp . y - r ;
94
+ let max_y = cp . y + r ;
84
95
85
- let vx = sqrt (c . x * c . x + czr2 );
86
- let min_x = (vx * c . x - cr . z) / (vx * c . z + cr . x);
87
- let max_x = (vx * c . x + cr . z) / (vx * c . z - cr . x);
96
+ return vec4 (min_x * inv_width , 1.0 - max_y * inv_height , max_x * inv_width , 1.0 - min_y * inv_height );
97
+ } else {
98
+ // Perspective
99
+ let c = vec3 (cp . xy, - cp . z);
100
+ let cr = c * r ;
101
+ let czr2 = c . z * c . z - r * r ;
88
102
89
- let vy = sqrt (c . y * c . y + czr2 );
90
- let min_y = (vy * c . y - cr . z) / (vy * c . z + cr . y );
91
- let max_y = (vy * c . y + cr . z) / (vy * c . z - cr . y );
103
+ let vx = sqrt (c . x * c . x + czr2 );
104
+ let min_x = (vx * c . x - cr . z) / (vx * c . z + cr . x );
105
+ let max_x = (vx * c . x + cr . z) / (vx * c . z - cr . x );
92
106
93
- let p00 = view . projection[0 ][0 ];
94
- let p11 = view . projection[1 ][1 ];
107
+ let vy = sqrt (c . y * c . y + czr2 );
108
+ let min_y = (vy * c . y - cr . z) / (vy * c . z + cr . y);
109
+ let max_y = (vy * c . y + cr . z) / (vy * c . z - cr . y);
95
110
96
- var aabb = vec4 (min_x * p00 , min_y * p11 , max_x * p00 , max_y * p11 );
97
- return aabb . xwzy * vec4 ( 0.5 , - 0.5 , 0.5 , - 0.5 ) + vec4 ( 0.5 );
111
+ return vec4 (min_x * inv_width , - max_y * inv_height , max_x * inv_width , - min_y * inv_height ) + vec4 ( 0.5 );
112
+ }
98
113
}
0 commit comments