Files
IfcOpenShell/src
Dion Moult 61726e00a4 wgpu backend: CPU frustum cull + per-mesh draw compaction
Stage 6 of the wgpu port. Replaces the one-draw-per-(mesh, instance) loop
with a CPU cull pass that survives one drawIndexed per non-empty mesh
with packed instanceCount.

Adds to WgpuModelGpuData:
  - visible_buffer: u32[] storage SSBO, pre-sized to instance_count at
    applyCachedModel so the bind group reference never invalidates.
    Re-uploaded each frame via wgpuQueueWriteBuffer.
  - mesh_draws: per-mesh schedule (first_instance, instance_count,
    first_index, base_vertex, index_count). instance_count==0 means the
    mesh contributed nothing this frame and the draw is elided entirely.

cullModelCpu per-frame:
  - Extract 6 frustum planes from the same VP we write into the uniform.
    WebGPU clip-space z is [0, 1], so near plane = matrix row 2 (not
    row 3 + row 2 as in GL); rest of the derivation is standard.
  - Per-instance AABB-vs-frustum test using the p-vertex shortcut
    (cheapest correct early-out for AABBs).
  - Bucket survivors by mesh_id; flatten into a contiguous u32 list;
    upload via wgpuQueueWriteBuffer. Per-mesh slice is [first_instance,
    first_instance + instance_count).

WGSL adds @group(1) @binding(3) var<storage, read> visible: array<u32>
and an extra indirection: instance_idx = visible[iid]; the rest of the
shader is unchanged. firstInstance on each drawIndexed offsets into
visible[], so each mesh reads its own slice.

Verified two ways:
  1. basic.ifc (3 instances, all on-screen) renders pixel-identically
     to pre-stage-6 — proves cull keeps everything it should.
  2. basic.ifc + a synthetic instance placed at (100, 100, 100) is
     culled cleanly: only the cube renders, the far quad is rejected
     by the frustum test. Proves cull actually rejects out-of-frustum
     geometry rather than passing everything through.

Contribution culling, HiZ, and LOD selection arrive in stages 7 and 8;
they all hook into the same cullModelCpu seam.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:05:58 +10:00
..
2026-02-27 14:52:55 +05:00
2026-01-26 17:13:18 +05:00
2026-02-27 14:52:55 +05:00
2026-04-07 09:46:45 +02:00
2026-05-26 13:36:03 +10:00
2026-05-09 21:03:55 +02:00
2026-05-09 21:03:55 +02:00
2026-05-08 10:56:41 +02:00
2026-05-10 17:01:11 +02:00
2026-03-31 20:51:46 +02:00
2026-03-18 10:29:09 +05:30