Post 123

Too Still to See

Depth of field, ambient occlusion, and any post-FX downstream of a still scene would quietly go black a few seconds after you stopped touching the patch. The engine mistook stillness for abandonment. It no longer does.

Three spheres at different depths, correctly blurred by depth of field

Park the camera, dial in a depth-of-field look, and stop moving anything, and within a few seconds the blur you built vanished. Not glitched, not corrupted. Gone, replaced by the clear color, as if the DOF node had never existed. Ambient occlusion did the same thing. So did anything else sitting downstream of a scene that had stopped changing.

The scene itself was fine the whole time. RenderScene redraws every frame regardless, camera locked or not. The DOF node downstream of it, though, is not obligated to redo work when its inputs haven’t changed, and once focus distance and the color/depth textures feeding it settle, it stops. That’s the entire point of dirty-tracking: don’t waste a frame recomputing an unchanged blur.

The engine’s per-frame cleanup didn’t know that “stopped re-computing” and “no longer needed” are different things. It watches for textures nobody mentioned this frame and hands them back to the pool for reuse, which is exactly the right instinct for a shader that mints a fresh texture every tick and never explains itself. DOF sitting quietly on last frame’s answer looked identical from the cleanup’s seat: silence. So it reclaimed the texture the image on your screen was still built from, out from under it, while the output still pointed straight at it.

Silence is not surrender

The fix teaches the cleanup pass the difference: before it reclaims anything, it now checks what the frame you’re about to see is actually drawing, not just what ran this tick. A texture named there survives, whether or not its node had anything new to say this frame. A second, slower version of the same mistake was hiding a few seconds further out, an idle sweep with its own “hasn’t been touched in a while” rule, which used exactly the same silence to reach exactly the same wrong conclusion on a longer clock. Both now know a resting filter is still on duty.

Before, a few seconds after the scene stopped moving:

Depth-of-field scene rendered black after settling

After, same patch, same wait, still there:

Depth-of-field scene rendering correctly after settling

Nothing about the churn itself changed. Filters that mint a new texture every frame still get recycled exactly as before, and the allocation floor on a stress patch measures identical down to the count. The only thing that changed is that going still no longer reads as going away.

← All posts