Screen Space Reflections

Started by
16 comments, last by cowsarenotevil 10 years, 10 months ago

I have a lot of small water surfaces that can be visible at once in my scene that can lie on different plane heights. Currently I am doing a full reflection pass for each one (rendering the scene from a mirrored camera). However, this increases my total per frame draw count a lot and is hurting my performance. I am looking at two solutions: Static cube maps for reflections (won't handle dynamic objects), but should be good enough since the water surfaces are small. I'm also looking into screen space reflections that Crytek uses. The two main issues I see with screen space reflections are:

1. The reflection vector shoots off screen so we have no info.

2. False reflections due to only have depth info.

Does anyone have any experience with screen space reflections? How do they work for planar surfaces (like water where there will be some wave distortion)? Any other issues than the above 2 I mention?

-----Quat
Advertisement


1. The reflection vector shoots off screen so we have no info.

Maybe you can use a "clamp" texture addressing mode so you just get the value at the edge? Or do it manually such that the transition is a little smoother (not sure how to explain it properly, but have your texture coordinates "slow down" as they approach the edge of your screen texture).

I'm not sure it would suit your needs, but I use a technique that stores the elevation angle of surrounding terrain (and possibly objects) for each water vertex. It's very limited: no dynamic objects, and the reflection has no details in it (it just results in the water being a darker shader), but it comes at very little perf impact:

http://mtnphil.wordpress.com/2012/09/12/faking-water-reflections-with-fourier-coefficients/

http://mtnphil.wordpress.com/2012/09/15/water-shader-follow-up/

http://www.guerrilla-games.com/presentations/Valient_Killzone_Shadow_Fall_Demo_Postmortem.pdf

http://www.guerrilla-games.com/presentations/Drobot_Lighting_of_Killzone_Shadow_Fall.pdf

New Killzone have three different methods for reflections. First screenspace reflection is used and if that fails then it try to find is that point inside of static local cube map AABB and use that instead. If both these fails global skycube is used. Add some smooth tweening instead of binary fail and result should be good enough in most cases

SS Reflections work really, really good for water (lakes, river, puddles) because of the Fresnel effect: It's most reflective when perpendicular to the view vector (which means there's plenty of depth information available) and is translucent when looking straight into it (which is when you have the least or even no relevant depth information on screen)

For the rest of the surfaces, "it depends". There's a lot of factors coming into play, which boil down on how much of the screen they occupy, blocking all of the surrounding; and their normal relative to the view's.

Also another alternative is to use hybrids:

  1. Pick between static map and SS reflections for far objects.
  2. Use real time updated env. map (or planar map reflection) for closest objects.

I've never seen screenspace reflections work "very well". By its very nature you are missing any and all information not directly onscreen, and anything but purely reflective (zero roughness in whatever BRDF you're using) will also be problematic, as you vastly increase the chance your sample isn't onscreen.

SS reflections can work OK in the case of rain as a kind of planar reflection hack on the ground, where it's not too noticeable that you're missing a ton of reflectivity, you've got a layer of water for reflectivity you don't have to take roughness into account for, and you've got a strong fresnel effect hiding everything as well. But playing around with it, it's not really a "solution" for reflections, just a nice piece of eye candy you have to control very tightly (or compensate for at every turn ala Killzone).

Even on a lake or other body of water, you've got strong reflections a lot of the time, if your player can control the camera they'll say, look down at the water and as they do far reflections will just clip out entirely as the reflected areas leave screenspace before the water reflecting them does, and you'll just have a blank area where reflections should be. And that's just one scenario that will happen all the time. It's a rather ugly hack all in all.

I see screen space reflection more an occlusion technique for ambient speculars than reflection technique.

Basically stripped down version would just check reflection ray against depth buffer to determine is ambient specular cube used or not.

Thanks for the feedback. It seems simple enough to implement and try. I'm going to try a hybrid of screen space and local cube map reflections. If it works, it would be a huge savings not to redraw the scene for water surfaces on different planes.

I do have one implementation question. When I compute the reflected ray in view space (by reconstructing the view space position from the depth map and sampling the normal map), I need to march along that ray and test againt the depth buffer. My question is, what should be the ray march step size in view space? Would it basically be MaxNumSamples / FrustumLength? That seems like a pretty big step unless there are a lot of samples.

-----Quat

I've never seen screenspace reflections work "very well". By its very nature you are missing any and all information not directly onscreen, and anything but purely reflective (zero roughness in whatever BRDF you're using) will also be problematic, as you vastly increase the chance your sample isn't onscreen.

SS reflections can work OK in the case of rain as a kind of planar reflection hack on the ground, where it's not too noticeable that you're missing a ton of reflectivity, you've got a layer of water for reflectivity you don't have to take roughness into account for, and you've got a strong fresnel effect hiding everything as well. But playing around with it, it's not really a "solution" for reflections, just a nice piece of eye candy you have to control very tightly (or compensate for at every turn ala Killzone).

Even on a lake or other body of water, you've got strong reflections a lot of the time, if your player can control the camera they'll say, look down at the water and as they do far reflections will just clip out entirely as the reflected areas leave screenspace before the water reflecting them does, and you'll just have a blank area where reflections should be. And that's just one scenario that will happen all the time. It's a rather ugly hack all in all.

You've made your dislike of SS reflections pretty well known at this point, but I really can't agree with you. Yes, they aren't perfect. Neither is SSAO, for the exact same reasons, and yet SSAO is infinitely better than no AO, which is why just about every game now uses it. The same goes for reflections.

The reflections in Killzone 4 look pretty amazing, thanks in part to their use of SS reflections.

I've never seen screenspace reflections work "very well". By its very nature you are missing any and all information not directly onscreen, and anything but purely reflective (zero roughness in whatever BRDF you're using) will also be problematic, as you vastly increase the chance your sample isn't onscreen.

SS reflections can work OK in the case of rain as a kind of planar reflection hack on the ground, where it's not too noticeable that you're missing a ton of reflectivity, you've got a layer of water for reflectivity you don't have to take roughness into account for, and you've got a strong fresnel effect hiding everything as well. But playing around with it, it's not really a "solution" for reflections, just a nice piece of eye candy you have to control very tightly (or compensate for at every turn ala Killzone).

Even on a lake or other body of water, you've got strong reflections a lot of the time, if your player can control the camera they'll say, look down at the water and as they do far reflections will just clip out entirely as the reflected areas leave screenspace before the water reflecting them does, and you'll just have a blank area where reflections should be. And that's just one scenario that will happen all the time. It's a rather ugly hack all in all.

You've made your dislike of SS reflections pretty well known at this point, but I really can't agree with you. Yes, they aren't perfect. Neither is SSAO, for the exact same reasons, and yet SSAO is infinitely better than no AO, which is why just about every game now uses it. The same goes for reflections.

The reflections in Killzone 4 look pretty amazing, thanks in part to their use of SS reflections.

Oh certainly, with a lot of help they're ok. Just using it by itself though is the problem, as I said that lake scenario would cause any player to just shake their head sadly. And if you're going with screen space reflections and cubemaps, you'll do a lot better, but your scene is now mostly static by default.

I guess I'd just like a really good engineering solution, something that you can say "ok, this works for everything everywhere all the time" and you don't need X to back it up. But until then, if you're doing something like Killzone, then it can look solid enough.


I guess I'd just like a really good engineering solution, something that you can say "ok, this works for everything everywhere all the time" and you don't need X to back it up.

I think path tracing meets that criteria. wink.png

It is sort of like Heisenberg's uncertainty principle in a way. You can't have a general solution that works well for all scenarios and is computationally cheap at the same time.

This topic is closed to new replies.

Advertisement