mirroring surfaces

Hello,

I am thinking about mirroring surfaces such as water, in fact, I need answers to some questions.

When a surface is flat, like for example a water plane, it is quite easy: the scene can be rendered upside-down, mirrored at the height of the water plane, and later be mapped orthogonally on the finished scene.

But what to do when a surface is not flat, like a river that flows down from a mountain, or a mirroring wet curvy road that winds through a mountain range? Then, there is not one single height of the mirroring surface at which the scene could be mirrored (and rendered upside-down). Is there a technique to manage this? A simple solution would be to draw only things that are so far away that the inaccuracy would not be disturbing, like sky and clouds. But what to do if you want the whole scene to be reflecting accurately on a non-flat surface?

I guess this can not be done with environment mapping as this rather leads to pseudo-accurate results, and is not suitable for scenes where a correct reflection is neccessary? Like for example, at parts where the “normal” and the upside-down/mirrored scene match, it would look awful if this is perfectly correct.

Any ideas? Pls, I need help… :wink: Is there a secret magic technique of how to do this that I simply don’t know? Or can I simply tell the client “sorry, this is not possible”?

Regards
Jan

Today the most common solution consists in managing an environment map at the object level, storing the env map in a cube (i.e. six 2D maps) which makes it very convenient to sample from the reflection vector.
This works very well for tiny objects, typically bullets, but can’t work (or hardly works) for huge objects … unless you try to split them, but in this case you have to deal with seams which is a big problem too.

For big objects that are almost flat (like ocean with waves) there is a simple approximation which works pretty good : grab a picture of the “reflected world” and map it in eye space, with some perturbation that simulate the waves.

There has been a lengthy thread about dynamic reflections lately on the GDAlgorithms list. Maybe you want to check out.

https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list

“For big objects that are almost flat (like ocean with waves) there is a simple approximation which works pretty good : grab a picture of the “reflected world” and map it in eye space, with some perturbation that simulate the waves.”

vincoof: isn’t this more or less what I am doing? Render the scene upside down, mirrored at the height of the reflecting surface, and map it onto the screen as a 2d quad?

isn’t this more or less what I am doing?
Almost.
What I (am trying to) say is that you can perturb the texture mapping and it still “looks” ok even though it is not mathematically correct.

As a side note, for a flat plane, rendering the scene “upside down” could also be done using the stencil buffer (thus doesn’t require the render-to-texture hassle) but it has no ability to perturb the reflected scene.

Hi,

This is a tough problem, and having given is some thought in my past projects, it seems like it’s best solved in the art department.

What you can do is mirror the geometry locally subject to the height of the road closest to each object/vertex. This hard to do programmatically, but an easy job for your average summer job artist. Most geometry doesn’t have to be mirrored at all, only the parts visible in the reflections.

Then you just draw the mirrored geometry below the road, preferably modulated by a gloss map, and it’ll look ok for as long as the road doesn’t have too big height differences. You can still render the reflections to a texture if you want to perturb or blur them.

-Ilkka

That’s a lot of geometry duplication (and seems like extra processing too)… Go with the plane reflection if you can.

If it can be approximated as a plane then go with the perturb texture approach (perturbation using embossmapping or something similar). The same can be said for sphere’s and cubes (though those are mostly the same). However if it deviates to far from this shape, it will start to look weird (really violent water, or lots of changeds in the smoothness of road). You could try breaking the problem down (render different plane approximations for different sections), but that can reach a level of impracticality.

Sorry, no secret magic technique that I’ve heard of :slight_smile: . Especially if you’re trying to get accurate results.

Render you scene to the 6 sides of a cube map and use this as your reflection source. Yeah, i know, it won’t very fast but i think it’s “The Right Way™” for such reflections.

thanks for your answers :slight_smile: .

If I got the cube mapping thing right, it works as follows:

for each object in the scene that is reflecting, there is a cube map which contains the scene seen from the objects point of view. When rendering the object, the reflection vector from the objects’ surface is computed per-pixel and used as texture coordinate for this cube map, and the result is a nearly perfect reflection.

I guess this works nearly perfect for rather small objects (like the above mentioned bullets), but what if the “object” is a landscape of the size of 1000 x 1000 km (or rather, the water that covers the landscape, rivers and sea)? I am quite sure that a different technique is required for that?

Originally posted by JanHH:
I guess this works nearly perfect for rather small objects (like the above mentioned bullets), but what if the “object” is a landscape of the size of 1000 x 1000 km (or rather, the water that covers the landscape, rivers and sea)? I am quite sure that a different technique is required for that?
AFAIK those huge objects are always seas or lakes and so forth treated as flat planes with little perturbation in the texture coordinate (be it at the vertex level or the fragment level – just depends on the quality / performance ratio you expect). Even rivers can be approximated as planes, considering the planes are not horizontal. And for complex rivers with little waterfalls (like the ‘nature’ scene in 3DMark2k3) you can split your river as a group of little planes, and seams aren’t visible thanks to the waterfalls.

we are actually using the plane method (with perturbed texture coordinates), screenshots:

http://de.geocities.com/westphj2003/scene1.jpg
http://de.geocities.com/westphj2003/scene2.jpg

(note: if the links don’t seem to work, re-type them in the browsers’ text field and hit enter).

I am simply afraid that this looks awkward if the “normal” and the “mirrored” scene do not match exactly at the border between ground and water if you look at that from a close enough viewpoint. In the scene the screenshots are taken from, the water is a flat plane, but in another scene, this is not the case (rivers), and I have no idea of how to manage this then.

If the reflection precision is critical on the borders, then use a falloff 1D texture that attenuates reflection intensity when very close to the border…

Originally posted by Adruab:
That’s a lot of geometry duplication (and seems like extra processing too)…
Not really, you only need to duplicate stuff right next to a river/road, so in fact you’re drawing far less polygons than when using standard planar reflections where you mirror the entire scene. And it’s all preprocess, so the run-time costs are very low for the basic technique. In this scene, for example, rendered with an old cosmo player, the cost for the reflections was practically unnoticable.

-Ilkka

I can imagine it was unnoticeable considering the quantity of tree drawing dragging your render time down. :slight_smile:
How did you do your trees, just out of interest?

Well… Better get a VRML player and see for yourself, the model can be found at http://www.viipuringolf.fi/VG/field.wrl

Don’t get disappointed, it’s not exactly the most hi-tech solution available. Didn’t have much problems with the fps, though :slight_smile:

-Ilkka

but the water in the golf scene is perfectly planar, isn’t it?

Yes, unless you count the ponds being slighly above the lake level. But if I had an unplanar river, for example, I’d just mirror each tree by the river across the river’s height near that particular tree. That way I can get a similar effect, but with correct contact spots for all the tree reflections. The same thing can be done for the terrain too, but in the golf scene I didn’t bother, since it would’ve only had a minor visual effect.

-Ilkka