Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Quaternion Water Reflection

Started by ultimastrike Mar 7, 2009 at 1:38 PM 3 replies 1k views
Original Post
ultimastrike
ultimastrike
Hello all. I have made a lot of progress from my last post here, but I have encountered another snag. I've been following Reimer's tutorial on terrain, and am trying to create water reflections. I've done his jpg output debugging and my Refraction map looks perfectly correct. My problem is with the reflection map. The difference between my code and his is that I'm storing my camera's orientation in a quaternion whereas he has a simpler implementation, so I am having difficulty figuring out how to get the reflection camera. I understand that I need Camera B's position, target and up vector. This is the code I have to figure them out based on the camera's Orentation quaternion. Note that Camera A is an orbit camera, so its target is always player1.Position.

            Matrix cameraRotation = Matrix.CreateFromQuaternion(camera.Orientation);
            Vector3 cameraFinalTarget = Player1.Position;

            Vector3 reflCameraPosition = camera.Position;
            reflCameraPosition.Y = -camera.Position.Y + waterHeight * 2;
            Vector3 reflTargetPos = cameraFinalTarget;
            reflTargetPos.Y = -cameraFinalTarget.Y + waterHeight * 2;

            Vector3 cameraRight = Vector3.Transform(new Vector3(1, 0, 0), cameraRotation);
            Vector3 invUpVector = Vector3.Cross(cameraRight, reflTargetPos - reflCameraPosition);

            reflectionViewMatrix = Matrix.CreateLookAt(reflCameraPosition, reflTargetPos, invUpVector);
I have tried to model the code Reimer uses in his UpdateViewMatrix function, but I can't seem to get it to work right for quaternions. I get endlessly repeating patterns of little sky ovals stretching away into the distance between huge black bands. Is this enough information, or should I post a screenshot?
ultimastrike
ultimastrike
I guess this is a pretty specific subject, heh. Not a lot of people must know how to do this, or it must be so dumb that no one ever does do it.
Zakwayda
Zakwayda
I don't know enough about the context to say for sure what's wrong, but this line looks a little suspicious:
Vector3 invUpVector = Vector3.Cross(cameraRight, reflTargetPos - reflCameraPosition);
Unless there are constraints in place that aren't evident from what you posted, invUpVector won't necessarily be unit length, in which case the view matrix will most likely be incorrect.
ultimastrike
ultimastrike
Currently I am using this code, which is much simpler but seems to yield the same results:

Vector3 reflectPos = camera.Position;
Vector3 reflectForward = camera.ViewDirection;
reflectForward.Z = waterHeight - (reflectForward.Z - waterHeight);

reflectionViewMatrix = Matrix.CreateLookAt(reflectPos, reflectPos + reflectForward, new Vector3(0,0,1));

This is an image of the results:

Failed Reflection

These are screencaps of the Reflection map and the Refraction map. As you can see, the refraction map is correct but the reflection map is bonkers.

Reflection Map

Refraction Map
ultimastrike
ultimastrike
I'm a lot closer, but it still isn't right. I get sky and land reflections, but they seem to be upside down! This is what I'm working with now.

Vector3 reflectPos = camera.Position;
Vector3 reflectForward = camera.ViewMatrix.Forward;
reflectPos.Y = -reflectPos.Y + 2 * waterHeight;
reflectForward.Y = -reflectForward.Y + 2 * waterHeight;

reflectionViewMatrix = Matrix.CreateLookAt(reflectPos, reflectPos + reflectForward, camera.ViewMatrix.Up);

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.