Inverting Environment for Reflections

Started by
6 comments, last by Haptic 14 years, 8 months ago
Hey guys, I'm making some reflective water using a 2D texture (no cubemap if that makes a difference). Everything is fine except: I’m struggling to invert my environment correctly to render to the reflection texture. I want a mirror image of what's above water about the water's plane (y = 0) regardless of how I transform my terrain. I've duplicated my rendering functions for simplicity till I get it working, and in the reflected function Ive tried using glScalef(1, -1, 1) and inverting various translate/rotate parameters. The reflection doesn't match up with the terrain and also, the reflection includes what was under the water. I realise there's plenty of tutorials around - but I cant get my head around this. Thanks.
- Haptic
Advertisement
If the water surface is parallel to any axe in world space you can just do the reflection very simple. e.g:

[1.0 0.0 0.0 0.0]
[0.0 -1.0 0.0 0.0]
[0.0 0.0 1.0 0.0]
[0.0 0.0 0.0 1.0]
plane positioned in origo with Y-axe up.

mtxWVP_Refl = mtxWorld * mtxRefl * mtxView * mtxProj

Remember to flip the winding order of front-facing when you render the reflection.

If the mirror got arbitrary orientation use this formula to get the rotation matrix.

To remove underwater geometry, use a clip plane :)
Ah so thats what a clip plane is! My basic theory is sometimes not very apparent =).

As for the inversion, I'll try that now and post the results later.

Thanks alot 51mon, much appreciated!
- Haptic
an even easier way: in the vertex shader just set the world position y value to waterheight-worldpos.y...make sure to reverse culling, and clip() in the pixel above the waterline.
Ok, I have narrowed down my issue.

My actual model inversion works perfectly. The issue arises when I turn the inverted model into a texture and then map it to my water. I assume this is because my water is viewed from arbitrary angles and not straight on.

Is there anyway to ensure that what I see in the texture version, is exactly what I see in the model version - even when viewed from different angles?
- Haptic
After doing some more reading, perhaps projective texture mapping meets my needs. By face value it seems like what I want, but I don't know an awful lot about it..

If I'm wrong could you please let me know so I don't spend hours looking into the wrong thing (it couldn't hurt to learn it anyway, I suppose).
- Haptic
It's quite simple. I don't know exactly what you want to achieve :) But this should probably work for you.

* During initialization create a render target the same size as the screen.
* In the first pass render to the off-screen render target with mtxWVP_Refl as transforamtion matrix
* Then switch to the frame buffer render target. And perform the second pass in which you render all "actual" geometry.
* Have a special shader for the water surface. Use the reflective rendition you made earlier as the texture for the water.


There are two ways to obtain the right coordinates for the water surface. Either transform the vertex position in VS with mtxWVP_Refl * mtxTex. And do the texture fetch with tex2Dproj.

[0.5 0.0 0.0 0.0]
[0.0 -0.5 0.0 0.0]
[0.0 0.0 1.0 0.0]
[fHalfTexelWith fHalfTexelHeight 0.0 1.0]
mtxTex, if you are using DX9, otherwise exchange fHalfTexelWith & fHalfTexelHeight for 0.0

Or use the VPOS / WPOS register in PS, which gives you absolute texture coordinates in screen space. Then you have to normalize them (0.0 -> 1.0)
Sorry about the delay, I finally had time to try this out!
Everything now works fine, thanks for the responses.

The reason things weren't lining up properly is because I had some sneaky translations hidden in the render code which came after the glScalef(). Put everything out of whack.

Here's a picture of the final product:
Photobucket
The skybox textures were created by 'Hazel.H' from the Unreal Tournament forums.
- Haptic

This topic is closed to new replies.

Advertisement