Feature 6 – Post Mortem
Rendering moving water was by far the most difficult task that I had to do all semester. I thought that I had everything working right away, but I soon found out that the water was not properly reflecting the skybox around it. Essentially, since we were reflecting the position of the water fragment in eye-space about the normal in order to read from the skybox texture, the position of that fragment was always down the -z zxis (because in eye-space, everything that you look at is down the -z axis). Then, when we would read from the skybox texture, we would always read in whichever side of the skybox was on the -z axis in world-space, causing the water to reflect the same image regardless of the camera’s position.
I came up with a solution which involved passing the world-space position of the camera into the shaders, drawing a vector from that position to the fragment position, and reflecting that vector about the normal to read from the skybox texture. This works because the world space coordinates of the camera are not always (0, 0, 0) and this prevents whatever the camera is pointed towards as always being interpreted as if it is down the -z axis.
Fixing the issue turned out not the be the difficult part. As it turns out, I had a very embarrassing little error, in which I was not passing the world-space coordinates of my camera to the correct program shader. I didn’t catch the error until I had literally scoured the Internet and read about 4 different articles about understanding all of the different “spaces” in computer graphics. I suppose that some good did come out of all of it though. I definitely have a better understanding of the spaces now.
Anyway, my last issue was the fact that my water looked terrible for some reason. I am not sure how everyone else did it, but I eventually got it looking half-way decent by applying the marble noise texture that Dr. Johnson provided for us. Just as we all saw in the video, I used the 3D noise class provided to us, and animated my water by passing a time uniform to the shaders, which was continually updated in OnDraw().
Underneath the water!
Other screenshots…
Here is a video of my water!