Real-time reflections off an animated surface.

Started by
1 comment, last by GuyWithBeard 10 years, 7 months ago

Hi,

I have a dynamic mesh grid as the water surface in my game, in Unity Pro. I animate it over time to simulate waves. I would like the surface to reflect the objects rendered above and partly intersecting (floating on) the surface. First I thought about using a cubemap and standard reflection shader but that only works if the surface is flat.

Can you point me in the right direction, since I have no idea how I should start tackling this, thanks!

Advertisement

cube maps actually work worst for flat surfaces, as the reflection is usually based on the normal direction and a flat surface points into the same. depeding on your water size (ocean vs fountain), having a cubemap might lead to good results.

but for big water areas, it's common to render a reflection map, that's like rendering from the reflection view from under the water level. you then project that reflection texture to the water plane and to simulate waves, you offset the UV coordinate based on normals. that's more of a tweakable value than anything scientific.

There exists an old, old, old Geforce 6 demo which calculates the water surface perturbed by a little boat and does reflection mapping. Whitepaper here.

Note that this is not physically correct since you can only reflect/refract onto pixels that are facing the camera, i.e. some reflected rays are necessarily incorrect (a cubemap would be able to provide a much more correct result), but nobody will see the difference. It looks good enough by all means.

My body of water is big, but I though about having one reflection map or cubemap or whatever I end up using per mesh, which is currently 32x32 grid patches. That way I could cull out the ones that don't show.

You are right about the cubemap. I guess, the biggest problem here is positioning the camera from which we render it. We can of course have a height which the water is not allowed to go below, but I am still a bit unsure of how have, say, one camera positioned at the center of the water mesh creates a cube map which can be used to render the reflections correctly.

Basically, one could even do the reflection part as a very simple post-process only. Water reflections are rather distored, so as long as what you see on the water looks remotely like a wobbly streak roughly the color of something far away, you will probably believe it. Only for refractions you really need a separate map.

Cube maps, like I said, sure they are "more correct", but who cares.

Stuff like this has been around written in Java (and later on in Flash) for about 15 years, and it has of course forever been a functionality of major photo retouche programs. And although this postprocess-only technique is as pathetic as it can be (not even 3D!!!), it still looks quite convincing. You really have to look twice to notice that something is not 100% correct. And if the person doing the retouche has a little bit of artistic skill (well-chosen motif, placing waterline correctly), you don't have a chance at all. Like, virtually every photo in a typical glossy magazine.

Now when you use such a technique on an actual, displaced water surface, show me someone who will really be able to tell.

.... which reminds me of an awesome game from 1987. Sure enough these are not real reflections, but you get the idea. The sunset looks very realistic even with only 16 colors (or was it 256?) and a resolution of something like 320x200 back then. All you see is a wiggly smear that has approximately the same color as the sun, but that's good enough to be convincing.

This topic is closed to new replies.

Advertisement