Skip to content

Built-in Passes

All built-in passes live in src/modules/renderer/systems/render-system/passes/. Each is a concrete RenderPass subclass registered with the render graph.

GeometryPass

Name: "GeometryPass"

The main scene pass. Renders all Object entities by iterating the entity manager and invoking per-component update logic.

Resources consumed:

Resource nameAccessPurpose
shadow_mapReadBinds shadow depth texture to objects' shaders
scene_colorWriteRender target for lit scene

Per-frame logic:

  1. Updates all Camera entities - recalculates projection and view matrices.
  2. Collects all LightComponents from the component manager.
  3. For each Object: updates TransformComponent, ResourceComponent, MaterialComponent, then uploads camera matrices (view, projection, view_position) and light data to the shader.

Shadow integration:

If a shadow_map framebuffer resource is present, the geometry pass binds the shadow depth texture to the shadowMap sampler uniform at the next available texture slot.

ShadowPass

Name: "ShadowPass"

Renders the scene depth from the light's perspective into a depth framebuffer for shadow mapping.

Resources consumed:

Resource nameAccessPurpose
shadow_mapWriteDepth-only framebuffer

Setup: Creates and loads the shadow_mapping_depth shader automatically.

Per-frame logic:

  1. Binds the shadow map framebuffer.
  2. For each Object: temporarily replaces its shader with shadow_mapping_depth, renders the mesh with front-face culling, then restores the original shader.

SkyboxPass

Name: "SkyboxPass"

Renders all Skybox entities as cube meshes using DepthMode::LessEqual so the skybox appears behind all geometry.

Resources consumed: None (writes directly to the bound scene framebuffer).

Per-frame logic:

Sets depth mode to LessEqual, renders each active skybox with its cubemap texture and camera matrices (view_without_transformation, projection), then restores Less depth.

PostProcessPass

Name: "PostProcessPass"

Renders a full-screen quad using the HDR tone-mapping shader. Runs after the scene has been rendered to the HDR framebuffer.

Resources consumed:

Resource nameAccessPurpose
scene_colorReadHDR source for tone mapping

Setup: Automatically creates a PostProcessing entity with a quad mesh and the shaders::hdr shader.

Per-frame logic:

  1. Unbinds the scene framebuffer (switches to default framebuffer).
  2. Disables depth testing.
  3. For each PostProcessing entity: updates the resource, post-processing component, and draws the quad.

MeshPass

Name: "MeshPass"

A lightweight pass for rendering meshes outside of the full geometry pipeline. Used when lighter-weight rendering without light evaluation is needed.

TextPass

Name: "TextPass"

Renders all Text entities. Handles font atlas binding and per-glyph draw calls.

DebugPass

Name: "DebugPass"

Optional debug visualization pass. Renders bounding volumes, normals, or other debug primitives.

Custom Passes

Implement RenderPass to add custom passes:

cpp
class MyPass : public RenderPass {
public:
    void setup(Ref<RenderTarget> target,
               const std::vector<const RenderGraphResource*>& resources) override {
        m_render_target = target;
        // find resources by name, do one-time setup
    }

    void begin(double dt)   override {}
    void execute(double dt) override { /* draw calls */ }
    void end(double dt)     override {}
    void cleanup()          override {}

    std::string name() const override { return "MyPass"; }
};

Register it in RenderGraphBuilder:

cpp
uint32_t my_res = builder.declare_framebuffer("my_output", width, height);

builder.add_pass(create_scope<MyPass>())
    .read(scene_color)
    .write(my_res)
    .end();