next up previous contents
Next: Stairs Up: Get Your Hands Dirty Previous: Get Your Hands Dirty   Contents


Default Surface Shader

In section 3 I mentioned a RenderMan shader called defaultsurface which allows to render an image without any light and surface shaders used in the RIB file. We want to write a similar shader for mental ray now. Let's have a look how AIR26 implements the defaultsurface shader:

surface defaultsurface (float Ka=.2, Kd=.8)
{
   Oi=Os;
   Ci=Os*Cs*(Ka+Kd*abs(normalize(I).normalize(N)));
}

The implementation of the mental ray shader is straight forward. The only difference is that mental ray has no global state for the current surface color and opacity. The RenderMan shader takes the values of Os and Cs into account. This color values can be set in the RIB file by using Opacity or Color. If you want a similar behaviour within the mental ray shader you should use additional shader parameters for the color and opacity values. Here is the header file for the mental ray shader:

# myDefaultSurface.mi

declare shader
        color "myDefaultSurface" (
                scalar          "Ka",
                scalar          "Kd"
        )
        version 1
        apply material
end declare

To use this shader in a MI file I changed the example from section 3.1 a bit:

...
link "myDefaultSurface.so"
$include <myDefaultSurface.mi>
...
material "mtl"
        opaque
        "myDefaultSurface" (
                "Ka" 0.2,
                "Kd" 0.8
        )
end material
...
object "Monkey"
        visible trace shadow
        tag 1
        group
                0.4375 0.1640625 0.765625
...
                p "mtl" 504 322 320 390 
        end group
end object

instance "Monkey_inst" "Monkey"
        transform
                        1.0 0.0 0.0 0.0
                        0.0 1.0 0.0 0.0
                        0.0 0.0 1.0 0.0
                        0.0 0.0 5.0 1.0
end instance

instgroup "rootgrp"
        "Camera_inst"
        "Monkey_inst"
end instgroup

render "rootgrp" "Camera_inst" "opt"

First of all you have to link your shared library and include the appropriate header file. If you can't copy the compiled shader and the header file to a place where mental ray can find it -- e.g. because you don't have root permissions on an Unix system -- you can specify the full path in the MI file.

After having defined the shader and its parameters as a material within the MI file you can use the material in the definition of the Monkey object. Notice that there is only a camera and one geometry object defined -- no lights. The shader itself looks like this:

/* myDefaultSurface.c */

#include <shader.h>

struct myDefaultSurface
{
  miScalar Ka;
  miScalar Kd;
};

DLLEXPORT miBoolean 
myDefaultSurface(
                 miColor* result,
                 miState* state,
                 struct myDefaultSurface* paras
                 )
{
  miScalar Ka, Kd;
  miScalar abs_dot_nd;

  /* get parameters */
  Ka = *mi_eval_scalar(&paras->Ka);
  Kd = *mi_eval_scalar(&paras->Kd);
  /* dot product of the normal and the direction vector */
  abs_dot_nd = fabs(state->dot_nd);
  /* result */
  result->r = Ka + Kd * abs_dot_nd;
  result->g = Ka + Kd * abs_dot_nd;
  result->b = Ka + Kd * abs_dot_nd;
  result->a = 1.0;

  return(miTRUE);
}

Notice that you don't have to calculate the dot product of the normal and the direction vector yourself because it's already stored in the state.


next up previous contents
Next: Stairs Up: Get Your Hands Dirty Previous: Get Your Hands Dirty   Contents
Jan Walter 2004-02-09