-
Concept: Temporal Accumulation
-
Core Idea
- Reuse samples from previous frames to increase effective sample count
- Frame N has 1 spp, but after 64 frames: 64 effective spp
- Free quality improvement — no extra ray tracing cost
-
Basic Algorithm
- Exponential moving average (EMA)
accumulated[t] = lerp(accumulated[t-1], current[t], α)
α = 1/N where N = number of accumulated frames
α = 1.0 → no accumulation (current frame only)
α = 0.1 → blend 10% new, 90% old (slow to respond to changes)
- Running average (exact)
accumulated[t] = (accumulated[t-1] * (N-1) + current[t]) / N
- Exact average of all N frames
- Problem: N grows unboundedly — old frames from different scene state
-
Motion Vector Reprojection
- Camera and objects move between frames
- Must find where current pixel was in the previous frame
- Motion vector:
mv = current_uv - previous_uv
- Reprojection:
prev_uv = current_uv - motion_vector
- Sample previous accumulation buffer at
prev_uv
- Bilinear interpolation for sub-pixel accuracy
- Computing motion vectors
- For static objects: only camera motion
prev_clip = prev_view_proj * world_pos
mv = (current_ndc - prev_ndc) / 2 (in UV space)
- For dynamic objects: object transform also changes
- Store previous frame’s transform per object
prev_world_pos = prev_transform * local_pos
-
Blend Factor Tuning
- High blend factor (α = 0.5): responsive but noisy
- Low blend factor (α = 0.05): smooth but slow to update, ghosting
- Adaptive blend factor: increase α when rejection detects stale samples
- Typical:
α = 0.1 for stable regions, α = 1.0 for rejected pixels
-
Variance Estimation
- Track variance of accumulated samples for denoiser guidance
- Online variance:
var = E[x²] - E[x]²
- Accumulate both
sum and sum_sq over time
mean = sum / N, variance = sum_sq/N - mean²
- Used by SVGF to guide spatial filtering strength