This image shows three views from an OpenGL refraction engine that I put
together two years ago. Do not think for an instant that it's being drawn
real time! Last I checked, getting over one frame per second is blazing
fast for the diamond model. The number of distinct images visible in your
average top or side view of a brilliant cut diamond is mind-boggling. (Note
that grey areas in the topmost image are places exceeding 31 refractions.)
Of course there is a whole host of optimizations that can be done to speed
things up, but don't expect to see this on your Xbox any time soon.
This algorithm really puts the stencil buffer through its paces. The basic
process, illustrated in the lower right image, is this:
Draw a "primary" face of the model (outlined in red) into the stencil
buffer, incrementing the previous stencil value by one.
The hard part is optimizing the algorithm so that only the faces visible in
the previous face are calculated. The number of faces tested and drawn
grows exponentially at each level of recursion, so tiny improvements in this
culling yield huge speedups. This is where the work is stalled currently;
I'm using stencil testing, scissor testing, custom clipping planes, and a
handmade polygon clipping thingy, and I'm still not happy. There is even
potential to make this viable in a real-time engine if you're willing to
cheat a little and render a simplified scene in the refractions.
Calculate the angle of refraction - or internal reflection - and apply
what amounts to a shear matrix to the current modelview transform based on
this angle and the orientation of the face being drawn.
Turn on the stencil test so that drawing only occurs where stencil ==
(recursionLevel - 1). This effectively clips the scene to the visible area
of the previously drawn face.
Draw the scene again, into refracted space. Recurse if necessary (as
shown by the green outline). If "normal" scene data is drawn, set the
stencil to zero to indicate that this area is done.
I don't have source code because it is not exactly stable for public release
yet, but there is a 75% finished HTML tutorial sitting on my hard drive
staring at me. I still plan on publishing it along with a streamlined
version of the code one of these days. If you really want to see it, drop
me a line and tell me to get working on it. The main reason this has been
collecting dust is that I have no intention of using it in the future, but
if someone wants to use it in a game or something, that will be inspiration