Context
The engine currently uses `VkDrawIndirect` with a CPU-built command list. CPU frustum culling (#644) filters the command list on the render thread before submission — adequate for scenes up to ~10K instances.
For large open-world scenes (virtual geometry streaming, streaming chunks, dense foliage), GPU-side culling is required.
Desired design
A compute dispatch runs before the G-buffer pass each frame:
CPU: upload full InstanceData[] + BoundsData[] to GPU
→ dispatch ComputeCull(N threads, 1 per instance)
GPU: each thread tests instance bounding sphere vs. frustum planes
→ atomically appends visible VkDrawIndirectCommand to output buffer
→ writes visible count to counter buffer
→ barrier: compute write → indirect draw read
G-Buffer Pass: vkDrawIndirectCountKHR(output_buf, counter_buf, MAX_DRAWS)
Prerequisites
Notes
Context
The engine currently uses `VkDrawIndirect` with a CPU-built command list. CPU frustum culling (#644) filters the command list on the render thread before submission — adequate for scenes up to ~10K instances.
For large open-world scenes (virtual geometry streaming, streaming chunks, dense foliage), GPU-side culling is required.
Desired design
A compute dispatch runs before the G-buffer pass each frame:
Prerequisites
vkDrawIndirectCountKHRwired inAppRenderPipeline(or core Vulkan 1.2vkDrawIndirectCount)TransformSB✓Notes