simvx.graphics.renderer.taa_pass

Temporal anti-aliasing resolve pass (desktop Vulkan).

Full-screen HDR pass that runs AFTER the forward pass (and volumetric fog) and BEFORE tonemap. Each frame it:

  • samples the current (jittered) HDR colour + depth,

  • reconstructs the per-pixel CAMERA motion vector from depth + the previous view-projection (depth -> world -> prev-clip -> prev_uv), covering camera + static-geometry motion,

  • reprojects the previous resolved frame (history) through that motion vector,

  • applies a 3x3 YCoCg neighborhood AABB clamp to the reprojected history (Karis/Lottes), falling back to the current colour where the reprojection lands offscreen (disocclusion),

  • blends current vs clamped-history (~0.9 history weight),

  • writes the resolved HDR into one of two ping-pong history targets.

The renderer re-points the tonemap HDR input at this pass’s resolved output (the same descriptor-swap mechanism volumetric fog uses) ONCE, when TAA is toggled. Two persistent R16G16B16A16_SFLOAT targets: a fixed _output target the tonemap always samples (so its descriptor never flips), and a _history target sampled as last frame’s resolved result. After each resolve the output is blitted into the history target for next frame – this keeps the tonemap binding stable (no per-frame descriptor rewrite / device-wait stall) while still accumulating temporally.

Matches the web taa.wgsl resolve math (YCoCg clamp + blend) so both backends behave alike; the velocity here is reconstructed from depth rather than sampled from a precomputed velocity texture.

SCOPE: camera + static-geometry motion only. Skinned meshes / GPU particles have no prev-frame joint/particle state at this boundary, so they reproject as static (mild self-motion ghosting; camera motion still resolves). Per-object velocity (MRT + prev-transform SSBO + prev-joint buffer) is a flagged follow-up.

Module Contents

Classes

TAAPass

Temporal AA resolve over the post-forward HDR target.

Data

API

simvx.graphics.renderer.taa_pass.__all__

[‘TAAPass’]

simvx.graphics.renderer.taa_pass.log

‘getLogger(…)’

class simvx.graphics.renderer.taa_pass.TAAPass(engine: Any)[source]

Temporal AA resolve over the post-forward HDR target.

Initialization

property output_view: Any[source]

Stable colour view of the resolved HDR result (tonemap input).

setup(width: int, height: int, cur_colour_view: Any, depth_view: Any, colour_format: int) None[source]

Allocate the two history targets, UBO, descriptors and pipeline.

cur_colour_view is the post-forward HDR colour the resolve samples (binding 0); the renderer updates it per frame via :meth:set_inputs.

set_inputs(cur_colour_view: Any, depth_view: Any) None[source]

Re-point binding 0 (current HDR) + 2 (depth) at new views.

Called when the current-frame HDR source changes (fog toggled on/off, so the resolve samples the fog output instead of the raw HDR colour) or on resize. Cheap: a single batched descriptor update.

set_velocity_view(velocity_view: Any) None[source]

Point binding 4 at the per-object velocity buffer (or clear it).

Called each TAA frame by the renderer with VelocityPass.velocity_view (the RG16F per-object motion target). Passing None reverts to the sentinel dummy (depth fallback everywhere). Only rewrites the descriptor when the view actually changes, so the steady state is a flag-only update.

set_frame_matrices(inv_vp: numpy.ndarray, prev_vp: numpy.ndarray) None[source]

Stash the current inverse VP + previous VP for the next render.

render(cmd: Any) None[source]

Resolve TAA into the fixed output target, then blit it to history.

No-op when off. The output target’s view is stable (tonemap always reads it), so this pass owns no per-frame descriptor rewrite. After resolve the output is copied into the history target so next frame can reproject it.

resize(width: int, height: int, cur_colour_view: Any, depth_view: Any, colour_format: int) None[source]
cleanup() None[source]