r/GraphicsProgramming 6h ago

Hierarchical screen-space tracing against depth buffers

Enable HLS to view with audio, or disable this notification

Dear r/GraphicsProgramming,

Before I commence: this effect is really reserved for the reflection component of transparent materials with the refraction being screen-space as well. My gloss trace resolution is low in both SDF-BVH and HWRT approaches and the SDF-BVH one produces blocky reflections which is not a good fit here.

So my engine already had a screen-space tracing approach. But it was fetching world positions from the gather resolve pass which was incredibly slow and sampling pressure heavy. It would sample world positions along a screen-space ray until said position would form a unit vector against the origin that was very directionally similar to the reflection vector. It had to do this for hundreds of fragments for the reflections to not cut-off prematurely. Which prompted me to gimp it to 10 iterations and relax the similarity requirement for the recent release, effectively killing the feature.

Having had to spend the last almost 3 years gutting Unreal for work, I was intrigued by how they simply just traced against the depth buffer. Additionally, their hole skipping approach via using coarser depth tiles was saving them tons of needless sampling. So these past couple of days I set out to produce something similar:

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe

The first thing I had to change was my depth mipping approach. I now had to effectively generate both MinZ and MaxZ depth pyramids. Previously only MaxZ would be generated (MinZ for the visibility buffer pass since it used ReverseZ):

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe#diff-5a79aee1ef1f826152e0b4ba07cfdced0a1956f2d60fdc82cf631f01c25f7dc4

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe#diff-da568e877110744c46e4bff11a4e3d6bff89e95d440085883e3e7b2ec6c6e297

The second thing was to effectively trace the 32x32 mip and capture hits within some threshold (0.006 to be specific):

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe#diff-60cfbc940e6376b2eeb022453df681a66e4a50b29d0a621cc34192b9238a2e5bR212-R230

If a hit was found, proceeding to step back and continue tracing the 64x64 mip within a smaller threshold (this really is my highest depth mip resolution before the full depth buffer):

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe#diff-60cfbc940e6376b2eeb022453df681a66e4a50b29d0a621cc34192b9238a2e5bR232-R255

And finally, trace against the actual thing in case there's a hit with the 64x64 mip:

https://github.com/toomuchvoltage/HighOmega-public/commit/d304558dacbf495f286301bfc198e3f67b5886fe#diff-60cfbc940e6376b2eeb022453df681a66e4a50b29d0a621cc34192b9238a2e5bR257-R274

Now the trace loops aren't water-tight. Which brings me to this paper: https://jcgt.org/published/0003/04/04/paper.pdf . It would be interesting to implement a full on DDA approach. It would probably remove the blocky artifacts near the edge of the screen where the probability of disocclusion is high. That said, I find some of the additions in the paper quite prohibitive. Depth peeling is interesting and quite possibly reduces disocclusion by a decent amount but is also very slow.

My approach is probably closer to something like this: https://sugulee.wordpress.com/2021/01/19/screen-space-reflections-implementation-and-optimization-part-2-hi-z-tracing-method/

One of the annoying things in this approach is the fact that I'm using the mip chain from the TwoPass culling pre-pass. Which blanks out under scene changes -- as in samples the skybox only -- for 1 frame. This is due to the tracking buffer being recreated. Fixing this means generating yet another mip chain for the main pass in TwoPass and since it doesn't happen very frequently, I'm going to leave it. Curious to hear feedback. And if you liked the post, consider buying a copy of my game C.L.A.S.H :D. Which runs on the same engine: https://store.steampowered.com/app/4796200/

Cheers,
Baktash.
HMU: https://x.com/toomuchvoltage

27 Upvotes

2 comments sorted by

3

u/snerp 1h ago

Thanks for linking the papers you reference! Also congrats on releasing your game! I've seen your engine posts for a while now, can't wait to try it out!

1

u/too_much_voltage 1h ago

Thank you so much. Reading these gives me a lot of encouragement. Particularly now since things are a bit uncertain for me at the moment.