Temporal re-projection for the viewport (Cycles)
I ran a few quick searches and was unable to find a open topic for this. Sorry if this is a repeat.
Temporal re-projection is a important part of achieving high quality ray tracing in games like Minecraft DXR and for the global illumination system of Unreal Engines DXR implimentation.
I would love to see this feature implemented in a production ready renderer like Cycles.
For anyone wondering what temporal re-projection is, it's a technique which allows samples from one frame to be projected onto another frames to reduce noise. Cycles already has a feature like this, but it only works while the camera is stationary. The feature I'm talking about is the ability to re-project samples between frames while the camera is moving, something much harder to do than a stationary camera.
I understand that this feature can be hard to implement for glossy and refractive surfaces as what's seen in a reflection or refraction depends on the angle you're viewing the material from, but as far as I can tell diffuse passes are simple to setup as from what I understand diffuse lighting for a surface does not change based on the angle it is viewed from.
Obviously there are some limitations in how this can be implemented while avoiding artifacts so here's a few ideas I propose.
- This is a setting that can be enabled by the user but is disabled by default.
- All re-projection information is dis-regarded if an object moves, current frame changes, or a material property is changed. This could be improved upon with future iterations of this system, but for an initial implementation I believe this is a good compromise between getting the feature into Blender and avoiding issues.
- This feature is NOT available for final renders of animations. The dis-occlusion errors will produce too many artifacts and will most likely cause many bug reports from users that don't fully understand the feature.
So, what needs to be implemented for this feature to work? From my understanding this:
- Motion vectors - This is used to tell how the objects have shifted in screenspace when the object moves. Cycles already generates these, but I'm unsure if they're usable for re-projection and whether or not they're even generated during viewport rendering.
- Dis-occlusion/occlusion buffer - A buffer that simply tells the re-projection technology which objects have been occluded or un-occluded as the camera shifts so the re-projection technology knows what's new information and what information is no longer needed.
- A re-projection technology - I'm unsure how to get a system like this to work. And hence why I'm proposing this idea to the Blender developers and community rather than developing it myself.
And as you can guess from the comments I made above, this is a feature request. I have no idea how to program this and my knowledge in programming is very limited. The chances of me learning enough to program this by the end of bcon 1 for 2.90 or 2.91 is very low. Especially with other personal projects plus the fact that I can still use Cycles perfectly fine without this technology. But having it implemented into Blender could be very useful.
As for white papers and resources on how this technology may work, I'm unsure where to point you. If I was to take a guess many of the technologies applied to temporal anti-aliasing will also apply to temporal re-projection. Also the white paper on the Spatial-temporal Variance Guided Filtering may have some useful information.
2 Comments
Current denoisers (AI or whatever) miss out on a huge speed up potential when they ignore the temporal samples. This currently makes Cycles 3 times slower (requiring more spacial samples) for animation.
With temporal samples, there is great potential for animation frames to be rendered faster than stand alone stills. Optical flow for example, can generate 60Hz from 30 Hz very inexpensively (used in most TVs). Cycles and Eevee already has access to far more accurate motion vectors.