Water reflections

Started by
67 comments, last by Yann L 19 years, 10 months ago
Hey all, Well, I'm really stuck with something that I'm certain should be rather simple. I'm trying to render my terrain to texture so that I can project it as a reflection on my water surface. Now I've got no problem with the render to texture part, but setting up the view/world/projection matrices has got me stumped. I've read the VCP article here on Gamedev, but to be honest it just confuses me, in particular, the part about moving mirror vertices. Am I just being thick, but why would I want to move my mirror vertices when all I want to do is change the position and orientation of the camera to render the view from the mirrored camera position, I don't understand why vertices need to be touched at all? So basically I guess my question is how do I reflect the camera position/orientation so that it is in the correct place to render the reflection? I'm using DirectX 8.1 in case that helps. My guess would be that Camera.xPos stays the same Camera.yPos = -(y distance from mirror plane) Camera.zPos stays the same Camera orientation, clueless on this one... mm anyways I'll continue reading up and perhaps find the answer on my own, but if anyone can provide a simpler explanation than the article on how to do this, I'd really appreciate the help. Cheers, Steve AKA Mephs
Cheers,SteveLiquidigital Online
Advertisement
I'm not sure exactly what you're trying to do, but probably the easiest way to do this would be to invert the terrain's transformation matrix (so that it becomes upside down under the water) and render it again. If you render the water to the stencil buffer, then you can clip the terrain against the stencil test. You'd apply some kind of blending mode to the water, of course, so that it would be water, rather than a clean mirror [wink]
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Does inverting the geometry have the same effect as mirroring the camera position/orientation though? I'm somewhat confused by it all, but would this not produce anomalies due to the viewing angle not being taken into account? Maybe it wouldn't but like I say.... I'm confused!

Basically I'd like the camera to be mirrored in position relative to the mirror plane, with its direction vector being the same as that of a reflected light vector from the original view, dos this achieve the same effect or is it just an approximation?
Cheers,SteveLiquidigital Online
Assuming your water plane is at y = 0, and y is the up axis, then the easiest method is to simply multiply the view matrix with a mirror matrix like this one:
1  0  0  00 -1  0  00  0  1  00  0  0  1

That will flip the geometry (or the camera, it's the same, just seen from a different coordinate frame) around the Y axis.

If your plane is not exactly at y=0, then you need to adjust the translation part accordingly.
Okay, I've tried that, but didn't get the expected results. Perhaps I overlooked something. What I still don't get though, is that if it is as simple as creating a reflection matrix (which can be done with D3DXMatrixReflection), then why go into the huge number of steps taken in the Virtual Camera Position article, it just seems to be a hugely long way around the problem, or am I missing something?

Thanks for the response, and hopefully sooner or later I'll have it up and running :P

Steve
Cheers,SteveLiquidigital Online
I haven't read the article you mentioned, but there are various ways to achieve what you want. They are all conceptually equivalent, but operate in different coordinate systems. The one I mentioned (or in more general form - a simple plane reflection matrix) works in world space. So it should be applied before doing any camera dependent transforms. That's the usualy chain of transforms:

Object -> World -> *Reflect* -> Camera transform -> Projection

So yes, it's as easy as inserting a single reflection matrix in this chain. Theoretically, you can insert it anywhere you want, but it has to match the geometry's coordinate frame at that position. Inserting it after the local object to world transform, and before the camera transform, is most intuitive for water IMO. It lets you specify the reflection matrix in world space coordinates.

Can you post the matrices you use for transformation, and the order you multiply them ?
// Grab the view transformationm_Graphics->GetDeviceCOM()->GetTransform(D3DTS_VIEW, &view_matrix);// Set up a reflection planereflect_plane.a = 0;reflect_plane.b = 1;reflect_plane.c = 0;reflect_plane.d = 0;// Create a reflection matrix and multiply it with the view matrixD3DXMatrixReflect(&reflect_matrix, &reflect_plane);D3DXMatrixMultiply(&view_matrix, &view_matrix, &reflect_matrix);// Set mirrored view matrix for render to texturem_Graphics->GetDeviceCOM()->SetTransform(D3DTS_VIEW, &view_matrix);// Render terrain to texture here// Reflect the view matrix back into its original form ready to render to backbufferD3DXMatrixReflect(&reflect_matrix, &reflect_plane);D3DXMatrixMultiply(&view_matrix, &view_matrix, &reflect_matrix);// Render terrain to backbuffer here


That's pretty much what I'm currently doing, the D3DX function builds the reflection matrix for me, and creates the matrix you showed earlier (checked when debugging).


I now seem to be getting anomalies with my fog that I hadn't previously noticed, and I'm not sure if they were present before, or if it's due to the view matrix tampering, but that could be a clue?

I saw something in another thread about reversing the cullmode to get correctly rendered geometry in the render to texture, is this necessary or should I be ok with the CCW culling I'm doing at present?

Thanks!
Cheers,SteveLiquidigital Online
You left out the interesting part: how do you create the view matrix in the first place ? In that code snippet, you simply multiply the current view matrix with the reflection matrix, but the relationship between your view matrix and the camera transform is not clear. What kind of effects do you get with that code ? Does the geometry reflect ? Or what else does it do ?

About the culling, yes you need to reverse it, since you're applying a negative scale which will invert the vertex order.
Hmm, not sure what you mean there. My view matrix is created by the cCamera class, which creates the view matrix using the D3DXMatrixLookatLH function. I basically feed in a position and rotation each frame and it calculates my view matrix for me.

Aside from that, I've found what is causing the anomaly with the fog. It appears that some of the terrain I'm rendering to texture is being rendered in the backbuffer or the zbuffer (or rather perhaps it is still affecting the old buffer after making the switch) which is causing the terrain rendered to texture to occlude some of the actual terrain with the fog colour. I'm guessing that it could be that when the render to texture part does it's job, it leaves it's zwrites on the zbuffer or something like that, even though I switch back to the previous zbuffer... not quite sure why that's happening.



Above is an image of the current terrain, along with it's reflection (I've now reversed culling on render to texture). I still get the anomaly I mentioned though but I'll sort. Does it look about right?
Cheers,SteveLiquidigital Online
Quote:Original post by Mephs
It appears that some of the terrain I'm rendering to texture is being rendered in the backbuffer or the zbuffer (or rather perhaps it is still affecting the old buffer after making the switch) which is causing the terrain rendered to texture to occlude some of the actual terrain with the fog colour. I'm guessing that it could be that when the render to texture part does it's job, it leaves it's zwrites on the zbuffer or something like that, even though I switch back to the previous zbuffer... not quite sure why that's happening.

Well normally you'd ask for a render texture with it's own zbuffer. There should be no interference with the framebuffer once the switch to the RTT was made. Are you clearing the zbuffer of the RTT before use ?

Quote:Original post by Mephs
Above is an image of the current terrain, along with it's reflection (I've now reversed culling on render to texture). I still get the anomaly I mentioned though but I'll sort. Does it look about right?

Hmm. Where is your water plane in that screenshot ? It looks like the geometry is reflected around the up camera axis, unless you have the camera at water level - in that case it would be OK. Otherwise, you're doing the reflection in camera space, not in world space - a quick fix would be to reverse the matrix multiplication order from view*reflect to reflect*view.

This topic is closed to new replies.

Advertisement