next up previous contents
Next: Light Source Shaders Up: Get Your Hands Dirty Previous: Caustics   Contents


Baking

Larry Gritz described at SIGGRAPH 2002 ``A Recipe for Texture Baking'' in course 16 called ``RenderMan in Production''. In the same course Hayden Landis, working for Industrial Light + Magic, described several ``occlusion'' passes in ``Production-Ready Global Illumination''. At that time PRMan didn't support global illumination (GI) and Landis basically showed how to fake certain effects of GI.

Today a lot of renderer do support GI but it might be still worth to invest some time to think about efficiency. The problem with GI is that most of the time you will end up with flickering in an animation because the solution might be slightly different from frame to frame.

The image in figure 20 shows the Chrysler Building rendered with a renderer called Lucille35. The renderer is in very early development but it allows you to render RIB files using geometry with only triangle polygons. Which means that you can't easily render RIB files from production yet but on the other side the examples coming with Lucille can be modified to render with other RenderMan compatible renderers and we can use them to test the techniques described at the SIGGRAPH course and compare rendering times, quality, etc. with the results from Lucille.

Even if the baking process takes quite a long time it might be worth to do it if you can reuse the baked information for a whole sequence. Larry Gritz' arguments why you might want to bake complex computations into texture maps were:

The process described in the SIGGRAPH paper was quite technical and showed how to implement the baking by writing ``DSO Shadeops''36. The main reason for that is that in the shading language of RenderMan you can't open files. In mental ray this would be easy because the shading language is using C or C++ anyway. I use this technique quite often to dump any information needed later in a shader to a binary file, read the information in the init phase of the shader, attach it to the state as user data, and reuse the information in the main shader.

In the meantime a lot of renderers support baking natively. For example SiTex Graphics offers a special version of their renderer AIR called BakeAIR for especially the purpose of baking and mental ray 3.0 supports ``light mapping'' for similar reasons.

Before I show a few examples how to bake information with BakeAIR I want to go back to the example I mentioned earlier. In the part called ``Production-Ready Global Illumination'' of the SIGGRAPH course the author talks about both HDR37 images and ambient occlusion.

Figure 20: Chrysler Building rendered with Lucille
\includegraphics[scale=0.5]{lucille.ps}

I just took the example coming with Lucille and changed the RIB file a bit to use it with a renderer called 3Delight38. With 3Delight there comes an example how to use HDR images and I just added the commands necessary to use a light probe as an environment map and to add some ambient occlusion to the result. It makes a big difference to the picture you would get with just the defaultsurface shader. And it's rendered with just one pass.

Figure 21: Chrysler Building rendered with 3Delight
\includegraphics[scale=0.5]{3delight.ps}

The steps necessary are quite simple. First I removed all Surface lines, the AreaLightSource and all lines the renderer was complaining about from the original RIB file. This allows me to render without any lights using the defaultsurface shader. Then I added the following lines for 3Delight:

Attribute "visibility" "transmission" "opaque"
LightSource "envlight" 3 "float samples" 32
            "string envmap" "grace_probe.tdl"
            "float Kenv" .5 "float Kocc" 0.5
Surface "matte" "float Kd" 0.5

Objects contributing to occlusion have to be tagged as visible to transmission rays. This is done by the first line. The ambient occlusion is calculated by the light shader envlight. Have a look at the implementation of the shader. The same shader takes the HDR image, which was downloaded from http://www.debevec.org/Probes and converted to a texture, as an environment map to light the scene purely based on that image. AIR has a very similar shader with the same name but different parameters. I didn't try the HDR image with AIR but I checked the ambient occlusion with the following line39:

LightSource "envlight" 3 "float occlusionsamples" 32

Unfortunately we can't use this example easily to demonstrate baking with BakeAIR because polygons and subdivision surfaces lack a natural coordinate system for 2D textures. If the model would have been made of NURBS it would be easier to bake the ambient occlusion. Nevertheless ambient occlusion can be used with polygons without baking it and there are examples coming with BakeAIR which demonstrate how to bake with NURBS surfaces. An interesting example how to bake displacements can be found online at the following two addresses:

http://www.drone.org/tutorials/displacement_maps_air.html
http://www.seanomlor.com/owenr

Figure 22: Baked normals and positions of a head
\includegraphics[scale=0.5]{head1.ps}

The idea is to use a low-res version of a subdivision surface and measure the distance to a high-res version. Once that information is baked you can render the low-res version and use the baked information to displace it back to the original high-res version. But why would you like to do that? Well, this way you can use arbitrary shapes and morph them into each other by animating the displacement over time.

Let's have a look at one of the examples where you bake the normals and positions of a face and use them later to place hairs over the whole face. Figure 22 shows the resulting image for baking the normals on the left, and for baking the positions on the right. First you have to define for a each texture you want to create through the baking process a Display line:

Display "headP.tif" "file" "P" "quantize" [0 0 0 0]
Display "headN.tif" "file" "N" "quantize" [0 0 0 0]

The next step is to either specify a camera which will produce a tessellation during the rendering process which will be used for the baking or to explicitly control the tessellation with some additional commands:

Attribute "divide" "u" 64

Now you specified the tessellation and the filenames for the baking but you didn't say which geometry should be used. This is done by adding the following lines to the geomtry definition:

NuPatch ... "P" [ ... ]
"constant string bakemap_P" "headP.tif"
"constant string bakemap_N" "headN.tif"

Figure 22 shows the baked textures which are used to grow hair on the NURBS surface. Look at figure 23 for the result.

Figure 23: Use a procedural shader to grow hair
\includegraphics[scale=0.5]{head2.ps}

But how was the hair placed onto the head? AIR allows you to write -- beside the five standard shader types mentioned earlier -- shaders of two additional shader types: The transformation and procedure shaders. In the RIB file creating the image of figure 23 you will find at the very end the following lines:

...
  Surface "VHair" "color RootColor" [.03 .02 .01] 
                  "color TipColor" [.6 .6 .2]
  Procedure "growhair"
    "float ns" 400
    "float nt" 400
    "string Pfile" "headP.tif"
    "string Nfile" "headN.tif"
    "float height" .3
    "float width" .02
    "float vary" .2
  WorldEnd
FrameEnd

This attaches a surface shader called VHair with some parameters to the geometry which will be created by a procedure shader with the name growhair. The surface shader is coming with the AIR distribution and the compiled version of the shader was created from file which can be found in the $AIRHOME/vshaders folder. All the file in this folder were created visually by using VShade on Windows. See section 1 for a screenshot of this program. Nevertheless the file is stored in a human readable way and shouldn't be too different from standard shaders. The source code for the other shader can be found in $AIRHOME/bakeexamples/fuzz. Basically a procedure shader uses ribprintf commands to create the lines for the RIB file where the shader is called.


next up previous contents
Next: Light Source Shaders Up: Get Your Hands Dirty Previous: Caustics   Contents
Jan Walter 2004-02-09