@@ -19,9 +19,6 @@ fn lod_error_is_imperceptible(lod_sphere: vec4<f32>, simplification_error: f32,
19
19
20
20
let projection = view . clip_from_view;
21
21
if projection [3 ][3 ] == 1.0 {
22
- // let world_sphere_radius = lod_sphere.w * world_scale;
23
- // let norm_error = simplification_error / world_sphere_radius * 0.25;
24
- // return norm_error * view.viewport.w < 1.0;
25
22
let world_error = simplification_error * world_scale ;
26
23
let proj = projection [1 ][1 ];
27
24
let height = 2.0 / proj ;
@@ -144,8 +141,9 @@ fn sample_hzb_row(sx: vec4<u32>, sy: u32, mip: i32) -> f32 {
144
141
return min (min (a , b ), min (c , d ));
145
142
}
146
143
144
+ // TODO: We should probably be using a POT HZB texture?
147
145
fn occlusion_cull_screen_aabb (aabb : ScreenAabb , screen : vec2 <f32 >) -> bool {
148
- let hzb_size = ceil (screen );
146
+ let hzb_size = ceil (screen * 0.5 );
149
147
let aabb_min = aabb . min. xy * hzb_size ;
150
148
let aabb_max = aabb . max. xy * hzb_size ;
151
149
@@ -156,16 +154,16 @@ fn occlusion_cull_screen_aabb(aabb: ScreenAabb, screen: vec2<f32>) -> bool {
156
154
157
155
// note: add 1 before max because the unsigned overflow behavior is intentional
158
156
// it wraps around firstLeadingBit(0) = ~0 to 0
159
- var mip = max (firstLeadingBit (max_size ) + 1u , 2u ) - 1u ;
157
+ // TODO: we actually sample a 4x4 block, so ideally this would be `max(..., 3u) - 3u`.
158
+ // However, since our HZB is not a power of two, we need to be extra-conservative to not over-cull, so we go up a mip.
159
+ var mip = max (firstLeadingBit (max_size ) + 1u , 2u ) - 2u ;
160
160
161
161
if any ((max_texel >> vec2 (mip )) > (min_texel >> vec2 (mip )) + 3 ) {
162
162
mip += 1u ;
163
163
}
164
164
165
165
let smin = min_texel >> vec2 <u32 >(mip );
166
166
let smax = max_texel >> vec2 <u32 >(mip );
167
-
168
- mip -= 1 ;
169
167
170
168
let curr_depth = sample_hzb (smin , smax , i32 (mip ));
171
169
return aabb . max. z <= curr_depth ;
0 commit comments