Water rendering

Since the last update, I’ve been moving into a new place. The time it’s taken has had an adverse impact on planning for the year. Originally, it wasn’t supposed to happen until the New Year, but it was accelerated and now here I am.

For the past month, I was curious about rendring water from the Game Programming Gems book (Chapter 5.11 Refraction Mapping for Liquids in Containers). Most of the time went into converting the OpenGL code into a left-handed version. Changing the chirality led to taking another pass over the operations being performed and once again checking that the outcome is correct. More tests should be written to quash these uncertanties. There was also the reliance on OpenGL’s texture coordinate generation functions that took longer than anticipated to figure out how they work. I failed to understand it well enough from the OpenGL standard, so turning to the OpenGL wiki’s Mathematics of glTexGen made everything much clearer. 3D Games: Real-time Rendering and Software Technology and Real-time Rendering were very useful for the environment mapping, too.

Quaternion multiplication may be messed up. Writing the free-look camera showed that the results were completely wrong. The skeletal animations haven’t been played through since the change, so I’m guessing that will need to be reworked.

The Kamui2 renderer also appears to be performing very inefficiently. The best approach may be to treat the updating of vertices like that of vertex shaders. Instead of a separate pass for transforming the vertices then throwing them down for rendering, immediately after the transform is complete, DMA the vertices so that by the time the transfer is complete there are more vertices that can be handled.

The basic profiler has been very useful during the process of speeding things up. It went from handling a 32x32 grid (the original was 59x59) to 40x40. Not the biggest difference in the world, and still at 30FPS. By comparison, I’m using a pair of Pentium III’s at 933MHz with a GeForce3, which handles it without any issue. Though of course, this is an unfair configuration.

Blending operations with transparency also seem to depend on auto-sorting, which is a shame as I’d like to not have it enabled for this. With eight passes available, I’m not sure if there will be any advantage to using two to implement this, but a pass to handle the 2D GUI would be handy, disabling auto-sort and just rendering without any need to worry about performance penalties.

Here are some images of the water rendering:

Still surface

Still surface

With antialiasing

Still surface (antialiased)

Now in anamorphic widescreen (this and the next image have been modified to reflect a widescreen display)

Still surface (widescreen)

Antialiased and in widescreen

Still surface (antialiased and widescreen)

The rest of the images are in 4:3 without antialiasing

Animated surface

Animated surface

Shallow angle to display the Fresnel effect

A lowered elevation to observe the surface

Elevated position, again displaying the Fresnel effect

A look at the surface from above with a hint of Fresnel

Another elevated shot

A look at the surface from above

Links to download the demo:



The PAL version is only running at 50Hz. With a VGA connection, this will improve to 60Hz.

I’d like to try and get back to the scripting language before finishing off the Pixel City demo. Plus, I think I may have to fix the way skeletal animations are handled now that the quaternion multiplication has changed. I’m tempted to cut this code out from Shambler in case anyone finds it useful, but that would be more work and it’s the same problem we find making demos while the game’s being worked on. Preferably, I would have written this in isolation from the rest of the codebase.