The caustics in the image were generated using a technique found in the Watt and Watt book, "Advanced Animation and Rendering Techniques". The procedure is as follows:
1) A heightfield representing the caustic producing water was created through the addition and normalization of several dozen sinusoids of various frequencies, phases and directions. White noise was also added to break up the caustics. The design of the heightfield represents one of the most challenging and time consuming parts of the caustic generation process as it defines what the caustics will look like later in the rendering phase. Modification of the heightfield, to add features to the caustics, necessitates the recomputation of the caustic intersections before rendering can even begin... a process that takes quite a bit of time.
2) A triangle mesh is created from the heightfield definition and the refraction of light through these triangles are calculated. The interaction between these "caustic beams" on the surface of scene objects create the caustic effect. The program defwater saves the beam definitions in a file and exits.
3) All beams are intersected with all triangles in the scene. All beams which intersect a particular triangle are stored in a list with that triangle. This procedure is an optimization step that will allow the renderer to search a subset of beams when finding the color for a specific pixel on a specific triangle. The results of this step are also saved to file so that rendering parameters and algorithms can be tweaked without recalculating the beam intersections. This additional optimization step saves hours on the rendering cycle.
4) When the color of an intersection point on a triangle is being calculated, the caustic beams are checked for intersection with the hit point. All beams which intersect the hit point add to the color of the point as if the beam was a light source.
An independent program called viewer was also created so that the status of the rendering could be checked as rendering progressed. This program was simple to create and shaved dozens of hours from the process.
Rendering time from beginning to finish on a 384MB Pentium II - 600MHz was approximately 3.5 hours on a 320x240 scene with 3x3 sampling. There were approximately 4500 triangles in the scene.