Comping With Z-depth
June 7th, 2007This article describes a way to use z-depth data to composite 3D layers.

Comp this, wise guy
When rendering a 3D scene, it’s often convenient to render separate elements on their own layers and composite them together. This method has two major advantages: 1) if you make a change to your scene, you can simply re-render the appropriate layer rather than the whole scene; 2) you can make adjustments to specific layers in the comp rather than re-rendering.
However, when comping together 3D projects, it’s not enough to put the elements in the right place on the screen. There’s a third dimension, or “D” as we call it in the industry: depth. Objects in your scene may move in front of objects they once were behind, or may be intertwined in some way. In these cases, simple layer-arrangement in the comp won’t do the trick.
Maya 6 and the After Effects 6.5 Production Bundle both have the rudimentary capacity to handle files with z-depth channels, which store information about how far from the camera objects are. Here’s one way to use RLA files and AE’s “3D Channel Extract” plugin to comp most intersecting layers without any special shaders or passes.
The method
The generalized method is as follows: for each layer, apply a matte derived from the difference between the layer’s depth map and the depth maps of all the layers which occlude it.
Before making such a matte, make sure you need it — the process is kind of a pain, and isn’t always necessary. For instance, say you have two layers in your shot: a geisha and a tree. If the geisha starts in front of a tree and then runs around behind it, depth maps of both objects will be needed, but only the top layer in the comp will need a matte.
In the image at the top of the page, neither object is “in front” — so either could get the matte. Let’s make a matte for the blue ring, and put the red ring underneath. To make the matte, first we need depth maps of both rings.
The setup
The RLA file format can accommodate an 8-bit z-depth channel, which is accessible by After Effects. When the “Depth Channel” box is checked in Maya’s output settings, Maya will add an extra channel to the RLA file with an 8-bit bitmap of depth values.
If the range of actual depth values in your shot is very large, or if your scene involves very subtle depth interactions between objects, 256 depths may not be enough. In that case you’ll have to hand-roll your depth maps with a depth shader such as DepthShader 1.0 or zDepthDOF 1.6.0. Maya can write IFF files with 32-bit floating point z-depth channels, but alas, After Effects can’t read them.
The delivery
Once you have depth maps for every layer you want to z-comp, the next trick is to prise the maps out of their RLA files and convert them to a useful form. The After Effects 6.5 Production Bundle includes a number of plugins for using depth channels; the one we need is called “3D Channel Extract.” When this effect is applied to a layer, the layer’s content is replaced with a grayscale representation of its depth channel. The plugin takes values for black and white points, intended to be matched to the furthest and nearest depths in the map.
Sadly, this matching must be done manually, and some math is necessary. Maya’s file-viewing utility, fcheck, has the ability to display depth channels as grayscale images, auto-normalizing the range so that it’s clearly visible. It also displays the range in scientific notation in the output window, like so:

Those values look helpful, but if you drop them straight into the plugin, you get nothing. To view the depth map, you must first divide the values by 2147483648, better known by its street name of 2^32.
In the above example, 3.30193e+007 (aka 33019300) can be pasted directly into the Windows Calc utility and divided. The result (0.0153758…) can then be pasted into the plugin’s black point field. Though the plugin fields only display four digits after the decimal place, they respect up to seven.
When the black and white values have been entered into the plugin, your depth map should be visible in the comp. Note that it is not anti-aliased — smoothing would affect the apparent depth of the object’s edges. Save your blurs for the matte itself, after you’ve done the operations on the depth maps.
The old one-two
To create the depth matte, make another comp containing two copies of the occluding layer’s depth map with the depth map of the occluded layer in between. Set the top layer’s mode to “difference” and the middle’s to “lighten.” Then add an adjustment layer to all three, with a “levels” effect, setting the “Input Black” to 0 and the “Input White” to 0. This turns every pixel that isn’t black to white.

Here are the layers at 50%; first the two bottom layers:

With the difference layer applied:

And with the adjustment layer:

Use this precomp as a Luma matte for the occluded layer, and here’s the result:

Add a 2-pixel Simple Choker to the occluded layer and you’ve got something that looks very like the original.


As if that wasn’t enough
If your subject layer is occluded by more than one other layer, things get more complicated. You’ll keep the structure of the layer sandwich in your matte, with copies of the occluding layers’ depth maps above and below the matted layer’s map. However, because there are multiple layers to be “differenced,” you’ll need to pre-comp those layers first, like so:


In theory, because each of these three rings occludes the other, we could make mattes for each of them using the z-depths of the other two, which would give us this:

And with a 2-pixel Simple Choker on each ring, and a 2-pixel Fast Blur on each matte:

With this arrangement, the rings’ layers can be in any order in the comp we like. But mattes made in this way are clearly not ideal; the limitations of the process are exaggerated, and halos and glitches abound. Instead, it’s best to let the alphas do as much work as possible, by choosing an arbitrary depth order.
Let’s call green the top and red the bottom. This way we only need the complicated matte for green, blue only needs a matte made from red, and red doesn’t need a matte at all. With the choker on both matted layers and the blur on both mattes, we get a much better result:

The fine print
This is a bit of a hack. It can work for many low-budget situations, but it’s no replacement for a real matte pass (not to mention a real compositing program), and it won’t suffice if precision is necessary. You’ll likely have to do some experimenting to make it work, so here are some caveats:
But all that aside, it’s perfect.
« previously: Seadragon and Photosynth demos | Home | next: Face mapping plus »