Distort/Shimmer Effect Respecting Depth

Started by
3 comments, last by MetaKnight 14 years, 8 months ago
I was wondering if anyone knows of a distort/shimmer effect, or anything post process effect that respects depth? So for example, when you have a heat shimmer, it'll only distort the samples behind it, and not sample from objects that are drawn in front of it? I was thinking of ether checking the depth information of the distorted pixel from the current one, or may be dumping the whole backbuffer to a render target sometimes during the scene. What's everyones thoughts and ideas?
Advertisement
You can control how a heat shimmer looks with the geometry that you use to render it. For example, a possible setup would include having the scene rendered without distortion and then copy it to a texture. Then render the geometry of what will represent the heat wave, and have it use the depth buffer comparision which should put it in the proper z-position with respect to the rest of the objects in the scene. You might end up with a little blurring around the edges of the foreground object, but that shouldn't be too objectionable.

If you wanted perfect blurring (i.e. no blurring at all on foreground objects) then you could also sample a depth buffer for your samples when performing the distortion to ensure that the sampled texels aren't closer to the camera than your heat wave geometry. That would likely be quite a bit more expensive though, so you would need to weigh the pros and cons...
The only way I know of is to draw stuff back-to-front. But that's really quite expensive, and requires several passes:

1) Find the shimmery object furthest away from the camera.
2) Render everything behind it (front-to-back)
3) Render the shimmery object on top of that.
4) Get the shimmery object next furthest away from the camera.
5) Render everything behind that shimmery object (that you haven't already rendered)
6) Go to 3)

This method will produce correct results, but for each shimmery/distort effect you want to render, it involves copying the back buffer to a texture (so you can sample from it). As you might imagine, this is very expensive if you have more than a few shimmery objects.

Most of the time, this problem is "solved" by just rendering all the distortion effects last and turning on Z-testing. This will ensure that a distortion effect will be occluded by objects in front. But you'll still come across this problem:



The space around the ship is being distorted inwards towards the centre. This shader effect was done just by rendering a quad with a shader, in front of the space ship. Even though the quad itself is occluded by the character in the foreground, the shader (running on the un-occluded parts) is still sampling pixels from it.

In most instances, this is an acceptable result as the amount of distortion is usually low. This is only a "good enough" solution, but I don't know of any perfect solutions that are fast enough for realistic use.
NextWar: The Quest for Earth available now for Windows Phone 7.
What I have done in the past and seen other games do is sample the depth of the source pixel, and if it's too far in front of the destination pixel, do nothing (no distortion at that location). If the amount of distortion is independent of depth, this works pretty well, although there are some artifacts if you look closely. It's pretty easy to set up if you have a deferred renderer or can sample z depth in some fashion--otherwise painful.

edit--Actually what I referring to here was more specific to water, where there's a surface closer than which you don't want to sample. For heat shimmer this is probably useless. Sorry about that.
Thanks guys, I guess sampling the depth is the only viable solution. But like you guys said, it's probably doesn't create very noticeable artifacts

This topic is closed to new replies.

Advertisement