feat(pipeline): per-instance visibility for batched hatches (Phase 4-B, step 4)
Adds a dedicated `visibility: array<u32>` storage buffer (binding 4) alongside the existing batched hatch buffers. Vertex shader reads `visibility[v.instance_index]` — 0 → emit an out-of-NDC clip position so the GPU rasterizer clips the primitive before the fragment stage runs. `compute_hatch_lod` now drives this buffer instead of (or alongside, for the per-hatch fallback) `hatch_skip_flags`. Walks a per-instance CPU AABB mirror that the builder fills at upload time (`instance_aabbs`), applies the same `aabb_below_pixel` (sub-pixel LOD) OR `aabb_offscreen` (frustum cull) rule the legacy path used, and pushes the resulting 0/1 flags via `queue.write_buffer` on a separate 4 B-per-hatch buffer — ~40 KB per pan tick for 10 k hatches, far cheaper than re-writing the 112 B-per-instance data. Step 5 will remove the legacy `gpu_hatches` Vec, the per-hatch draw loop, and `hatch_skip_flags` once the batched path has soaked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
cfe53bd789
commit
398eee551d
4 changed files with 99 additions and 19 deletions
|
|
@ -745,7 +745,32 @@ impl Pipeline {
|
|||
/// fragment in the bounding quad. Pairs with the shader-side
|
||||
/// solid-fill substitution for hatches between 2 px and the dense
|
||||
/// pattern threshold.
|
||||
pub fn compute_hatch_lod(&mut self, view_proj: glam::Mat4, clip_w: u32, clip_h: u32) {
|
||||
pub fn compute_hatch_lod(
|
||||
&mut self,
|
||||
queue: &wgpu::Queue,
|
||||
view_proj: glam::Mat4,
|
||||
clip_w: u32,
|
||||
clip_h: u32,
|
||||
) {
|
||||
// Phase 4-B batched path — write the same skip rule (sub-pixel
|
||||
// LOD OR offscreen) into the GPU visibility buffer. The vertex
|
||||
// shader maps 0 → out-of-NDC clip → primitive culled before
|
||||
// fragment stage; equivalent to the per-hatch `skip_flags`
|
||||
// gate but at GPU-side cost.
|
||||
if let Some(batch) = &mut self.gpu_hatch_batched {
|
||||
// Same skip rule as the legacy per-hatch path: sub-pixel
|
||||
// LOD (`aabb_below_pixel`) OR offscreen (`aabb_offscreen`).
|
||||
// Walks the per-instance AABB mirror — no GPU readback.
|
||||
for (i, aabb) in batch.instance_aabbs.iter().enumerate() {
|
||||
let skip = aabb_below_pixel(*aabb, view_proj, clip_w, clip_h, 2.0)
|
||||
|| aabb_offscreen(*aabb, view_proj, clip_w, clip_h);
|
||||
batch.visibility[i] = if skip { 0 } else { 1 };
|
||||
}
|
||||
batch.upload_visibility(queue);
|
||||
return;
|
||||
}
|
||||
|
||||
// Per-hatch (legacy) fallback path.
|
||||
self.hatch_skip_flags = self
|
||||
.gpu_hatches
|
||||
.iter()
|
||||
|
|
|
|||
Loading…
Reference in a new issue