simvx.graphics.renderer.light2d_pass¶
2D light accumulation pass: renders Light2D nodes as additive radial gradients.
Renders each light as a screen-space quad with radial falloff. The accumulated light texture is provided to Draw2DPass for final compositing (multiply blend).
Shadow casting (desktop, POINT + DIRECTIONAL lights) follows the FROZEN Phase-0
spec (shadow_ref.py). Three GPU stages, run only when a frame has at least
one shadow-casting light AND at least one occluder:
S1 rasterise occluder triangles into a screen-sized R8 coverage mask
(light2d_occluder.*).
S2 build a 1D shadow atlas (R16F, W columns x MAX_SHADOW_LIGHTS rows): each
shadow light ray-marches the occ mask into its own row
(light2d_shadowmap.*, one draw per light into a 1-px viewport strip).
S3 the disk fragment shader (light2d.frag) PCF-samples its atlas row and
folds visibility into the lit colour.
When no light casts a shadow the atlas/mask are never allocated and every light
pushes shadow_row = -1 -> byte-identical to the pre-shadow path.
Module Contents¶
Classes¶
GPU pass that renders 2D lights to an offscreen accumulation texture. |
Data¶
API¶
- simvx.graphics.renderer.light2d_pass.__all__¶
[‘Light2DPass’]
- simvx.graphics.renderer.light2d_pass.log¶
‘getLogger(…)’
- simvx.graphics.renderer.light2d_pass.PUSH_SIZE¶
88
- simvx.graphics.renderer.light2d_pass.OCC_PUSH_SIZE¶
8
- simvx.graphics.renderer.light2d_pass.SM_PUSH_SIZE¶
32
- simvx.graphics.renderer.light2d_pass.SHADOW_MAP_RESOLUTION¶
256
- simvx.graphics.renderer.light2d_pass.MAX_SHADOW_LIGHTS¶
16
- simvx.graphics.renderer.light2d_pass.RAYMARCH_STEPS¶
256
- simvx.graphics.renderer.light2d_pass.N_PCF¶
5
- simvx.graphics.renderer.light2d_pass.MAX_GRADIENT_SETS¶
32
- class simvx.graphics.renderer.light2d_pass.Light2DPass(engine: Any)[source]¶
GPU pass that renders 2D lights to an offscreen accumulation texture.
Usage from the forward renderer: 1.
begin_frame(): clears per-frame submission lists 2.submit_light(...)/submit_occluder(...): queue data 3.render(cmd, extent): render all lights to accumulation RT 4.get_light_texture_view(): returns the image view for compositingInitialization
- submit_light(position: tuple[float, float], colour: tuple[float, float, float], energy: float, light_range: float, falloff: float = 1.0, inner_radius: float = 0.0, falloff_gradient: Any = None, blend_mode: str = 'add', shadow_enabled: bool = False, shadow_colour: tuple[float, ...] = DEFAULT_SHADOW_COLOUR, shadow_softness: float = 1.0, light_type: str = 'point', direction: tuple[float, float] = (0.0, -1.0)) None[source]¶
Queue a light for rendering this frame.
falloff_gradientis an optional 1-D intensity LUT (float array in[0, 1]) that overrides the analytic falloff; it is uploaded as a 1-row texture and sampled by the remapped distance.light_type/directiondescribe the light for shadow casting."point"builds/samples a radial shadow map;"directional"builds an orthographic 1D map alongperp(direction)and renders a flat fullscreen contribution.
- submit_occluder(polygon_vertices: list[tuple[float, float]]) None[source]¶
Queue an occluder polygon for shadow casting this frame.
- render(cmd: Any, extent: tuple[int, int], lights: list[dict] | None = None, occluders: list[list[tuple[float, float]]] | None = None) None[source]¶
Render all queued lights to the accumulation render target.
Must be called outside the main render pass (in pre_render phase).
lights/occludersdefault to the liveself._lights/self._occluders(the synchronous path). In pipelined mode the render thread passes the packet’s OWNED snapshots so it never reads the live lists the main thread is concurrently rebuilding.