public sealed class InstanceCullerCulls the instances of a batch one at a time, and compacts the survivors.
Remarks
The second stage [docs/plan/31 § B2] names. InstancingRenderFeature's own remarks say a batch is culled as one object — "a forest drawn as one object with ten thousand transforms is culled as one object, so its bounds have to enclose the whole forest" — and answer it with "batching by locality is the caller's decision because only the caller knows the scene's shape". A foliage cell is that caller and it does know: it is a grid. This is what happens after the cell survives, and it is why a 32 m cell of grass whose far half is behind a hill does not draw its far half.
Per instance, which LodRenderFeature structurally cannot be. That feature is right for its case — a LOD group is several render objects and it clears the bits of the ones a view is not showing — and the level it picks is a property of the object. Here the level is a property of the instance: four thousand trees in a cell are at level 1 and six hundred of them are at level 2, and no amount of clearing object bits expresses that. So the survivors are binned into a run per level and the cell draws once per level rather than once. See [docs/plan/31 § D9].
A CPU reference, first and deliberately. [docs/plan/22 § improvement 4] — "a CPU reference for the parts that fail silently" — and the whole of GpuCulling is the same shape: arithmetic that a device will run, written where a test can run it without a device in the room. A per-instance cull fails silently in both directions (too few and the forest has holes; too many and nothing looks wrong at all, it is merely slow), so the definition wants to exist before the dispatch that mirrors it.
⚠ The dispatch does not exist yet. What is here is the definition and the compaction, not a compute shader — see the class remarks in GpuCulling for the pairing this is one half of, and [docs/plan/31 § T5] for where the other half lands.
Fields and properties (5)
public int SurvivorCountHow many instances survived the last cull, across every level.
public int LevelCountHow many levels the last cull binned into.
public ReadOnlySpan<uint> SurvivorsThe survivors' indices into the batch, grouped by level and ascending within each group.
public ReadOnlySpan<InstanceParameters> ParametersThe survivors' parameters, at the same indices as Survivors.
public ReadOnlySpan<InstanceLodRun> RunsWhere each level's survivors are in Survivors.
Methods (2)
public int Cull(ReadOnlySpan<InstanceBounds> instances, ReadOnlySpan<InstanceParameters> source, in InstanceCullSettings settings, ReadOnlySpan<float> lodDistances)Culls a batch and compacts what is left.
public void FillCommands(ReadOnlySpan<DrawCommand> mesh, uint firstInstance, Span<DrawCommand> commands)Fills one indirect draw command per level from the last cull.
Used by (4)
- FoliageCullParityTestsVixen.Rendering.Terrain.Tests
- FoliageRendererVixen.Rendering.Terrain
- GrassRendererVixen.Rendering.Terrain
- InstanceCullingTestsVixen.Rendering.Tests