simvx.graphics.renderer.post_process

Post-processing pass: HDR tone mapping, FXAA, bloom, DoF, motion blur, film grain, vignette, chromatic aberration.

Module Contents

Classes

PostProcessPass

Renders HDR scene to offscreen target, then tone-maps to swapchain.

Functions

near_far_from_proj

Recover (near, far) from a reverse-Z projection matrix.

Data

API

simvx.graphics.renderer.post_process.__all__

[‘PostProcessPass’, ‘near_far_from_proj’]

simvx.graphics.renderer.post_process.log

‘getLogger(…)’

simvx.graphics.renderer.post_process.near_far_from_proj(proj: numpy.ndarray) tuple[float, float]

Recover (near, far) from a reverse-Z projection matrix.

For SimVX’s perspective (perspective() in core.math): row-major, m[2,2] = n/(f-n), m[2,3] = fn/(f-n), m[3,2] = -1 (the Vulkan Y-flip only touches m[1,1]). For its orthographic, m[2,2] = 1/(f-n) and m[2,3] = f/(f-n) with a constant w row, which is what tells the two apart. Both invert as n = m23 / (m22 + 1) under perspective and f = m23 / m22 under either. Falls back to a sane 0.1/100 if the matrix is degenerate.

A camera’s near and far planes are nowhere else in the render path:

Class:

~simvx.graphics.types.Viewport carries only the two matrices, so anything that needs the planes recovers them from the projection here.

simvx.graphics.renderer.post_process.FLAG_FXAA

None

simvx.graphics.renderer.post_process.FLAG_BLOOM

None

simvx.graphics.renderer.post_process.FLAG_SSAO

None

simvx.graphics.renderer.post_process.FLAG_DOF

None

simvx.graphics.renderer.post_process.FLAG_GRAIN

None

simvx.graphics.renderer.post_process.FLAG_VIGNETTE

None

simvx.graphics.renderer.post_process.FLAG_CHROMATIC

None

simvx.graphics.renderer.post_process.FLAG_MOTION_BLUR

None

simvx.graphics.renderer.post_process.FLAG_VOLUMETRIC_FOG

None

simvx.graphics.renderer.post_process.FLAG_LUT

None

simvx.graphics.renderer.post_process.FLAG_CRT

None

simvx.graphics.renderer.post_process.FLAG_PIXELATE

None

simvx.graphics.renderer.post_process.FLAG_BLUR

None

class simvx.graphics.renderer.post_process.PostProcessPass(engine: Any)

Renders HDR scene to offscreen target, then tone-maps to swapchain.

The pass owns an HDR render target. When enabled:

  • 3D scene renders to the HDR target (pre_render phase)

  • Bloom extraction + blur (optional)

  • Tone mapping + FXAA + cinematic effects renders to swapchain (main render pass)

Initialization

property enabled: bool
property hdr_target: simvx.graphics.renderer.render_target.RenderTarget | None
property gbuffer_view: Any

Thin G-buffer normal/roughness view, or None when inactive.

property bloom_enabled: bool
property motion_blur_enabled: bool
property lut_tex_id: int
setup() None

Initialize HDR target and tonemap pipeline.

update_ssao_descriptor(ao_view: Any) None

Update binding 4 with the SSAO output image view.

register_lut(tex_id: int, lut_data: numpy.ndarray, *, pool: Any) None

Upload a 3D colour-grading LUT and register it under tex_id.

lut_data is an (size, size, size, 4) uint8 array (the format produced by colour_grading.generate_*_lut), uploaded as a 3D rgba8 image: byte-for-byte the web runtime’s LUT representation. Re-registering an id replaces the previous texture. Select the active LUT with lut_tex_id.

pool is the command pool the staging copy is recorded into, passed down to :func:~.colour_grading.upload_lut_3d, whose docstring says which pool each caller owes. Engine.register_lut is the tick-time entry point and hands over the engine’s upload pool with its lock held.

update_motion_blur_matrices(view: numpy.ndarray, proj: numpy.ndarray) None

Update the motion blur UBO with current inverse VP and previous VP.

Call once per frame before render_tonemap() with the current camera matrices. Uses temporal smoothing to prevent sudden jumps from frame time variance.

next_taa_jitter(width: float, height: float) tuple[float, float]

Advance the Halton jitter index and return this frame’s sub-pixel offset.

Called once per frame (only when taa_enabled) before the forward draw. The renderer applies the returned offset to the forward-draw projection via :func:simvx.core.math.apply_jitter, while leaving the unjittered camera_proj intact for culling and motion-vector reprojection. The jitter is stored so :meth:taa_jitter can hand it to the resolve pass.

width / height are the render extent; the offset is in pixels.

update_taa_matrices(view: numpy.ndarray, proj: numpy.ndarray) None

Capture the unjittered current/previous view-projection for TAA resolve.

Call once per frame (only when taa_enabled) with the clean (unjittered) camera matrices, before the forward pass jitters its own projection copy. Stores the current VP, its inverse, and rolls the previous-frame VP so the future resolve pass can reconstruct each pixel’s world position from depth and reproject it through the previous VP (camera + static-geometry motion).

Independent of motion blur so TAA functions whether or not motion blur is enabled. On the first frame prev_vp == cur_vp to avoid a velocity spike.

property taa_jitter: tuple[float, float]

This frame’s applied sub-pixel jitter (pixels); for un-jittering in resolve.

property taa_cur_vp: numpy.ndarray

Unjittered current-frame view-projection (row-major).

property taa_prev_vp: numpy.ndarray

Unjittered previous-frame view-projection (row-major).

property taa_inv_vp: numpy.ndarray

Inverse of the unjittered current VP (depth->world for resolve).

property taa_depth_view: Any

HDR target’s samplable depth view: the resolve pass’s reprojection source.

begin_hdr_pass(cmd: Any) None

Begin the HDR render pass (call before 3D rendering).

end_hdr_pass(cmd: Any) None

End the HDR render pass.

rebegin_hdr_pass(cmd: Any) None

Re-begin the HDR pass with the colour+depth LOAD variant.

Used by the scene-read pass split: after end_hdr_pass and the scene colour/depth copy, this loads the opaque colour + depth (no clear) so the transparent phase blends over the scene and depth-tests against it.

render_bloom(cmd: Any) None

Execute bloom pass (extract + blur). Call after end_hdr_pass.

render_tonemap(cmd: Any, width: int, height: int) None

Render tone-mapped fullscreen quad to current render pass (swapchain).

resize(width: int, height: int) None

Recreate HDR target and pipeline for new dimensions.

cleanup() None

Release all GPU resources.