simvx.graphics.renderer.occlusion_cull¶
GPU Hi-Z occlusion cull pass (phase O3).
Patches per-instance instance_count in an indirect draw buffer IN PLACE:
0 to cull, 1 to keep. Batching guarantees one command per instance, so zeroing a
command drops exactly that one object. CONSERVATIVE: an object is culled only
when its nearest screen depth is strictly farther than the Hi-Z (MAX) occluder
footprint; every degeneracy keeps the object. See occlusion_cull.comp.
Single-phase against LAST frame’s Hi-Z pyramid: the cull runs BEFORE the forward
pass (compute is illegal inside a render pass), consuming the pyramid the prior
frame built. Fully gated by Renderer._occlusion_culling_enabled and by a
hiz_built_once flag (skip until a pyramid exists), so the default path
allocates and dispatches nothing.
Module Contents¶
Classes¶
Two-phase Hi-Z occlusion cull: GPU phase-1 selection + phase-2 cull. |
Data¶
API¶
- simvx.graphics.renderer.occlusion_cull.__all__¶
[‘OcclusionTwoPhasePass’]
- simvx.graphics.renderer.occlusion_cull.log¶
‘getLogger(…)’
- class simvx.graphics.renderer.occlusion_cull.OcclusionTwoPhasePass(engine: Any, max_sets: int = 16)[source]¶
Two-phase Hi-Z occlusion cull: GPU phase-1 selection + phase-2 cull.
Reuses
occlusion_two_phase.comp(one shader, dispatched twice). Owns a descriptor set per(indirect buffer, frame parity): bindings 4/5 (vis_prev, vis_next) swap each frame, so a fresh set is allocated for each parity and then cached. Bindings 0-3 (draws, transforms, aabbs, hi-z) match the single-phase layout. See the shader header for the conservative invariant.Initialization
- dispatch(cmd: Any, *, phase: int, skip_cull: bool, indirect_buffer: Any, draw_count: int, transform_buf: Any, aabb_buf: Any, hiz_view: Any, hiz_sampler: Any, vis_prev_buf: Any, vis_next_buf: Any, parity: int, view_proj: numpy.ndarray, base_extent: tuple[int, int], mip_count: int, max_objects: int, host_barrier: bool = False) None[source]¶
Record one phase of the two-phase cull.
phase1 = selection (seed phase-1 batch + vis_next from vis_prev), 2 = cull (test set B against the fresh Hi-Z, write final instance_count + vis_next). The caller guarantees this runs OUTSIDE any render pass.Barriers:
host_barrier(phase-1 only) makes the CPU indirect/transform/ aabb/visibility uploads visible. After the dispatch a buffer barrier makes the patchedinstance_countvisible to the indirect draw that reads it (phase 1 -> depth prepass, phase 2 -> colour pass).