Depth
Map Based Ambient Occlusion

May,
2003
template:ambocc.slim
Introduction
PRMan11
provides a raytraced occlusion shadeop to render ambient occlusion, but
I don't think most people have enough time and resources to pay the price.
When the model gets a little heavier, it is opten hard to tell how long
the render will take.
Thanks
Andrew Whitehurst for his great tutorial about Depth
Map Based Ambient Occlusion Lighting, we get a faster non-raytrace
alternative.
I
modify his shaders a bit and give a guide to use them.
The
Test Scene
Inspired
by T3 trailer, I took time to model the copter and I hate to test a cool
shader on boring sphere or box. You can download the model (1.94MegaByte)
here.

I
set up a simple lighting with an ambient light and a shadow-casting distant
light.

The
traditional ambient light is quite boring since it simply throw a flat
color onto the surface, discarding too much details. It must be attenuated
properly.
Shadow
Buffering

The
basic idea of depth map based solution is to make a dump of the shape
of geometry with a number of depth(shadow) maps shot from different viewpoints(spotLights).
Like shooting random sample rays in a hemisphere as we do in the ray-traced
solution, we need a dome of spotLights. You can download them here.
I have 250 spotLights in it, but I think much less number of lights such
as 180 also works.

Each
of them is attached to a special light shader "domeSpot", which
does not actually light things up, and it just tell the surface shader
which shadow map should be used. And a shadow map generator is also attached
to them.

If
your model is stationary within the animation, the map generation frequency
may be set to "Once Per Job", or you must use "Every Frame".

Import
the light dome and transform the group to let every light's cone tightly
fit the copter so more pixel of the shadow maps will be useful.
If
you launch render now, you will have to wait a very long time until any
render begins because there are 250 RIB file for shadows, around 700 MegaByte,
data to write! So you must use RIBBox here.

Hide
all the lights and set Renderer to "none" and do not Cleanup
"rib" and "map", then launch render-- nothing happened
but a new RIB appeared in the /rib directory in your project.

Open
it with some editor and delete the last two line.

Find
the line:
Surface
"defaultsurface"
and
delete it with all lines before it.

Delete
all Surface declarations, so this RIB only contains geometry description.
Save it in /rib directory and name it "copter.rib". You can
download it here(right-click and save
target).

Create
a RIBBox and type:
ReadArchive
"rib/copter.rib"
in
it. Name the box "world" to let RIB generation insert the RIB
archive into the "world" coordinate system, so that huge amount
of data will not have to appear in every RIB.
Now
turn off "Primary Visibility" of the copter in the scene and
turn on the light dome.

It's
time to render the shadow maps! You can simply change renderer to "prman"
or "netrender" and launch render. But I don't use Alfred here
because "server busy" or "server in use" seems inevitable.
I still set "none" and use a DOS command line instead.

It
is a MEL script can start prman.exe to render selected RIB(s).

Click
"+" to pick up a shadow RIB.

Delete
characters after "_". Because the shadow map generation frequency
is "Every Frame" and current frame is one, the map extension
is ".shd.0001.rib". If "Once Per Job" is used, use
".shd.rib" instead.

Set
the start and end of the dome lights, and in this case we use 0 and 249.
A DOS window will splash out when you click "r".
It
takes a PIII 550 MHz CPU around 80 minutes to render all those 250 shadow
maps with 1024 resolution. I think the speed is acceptable.
Baking
Occlusion and Bent Normal Data
When
the shadow map render is done, make sure to turn on "Laziness"
of the domeLight shadow generator! You can keep reusing those maps--for
this frame at least.

Create
an Ensemble and name it "world".

Rename
RIBBox "world" to "copter", and connect it into the
ensemble. Plug a surface shader "amboccD" in the "Surface"
line.

The
"bias" control is a small distance to eliminate incorrect self-shadow.
When
the light dome is visible, invoke a lower Shading Rate like 4, render
the scene.

Wait
a monent, we get the black-and-white occlusion data representing how much
ambient light hits on specific surface point. Save it as occlusion pass
in tiff format.

Turn
on "Do bentNormal" and launch render again, and this time is
the colorful bent normal data representing the difference between Surface
Normal and "average light direction".

Save
it as bentnormal pass in tiff format.
These
passes will be projected to "NDC" coordinate of the active camera
to affect abient light, and they are never viewpoint-independent. So you
will have to re-render them if camera is changed.
Ambient
Lighting

Create
an "OccAmbient" light in palette and attach it to a Maya ambient
light. Load occlusion pass, bent normal pass and environment map in it.

Connect
a "Matte" into "world" ensemble, hide the light dome,
then launch render.

This
is ambient light only.

Add
on a shadow-casting distant light.
Most
common shading models has the Ambient() call, so you can apply any textured
shader on the model, but remember to set "Ka" high enough, or
the ambient light will be invisible.
Advantage
and Disadvantages
The
most time-consuming shadow buffering is viewpoint-independent, which is
the most advantage that depth map based ambient occlusion has over a ray-traced
solution. We can quickly change the camera and re-render occlusion and
bent normal pass, then the final lighting, just use the shadow maps again
and again.
 
 
 
It
is a very suitable way to match the lighting for stationary model such
as architectures. For animated models, shadow buffering has to be done
at a per-frame frequency! If the model is not quite complex and covers
not too much pixels of the image, try a raytraced occlusion render first!
And it can not handel any indoor scene.
Depth
map based solution cantains three stages of render, and each of they requires
using special shaders and a lot of tricks. If you haven't any idea of
what shader, map, NDC, RIB or ambient occlusion is, please try some more
basic tutorials first. If you have gotten really tired to fuss about Pixar's
occlusion shader, I hope it useful to help you get things done.
|