Earlier frames are useful data#
A current frame can contain too few samples to represent edges, reflections, or indirect light stably. Temporal methods combine information from previous frames. They improve stability when correspondence is correct and create ghosts when it is not. QubicEngine’s reference design retains previous view/projection data, previous instance transforms, motion vectors, depth, and HDR history. Current raster sampling uses a known jitter sequence. The temporal pass reprojects history into the current frame and validates whether it belongs to the same surface.
Motion is a contract#
Motion vectors encode a chosen direction and units, such as current pixel to previous pixel. Camera motion and object motion both contribute. Skinning needs previous deformed positions or an equivalent policy; using only the entity transform misses moving limbs. Projection jitter must be handled consistently when deriving motion. A new object, a camera cut, a teleported character, or a resized viewport may have invalid history. Mark those cases rather than blending them as if continuity were certain.
Reject history when it stops making sense#
Depth and normal agreement detect many disocclusions. A neighborhood clamp limits colors that no longer match the current surface. Reactive or confidence signals reduce accumulation for changing transparency or emission. The exact policy balances stability, blur, and response time. More history weight smooths noise but reacts slowly. Less history weight responds quickly but reveals sampling noise. There is no single weight that fixes every surface. Diagnostics should expose confidence, rejection, motion, and current/history contributions independently.
Reference history ownership
HistoryPair contains two persistent textures and a validity record. One stores the previous completed frame’s result; the other receives the current temporal result. Swap their logical roles at the defined frame boundary while retaining native resources through GPU completion. A resize allocates a matching pair and marks history invalid. An old pair is retired after its last-use fence. A graph pass imports the previous history resource rather than pretending it is a transient target with no earlier producer.
HDR, exposure, and tone mapping#
Lighting values stay linear in a floating-point buffer. Auto exposure estimates a scene response from a luminance distribution with temporal smoothing and a defined adaptation rate. It should not be dominated by a single bright pixel or change arbitrarily with resolution. Tone mapping maps that HDR range to the chosen display response. SDR output is encoded appropriately for the output view. HDR display output needs a different swap-chain/color-space configuration and capability checks; an HDR intermediate alone does not make the monitor output HDR. Bloom extracts and filters bright energy, then combines it in linear space. Depth of field and motion blur add their own sampling costs and artifact risks. The pass order determines which signals they receive and whether temporal reconstruction operates on stable inputs.
Costs and troubleshooting#
History consumes persistent bandwidth and storage. Full-resolution motion/depth processing can cost more than the filter arithmetic. Lower-resolution temporal paths need careful reconstruction and edge handling. Measure individual passes and retained bytes, then consider resolution or format changes. Ghosting suggests invalid motion or overtrusted history. Shimmering suggests unstable samples or insufficient history confidence. Exposure pumping suggests a noisy or poorly chosen luminance statistic. Blur after resize suggests stale history dimensions. Inspect these intermediate signals before tuning unrelated lighting parameters. The native triangle and texture samples intentionally omit temporal effects. This chapter is the larger reference renderer’s extension, with render-graph lifetimes supplying the ownership model.