thumbnails | next

causticsSceneBig_2.JPG

clig for bick

Copyright © Tom Kluyskens 2001

 

 

 

 

The light patterns on the walls and floor are called 'caustics' and are the result of light being reflected or refracted by different types of surfaces. Look in your coffeecup, and you'll most likely see a heart-shaped caustic pattern, result of light reflecting on the cup's inside walls :

 

The image on top is the first caustics image ever made with Maya. At the time of creation there was no global illumination renderer available for Maya, and you typically need such an advanced renderer to create accurate caustic patterns.

So how was it done?

 

Recognize the bright dot on the floor? Same thing as what you get when you're trying to burn ants under the sun with a magnifier glass. The transparent sphere acts as a light focusser. Nice thing here is that the light doesn't come directly from the lightsource, but has been bounced off a mirror first :

 

 

If you think of light as small particles (photons) emitted by lightsources, and bouncing around the scene, caustics are really simple to understand. These particles go through the scene following straight lines (rays) that change direction when they hit a reflective or transparent (refractive) surface.

Exactly the way a raytracer follows a viewing ray (kindof the inverse direction of a lightray) through the scene. So I thought I'd use the standard built-in Maya raytracer to calculate the photon's paths through the scene.

 

More specificly, I stored the positions of where these photon rays died on the walls and floor. I did this using MEL (Maya Embedded scripting Language).

For each wall/floor surface, I created a 512x512 array, to be compared to a 512x512 pixel texture. Then I did a raytrace from the light's POV (this turns the viewing rays into lightrays). Each pixel being rendered corresponds to 1 photon, one lightray shot into the scene. If a fraction of the wall/floor surfaces turns up in that pixel (directly, or through reflection/refraction), the corresponding position in the array is incremented by 1. Thus, the parts of the surface getting the most light, would result in the highest array numbers :

global matrix $CountFloor[512][512];
int $U=(samplerInfoFloor.uCoord)*512;
int $V=(samplerInfoFloor.vCoord)*512;

$CountFloor[$U][$V] = $CountFloor[$U][$V] + 1;

This expression gets triggered automatically every time UV coordinates have to be evaluated for the floor, which is for every pixel that contains a part of the floor.

In the second pass render (final render, from viewer's POV), I read out and normalize (0 to 1) the array, and drive a black-to-white ramp with it :

if ($maxCount > 0) ramp1.vCoord = $CountFloor[$U][$V]/$maxCount;

Connect the ramp to the incandescence/illuminance of the right surface, and you get really acceptable results as can be seen above.

Maya's shading networks are powerful enough to handle this kind of situation, and still have fast renders. You can even preview the array in the interface :

 

 

Nice side-effect is that you get direct illumination and raytraced shadows for free!

Of course this was only a start, and the method was quite convoluted, so the whole thing got rewritten into a much faster plugin, which is in fact nothing more nothing less than a 3D photon map (a kindof 3D lookup table).

 

A tutorial and tech doc on this plugin is available here. So is the plugin itself.

 

Here's some more images created with the Maya Caustics Plugin :


(c) 2001 FFFP. All Rights Reserved. Square Pictures Inc.
plugin used in Final Fantasy!

 


glass by Gary Mundell

 

SnowSpikes.JPG