Core Philosophy: GPU-Driven Rendering & Data-Oriented ECS
One of the most significant challenges for modern AAA game engines is the efficient real-time management of millions of entities within a hybrid CPU-GPU environment. The traditional object-oriented paradigm presents severe performance bottlenecks in this context, manifesting as frequent cache misses, poor parallelizability, and cumbersome GPU synchronization.
To overcome these limitations, the Synapse Engine was built on a fundamentally different approach: integrating a fully data-oriented Entity-Component-System (ECS) with a high-performance GPU-driven rendering and hierarchical culling architecture.
1. Segmented Data-Oriented ECS
In our data-oriented paradigm, entities are simple numerical identifiers, and data is stored in homogeneous, compact vectors. This ensures excellent cache locality and SIMD-friendly parallel processing.
Our custom architecture utilizes a sparse-set data structure to achieve true O(1) component lookups. To eliminate redundant CPU iterations over unmodified data, we introduced two key innovations:
- Segmented Component Storage: The compact array is physically partitioned into three regions based on update frequency: Static, Dynamic, and Stream.
- Bitflag-Based Change Tracking: Components maintain a bitflag vector to signal required updates, allowing systems to bypass unmodified data entirely.
2. Fully GPU-Driven Rendering Pipeline
The core objective of our rendering architecture is to eliminate the bottlenecks associated with CPU-side draw call management. In Synapse Engine, the CPU is entirely oblivious to the specific details of the scene being rendered. Compute shaders manage the entire lifecycle of a frame, from visibility determination to draw call generation, utilizing indirect draw calls.
The Eight-Bucket Indirect Draw System
All indirect draw commands for the entire scene are stored within a single, large global buffer partitioned into eight distinct buckets. This separation is based on two criteria:
- Rendering Pipeline: Traditional Vertex Shader Pipeline vs. Modern Mesh Shader Pipeline.
- Material Type: Opaque 1-sided, Opaque 2-sided, Transparent 1-sided, and Transparent 2-sided.
3. Hierarchical Culling Architecture
Visibility is evaluated entirely within compute shaders at three distinct levels, ensuring complex geometry is filtered with increasing precision:
- Model-Level: Tests pre-transformed world-space colliders (AABB and Sphere) against the camera frustum and Hi-Z depth buffer.
- Mesh-Level: A collaborative compute pass evaluating visibility on a per-mesh basis, applying frustum, Hi-Z occlusion, and zero-pixel-triangle tests. This stage also handles projection-based Dynamic Level of Detail (LOD) selection.
- Meshlet-Level (Task Shader): Meshlets (small, localized geometry clusters) undergo rigorous tests, including software-based cone culling to discard backfaces before rasterization.
4. Bindless Resource Management
To replace CPU-side binding overhead, the engine uses a bindless buffer addressing architecture. The Model and Animation Managers construct centralized address buffers, allowing shaders to dynamically access per-model vertex and index data using merely an integer index. Furthermore, a double indirection mechanism enables per-instance material overrides directly on the GPU.
Ultimately, this architecture sustains real-time performance even with over one million entities, significantly outperforming traditional ECS and rendering setups.