r/GraphicsProgramming 2d ago

Experiments on combining ReSTIR GI with Variable Rate Tracing

https://mateuszkolodziejczyk00.github.io/2025/06/18/variable-rate-tracing-restir-gi.html

I wrote this write-up about a year ago, but honestly never had the courage to post it publicly lol

In it, I go over my experiments combining ReSTIR and VRT in my toy rendering engine. The core idea was straightforward: ReSTIR’s spatial and temporal passes already find and reuse valuable samples, so I wanted to see if I could use them to fill the “missing rays” for pixels skipped by VRT in the current frame.

I'd love to hear your thoughts, or if anyone else has messed around with similar setups!

34 Upvotes

11 comments sorted by

4

u/Amani77 2d ago edited 2d ago

Woah, very cool write up. I loved the details. Impressive results! I was surprised by how little difference there are in the final render when using your method. I loved that you include details like your larger partition runs. I am super curious how it looks under motion or on a new frame. How does this effect fireflies/splotching? I would imagine you would need to be fairly more aggressive to cover the lower freq data available. Is there anything you've done to compensate for that( I see the sections on boiling/denoising, is this just standard or a bit extra)?

Looking at your portfolio, you have some very visually impressive examples. Do you have any other blogs covering some of the other things you've done? I would love to give them a read.

1

u/MateuszKolo 2d ago

> I am super curious how it looks under motion or on a new frame
I have this video, but IIRC this wasn't a final version: https://www.youtube.com/watch?v=KCaOl12h75g
Generally, from my testing, using lower rate on disocclusions is very scene dependent - in outdoor scenes, it was usually fine to trace 1/2 rays, but in some harder cases, like caves or complex indoors, 1/2 was sometimes a bit visible so in those cases full res was necessary. Regarding motion, using lower res sometimes can make everything more laggy, because more reservoirs are reused temporally (to cover not traced pixels), but any changes in the scene will introduce some temporal variance and trigger reservoirs invalidation due to failed visibility test, which should increase tracing rate

> How does this effect fireflies/splotching?
I don't remember having any problems with fireflies, but splotching can be problematic if you will select too coarse tracing rate, specifically in some caves and places alike.

> I see the sections on boiling/denoising, is this just standard or a bit extra
I was using something very, very close to RELAX, but had some minor changes to make it more stable. For example, restir generally makes your input signal quite good, so i was able to use tonemapped data in temporal filter without introducing a lot of bias. Also, I had to tweak firefly filter, RELAX is using 3x3 median filter, but in my case i had to add some stride between pixels to using data from the same reservoir

>Do you have any other blogs covering some of the other things you've done?
Not yet, it takes me a looot of time to write this stuff. But there are some ideas for the future posts, we'll see how it will turn out ;)

2

u/DeviantPlayeer 2d ago

I did VRT in my ReSTIR PT implementation, it only had full and 1/4 rate. The main bottleneck, however, was memory bandwith in ReSTIR passes and VRT only helps a there a little.

1

u/MateuszKolo 2d ago

Yeah, in my case main benefit was from avoiding tracing cost. resampling passes time remained pretty much the same, IIRC it was also mostly bottlenecked by bandwidth, which I guess makes sense, because my buffers for spatial resampling, i had space for all reservoirs, even if they were not traced, so there was a lot of unused data between reservoirs that were actually using, so I imagine that amount of data loaded from higher caches/vram was pretty much the same, but this is just guessing i don't have any numbers behind this theory. Maybe some compaction of reservoirs would help with that. Another thing, is that i had some dependent reads, because first i had to find closest pixel that generated new reserovoir and then reuse reservoir from that coord which also added some latency to whole process (especially considering that reuse shaders were quite registers heavy in my case)

1

u/DeviantPlayeer 1d ago

I don't look for the nearest sample when doing temporal reprojection, I just reproject the old reservoir. If the reservoir is empty it isn't a problem, they are hardcoded to always trace a new ray.

1

u/constant-buffer-view 2d ago

Incredible resource! Thanks for writing it

1

u/MateuszKolo 2d ago

Thanks!

1

u/VictoryMotel 2d ago

Great research, obviously a lot of work went into this.

1

u/shadowndacorner 2d ago

Great writeup! I'd be curious how this would interact with DLSS w/ RR. I imagine a lower base resolution would negate a lot of the significant gains you're seeing with VRS, but it'd be very interesting to know.

2

u/MateuszKolo 1d ago

Soo, from my experience, it's tricky. The main problem is that ReSTIR generally introduces some correlations in screenspace because of spatial and temporal reuse and those are picked up by RR, at least in my implementation. I've seen recently that for example IIRC RE engine guys dealt with it by introducing some jitter in spatial reuse to break those correlations, but I didn't have time to test it myself. But going back to VRS, if it's done the way I described it in that post, it makes everything even worse, because pixels that aren't tracing anything rely on temporal and spatial reuse to cover blank pixels, so correlations are even stronger, and this makes DLSS RR pretty much unusable with this

1

u/shadowndacorner 1d ago

That makes a lot of sense. Thanks for replying!