Built-in Shaders

Built-in shaders exist to support SOFTIMAGE and Wavefront compatibility. All shaders are described by listing their parameters, both in .mi scene file format and as a C structure. The C structure is particularly useful if custom shaders are written that improve on the operation of existing shaders by building or re-using the C structures of existing shaders and calling them, and modifying the results.

The shading models supported by the SOFTIMAGE and Wavefront material are given as equations, which use the following variables:

 ns is the shinyness,
 d  is the transparency,
 t  is the refraction,
 nr is the reflectivity,
 ka is the ambient color,
 kd is the diffuse color,
 ks is the specular color,
 ft is the transmission filter,
 N  is the surface normal,
 V  is the vector pointing at the viewer,
 n  is the number of light sources,
 Li is the vector pointing at light i,
 H  is the vector halfway between V and the direction of the reflection,
 Hi is the vector halfway between V and Li
 f  is the Fresnel function.
 Ii is the intensity contributed by light i,
 Ir is the intensity contributed by reflection, and
 It is the intensity contributed by transmission (transparency).
 

Note that the Wavefront dissolve parameter is equivalent to 1 - transparency in mental ray.


SOFTIMAGE Shaders

Seven shaders implement SOFTIMAGE compatibility. The material and light shader are controlled by a mode parameter that controls which behavior is desired. There are also five compatibility shaders that are no longer required for SOFTIMAGE compatibility, but were present in version 1.8 of mental ray and are still supported to allow version 1.8 .mi scene files to be read. These shaders are not recommended for new developments and may not be supported in future versions of mental ray.

 name                    operation 
 
soft_material material shader, also used as shadow shader soft_color 2D texture shader soft_color_3d 3D texture shader soft_vertex_color RGB vertex color shader soft_vertex_color_alpha RGBA vertex color shader soft_light light shader: point, infinite, spot soft_displace displacement shader soft_env_sphere spherical environment shader soft_fog standard fog volume shader soft_layered_fog layered fog volume shader lens_depth_of_field depth-of-field lens shader
soft_shadow obsolete shadow shader, calls soft_material soft_point point light shader, calls soft_light soft_infinite directional light shader, calls soft_light soft_spot spot light shader, calls soft_light

If any of these shaders is used in a .mi scene file, the scene file must include the softimage.mi header file that contains the shader declarations, using a $include command (see include command) . The C structures are declared in a file mi_softshade.h, to be included in the C source file of custom shaders making direct calls to SOFTIMAGE shaders. Note that these files must always match the version of mental ray, or shaders will operate incorrectly or even crash.

soft_material

(see material shader) The material shader implements constant, Lambert, Phong, and Blinn shading. Its operation includes inside/outside determination, texture evaluation, light illumination, reflection, and transparency.

This shader can also be used as a shadow shader; it recognizes this case automatically and performs the subset of the material evaluation required for determining the color of light transmitted by the material. This includes testing whether the light that cast the shadow ray is in the shadow material's light list, collecting the diffuse and transparency contributions of textures only, and calculating the resulting transmission color. All other operations are omitted. The material shader considers itself a shadow shader if the state variable type has the value miRAY_LIGHT.

For a general explanation of shading in computer graphics, refer to [Hall 89] or [Foley 90]. The illumination of a surface using Phong mode is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns Ii
+ nr Ir
+ t It
.

Blinn mode differs from the Phong mode in that it attenuates the specular highlights by a geometrical attenuation factor G (see [Foley 90]). The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns G(<Li,Hi,V,N>) Ii
+ nr Ir
+ t It
.

Lambert mode only calculates the contribution of the ambient color and diffuse color and omits the specular component.:

ka + kd Sumi=0^n-1 <N,Li> Ii
+ nr Ir
+ t It
.

Constant shading simply assigns the diffuse color, without actually performing illumination calculation, and disregards both the ambient color and specular color:

kd + nr Ir
+ t It
.

The material shader has the following .mi scene file declaration:

     declare "soft_material" (
        integer         "mode",         # 0=flat, 1=lambert, 2=phong, 3=blinn
        color           "ambient",
        color           "diffuse",
        color           "specular",
        color           "ambience",
        scalar          "shiny",
        scalar          "transp",
        scalar          "reflect",
        scalar          "ior",
        
        array struct    "texture" {
        
                color texture   "map",
                integer         "space",
                integer         "mask",
                integer         "comp",
                integer         "method",
                scalar          "blend",
                scalar          "ambient",
                scalar          "diffuse",
                scalar          "specular",
                scalar          "transp",
                scalar          "reflect",
                scalar          "bump",
                scalar          "u_unit",
                scalar          "v_unit",
                scalar          "u_wrap",
                scalar          "v_wrap",
                boolean         "blackwhite"
        },
        array light     "lights",
        boolean         "sblur",
        scalar          "sblurdecay",
        boolean         "notrace",
        array light     "difflights"
     )

The corresponding C structure is:

    struct soft_material {
       miInteger      mode;        /* flat,lmb,phong,blinn*/
       miColor        ambient;     /* ambient color */
       miColor        diffuse;     /* diffuse color */
       miColor        specular;    /* specular color */
       miColor        ambience;    /* ambience factor */
       miScalar       shiny;       /* specular decay */
       miScalar       transp;      /* transparency */
       miScalar       reflect;     /* reflectivity */
       miScalar       ior;         /* refraction index */
       int            i_texture;   /* index of 1st texture*/
       int            n_texture;   /* number of textures */
       struct Tex {
          miTag       map;         /* texture file */
          miInteger   space;       /* texture vertex space*/
          miInteger   mask;        /* 0=none,1=alpha,2=int*/
          miInteger   comp;        /* 1=alpha,2=intens */
          miInteger   method;      /* 0..4=XY,YZ,XZ,UV,cyl*/
          miScalar    blend;       /* overall blending */
          miScalar    ambient;     /* ambient weight */
          miScalar    diffuse;     /* diffuse weight */
          miScalar    specular;    /* specular weight */
          miScalar    transp;      /* transparency weight */
          miScalar    reflect;     /* reflectivity weight */
          miScalar    bump;        /* bump mapping weight */
          miScalar    u_unit;      /* epsilon dist in tex */
          miScalar    v_unit;      /* space, for bump grad*/
          miScalar    u_wrap;      /* u_unit if u+u_unit */
          miScalar    v_wrap;      /* is outside of [0, 1)*/
          miBoolean   blackwhite;  /* white or black->t=0 */
       }              *texture;    /* texture array */

       int            i_light;     /* index of first light*/
       int            n_light;     /* number of lights */
       miTag          *light;      /* list of lights */

       miBoolean      sblur;       /* static blur mode */
       miScalar       sblurdecay;  /* sblur falloff */
       miBoolean      notrace;     /* no refl, just env */

       int            i_difflight; /* index of first */
       int            n_difflight; /* number of lights */
       miTag          *difflight;  /* diffuse lights */
    };

If the shader is used as a shadow shader, only the diffuse and transparency components, the light list and the diffuse light list (the material is ignored if it does not list the shadow-casting light in either list), and the texture array are used. Of the texture array elements, only map, mask, comp, blend, diffuse, and transp are used. All other fields are ignored in shadow shader mode.

The shader assumes that there are enough texture coordinates and bump basis vectors stored in the state to satisfy all space parameters. That is, if there the largest space parameter is n, there must be n+1 texture coordinates. No bump basis vectors are required for bump mapping, they are computed on the fly.

As described in the ``Writing Shaders'' chapter, every array appears in the C structure as two integers giving the index of the first element and the number of elements, and the array itself, with one member regardless of the true array size. Arrays are indexed with code like

     for (n=0; n < paras->n_array; n++)
             do_something(paras->array[paras->i_array + n]);

In the rest of this chapter, the array support integers prefixed with i_ and n_ follow these rules and are not described explicitly. This is a list of all material shader parameters:

mode
This integer selects the shading model of the material: 0 for constant, 1 for Lambert, 2 for Phong, and 3 for Blinn.
ambient
The ambient color of the material that is always added, regardless of the illumination, in modes 1, 2, and 3. It is ignored in mode 0. The ambient color is multiplied by the ambience before being added, see below. This and the next three colors are RGB colors, alpha is ignored.

diffuse
The diffuse color of the material. It determines the color of the material in mode 0. In all other modes, it is added to the material color after multiplication with factor depending on the illumination direction and the normal, evaluated once for each light.

specular
The specular color is added to the material color in modes 2 and 3, after multiplication with a factor depending on the mode, the illumination direction, and the normal, and the shinyness factor, evaluated once for each light.

ambience
The ambience color is a factor that is used by SOFTIMAGE to adjust the amount and color of ambient illumination in the entire scene. Each ambient component is multiplied by the corresponding ambience component. Typically, all materials in a scene contain the same ambience color.

shiny
The shinyness factor is used in modes 2 and 3 to control the size of the highlight. It is also know as Phong exponent. Larger numbers reduce the highlight size. 50.0 is a typical value for dull metals.

transp
The transparency of the material. Transparency causes transparency or refraction rays to be cast, depending on whether ior is 1.0 or not, to determine the color of the next object ``behind'' the current one that can be seen through the material. 0.0 is fully opaque; 1.0 is fully transparent. The contribution of the material color is reduced by 1 - transp. Transparency is evaluated after textures.

reflect
The reflectivity of the material. Reflections are calculated by casting reflection rays. 0.0 is nonreflecting, 1.0 is fully reflecting. The contribution of the material color and transparency is reduced by 1 - reflect. Reflectivity is evaluated after textures and after transparency.

ior
The index of refraction is used if the object is transparent to determine the direction of the continuing ray. The index of refraction is typically set to 1.0 for air, 1.33 for water and 1.5 for glass. The material shader uses its inside/outside calculation to determine the refraction direction.

sblur
This flag turns on static blurring, which increases the transparency proportionally to the angle between the incident ray and the normal. The effect fades the edges of an object, resulting in a glow effect. To achieve SOFTIMAGE compatibility, this should be used in conjunction with an expansion of the object by translating all vertices along their normals by a constant amount. This expansion can be performed by a translator or a displacement shader; a material shader has no control over geometry. There is a trivial displacement shader soft_staticblur that returns a constant value given by its only argument, width.

sblurdecay
If static blurring is enabled, this value controls the falloff of the static blur.

lights
The light array lists the lights for which the diffuse and specular color contributions should be accumulated. If the shader is used as a shadow shader, the current shadow-casting light is looked up in the light list, and the material is ignored if the light is not found.

difflights
The diffuse light array lists more lights for which only the diffuse color contributions should be accumulated. Even if the mode indicates Phong (2) or Blinn (3) shading, these lights contribute only diffuse light.

texture
SOFTIMAGE materials allow an arbitrary number of textures that are layered ``on top of'' the base color computed from the ambient, diffuse, and specular colors and their factors.Future versions of mental ray will replace the texture pointer with an array of size [1]. The alpha value of textures is taken into account for blending. Each texture comes with a number of parameters that describe the attributes of layering:

texture[ ].map
The map is the texture to look up. This can either be a procedural texture or an image texture. The SOFTIMAGE translator always stores a procedural texture (such as soft_color) here. The texture is given as a tag, which can be evaluated by calling mi_call_shader, which looks up the texture and returns the color at the proper location on the texture, or returns miFALSE if the texture does not apply.

texture[ ].space
Different textures can use different mappings, such as orthographic, spherical, or cylindrical projections. The state->tex_list contains an array of texture coordinates, one for each projection on this material. The texture space is an index into this array. When evaluating texture i, the material shader copies state->tex_list[paras->texture[i].space] into state->tex before evaluating the map, which is where the texture shader picks it up.

texture[ ].mask
Masking controls the blending method. If mask is 0, the texture is layered opaquely disregarding its alpha, mask 1 makes the texture transparent where its alpha is less than 1.0, and mask 2 does the same but uses the texture intensity instead of the texture alpha. The blend factor is multiplied by the result of this calculation.

texture[ ].comp
The comp flag selects whether the scalar mapping factors transp, reflect, and bump should be derived from the texture alpha (if comp is 1) or the texture intensity (if comp is 2).

texture[ ].method
The original texture projection method selected in the texture menu: 0 for XY, 1 for YZ, 2 for XZ, 3 for UV, or 4 for cylindrical or spherical projections. The method number of 3D textures is 666. This variable does not control the mapping itself; mapping is controlled by texture vertices. It is used for the computation of bump basis vectors to ensure that the normal is perturbed in the correct direction depending on the projection.

texture[ ].blend
Blending reduces the effect of layering the texture. If blend is 0.0, the texture is ignored; if blend is 1.0, it is added opaquely, and values in between fade the texture. The mask parameter can be used to ``punch holes'' into the texture at places where it has a low alpha or a low intensity; blend is the global blending factor.

texture[ ].ambient
This factor adjusts the effect of the texture on the ambient component. It works like an additional blending factor that controls the ambient color only. 1.0 does not reduce ambient contribution, 0.0 turns it off.

texture[ ].diffuse
This factor does the same thing for the diffuse color.

texture[ ].specular
This factor does the same thing for the specular color.

texture[ ].transp
This factor does the same thing for transparency. In addition, negative values are allowed that in effect reverse the transparency map; transparent areas become opaque and vice versa.

texture[ ].reflect
This factor does the same thing for reflectivity. Negative values are also allowed.

texture[ ].bump
This factor does the same thing for bump mapping. Negative values are also allowed; they effectively turn bumps into dents and vice versa.

texture[ ].u_unit, texture[ ].v_unit
Bump mapping is done by evaluating the texture three times, at the current location and a small distance above and to the right, and using the two differences to perturb the normal. The u_unit and v_unit parameters determine the distance in texture space, which ranges from (0, 0) in the lower left corner to (1, 1) in the upper right corner.

texture[ ].u_wrap, texture[ ].v_wrap
For bump mapping: if u + u_unit is outside the interval [0,1), the texture lookup is dependent on u_wrap: If u_wrap is zero, the differences to perturb the normal are calculated to the left (below) at u - u_unit. If u_wrap is different from zero, texture wrapping is assumed and the lookup is performed at u + u_wrap. The same procedure applies to the v_wrap parameter.

blackwhite
This flag enables a mode where the transparency is set to 1.0 if the color returned by the texture map is either completely white or completely black (all three color components are either less than or equal to 0.004 or greater than or equal to 0.996).


soft_color

(see texture shader) This shader implements 2D textures. It works by calculating the texture coordinate and looking up an image texture. Standard SOFTIMAGE 2D textures are always evaluated in two stages, the first being a procedural texture shader, and the second being an image file. This shader implements the first stage. It can perform various cropping, scaling, rotation, and swapping operations. This is the .mi scene file declaration:

    declare "soft_color" (
        color texture   "texture",
        integer         "repu",
        integer         "repv",
        boolean         "altu",
        boolean         "altv",
        boolean         "swap",
        scalar          "minu",
        scalar          "maxu",
        scalar          "minv",
        scalar          "maxv",
        transform       "transform",
        boolean         "u_torus",
        boolean         "v_torus",
        integer         "method"
    )

The corresponding C structure is:

    struct soft_color {
        miTag       texture;      /* texture shader */
        miInteger   repu, repv;   /* repetition, >= 1 */
        miBoolean   altu, altv;   /* flip alternates */
        miBoolean   swap;         /* swap U and V coords */
        miScalar    minu, maxu;   /* horizontal cropping */
        miScalar    minv, maxv;   /* vertical cropping */
        miMatrix    transform;    /* transformation */
        miBoolean   u_torus;      /* map is cyl/spherical */
        miBoolean   v_torus;      /* wrap V (patch only) */
        miInteger   method;       /* 0..5=XY, YZ, XZ, UV, */
                                  /* cyl/sphere, UV wrap */
    };

texture
The tag of the image texture that actually delivers the colors. The shader uses it to retrieve multiple colors for each sample, and filters them to a single result value.

repu, repv
Repetition packs multiple copies of the image texture, after cropping, into the available space defined by the transform matrix. No repetition is done if both parameters are 1. repu controls repetition in the U parameter direction, and repv in the V direction. The UV parameter values are taken from the X and Y components of the texture coordinate state->tex and then transformed with transform.

altu, altv
These flags control flipping of alternate tiles for repeating textures. If repu is greater than 1 and altu is miTRUE, every other copy of the texture is flipped horizontally. altv flips every other copy vertically.

swap
This flag, if miTRUE, exchanges the U and V coordinates after transformation, before repetition and tiling. The result is a diagonal mirror.

minu, maxu, minv, maxv
These parameters control texture cropping. All four work in texture image space, with (0, 0) in the lower left corner and (1, 1) in the upper right corner. minu is the width of the left margin, 1 - maxu is the right margin, minv is the bottom margin, and 1 - maxv is the top margin. The image is not cropped if minu=minv= 0 and maxu=maxv= 1.

transform
The texture transformation matrix converts the texture coordinate state->tex to UV coordinates. As an optimization, the shader ignores the matrix if matrix[15] is 0. Transformation may result in areas on the surface where the object result in U or V coordinates less than 0 or greater than 1. If this is the case for the current sample, it is considered a ``texture miss'', and the shader returns miFALSE. The caller (usually the material shader) then ignores this texture. The torus flags provide exceptions to this rule.

u_torus, v_torus
The rules for texture mapping have two exceptions controlled by these flags. First, spherical and cylindrical mappings cause the texture, if translated, to ``wrap around'' the U seam (where the U coordinate wraps from 1 back to 0). If u_torus is miTRUE, the shader performs this wrapping, rather than clipping the texture at the U=1 seam and leaving blank space at the U=0 seam. This does not apply to the V direction. The second exception applies if the object is a closed patch. On closed patches, the texture always wraps around in the parameter directions the closing applies to, so either or both of u_torus and v_torus may be miTRUE.

method
The original texture projection method selected in the texture menu: 0 for XY, 1 for YZ, 2 for XZ, 3 for UV, 4 for cylindrical or spherical projections, or 5 for UV with seamless wrapping. This is used by the remap_parameters subroutine of soft_color to check for UV coordinate mode (3 or 5), and use a different approach to finite repetition that emulates SOFTIMAGE UV texture mapping.


soft_color_3d

(see texture shader) 3D textures, like 2D textures, are based on texture coordinates as found in state->tex. However, 3D textures use all three texture coordinates X, Y, and Z, and compute the texture based on these coordinates without referring to a texture image. Three types of textures are supported: cloud, wood, and marble. Here is the .mi scene file declaration:

    declare "soft_color_3d" (
        integer         "seq",
        integer         "type",
        scalar          "spacing",
        scalar          "angle",
        scalar          "strength",
        scalar          "power",
        integer         "iteration",
        scalar          "weight1",
        scalar          "weight2",
        scalar          "weight3",
        color           "color0",
        color           "color1",
        color           "color2",
        color           "color3",
        color           "color4",
        transform       "transform"
    )

The corresponding C structure is:

    struct soft_color_3d {
        miInteger   seq;         /* unique seq. number */
        miInteger   type;        /* marble, wood, cloud */
        miScalar    spacing;     /* spacing (density) */
        miScalar    angle;       /* rotation */
        miScalar    strength;    /* amount of noise */
        miScalar    power;       /* deformation strength */
        miInteger   iteration;   /* polynomial order */
        miScalar    weight1;     /* color weights */
        miScalar    weight2;
        miScalar    weight3;
        miColor     color0;      /* 5-color color spread */
        miColor     color1;
        miColor     color2;
        miColor     color3;
        miColor     color4;
        miMatrix    transform;   /* xlate,scale,rotation */
    };

seq
Every instance of a 3D shader must have a unique sequential number. This number is used by the shader to uniquely identify the shading context, such that the interdependency of samples for one object can be maintained. Sequential numbers begin at 0.

type
Three types are defined: 0 for marble, 1 for wood, and 2 for clouds.

spacing
The spacing controls the distance between marble layers or wood grains. Valid values range from 0 to 10, the default is 1. Greater numbers decrease the distance.

angle
This value rotates the texture. Valid values range from 0 to 45 degrees. (This field is the only one in mental ray that is defined in degrees, not radians.)

strength
This parameter controls the amount of perturbation. Values range from 0 to 20, default is 1. Greater values increase the perturbation.

power
If the iteration is sufficiently high, deforms the pattern in a way similar to strength, but at a ``macroscopic'' level. Values range from 0 to 20, the default is 0.

iteration
The iteration controls the degree of the polynomial used to evaluate the texture. Valid values range from 1 to 8, default is 1. Higher values calculate more detail.

weight1, weight2, weight3
The weights distribute the five colors. The five-color spread is distributed from one marble layer or wood cylinder to the next, on a range from 0 to 1. Color 0 is at 0, color 1 is at weight1, color 2 is at weight2, color 3 is at weight3, and color 4 is at 1. This means that the weights must be specified in increasing order: 0 <= weight1 <= weight2 <= weight3 <= 1.

color0, color1, color2, color3, color4
These colors define the five-color spread, as RGBA colors.

transform
This transformation matrix is applied to the raw texture coordinate found in state->tex before the pattern is calculated.

soft_vertex_color

(see texture shader) The vertex color shader is very simple. It interprets the XYZ texture coordinate components as an RGB color, sets alpha to 1.0 and returns. Together with a translator that stores colors instead of texture coordinates for this shader, this implements vertex coloring. No lookup or other computation is required, and no parameters are accepted:

    declare "soft_vertex_color" ()

soft_vertex_color_alpha

(see texture shader) This is a variation of the previous shader. It exists for Softimage compatibility and is not recommended for other uses. It interprets the XYZ texture vector as an RGB color in the value range (0..255), instead of (0..1), taking each integer modulo 255. Additionally, the X component of the texture vector, divided by 256 and taken modulo 255, is used to set the alpha component of the returned color. With this trick four color components are extracted from three vector components. No lookup or other computation is done, and no parameters are accepted:

    declare "soft_vertex_color_alpha" ()


soft_light

(see light shader) This shader implements the infinite (directional) lights, point lights, and spot lights supported by SOFTIMAGE. The behavior is controlled by a mode parameter. Infinite lights use the light direction in the state, while point and spot lights use the origin in the state. Point and spot lights can have a distance attenuation, causing the light intensity to fall off with distance. The only difference between point lights and spot lights is that spot lights offer angle attenuation, which implements the spot effect by emitting the lights along a spot direction axis with a programmable falloff depending on the angle to that axis. Spot lights do not use the direction in the state as a spot direction axis.

This is the .mi scene file declaration:

    declare "soft_light" (
        integer         "mode",
        color           "color",
        boolean         "shadow",
        scalar          "factor",
        boolean         "atten",
        scalar          "start",
        scalar          "stop",
        vector          "direction",
        scalar          "cone",
        scalar          "spread"
    )

The corresponding C structure is:

    struct soft_light {
        miInteger   mode;         /* 0=inf,1=point,2=spot */
        miColor     color;        /* color of light source*/
        miBoolean   shadow;       /* light casts shadows */
        miScalar    factor;       /* penetrate opaque objs*/
                                  /* --- point/spot only: */
        miBoolean   atten;        /* distance attenuation */
        miScalar    start, stop;  /* if atten, dist range */
                                  /* --- spot only: */
        miVector    direction;    /* spot direction */
        miScalar    cone;         /* inner solid cone */
        miScalar    spread;       /* outer fuzzy cone */
    };

mode
The mode controls the operation of the light: 0 selects an infinite (directional) light, 1 selects a point light, and 2 selects a spot light.

color
The color of the light is an RGB color (no alpha) that specifies the color of the emitted light. If shadows are enabled using the shadow parameter, the shader casts shadow rays back towards the point to be illuminated in order to attenuate the light color depending on the shadow shaders of occluding objects. Occluding objects may change the light color based on their transparency. The end result is returned by the light shader.

shadow
If the shadow flag is miTRUE, the light shader attempts to cast shadow rays back to the illuminated point as found in state->point, giving the shadow shaders of occluding objects a chance to attenuate the light color. If the global shadow flag for the entire scene is turned off, no shadow shaders will be called, regardless of the shadow parameter.

factor
The shadow factor provides a way to reduce the effect of occlusion by objects between the light and the illuminated point. If the shadow factor is greater than 0, it will blend the color reduced by the shadow shaders toward the light color. If the shadow factor is 1, no shadow rays are cast. The shadow factor can be seen as the degree to which the light can penetrate opaque shadow-casting objects.

atten
This flag applies to point and spot lights only. It turns distance attenuation on, based on the distance to the illuminated object as found in state->dist and the start and stop parameters.

start, stop
If mode is 1 or 2, and if atten is miTRUE, these parameters bound the distance attenuation. If the distance is less than start, no attenuation takes place. If the distance is greater than stop, no light reaches the object, and a black color is returned. If the distance is beetween start and stop, the light color is faded to black in a linear way. Distance attenuation is applied before shadow rays are cast.

direction
If the light is a spot light, the direction vector specifies the direction of maximum illumination, i.e., the direction the spot light is pointing. This must not be confused with the direction of a directional light, which is taken from state->dir.

cone
If the light is a spot light, the cone value defines the radius of the cone around the direction axis in which the full light intensity is emitted without any angle attenuation. The value is specified as the cosine of the angle. Angle attenuation is applied to the light color before shadow rays are cast.

spread
If the light is a spot light, the spread value defines the radius of a cone around the direction axis outside of which no light is emitted at all. If the angle from the axis direction to the direction towards the illuminated point is greater than specified with spread, the light shader returns black; if the angle is less than specified by cone, no angle attenuation takes place. There is a linear falloff if the angle is between the angles determined by cone and spread. Like cone, spread must be set to the cosine of the desired angle.


soft_displace

The displacement shader is called once for every vertex generated by surface tesselation, and returns a value that specifies how far the vertex should be translated along its normal. The displacement shader derives this value from one or more textures, using a texture lookup much like the soft_material material shader. The scalar return value is derived from the RGBA result of the texture lookups in the same way and using the same parameters that the material shader uses to derive transparency, reflectivity, and bump intensity. Its parameters are declared in the .mi scene file as:

    declare "soft_displace" (
        array struct    "texture" {
            color texture   "map",
            integer         "space",
            integer         "comp",
            scalar          "displace"
        }
    )

The corresponding C structure is:

    struct soft_displace {
        int           i_texture;   /* index of 1st texture*/
        int           n_texture;   /* number of textures */
        struct DisTex {
           miTag      map;         /* texture file */
           miInteger  space;       /* texture vertex space*/
           miInteger  comp;        /* 1=alpha,2=intens */
           miScalar   displace;    /* weight of texture */

        }             *texture;    /* list of textures */
    };

The parameters are evaluated once for each texture, and their results are added.Future versions of mental ray will replace the texture pointer with an array of size [1].

texture[ ].map
The map is the texture to look up. This can either be a procedural texture or an image texture. The SOFTIMAGE translator always stores a procedural texture (such as soft_color) here. The texture is given as a tag, which can be evaluated by calling mi_call_shader, which looks up the texture and returns the color at the proper location on the texture, or returns miFALSE if the texture does not apply.

texture[ ].space
Different textures can use different mappings, such as orthographic, spherical, or cylindrical projections. The state->tex_list contains an array of texture coordinates, one for each projection on this material. The texture space is an index into this array.

texture[ ].comp
The comp flag selects whether the displace factor should be derived from the texture alpha (if comp is 1) or the texture intensity (if comp is 2).

texture[ ].displace
This factor adjusts the effect of the texture on the returned value. 1.0 adds the full result from the texture lookup, 0.0 turns it off. Negative values invert the direction of the displacement. Values greater than 1.0 (or less than -1.0) magnify the effect.


soft_env_sphere

(see environment shader) Environment maps are called to evaluate the color returned by a primary or secondary ray that goes to infinity without hitting an object, or to evaluate the color of a reflected secondary ray quickly without checking for intersections with other objects. The second case is called a ``non-raytraced reflection map'' in the SOFTIMAGE Creative Environment.

This shader works by assuming a sphere of infinite radius around the entire scene. One or more textures are mapped on this sphere, so that the color lookup operates in exactly the same way as texture lookups in the material and displacement shaders. The soft_env_sphere shader accepts the same types of arguments as these two shaders. Here are the .mi scene file declarations:

    declare "soft_env_sphere" (
        scalar          "rotate",
        array struct    "texture" {
            color texture   "map",
            integer         "mask",
            scalar          "blend"
        }
    )

The corresponding C structure is:

    struct soft_env_sphere {
        miScalar      rotate;      /* global rotation */
        int           i_texture;   /* index of 1st texture*/
        int           n_texture;   /* number of textures */
        struct EnvTex {
           miTag      map;         /* texture file */
           miInteger  mask;        /* none, alpha, intens */
           miScalar   blend;       /* overall blending */
        }             *texture;    /* list of textures */
    };

rotate
This parameter, if nonzero, rotates the texture around the Y coordinate.

The following parameters are evaluated once for each texture, and their results are added.Future versions of mental ray will replace the texture pointer with an array of size [1]. Note the similarity to the material and displacement shader parameters. No texture coordinates, and hence no space parameter, are required because the sphere is always mapped spherically.

texture[ ].map
The map is the texture to look up. This can either be a procedural texture or an image texture. The SOFTIMAGE translator always stores a procedural texture (such as soft_color) here. The texture is given as a tag, which can be evaluated by calling mi_call_shader.

texture[ ].mask
Masking controls the blending method. If mask is 0, the texture is layered opaquely disregarding its alpha, mask 1 makes the texture transparent where its alpha is less than 1.0, and mask 2 does the same but uses the texture intensity instead of the texture alpha. The blend factor is multiplied by the result of this calculation.

texture[ ].blend
Blending reduces the effect of layering the texture. If blend is 0.0, the texture is ignored; if blend is 1.0, it is added opaquely, and values in between fade the texture. The mask parameter can be used to ``punch holes'' into the texture at places where it has a low alpha or a low intensity; blend is the global blending factor.


soft_fog

(see volume shader) (see fog) (see atmosphere) The fog shader is a volume shader that implements simple distance-based fog. Whenever a visible or light ray is cast, the resulting color is modified by the fog shader based on the distance the ray travelled, as found in state->dist, by fading the color towards a fog color. The camera is considered to be surrounded by spherically shaped layer of fog whose inner radius is the start distance and whose outer layer is the end distance. The attenuation is a linear function of the distance traveled through this fog. This is the .mi scene file declaration:

    declare "soft_fog" (
        scalar          "start",
        scalar          "stop",
        scalar          "rate",
        color           "transmit",
        boolean         "lightrays"
    )

The corresponding C structure is:

    struct soft_fog {
        miScalar        start, stop;
        miScalar        rate;
        miColor         transmit;
        miBoolean       lightrays;
    };

start, stop
These parameters specify the distance where the fog begins and where it is totally opaque. Between these distances, the fog density is linearly interpolated between totally transparent (at start) to totally opaque as defined by rate (at stop).

rate
The rate allows to adjusts the maximum density of the fog. If rate is 0.0, the fog becomes totally opaque at stop; values between 0.0 and 1.0 reduce the maximum opacity.

transmit
The color of the fog that ray colors are faded towards.

lightrays
This flag controls whether light rays are also attenuated by fog. If it is miTRUE, light illumination is subject to fog attenuation; if it is miFALSE, lights can illuminate objects at any distance regardless of fog.


soft_layered_fog

(see volume shader) (see fog) (see atmosphere) This shader attempts to emulate the SOFTIMAGE layered fog shader while trying to avoid its problems. A layer of fog with a vertical extent in world space is simulated. The density of the fog is given by a Poisson distribution (numerically given) that is centered around half the fog layer's height, and drops to half of the maximum value at the edges. In addition to the vertical extent of the layer, the volume filled with fog can be specified by giving a start and a stop distance along the ray, which correspond to the ray entering and leaving the volume. To turn this distance clipping off, a starting distance of 0.0 and a very large ending distance such as 10000.0 should be chosen.

Note that distance clipping emulates a peculiarity of the SOFTIMAGE layered-fog shader: it only works correctly for primary rays; secondary rays such as reflected or refracted rays are treated as if they originated at the camera. The immediate effect is that, for start distances greater than 0.0, the first segment of the length as given by the start parameter of secondary rays is not affected by fog, even if the ray originates in the middle of the fog layer.

Here is the .mi scene file declaration:

    declare "soft_layered_fog" (
        scalar          "start",
        scalar          "stop",
        scalar          "base",
        scalar          "thickness",
        scalar          "density",
        color           "fogcolor",
        boolean         "lightrays"
    )

The corresponding C structure is:

    struct soft_layered_fog {
        miScalar        start, stop;
        miScalar        base;
        miScalar        thickness;
        miScalar        density;
        miColor         fogcolor;
        miBoolean       lightrays;
    };

start, stop
These parameters specify the distance where the fog begins and where it ends. Fog appears only between these two distances.

base
The base is the Y coordinate of the bottom edge of the fog in world space. There will be no fog below this base height.

thickness
The height of the fog layer above the base height. Fog will be visible between the Y coordinates base and base + thickness in world space. In this range, the density of the fog follows a Poisson distribution with a maximum at base + 0.5 *thickness, falling off to one half of the maximum density at base and base + thickness.

density
The fog density is multiplied by this factor. No fog appears if the density is 0.0. Typical values range between 0.0 and 1.0.

fogcolor
The color of the fog that ray colors are faded towards.

lightrays
This flag controls whether light rays are also attenuated by fog. If it is miTRUE, light illumination is subject to fog attenuation; if it is miFALSE, lights can illuminate objects at any distance regardless of fog.


lens_depth_of_field

(see lens shader) This lens shader implements depth of field by defining a focus plane parallel to the viewing plane, and a lens size as a radius. Depth-of-field blurring is performed using adaptive distribution ray tracing, by varying the camera ray origin over a disc centered at the camera with a specified radius, while also adjusting the ray direction such that it always passes through the original point at the focus plane. The effect is that there is no difference for objects at the focus plane, but objects closer or farther away are seen at jittered angles. Adaptive sampling is used to anti-alias the result by taking multiple samples for such points. The sample locations and directions are chosen using a Monte Carlo or Quasi-Monte Carlo algorithm, depending on the -mc or -qmc command-line options. The .mi scene file declaration is:

    declare "lens_depth_of_field" (
        scalar          "plane",
        scalar          "radius"
    )

The corresponding C structure is:

    struct lens_depth_of_field {
        miScalar        plane;
        miScalar        radius;
    };

plane
The negative distance of the focus plane from the camera. It may not be greater than or equal to 0.0. Since the scene is defined in camera space, the plane parameter is essentially the Z coordinate of a plane normal to the Z axis; the camera always looks down the negative Z axis.

radius
The radius of the disc centered at the camera, parallel to the focus plane. A value of 0.0 turns off depth of field; values greater than 0.0 increase the depth-of-field effect.


out_depth_of_field

(see output shader) This output shader implements depth of field by defining a a near and a far focus plane parallel to the viewing plane, and a lens size as a radius. All objects between the focus planes are in focus; objects outside this range are blurred. Unlike lens_depth_of_field, this shader computes the depth-of-field effect as a postprocessing step, using information collected during rendering. The shader must be installed in the view using an output statement, listed before the output statement that writes the image to a file:

     output "z,rgba" "out_depth_of_field" (...)

The .mi scene file declaration is:

    declare "out_depth_of_field" (
        scalar          "near",
        scalar          "far",
        scalar          "radius",
        integer         "max",
        scalar          "infinity"
    )

The corresponding C structure is:

    struct out_depth_of_field {
        miScalar        near;
        miScalar        far;
        miScalar        radius;
        miInteger       max;
        miScalar        infinity;
    };

near
The distance of the near focus plane from the camera. It may not be equal to 0.0. For compatibility with lens_depth_of_field, near, far, and infinity can bei either given as positive distances or negative Z coordinates; the absolute value is used.

far
The distance of the far focus plane from the camera. Its absolute value must be equal to or greater than the absolute value of near. Points whose Z coordinate is between near and far are in focus, all others are blurred.

radius
The radius of the disc centered at the camera, parallel to the focus plane. A value of 0.0 turns off depth of field; values greater than 0.0 increase the depth-of-field effect.

max
Cutoff value for the radius of the filter, in pixels. The filter size depends on the distance of objects; this value allows to avoid very large filter sizes that make no visible difference to the effect.

infinity
Reserved for internal use.

Note that this output shader, as opposed to the lens depth-of-field shader, is a fast and smooth, but not physically correct simulation of depth of field. In particular, it only uses the depth of the frontmost object to decide how much to blur. A glass window in front of the scene will cause incorrect blurring.


soft_shadow

(see shadow shader) This shader is obsolete. mental ray 1.8 and higher use the material shader as shadow shader, which avoids the need to duplicate the texture parameter block for a separate shadow shader. The shadow shader still exists for backwards compatibility reasons, in order to be able to read .mi scene files created before the change. It is strongly recommended to not use this shader in new develeopments.

The name soft_shadow indicates a SOFTIMAGE shadow shader and should not be confused with a mechanism generating soft shadows.

The parameter declaration in the .mi scene file and the C structure are identical to the parameter declarations of the soft_material shader. The soft_shadow shader does nothing but call soft_material.

soft_infinite

(see light shader) This shader has been replaced with the soft_light shader described above. It only exists for backwards compatibility with old .mi scene files. It has a declaration and a C data structure that differs slightly in layout from the parameter declaration of soft_light; the shader itself copies the parameter structure, selects an appropriate mode, and calls soft_light. The declaration in .mi scene files is:

    declare "soft_infinite" (
        color           "color",
        vector          "null",
        boolean         "shadow",
        scalar          "factor"
    )

The corresponding C structure is:

    struct soft_infinite {
        miColor     color;     /* color of light source */
        miVector    null;      /* spot has dir vector here*/
        miBoolean   shadow;    /* light casts shadows */
        miScalar    factor;    /* penetrate opaque objects*/
    };

For a description of these parameters, see soft_light.

soft_point

(see light shader) (see point light) This shader has also been replaced with the soft_light shader. It only exists for backwards compatibility with old .mi scene files. It has a declaration and a C data structure that differs slightly in layout from the parameter declaration of soft_light; the shader itself copies the parameter structure, selects an appropriate mode, and calls soft_light. The declaration in .mi scene files is:

    declare "soft_point" (
        color           "color",
        vector          "null",
        boolean         "shadow",
        scalar          "factor",
        boolean         "atten",
        scalar          "start",
        scalar          "stop"
    )

The corresponding C structure is:

    struct soft_point {
        miColor     color;       /* color of light source */
        miVector    null;        /* spot has dir vec here */
        miBoolean   shadow;      /* light casts shadows */
        miScalar    factor;      /* penetrate opaque objs */
        miBoolean   atten;       /* distance attenuation */
        miScalar    start, stop; /* if atten, dist range */
    };

For a description of these parameters, see soft_light.

soft_spot

(see light shader) (see point light) This is yet another light shader that has been replaced with the soft_light shader. It is also obsolete and only exists for backwards compatibility with old .mi scene files. It has a declaration and a C data structure that differs slightly in layout from the parameter declaration of soft_light; the shader itself copies the parameter structure, selects an appropriate mode, and calls soft_light. The declaration in .mi scene files is:

    declare "soft_spot" (
        color           "color",
        vector          "direction",
        boolean         "shadow",
        scalar          "factor",
        boolean         "atten",
        scalar          "start",
        scalar          "stop",
        scalar          "cone",
        scalar          "spread"
    )

The corresponding C structure is:

    struct soft_spot {
        miColor     color;       /* color of light source */
        miVector    direction;   /* spot direction */
        miBoolean   shadow;      /* light casts shadows */
        miScalar    factor;      /* penetrate opaque objs */
        miBoolean   atten;       /* distance attenuation */
        miScalar    start, stop; /* if atten, dist range */
        miScalar    cone;        /* inner solid cone */
        miScalar    spread;      /* outer fuzzy cone */
    };

For a description of these parameters, see soft_light.


Wavefront Shaders

Seven shaders implement Wavefront compatibility. The material shader is controlled by a illumination mode parameter that controls which shading model is desired. Note that Wavefront shader do not deal with the alpha channel; all alpha components are ignored and none are computed, with one exception: the mi_wave_material shader always returns an alpha of 1.0. This makes sure that a legal alpha channel is written to image files that contain an alpha channel.

 name                   operation 
 
mi_wave_material material shader: all shading models mi_wave_scalar_texture scalar texture shader mi_wave_vector_texture vector texture shader mi_wave_color_texture color texture shader mi_wave_light light shader: point, infinite, spot mi_wave_shadow shadow shader mi_wave_reflection_map environment shader

If any of these shaders is used in a .mi scene file, the scene file must include the wavefront.mi header file that contains the shader declarations, using a $include command (see include command) . The C structures are declared in a file mi_wavefront.h, to be included in the C source file of custom shaders making direct calls to Wavefront shaders.

mi_wave_material

(see material shader) (see Wavefront shaders) The material shader implements the Wavefront shading models 0 through 9. Illumination model 0 gives the surface a uniform color equal to the diffuse color. The illumination of a surface with this material is computed according to

kd
.

Model 1 is purely diffuse. The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
.

Model 2 includes both diffuse and specular components. The illumination of a surface with this material is computed using Phong shading according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns Ii
.

In addition to diffuse and specular components (Phong shading), model 3 includes the illumination contributed by reflections or reflection mapping. The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns Ii
+ ks Ir
.

Model 4 is similar to model 3 but is more suitable for a simulation of glass where the transparency is nearly 1.0, but the highlights should not be affected (should not fade out, as they would with model 3). The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns Ii
+ ks (1.0 + (d /1.0 - d - 1.0) / 5.0) Ir
.

Model 5 is similar to model 3 but with Fresnel calculation of reflected light. The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns f(<Li,Hi>,ks,ns) Ii
+ ks f(<N,V>,ks,ns) Ir
.

In addition to diffuse, specular and reflection contributions, model 6 includes refracted light similar to the calculation used by Whitted. Note that the distance the ray travels through the material is not taken into account. See also [Whitted 80]. The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns Ii
+ ks Ir
+ (1.0 - ks) ft It
.

Model 7 is the same as model 6 but with Fresnel calculation of reflected and refracted color. The illumination of a surface with this material is computed according to

ka + kd Sumi=0^n-1 <N,Li> Ii
+ ks Sumi=0^n-1 <N,Hi>^ns f(<Li,Hi>,ks,ns) Ii
+ ks f(<N,V>,ks,ns) Ir

+ (1.0 - ks) f(<N,V>,1.0-ks,ns) ft It
.

Models 8 and 9 are identical to 3 and 4, respectively, except that the contribution from reflected illumination can only come from a reflection map, not from reflected rays. This is useful to improve performance. (see material shader)

The material shader has the following .mi scene file declaration:

    declare "wave_material" (
        integer         "illum",
        color           "ambient",
        color           "diffuse",
        color           "specular",
        color           "transmit",
        scalar          "dissolve",
        scalar          "ns",
        scalar          "ni",
        color texture   "ambient_map",
        color texture   "diffuse_map",
        color texture   "specular_map",
        scalar texture  "dissolve_map",
        scalar texture  "ns_map",
        vector texture  "bump_map",
        array light     "lights",
        boolean         "use_reflectivity",
        color           "reflect"
    )

The corresponding C structure is:

    struct wave_material {
        miInteger illum;
        miColor   ambient;
        miColor   diffuse;
        miColor   specular;
        miColor   transmit;
        miScalar  dissolve;
        miScalar  ns;
        miScalar  ni;
        miTag     ambient_map;
        miTag     diffuse_map;
        miTag     specular_map;
        miTag     dissolve_map;
        miTag     ns_map;
        miTag     bump_map;
        int       i_lights;
        int       n_lights;
        miTag     *lights;
        miBoolean use_reflectivity;
        miColor   reflect;
    };

If one of the texture maps is defined, the shader requires exactly one set of texture coordinates, plus a set of bump basis vectors if a bump map, in the state.

illum
This integer selects the shading model of the material as described above.

ambient
The ambient color of the material that is always added, regardless of the illumination, in modes other than 0. It is ignored in mode 0. This and the next three colors are RGB colors, alpha is ignored.

diffuse
The diffuse color of the material. It determines the color of the material in mode 0. In all other modes, it is added to the material color after multiplication with a factor depending on the illumination direction and the normal, evaluated once for each light.

specular
The specular color is the color of diffuse specular highlights.

transp
The amount of light transmitted by the material; basically, the amount of transparency for each of the R, G, and B components. This takes the index of refraction into account and uses mental ray's refraction feature.

dissolve
Dissolve (see dissolve) is an non-physical effect that fades or blends the object out of the scene. The index of refraction is not taken into account. This is basically a switcher effect. It uses mental ray's transparency feature.

ns
The shinyness factor, which is used in Phong and Fresnel calculations to control the size of the highlight. It is also know as Phong exponent. Larger numbers reduce the highlight size. 50.0 is a typical value for dull metals.

ni
The index of refraction of the material. It is used if the object is transparent (transp is not (0, 0, 0)) to determine the direction of the continuing ray. The index of refraction is typically set to 1.0 for air, 1.33 for water and 1.5 for glass. No inside/outside calculation is done to reverse the effect when an object is exited.

ambient_map
If this parameter is nonzero, the ambient color is taken from this color texture map.

diffuse_map
If this parameter is nonzero, the diffuse color is taken from this color texture map.

specular_map
If this parameter is nonzero, the specular color is taken from this color texture map.

dissolve_map
If this parameter is nonzero, the dissolve parameter that fades the object is taken from this scalar texture map.

ns_map
If this parameter is nonzero, the shinyness scalar that controls the highlight size is taken from this scalar texture map.

bump_map
If this parameter is nonzero, a bump map is applied to the object by performing a vector texture lookup and perturbing the surface normal according to the bump basis vectors.

lights
The light array lists the lights for which the diffuse and specular color contributions should be taken into account.Future versions of mental ray may replace the light pointer with an array of size [1].

use_reflectivity
If this parameter is zero, the strength reflections is determined by the specular or specular_map parameters. That is, the color of the reflected objects is multiplied by the specular color. If the use_reflectivity parameter is nonzero, the color of the reflected object is multiplied by the reflect color instead, thus allowing to specify reflectivity independently of diffuse specular highlights.

reflect
If use_reflectivity is nonzero, the color of reflected objects is multiplied by this color. If it is black (0, 0, 0), no reflection rays are cast.


mi_wave_scalar_texture

(see texture shader) This shader implements a texture lookup function for scalar textures. Scalar textures are used for mapping the dissolve and shinyness parameters in the material. The shader requires a scalar texture image, it does not extract alpha or intensity from a color image. This is the .mi scene file declaration:

    declare "wave_scalar_texture" (
        scalar texture  "tex",
        vector          "origin",
        vector          "scale",
        scalar          "base",
        scalar          "gain"
    )

The corresponding C structure is:

    struct wave_scalar_texture {
        miTag           tex;
        miVector        origin;
        miVector        scale;
        miScalar        base;
        miScalar        gain;
    };

tex
The scalar texture to look up with the texture coordinate state->tex after the scale and origin parameters were applied. The scalar texture is evaluated at the point (state->tex /scale - origin).

origin
This parameter specifies the origin in the texture, effectively shifting the texture down and to the left for positive origin values.

scale
Scaling changes the size of the texture. Values greater than 1.0 reduce the size.

base
After the texture was looked up, the returned scalar is scaled into the range (base ... gain). The base specifies the lowest possible result.

gain
The gain specifies the highest possible result.


mi_wave_vector_texture

(see texture shader) This shader implements a texture lookup function for vector textures. Vector textures are used for bump mapping. This shader is similar to mi_wave_scalar_texture, except that it deals with 3D vectors and not with scalars. This is the .mi scene file declaration:

    declare "wave_vector_texture" (
        vector texture  "tex",
        vector          "origin",
        vector          "scale",
        vector          "base",
        vector          "gain"
    )

The corresponding C structure is:

    struct wave_vector_texture {
        miTag           tex;
        miVector        origin;
        miVector        scale;
        miScalar        base;
        miScalar        gain;
    };

tex
The vector texture to look up with the texture coordinate state->tex after the scale and origin parameters were applied. The vector texture is evaluated at the point (state->tex /scale - origin).

origin
This parameter specifies the origin in the texture, effectively shifting the texture down and to the left for positive origin values.

scale
Scaling changes the size of the texture. Values greater than 1.0 reduce the size.

base
After the texture was looked up, the X, Y, and Z components of the returned vector are scaled into the range (base ... gain). The base specifies the lowest possible result.

gain
The gain specifies the highest possible result.


mi_wave_color_texture

(see texture shader) This shader implements a texture lookup function for color textures. Color textures are used for ambient, diffuse, and specular color mapping. This shader is similar to mi_wave_scalar_texture, except that it deals with RGB colors and not with scalars. This is the .mi scene file declaration:

    declare "wave_color_texture" (
        color texture   "tex",
        color           "origin",
        color           "scale",
        color           "base",
        color           "gain"
    )

The corresponding C structure is:

    struct wave_color_texture {
        miTag           tex;
        miVector        origin;
        miVector        scale;
        miScalar        base;
        miScalar        gain;
    };

tex
The color texture to look up with the texture coordinate state->tex after the scale and origin parameters were applied. The color texture is evaluated at the point (state->tex /scale - origin).

origin
This parameter specifies the origin in the texture, effectively shifting the texture down and to the left for positive origin values.

scale
Scaling changes the size of the texture. Values greater than 1.0 reduce the size.

base
After the texture was looked up, the RGB components of the returned color are scaled into the range (base ... gain). The base specifies the lowest possible result.

gain
The gain specifies the highest possible result.


mi_wave_light

(see light shader) This shader implements Wavefront's omnidirectional, directional, and infinite light sources. In mental ray terminology, these are called point lights, spot lights, and directional lights. Point and spot lights may have distance attenuation; spot lights have angle attenuation. Various kinds of falloff are available.

This is the .mi scene file declaration:

    declare "wave_light" (
        color           "color",
        vector          "dir",
        boolean         "dist_linear",
        scalar          "dist_start",
        scalar          "dist_end",
        boolean         "dist_inverse",
        scalar          "dist_power",
        boolean         "angle_linear",
        scalar          "angle_outer",
        scalar          "angle_inner",
        boolean         "angle_cosine",
        scalar          "angle_power"
    )

The corresponding C structure is:

    struct wave_light {
        miColor         color;
        miVector        dir;
        miBoolean       dist_linear;
        miScalar        dist_start;
        miScalar        dist_end;
        miBoolean       dist_inverse;
        miScalar        dist_power;
        miBoolean       angle_linear;
        miScalar        angle_outer;
        miScalar        angle_inner;
        miBoolean       angle_cosine;
        miScalar        angle_power;
    };

color
The color of the light is an RGB color (no alpha) that specifies the color of the emitted light. If global shadows are enabled, the shader casts shadow rays back towards the point to be illuminated in order to attenuate the light color depending on the shadow shaders of occluding objects. Occluding objects may change the light intensity (but not the light color) based on their transparency. The end result is returned by the light shader.

dir
If the light is a spot light, the direction vector specifies the direction of maximum illumination, i.e., the direction the spot light is pointing.

dist_linear
If this parameter is miTRUE, linear distance attenuation is enabled. The light intensity is not attenuated for distances less than dist_start, then falls off linearly until no light at all remains at distance dist_end.

dist_start
This parameter is used only if dist_linear is miTRUE. It specifies the distance where attenuation begins.

dist_end
This parameter is used only if dist_linear is miTRUE. It specifies the maximum distance the light will reach.

dist_inverse
If this parameter is miTRUE and dist_linear is miFALSE, inverse distance attenuation is enabled. The light intensity is attenuated logarithmically based on the distance, proportional to the factor 1 /distance^dist_power.

dist_power
If dist_linear is miTRUE, this parameter specifies the speed of the falloff. For example, if it is 2.0, light intensity falls of with the square of the distance, with full illumination only directly at the light source.

angle_linear
If this parameter is miTRUE, angular attenuation is enabled. The light intensity is not attenuated for illuminations direction that form an angle of less than angle_inner to the illumination direction dir. If the angle is grater than angle_outer, no illumination takes place. Between the inner and outer angles, illumination falls off linearly.

angle_outer
If angle_linear is miTRUE, the angle of the inner full-intensity light cone.

angle_inner
If angle_linear is miTRUE, the angle of the outer soft light cone, outside of which no illumination takes place.

angle_cosine
If this parameter is miTRUE and angle_linear is miFALSE, cosine angular attenuation is enabled. The light intensity is attenuated proportionally to the cosine of the angle formed by the illumination direction Li and the spot direction dir, raised to angle_power: 1 /cos(angle)^angle_power = 1 /(Li *dir)^angle_power.

angle_power
If cosine angular attenuation is enabled, the power to which the cosine of the illumination direction and the spot light direction.

Wavefront area light sources are supported by mental ray's rectangular area light source type. This area light attribute can be used with any light source without changing light shader parameters.


mi_wave_shadow

(see shadow shader) Shadow shaders are called when a shadow ray intersects an object occluding the light source as seen from the illuminated point. The mi_wave_shadow shader reduces the intensity of the light color based on the dissolve value of the object, which can be either constant or texture-mapped. The object color is not taken into account. Here are the .mi scene file declarations:

    declare "wave_shadow" (
        scalar          "dissolve",
        color texture   "dissolve_map"
    )

The corresponding C structure is:

    struct wave_shadow {
        miScalar        dissolve;
        miTag           dissolve_map;
    };

The parameters are normally duplicates of the respective parameters of the mi_wave_material shader. Unlike the SOFTIMAGE shaders, the Wavefront material shader does not double as shadow shader.

dissolve
Dissolve (see dissolve) is an non-physical effect that fades or blends the object out of the scene. The index of refraction is not taken into account. This is basically a switcher effect. It uses mental ray's transparency feature.

dissolve_map
If this parameter is nonzero, the dissolve parameter that fades the object is taken from this scalar texture map, using a straight filtered scalar texture lookup.


mi_wave_reflection_map

Environment maps are called to evaluate the color returned by a primary or secondary ray that goes to infinity without hitting an object, or to evaluate the color of a reflected secondary ray quickly without checking for intersections with other objects. The Wavefront environment shader assumes that a single texture is mapped on the inside of an infinite sphere enclosing the scene. It looks up a color on the texture map based on the direction of the ray. This is the .mi scene file declaration:

    declare "wave_reflection_map" (
        color texture   "tex",
        transform       "transform"
    )

The corresponding C structure is:

    struct wave_reflection_map {
        miTag           tex;
        miMatrix        transform;
    };

tex
This parameter specifies the color texture to wrap on the infinite sphere.

transform
The transformation is applied to the ray direction state->dir before the coordinate on the texture map is calculated. It can be used to shift or rotate the texture map.


SOFTIMAGE Material Implementation

The Softimage material shader is a very complex shader that handles object inside/outside calculations, texture compositing, light illumination, secondary rays, and static blur, and is also usable as a shadow shader. This chapter explains the internals of this shader, to allow shader writers to write modified versions. For a general description of the shader parameters, see above.

The functions described in this chapter are all callable by external shaders. Note that they all rely on a material structure that is either identical to struct soft_material, or begins with a structure identical to struct soft_material.

Here is the actual source code of the soft_material shader mainline:

     miBoolean soft_material(
        register miColor     *result,
        register miState     *state,
        struct soft_material *paras)
     {
        struct soft_material m;              /* work area */
        miScalar             ior_in,ior_out; /* refr index*/

        if (state->type == miRAY_SHADOW) {
             if (!mi_mtl_is_casting_shadow(state, paras))
                        return(miFALSE);
        } else
             mi_mtl_refraction_index(state, paras,
                                        &ior_in, &ior_out);

        m = *paras;
        mi_mtl_textures(state, &m, paras, &state->normal,
                                        &state->dot_nd);
        mi_mtl_static_blur(state, &m);

        if (state->type == miRAY_SHADOW)
             return(mi_mtl_compute_shadow(result, &m));

        mi_mtl_illumination(result, state, &m, paras,
                                        ior_in, ior_out);
        mi_mtl_reflection(result, state, &m);
        mi_mtl_refraction(result, state, &m,
                                        ior_in, ior_out);
        return(miTRUE);
     }

This shader is based on a copy m of the material parameters paras. This copy is modified by certain functions, particularly mi_mtl_textures, avoiding a large number of pointer arguments such as ambient or transparency. Note that only those parts of the paras structure are copied that are defined by struct soft_material; this does not include the array contents, which is the reason why some functions have both a paras and an m argument. The mi_mtl_illumination function, for example, needs access to both the light array paras->lights and the ambient, diffuse, and specular colors in m, as calculated by mi_mtl_textures. This shader also checks twice if it is called as a shadow shader, by checking state->type, to shortcut certain operations only needed in material shaders.

The functions used by soft_material are:

     miBoolean mi_mtl_is_casting_shadow(
        register miState                *state,
        register struct soft_material   *paras)
     {
        register int                    num;

        for (num=0; num < paras->n_light; num++)
                if (state->instance ==
                    paras->light[paras->i_light + num])
                        return(miTRUE);
        for (num=0; num < paras->n_difflight; num++)
                if (state->instance ==
                    paras->difflight[paras->i_difflight
                                                + num])
                        return(miTRUE);
        return(miFALSE);
     }

This function is used only in the shadow shader case. It checks whether the light casting the shadow is in the material shader's light list (the shadow shader gets the same parameters as the material shader because the shadow soft_material statement in the .mi file has an empty parameter list).

     void mi_mtl_refraction_index(
        miState              *state,
        struct soft_material *paras,
        miScalar             *ior_in,
        miScalar             *ior_out)
     {
        register int         num;
        register miState     *s, *s_in;

        num = state->type == miRAY_REFRACT ||
              state->type == miRAY_TRANSPARENT;
        for (s_in=0, s=state->parent; s; s=s->parent) {
                if ((s->type == miRAY_REFRACT ||
                     s->type == miRAY_TRANSPARENT) &&
                     s->shader == state->shader) {
                        num++;
                        if (!s_in)
                                s_in = s->parent;
                }
        }
        if (num & 1) {
                *ior_in  = paras->ior;
                *ior_out = s_in && s_in->ior != 0 ?
                                          s_in->ior : 1;
                state->refraction_volume = s_in
                                ? s_in->refraction_volume
                                : state->camera->volume;
        } else {
                *ior_out = paras->ior;
                *ior_in  = state->parent &&
                           state->parent->ior != 0 ?
                                  state->parent->ior : 1;
                if (!state->refraction_volume)
                        state->refraction_volume =
                                              state->volume;
        }
        state->ior = *ior_out;
     }

This function computes the indices of refraction on the incoming and outgoing ray, and sets the appropriate volume shader in the state. It operates by following the state parent links all the way back to the primary ray, and counts the number of times this shader was called before. If it was called an odd number of times, the ray is exiting the object, otherwise it is entering. For example, on the back side of a sphere, this function will find that the material has been called once before (for the front side); 1 is an odd number so this ray must be exiting. Materials are distinguished by their parameters. Note that this implements a heuristic; mental ray operates with intersections, not volumes, and allows rendering non-volume objects such as SOFTIMAGE ``grids'' and collections of polygons with different materials where inside/outside calculations cannot be performed meaningfully.

     void mi_mtl_textures(
        miState              *state,   /* ray state */
        struct soft_material *m,       /* ret. new paras */
        struct soft_material *paras,   /* shader paras */
        miVector             *normal,  /* bumpmapped n */
        miScalar             *dot_nd,  /* n <dot> dir */
     {
        *normal = state->normal;
        *dot_nd = state->dot_nd;

        for (n=0; n < paras->n_texture; n++) {
             tex = ¶s->texture[paras->i_texture + n];
             if (!mi_lookup_color_texture
                           (&result, state, (miTag)tex->map,
                            &state->tex_list[tex->space])
                     || result.a < -0.001)
                  continue;
             { calculate blend and mask }
             { calculate m->diffuse }
             { calculate m->transp }
             if (state->type == miRAY_SHADOW)
                  continue;
             { calculate m->ambient }
             { calculate m->specular }
             { calculate m->reflect }
             if (tex->bump != 0 && !state->contour) {
                  { take color sample u_unit to the side }
                  { take color sample v_unit above }
                  { calculate bump basis vectors }
                  { perturb *normal according to diffs }
                  mi_vector_normalize(normal);
                  *dot_nd = mi_vector_dot(normal,
                                          &state->dir);
          }
        }
        { multiply m->ambient by m->ambience }
     }

This function looks up textures and applies the results to the copy m of the material parameters. Note that the light loop uses paras, not m, because m does not contain a copy of the arrays. The result of the texture lookup is checked for negative alphas to provide backwards compatibility to texture shaders written for version 1.8 of mental ray. The actual calculations are given as pseudocode enclosed in braces; the actual sorce code re-implements algorithms developed by SOFTIMAGE.

     miBoolean mi_mtl_compute_shadow(
        miColor                *result,
        struct soft_material   *m)

This function multiplies the result color by a color computed from m->diffuse and m->transp, and returns miTRUE if the resulting color is not black.

     void mi_mtl_static_blur(
        miState              *state, /* ray tracer state */
        struct soft_material *m)     /* textured mtl paras*/

If m->sblur is miTRUE, this function modifies m->transp according to state->dir, state->normal, and m->sblurdecay.

     void mi_mtl_illumination(
        register miColor     *result,  /* ret.illum color */
        miState              *state,   /* ray state */
        struct soft_material *m,*paras)/* mtl paras */
     {
        int                  n;        /* light counter */
        register miTag       *light;   /* current light */
        miColor              col;      /* light color */
        miVector             dir;      /* dir toward light*/
        miScalar             dot_nl;   /* normal <dot> dir*/
        miScalar             ns;       /* specular factor */

        if (m->transp >= 1) {
             result->r = result->g =
             result->b = result->a = 0;
             return;
        }
        if (m->mode == 0 || state->contour) {
             *result = m->diffuse;
             result->a = 1;
             return;
        }
        *result = m->ambient;
        for (n=0; n < paras->n_light; n++) {
            light = ¶s->light[paras->i_light + n];
            if (mi_trace_light(&col, &dir, &dot_nl,
                                 state, (char *)*light)) {
                result->r += dot_nl * m->diffuse.r * col.r;
                result->g += dot_nl * m->diffuse.g * col.g;
                result->b += dot_nl * m->diffuse.b * col.b;
                if (m->mode == 2) {
                    ns = mi_phong_specular(m->shiny,
                                           state, &dir);
                    result->r += ns * m->specular.r * col.r;
                    result->g += ns * m->specular.g * col.g;
                    result->b += ns * m->specular.b * col.b;
                }
                if (m->mode == 3) {
                    ns = mi_blinn_specular(m->shiny,
                                           state, &dir);
                    result->r += ns * m->specular.r * col.r;
                    result->g += ns * m->specular.g * col.g;
                    result->b += ns * m->specular.b * col.b;
                }
            }
        }
        for (n=0; n < paras->n_diff_light; n++) {
            light = ¶s->diff_light[paras->i_diff_light
	                                               + n];
            if (mi_trace_light(&col, &dir, &dot_nl,
                                 state, (char *)*light)) {
                result->r += dot_nl * m->diffuse.r * col.r;
                result->g += dot_nl * m->diffuse.g * col.g;
                result->b += dot_nl * m->diffuse.b * col.b;
            }
        }
        result->a = 1;
     }

This function calculates a result color based on the ambient, diffuse, and specular colors computed by mi_mtl_texture. It is a straightforward implementation of standard Lambert, Phong, and Blinn shading. The alpha of the resulting color is set to 1, effectively making the material opaque. If refraction rays are cast, the alpha will be reduced by mi_mtl_refraction later.

     void mi_mtl_reflection(
        register miColor     *result, /* ret. illum color */
        miState              *state,  /* ray tracer state */
        struct soft_material *m)      /* mtl paras */
     {
        miColor              color;   /* reflect ray color*/
        miVector             dir;     /* dir towards light*/

        if (m->reflect > 0) {
             miScalar f = 1 - m->reflect;
             result->r *= f;
             result->g *= f;
             result->b *= f;

             if (!state->contour
               && state->reflection_level <
                            state->options->reflection_depth
               && state->reflection_level +
                  state->refraction_level <
                            state->options->trace_depth) {

                  mi_reflection_dir(&dir, state);
                  if (!m->notrace &&
                      mi_trace_reflection (&color, state,
                                           &dir) ||
                      mi_trace_environment(&color, state,
                                           &dir)) {

                          result->r += m->reflect * color.r;
                          result->g += m->reflect * color.g;
                          result->b += m->reflect * color.b;
                  }
             }
        }
     }

If the material is reflective, and mental ray is not in contour rendering mode, this shader casts a reflection ray, and merges the result from that ray with the result color. The alpha value is not changed.

     void mi_mtl_refraction(
        register miColor     *result, /* ret. illum color */
        miState              *state,  /* ray tracer state */
        struct soft_material *m,      /* mtl paras */
        double               ior_in,  /* refraction index */
        double               ior_out;
     {
        miColor              color;   /* reflect ray color*/
        miVector             dir;     /* dir towards light*/

        if (m->transp > 0) {
             miScalar f = 1 - m->transp;
             result->r *= f;
             result->g *= f;
             result->b *= f;
             result->a *= f;
             if (state->contour)
                     return;
             state->refraction_level--;
             if (mi_refraction_dir(&dir, state, ior_in,
                                                ior_out)) {
                  miTag env_save = state->environment;
                  state->environment = 0;
                  ok = ior_in == ior_out
                     ? mi_trace_transparent(&color, state)
                     : mi_trace_refraction (&color, state,
                                            &dir);
                  state->environment = env_save;
             } else {
                  mi_reflection_dir(&dir, state);
                  ok = m->notrace
                     ? mi_trace_environment(&color, state,
                                            &dir)
                     : mi_trace_reflection (&color, state,
                                            &dir);
             }
             if (ok) {
                  result->r += m->transp * color.r;
                  result->g += m->transp * color.g;
                  result->b += m->transp * color.b;
                  result->a += m->transp * color.a;
             }
        }
     }

This function casts transparency or refraction rays if the material is transparent. In this case, the material alpha is reduced. If the incoming and outgoing indices of refractions are the same, the ray direction does not change and a transparency ray can be used; otherwise a refraction ray is used. Transparency rays are more efficient and can be performed by the scanline algorithm if enabled. If the index of refraction (less than 1.0) causes the ray to be cast on the same side as the incoming ray, a reflection ray is used instead. The environment state variable is cleared to prevent mental ray from sampling the environment if the refracted ray does not intersect with another object (which would be the normal behavior). Note that the indices of refraction are passed as doubles to allow shaders written in classic K&R C to call this function.



Table of Contents