RSL
Point Clouds & Brickmaps for Ambient Occlusion


return to main index

 


Introduction

This tutorial introduces the use of point clouds and brick maps for occlusion shading. The shader, listing 1, applies unusual color tinting to the occlusion that it assigns to a surface - figure 1.



Figure 1


Listing 1


surface 
tinted_occlusion (float samples = 32,
                        sampleangle = 90.0,
                        maxdist = 1000000;
               string   bakename = "",
                        channels = "";
                color   camera_color = 1;
         output varying float _occlusion = 0;
         output varying color _Cs = 0;
         )
{
normal n = normalize(N), 
       nf = faceforward(n, I);
float  d;
  
Oi = Os;
// We have the brickmap with the pre-calculated 
// occlusion values...
if(match("bkm$", bakename)) {
   texture3d(bakename, P, n,  
                       "_occlusion", _occlusion, "_Cs", _Cs);
   }
else    // we have to calculate the occlusion
   {
   if(rayinfo("depth", d))
      {
      if(d == 0) // ...I've been hit by a camera ray
         {
         color hitc = 0;
         gather("illuminance", P, n, 
                               radians(sampleangle), samples, 
                               "surface:Cs", hitc)
            {
            _occlusion += 1;
            _Cs += hitc;
            }
         else // gather failed to hit a surface
            _Cs += 1;     
         // Calculate the averages...
         _occlusion = 1 - _occlusion/samples;
         _Cs =_Cs/samples;
         if(bakename != "")
            bake3d(bakename, channels, P, n, 
                            "_occlusion", _occlusion, 
                            "_Cs", _Cs);
         }
      }
   }
// Note: Cs is not used
Ci = Os * camera_color * _occlusion * _Cs;
}

In addition to calculating an occlusion value - or reading a previously saved value from a brickmap - the tinted_occlusion shader averages the colors of the surfaces that occlude the surface being shaded. Thus a red sphere on a white polygon causes reddish occlusion to appear on the polygon. The color assigned to an object, say,

    Color 1 0 0
    Sphere 1 -1 1 360

does not effect the color of the object as seen by the camera but, instead, causes another surface that is occluded by the object to be tinted. The shader provides a parameter called "camera_color" and it is the color assigned to this parameter that controls the visual coloration as "seen" by the camera.

The shader either reads a brickmap, if the parameter "bakename" has the file extension "bkm", or it writes data to a point cloud. The two output variables "_occlusion" and "_Cs" are provided so that secondary images ie. render passes, can be generated. The names "_occlusion" and "_Cs" have been chosen because rib files produced by mtor/maya have default display channels with these names.

The scene must be rendered twice. A pre-pass render generates a point cloud file that is subsequently converted to a brickmap in preparation for the second render - the beauty pass. The point cloud or the brickmap can be viewed using ptviewer or brickviewer. Again, Cutter is setup to automatically use these utilities. Select the name of the map you wish to view. A right mouse click or control click (OSX) will popup the menu shown in figure 2.



Figure 2


Avoiding Gaps in the Point Cloud Data

To ensure all the occlusion data will be available for later use, the "bake-camera" must be setup not only so that it views as much of the scene as necessary but that three rib Attributes are set to ensure the "bake-camera" does not ignore rear-facing or hidden surfaces. When baking the point cloud the following must be active.

    Attribute "cull" "hidden" [0]
    Attribute "cull" "backfacing" [0]
    Attribute "dice" "rasterorient" [0]

If they are not present in a rib file their default value is [1]. Figure 3 shows a point cloud rendered using the attributes shown above. Figure 4 shows gaps in the point data because is was rendered with the default attribute values for "hidden", "backfacing" and "rasterorient".


Figure 3 - a complete point cloud


Figure 4 - an imcomplete point cloud.


Because the camera_color parameter to the shader in listing 1 plays no part in the tinting of the occlusion some unusual beauty pass renders can be achieved by setting camera_color to a color that do not correspond to the true color of an object. For example, in figure 5 the yellow sphere is producing a blue tinted occlusion on the poly-plane.



Figure 5


Listing 2 shows a sample rib file for the bake-pass. The point cloud will be saved to the same directory as cutter.jar. Use a full path to save the point cloud to your preferred directory. Listing 3 shows the rib file for the beauty pass.


Listing 2 (bake pass)


DisplayChannel "color _Cs" "quantize" [0 0 0 0] "dither" [0]
DisplayChannel "float _occlusion" "quantize" [0 0 0 0] "dither" [0]
  
Display "tinted_occlusion" "it" "rgb"
Format 400 400 1
Projection "perspective" "fov" 40
ShadingRate 100
  
Translate  0 0 10
Rotate -90 1 0 0
Rotate 0   0 1 0
Scale 1 1 -1
  
WorldBegin
   Attribute "visibility" "trace" [1]
   Attribute "visibility" "transmission" ["opaque"]
  
   Surface "tinted_occlusion"
       "samples" 32.0
       "sampleangle" 90.0
       "bakename" ["test.ptc"]     
       "channels" ["_occlusion,_Cs"] # no spaces
       "camera_color" [1.0 1.0 1.0]  # overrides true surface color
  
   Attribute "cull" "hidden" [0]
   Attribute "cull" "backfacing" [0]
   Attribute "dice" "rasterorient" [0]
  
   TransformBegin
      Scale 10 10 10
      Polygon "P" [-0.5 0 -0.5   0.5 0 -0.5  0.5 0 0.5  -0.5 0 0.5]
            "st" [0 0  1 0  1 1  0 1]
   TransformEnd
   TransformBegin
      Translate -1 0.5 0
      Color 0.956 1.0 0.2
      ReadArchive "pCube.rib"
   TransformEnd
   TransformBegin
      Translate 1 1 0
      Color 1.0 0.4 0.2
      Sphere 1 -1 1 360
   TransformEnd
WorldEnd
System "brickmake ./test.ptc ./test.bkm"


Listing 3 (beauty pass)


DisplayChannel "color _Cs" "quantize" [0 0 0 0] "dither" [0]
DisplayChannel "float _occlusion" "quantize" [0 0 0 0] "dither" [0]
  
Display "tinted_occlusion" "it" "rgb"
Format 400 400 1
Projection "perspective" "fov" 40
ShadingRate 100
  
Translate  0 -0.5 7
Rotate -90 1 0 0
Rotate 0   0 1 0
Scale 1 1 -1
  
WorldBegin
   Attribute "visibility" "trace" [1]
   Attribute "visibility" "transmission" ["opaque"]
  
   Surface "tinted_occlusion"
       "samples" 32.0
       "sampleangle" 90.0
       "bakename" ["./test.bkm"]     
       "channels" ["_occlusion,_Cs"]
       "camera_color" [1.0 1.0 1.0] 
   TransformBegin
      Scale 10 10 10
      Polygon "P" [-0.5 0 -0.5   0.5 0 -0.5  0.5 0 0.5  -0.5 0 0.5]
            "st" [0 0  1 0  1 1  0 1]
   TransformEnd
   TransformBegin
      Translate -1 0.5 0
      Color 0.956 1.0 0.2
      ReadArchive "pCube.rib"
   TransformEnd
   TransformBegin
      Translate 1 1 0
      Color 1.0 0.4 0.2
      Sphere 1 -1 1 360
   TransformEnd
WorldEnd




© 2002- Malcolm Kesson. All rights reserved.