Source code for simvx.graphics.renderer.render_pass
"""RenderPass base class and FrameContext — foundation for the render graph.
RenderPass is a concrete base class with no-op defaults (not abc.ABC) to avoid
ABC construction overhead and clutter. Subclasses override what they need.
"""
from __future__ import annotations
from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
import numpy as np
from .render_context import RenderContext
__all__ = ["RenderPass", "FrameContext"]
[docs]
class FrameContext:
"""Per-frame state passed to render passes during record().
Built once per frame by ForwardRenderer, then passed to every pass.
Packs all per-frame state so passes don't chain through engine attributes.
"""
__slots__ = (
"frame_index", "width", "height", "delta_time",
# Camera (from first viewport)
"camera_view", "camera_proj", "camera_pos",
"inv_vp", "near", "far",
# Renderer submission state
"instances", "ssbo_set", "mesh_registry",
"materials", "lights", "light_count",
"texture_descriptor_set",
"viewports",
"particle_submissions",
"gizmo_data",
)
def __init__(self) -> None:
self.frame_index: int = 0
self.width: int = 0
self.height: int = 0
self.delta_time: float = 1.0 / 60.0
self.camera_view: np.ndarray | None = None
self.camera_proj: np.ndarray | None = None
self.camera_pos: np.ndarray | None = None
self.inv_vp: np.ndarray | None = None
self.near: float = 0.1
self.far: float = 100.0
self.instances: list = []
self.ssbo_set: Any = None
self.mesh_registry: Any = None
self.materials: np.ndarray | None = None
self.lights: np.ndarray | None = None
self.light_count: int = 0
self.texture_descriptor_set: Any = None
self.viewports: list = []
self.particle_submissions: list = []
self.gizmo_data: Any = None
[docs]
class RenderPass:
"""Base class for a single render pass. Subclasses override setup/record/resize/destroy.
Class attributes (override in subclasses):
name: Unique identifier, e.g. "ssao".
stage: "pre_render" or "render" — controls which graph phase runs this pass.
inputs: Resource names consumed, e.g. ("hdr_depth",).
outputs: Resource names produced, e.g. ("ao_texture",).
"""
__slots__ = ()
name: str = ""
stage: str = "render"
inputs: tuple[str, ...] = ()
outputs: tuple[str, ...] = ()
enabled: bool = True
[docs]
def setup(self, ctx: RenderContext) -> None:
"""Initialise GPU resources. Called once at renderer setup time."""
[docs]
def resize(self, width: int, height: int) -> None:
"""Recreate resolution-dependent resources."""
[docs]
def record(self, cmd: Any, frame: FrameContext) -> None:
"""Record GPU commands for this pass. Called every frame by the RenderGraph."""
[docs]
def destroy(self) -> None:
"""Release all GPU resources."""