Deferred shading and planar reflections

Zeross

Regular
I'm currently working on a deferred shading renderer, everything is progressing well and the architecture is clean : decoupling geometry from lighting is really a big win IMO. But some effects really simple in a forward renderer become suddenly a lot more challenging : antialiasing and transparency for example. Of course I was aware of that but one thing I totally overlooked were reflections. You know the saying ? "If you can't make it good, make it shiny" ;) in my experience it's true : reflexions add a lot to the perceived quality of a scene by an "average" user.

I've used two techniques in my previous (forward) renderers : one using the stencil buffer and a mirror matrix, really simple and the effect looks good but it's only OK for a perfect (mirror-like) reflection. The other one with projective texturing which allows things like perturbating the reflexion along the per-pixel normal and blurring it.

But in a deferred renderer I can't see how to implement simple planar reflections without ending with a solution prohibitively expensive. I've tried to look for some papers, I'm sure there may exist some hacks that should do the trick even if it's not exactly correct but I haven't found anything interesting.

I was wondering how you were doing it for things like water or a shiny ground and if you could point me to some papers on the subject.

Thanks !
 
You can render the mirrored objects to your g-buffers just like you would do in your forward renderer (by using clip planes and stencil culling). However you have to mark the mirror pixels in some way (stencil buffer or g-buffer channel), so that you can calculate the surface positions correctly later in your lighting pass. Assuming of course that you calculate the surface position from the depth buffer. Create a matrix to convert the view space position to the mirror space and use this matrix to do the tranformation for the pixel... or transform the mirrored lights (saves GPU cycles, since you can do this once with CPU).

If you are rendering the lights as convex objects, you need to render the lights in the mirror space as well. Stencil clipping + clip plane clipping light objects is likely be the best choice here. Also remember to stencil clip out all the non mirrored lights from the mirror areas.
 
In that Crysis 2 DX11 patch they added screen space reflections. They probably just march through the depth buffer along the reflection vector until they find a potential intersection, and then sample the color buffer at that point. It obviously falls apart when something (like your gun) occludes the source of a reflection or if it's not in the camera's field of view, but on the upside you can get perturbed reflections on arbitrary surfaces without resorting to additional render targets.
 
That solution doesn't work very well in many cases, for the reason you pointed out. If it isn't already on the screen it won't be reflected. Though when it does work it works well and is pretty inexpensive apparently.
 
Back
Top