Overview
Developed a GPU-driven vegetation system designed to efficiently render the campaign map with thousands to millions of instances. The system leverages compute shaders, exploration based culling, and indirect rendering to minimize CPU overhead and maximize scalability.
Tree Rendering Pipeline
- Input (CPU -> GPU)
Instance data (position, scale, rotation) is uploaded to GPU buffers along with camera, exploration texture and bounding radius. - GPU culling & LOD selection (Compute shader)
- Culling using exploration texture.
- Dynamic LOD selection based on relative screen size (mesh or billboard), very small sizes are culled.
- Visible instances are written using AppendStructuredBuffer.
- Rendering (Indirect Drawing)
- Graphics.RenderMeshIndirect used for both mesh and billboard passes.
- Argument buffers written directly from compute.
Grass System
- Procedural Generation (Compute shader)
Grass instances are generated entirely on the GPU based on:- Terrain elevation map
- Density texture (biome based)
- GPU culling (Compute shader)
- Culling using exploration texture.
- Visible instances are written using AppendStructuredBuffer.
- Frustum culling is done at chunk level.
- Rendering (Indirect Drawing)
- Graphics.RenderMeshIndirect.
- Argument buffers written directly from compute.
Exploration and terrain updates
- When armies explore, the relevant visiblity cells (pixels) are updated in the texture and compute shader is dispatched again. Since all terrain chunks share the same texture, this is done once and not per chunk.
- If terrain information changes (most common case is vegetation removed from a cell when building on it) the base instance buffer are updated. This is done only on the relevant chunk.
Shading
- Vertex shader
- Per-instance transformationsÂ
- Wind animation (grass)
- Fragment shader
- Alpha clipping (grass & tree foliage).
- Tree texture selection from atlas.
- Foliage tint selection (biome based).
Migration summary
- 1.0
- Geometry shader grass.
- Rebuilding chunk meshes on exploration/terrain updates.
- 1.1
- Compute shaders for generation and culling.
- Indirect rendering.
- Buffer/texture update when data changes.
