-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Meshlet BVH Culling #19318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Meshlet BVH Culling #19318
Conversation
Readd software raster
return min(min(a, b), min(c, d)); | ||
} | ||
|
||
// TODO: We should probably be using a POT HZB texture? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep this TODO. The current HZB generation is wrong and misses information on the edges of certain mip levels, requiring us to be over-conservative in our culling.
} | ||
|
||
fn occlusion_cull_screen_aabb(aabb: ScreenAabb, screen: vec2<f32>) -> bool { | ||
let hzb_size = ceil(screen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mip 0 of the HZB is floor(screen * 0.5)
.
|
||
// note: add 1 before max because the unsigned overflow behavior is intentional | ||
// it wraps around firstLeadingBit(0) = ~0 to 0 | ||
var mip = max(firstLeadingBit(max_size) + 1u, 2u) - 1u; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the above change, I tested the following and it works, letting us sample one mip finer:
// note: add 1 before max because the unsigned overflow behavior is intentional
// it wraps around firstLeadingBit(0) = ~0 to 0
// TODO: we actually sample a 4x4 block, so ideally this would be `max(..., 3u) - 3u`.
// 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.
var mip = max(firstLeadingBit(max_size) + 1u, 2u) - 2u;
let smin = min_texel >> vec2<u32>(mip); | ||
let smax = max_texel >> vec2<u32>(mip); | ||
|
||
mip -= 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the above changes, this can be removed.
// let world_sphere_radius = lod_sphere.w * world_scale; | ||
// let norm_error = simplification_error / world_sphere_radius * 0.25; | ||
// return norm_error * view.viewport.w < 1.0; | ||
let world_error = simplification_error * world_scale; | ||
let proj = projection[1][1]; | ||
let height = 2.0 / proj; | ||
let norm_error = world_error / height; | ||
return norm_error * view.viewport.w < 1.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure how correct my change (from the commented code) is, though it seems to work.
Objective
Solution
Testing