Card/Opacity Shader

Introduction

When doing rendering that requires no form of post production, transparency requires no special consideration. One simply adds a transparency shader of some sort, and mental ray will render it correctly, and all is well.

However, as soon as one begins performing post production work on the image, and one is rendering to multiple frame buffers, even if simply using mental ray's built in frame buffers such as "z" (depth) or "m" (motion vectors), special thought must be put into how transparency is handled.

In general, mental ray collects it's frame buffer data from the eye ray, i.e. the ray shot by the camera that hits the first object. So the z-depth, motion vector etc. will come from this first object.

What if the first object hit is completely transparent? Or is transparent in parts, such as an image of a tree mapped to a flat plane and cut out with an opacity mask, standing in front of a house1?

When using most other transparency related shaders it is most likely that even though a tree is quite correctly visible in the final rendering and you can see the house between the branches, the "z" (depth) (and other frame buffers) will most likely contain the depth of the flat plane! For most post processing work, this is undesirable.

To solve this problem the mental ray API contains a function called mi_trace_continue which continues a ray "as if the intersection never happened". The shader mip_card_opacity utilizes this internally, and switches between "standard" transparency and using mi_trace_continue to create a "totally" transparent object at a given threshold.

mip_card_opacity

declare shader "mip_card_opacity" (
        color   "input",
        boolean "opacity_in_alpha",
        scalar  "opacity",
        boolean "opacity_is_premultiplied",
        scalar  "opacity_threshold"
    )
    version 1
    apply material
end declare

The input parameter is the color of the object.

If opacity_in_alpha is on, the alpha component of the input color is used as the opacity.

If opacity_in_alpha is off, the opacity parameter is used as the opacity.

If opacity_is_premultiplied is on, the input color is assumed to already be premultiplied with the opacity value. If it is off, the input color will be attenuated (multiplied by) the opacity value before being used.

Finally, the opacity_threshold sets the opacity level where the shader switches from using standard transparency to becoming "completely transparent". Generally this should be kept at 0.0, i.e. only totally transparent pixels are indeed treated as "not even there", but if one raises this value more and more "opaque" pixels will be considered "not there" for frame buffers. Note that the actual visible rendered result is identical, only the contents of other frame buffers than the main color frame buffer is affected by this.


Footnotes
1
Using flat images to represent complex objects is known as putting things on "cards" in the rendering industry, hence the name of the shader