next up previous contents
Next: Mantra Up: A Constant Surface Shader Previous: RenderMan   Contents

Mental Ray

The shader which can be used to create a similar effect in mental ray is called mib_opacity and seems to be significantly more complicated. You can download the MI file13, render it with the standard shaders shipping with mental ray, and have a look into the MI file to see how the shader is attached to the geometry:

...
camera "Camera"
...
        output          "rgb" "constant.rgb"
...
end camera
...
material "mtl2"
        opaque
        "mib_opacity" (
                "input" 0.0 1.0 0.0,
                "opacity" 0.5 0.5 0.5
        )
end material
...
object "Plane"
        visible trace shadow
        tag 1
        group
                1.0 1.0 0.0
                1.0 -1.0 0.0
                -1.0 -1.0 0.0
                -1.0 1.0 0.0
                v 0
                v 1
                v 2
                v 3
                p "mtl2" 0 3 2 1 
        end group
end object
...

I will not explain how a mental ray file is structured but here is in short how the shader is attached to the geometry: The shader is defined in the material block and the two necessary parameters input and opacity are set to the same values as in the RenderMan example. The shader is attached to the geometry in the object definition by mentioning the name of the material.

The shader mib_opacity is not really meant to be used as a standalone material shader but you can use it as one. Normally you would use it as an building block of a so-called Phenomenon. But that's something I will explain later.

Have a look at the source code for mib_opacity below. It should either come with your mental ray distribution or can be downloaded from mental images' FTP site14.

...
DLLEXPORT miBoolean mib_opacity(
        miColor         *result,
        miState         *state,
        struct mo       *paras)
{
  register miColor *opacity = mi_eval_color(&paras->opacity);
  miColor   inp;

  if (opacity->r == 1.0 && opacity->g == 1.0 &&
      opacity->b == 1.0 && opacity->a == 1.0)
    *result = *mi_eval_color(&paras->input);
  else {
    mi_trace_transparent(result, state);

    if (opacity->r != 0.0 || opacity->g != 0.0 ||
        opacity->b != 0.0 || opacity->a != 0.0) {
      inp = *mi_eval_color(&paras->input);
      result->r = result->r * (1.0 - opacity->r) +
              inp.r * opacity->r;
      result->g = result->g * (1.0 - opacity->g) +
              inp.g * opacity->g;
      result->b = result->b * (1.0 - opacity->b) +
              inp.b * opacity->b;
      result->a = result->a * (1.0 - opacity->a) +
              inp.a * opacity->a;
    }
  }
  return(miTRUE);
}

The result of the mib_opacity function (and most mental ray shaders) is stored in the variable result. In contrast to the shader language of RenderMan you are not forced to use that name but most of the example shaders will. The three calls of the function mi_eval_color are used to retrieve the shader parameters from the MI file15.

If the opacity is ``opaque'' just the input color is returned. If the material is at least a bit transparent you have to elongate the incoming ray by calling mi_trace_transparent16. The call might modify the result already before it get mixed with the current color based on the opacity value.


next up previous contents
Next: Mantra Up: A Constant Surface Shader Previous: RenderMan   Contents
Jan Walter 2004-02-09