Sign in to follow this  

Glossy Screen Space Reflections

This topic is 2036 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Glossy Screen Space Reflections

For my Game Architecture final project (@RPI), I worked on a glossy screen space reflection (SSR) tech demo. [url="http://lightway3d.blogspot.com/2012/05/glossy-screen-space-reflections.html"]Implementation details...[/url]

Video (best in 720P)

[media]http://www.youtube.com/watch?v=nSUzdBXusYs[/media] Edited by jameszhao00

Share this post


Link to post
Share on other sites
Very interesting. I couldn't see the timmings on the video but isn't this a performance killer? From what I understand, for each pixel you're casting a good deal of rays and ray casting them in screen space will require lots of sampling from the G-Buffer.

You should also use a more interesting test scene, with more complexity and lighting, to show the eye candy.

Anyway, great work! I'm curious to know more so don't hesitate to write a more detailed article on your blog about your implementation. Edited by jcabeleira

Share this post


Link to post
Share on other sites
Indeed this looks very interesting, but I'd also be interested in some performance specs

I've been looking into SSR for use in a game I'm working on, but the I always considered the performance hit too great to actually apply it
Would be nice to see how your technique performs :)

Share this post


Link to post
Share on other sites
[quote name='jcabeleira' timestamp='1336744215' post='4939295']
Very interesting. I couldn't see the timmings on the video but isn't this a performance killer? From what I understand, for each pixel you're casting a good deal of rays and ray casting them in screen space will require lots of sampling from the G-Buffer.

You should also use a more interesting test scene, with more complexity and lighting, to show the eye candy.

Anyway, great work! I'm curious to know more so don't hesitate to write a more detailed article on your blog about your implementation.
[/quote]

Thanks!

I only trace one ray per pixel. The intermediate result is extremely noisy, but you gotta live with that. The bilateral-ish blur pass smooths everything out.

Here're some pictures


[img]http://dl.dropbox.com/u/52097/ssr_pass0.png[/img]

[img]http://dl.dropbox.com/u/52097/ssr_pass1.png[/img]
I used this simple scene as SSR is quite... bad for anything complex. In the Crysis SSR videos I've seen, the reflection only contained cylindrical cans/bottles/tubes. I imagine if you're using glossy SSR in a real game, it would have to have to be for relatively rough surfaces where reflections fade out quickly with respect to reflection distance. This let's us constrain the SSR rendering to areas where we're likely to have information.

[quote name='Radikalizm' timestamp='1336750006' post='4939320']
Indeed this looks very interesting, but I'd also be interested in some performance specs

I've been looking into SSR for use in a game I'm working on, but the I always considered the performance hit too great to actually apply it
Would be nice to see how your technique performs [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]
My unoptimized, debug shader (the video) running at 1080p with no MSAA takes roughly 20 ms, evenly divided between the 2 passes (SSR and Blur). (for reflections on 3/4 of the screen). The bilateral-ish blur is a 9 tap rotated poisson disc, where I dynamically compute a gaussian weight for each tap (so probably the 2nd pass is way cheaper once you optimize it). For more details look on the blog [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

I cap myself at 30 samples per ray trace. I currently dynamically adjust the step size based on dist(actual z, desired z). You will probably also want to start out with a small step size (as the artifacts near the surface are the most visible) and increase it (to a cap). Also, you can probably get away with larger step sizes (thus more error) as the surface roughness increases.

[quote name='Bummel' timestamp='1336909108' post='4939752']
Perhaps dynamically creating a quad-tree over the depth buffer could speed up the whole process.
[/quote]

Yes you can definitely do min-max (more so the min) depth mip maps for this. I decided that glossy ssr wasn't worth pursuing so didn't implement it. Instead I'm now working on a hybrid path tracer/rasterizer techdemo [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] Edited by jameszhao00

Share this post


Link to post
Share on other sites
[quote name='jameszhao00' timestamp='1336910466' post='4939758']
I only trace one ray per pixel. The intermediate result is extremely noisy, but you gotta live with that. The bilateral-ish blur pass smooths everything out.
[/quote]

Only one sample? Impressive. I still think you could improve the blur to mask out the noise even further. Forget the poisson disc blur, not only it gives you a noisy result but the somewhat random texture sampling must be harming your performance. You should instead try applying a gaussian blur or even two passes of gaussian blur .

[quote name='jameszhao00' timestamp='1336910466' post='4939758']
I used this simple scene as SSR is quite... bad for anything complex. In the Crysis SSR videos I've seen, the reflection only contained cylindrical cans/bottles/tubes. I imagine if you're using glossy SSR in a real game, it would have to have to be for relatively rough surfaces where reflections fade out quickly with respect to reflection distance. This let's us constrain the SSR rendering to areas where we're likely to have information.
[/quote]

I have to disagree with you on that, SSR will shine on more detailed scenes because all the visual complexity will help hiding the fact that only the visible portions of the scene get reflected. The fresnel term will also help with this by forcing the reflection to show only at grazing angles. You should really try it out with a better scene. Edited by jcabeleira

Share this post


Link to post
Share on other sites
[quote name='jcabeleira' timestamp='1336987032' post='4940004']
Only one sample? Impressive. I still think you could improve the blur to mask out the noise even further. Forget the poisson disc blur, not only it gives you a noisy result but the somewhat random texture sampling must be harming your performance. You should instead try applying a gaussian blur or even two passes of gaussian blur .
[/quote]

Full gaussian blurs are very expensive in this case, as the blur is bilateral-ish and not separable (maybe you can still do it in a separable fashion... but I don't know how that would look). Temporal supersampling the reflection jittering might be a good choice though (for when nothing moves. you can't really temporally reproject reflections for motion).

[quote name='jcabeleira' timestamp='1336987032' post='4940004']
I have to disagree with you on that, SSR will shine on more detailed scenes because all the visual complexity will help hiding the fact that only the visible portions of the scene get reflected. The fresnel term will also help with this by forcing the reflection to show only at grazing angles. You should really try it out with a better scene.
[/quote]


Whether the quality is acceptable depends on the specific usage. If you have a fbx scene file that you want me to try out, please send it to me and I'll try it out [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Edited by jameszhao00

Share this post


Link to post
Share on other sites
[quote name='jameszhao00' timestamp='1336994067' post='4940021']Full gaussian blurs are very expensive in this case, as the blur is bilateral-ish and not separable (maybe you can still do it in a separable fashion... but I don't know how that would look).[/quote]When doing SS shadow/occlusion rays, I have used a separated horizontal/vertical bilateral-ish Gaussian blur ([i]even though it's actually not a separable filter![/i]).
For SSAO, at half-resolution, we took 4 samples per pixel ([i]kind-of 4 "rays", but without stepping/refinement - only 1 sample[/i]), which produced an extremely noisy result. We then bilateral blurred horizontally with gaussian-ish weights, then vertically ([i]optionally in a loop if you really want to kill the noise[/i]), and then we bilaterally upsampled back to full resolution.
Technically, it's really not correct ([i]you get different results whether you do the H pass or the V pass first[/i]), but the blur worked like a charm anyway.

As an aside that might be helpful for optimising your blur -- we only required our SSAO/SSDO effect to be applied to players in our world ([i]and not the world itself[/i]), which allowed for skipping a lot of work -- if most of your scene is non-glossy, you might be able to do the same, and then use a more expensive blur.
Our solution was to use the alpha channel to mask out these "self-shadow receivers" and then down-sampled that mask to be ~1/32[sup]th[/sup] resolution. This low-res mask is then used by a tile-classification scheme, where you break the screen up into small tiles of pixels -- e.g. at 1024*768, i can have a 32*24 mask where every mask-texel corresponds to a 32*32 area in the original resolution. When applying the blur passes, instead of using a full-screen quad, we use a grid of quads ([i]e.g. where each grid-square covers 32*32 pixels[/i]) and each quad samples the appropriate mask-texel to determine whether that quad is useful or not. If a quad isn't useful, it multiplies it's position by 0 to skip processing of any pixels in that tile. Edited by Hodgman

Share this post


Link to post
Share on other sites
[quote name='jameszhao00' timestamp='1336994067' post='4940021']
Full gaussian blurs are very expensive in this case, as the blur is bilateral-ish and not separable (maybe you can still do it in a separable fashion... but I don't know how that would look).
[/quote]

Actually, full gaussian blurs are more than appropriate for these cases. It's true they are not fully separable, but in practice they do an excelent job at removing the noise and the visual artifacts from not being separable are generally unnoticeable. Moreover, their performance is pretty good since they do coherent reads from the textures. In fact, they are already used by some people to remove the fine grained noise from effects like soft shadowmapping with randomized sampling.

Share this post


Link to post
Share on other sites
[quote name='jcabeleira' timestamp='1336987032' post='4940004']
I have to disagree with you on that, SSR will shine on more detailed scenes because all the visual complexity will help hiding the fact that only the visible portions of the scene get reflected. The fresnel term will also help with this by forcing the reflection to show only at grazing angles. You should really try it out with a better scene.
[/quote]

More complexity just guarantees that you have more places where a screen-space algorithm will fall completely flat on its face, due to the fact that the information that you need just isn't there. The algorithm is really at its worst when you have lots of complexity causing occlusion of the surfaces you need to sample...the scene that the OP demonstrated is probably the best case scenario in that regard.

Share this post


Link to post
Share on other sites
[quote name='Frenetic Pony' timestamp='1337033161' post='4940214']
Having actually seen SSR in action with Crysis 2, I have to agree that it's just not even worth looking into. The results are far, far too inconsistent and low quality for something that, even with optimization requires a relatively huge performance hit.
[/quote]
'terribleness due to scene complexity' depends heavily on camera placement and scene structure. Imagine a third person League of Legends style camera. In that case, the scene can be complex, but because of the camera angle (almost always top-down ish from the south), the camera distance (quite far away and thus the reflection is tiny), and scene structure (minimal height complexity), SSR would do a pretty good job. Edited by jameszhao00

Share this post


Link to post
Share on other sites

This topic is 2036 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this