simvx.graphics.renderer.post_process¶
Post-processing pass: HDR tone mapping, FXAA, bloom, DoF, motion blur, film grain, vignette, chromatic aberration.
Module Contents¶
Classes¶
Renders HDR scene to offscreen target, then tone-maps to swapchain. |
Functions¶
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 touchesm[1,1]). For its orthographic,m[2,2] = 1/(f-n)andm[2,3] = f/(f-n)with a constant w row, which is what tells the two apart. Both invert asn = m23 / (m22 + 1)under perspective andf = m23 / m22under 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.Viewportcarries 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
Nonewhen 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_datais an(size, size, size, 4)uint8 array (the format produced bycolour_grading.generate_*_lut), uploaded as a 3Drgba8image: byte-for-byte the web runtime’s LUT representation. Re-registering an id replaces the previous texture. Select the active LUT withlut_tex_id.poolis 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_lutis 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 unjitteredcamera_projintact for culling and motion-vector reprojection. The jitter is stored so :meth:taa_jittercan hand it to the resolve pass.width/heightare 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_vpto 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_passand 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.