Displacement shaders are called during geometry tessellation if the material of a polygonal or free-form surface object specifies a displace shader. Whenever the tessellator introduces or copies a vertex, the displacement shader is called and expected to return a scalar value that tells the tessellator to move the vertex by this distance along its normal vector. If 0 is returned, the vertex remains unchanged. If the object specifies displacement approximations, curvature introduced by displacement can lead to further subdivision. Here is an example:

```    struct mydisplace {
miTag             tex;
miScalar          factor;
};

miBoolean mydisplace(
miScalar          *result,
miState           *state,
struct mydisplace *paras)
{
miColor           color;

mi_lookup_color_texture(&color, state,
*mi_eval_tag(&paras->tex),
&state->tex_list[0]);

*result += (color.r + color.g + color.b) / 3 *
*mi_eval_scalar(&paras->factor);
return(miTRUE);
}
```

Note that the shader adds its displacement to the result instead of storing it. This allows chaining displacement shaders in shader lists. Shaders in shader lists get called in sequence, each adding its contribution to the result of the previous. mental ray calls the first displacement shader of the list with a result that is initialized to 0.

Displacement shaders may also change the vector along which the displacement will take place, or change , which is the original vertex position that the displacement is added to. However, note that mental ray does not check that surfaces resulting from such arbitrary displacements are free of self-intersections.

mental ray 3.x requires that an object that is displaced with a displacement shader must contain a max displace statement that specifies the maximum displacement of the object. This is the largest absolute value that any displacement shader may return. For example, if the max displace value is 2.5, then no displacement shader may move the surface more than 2.5 units in any direction. For typical displacement shaders that return a value but do not change , this means that the displacement shader must return a value in the range [-2.5, 2.5]. mental ray 3.x will print warning messages if the shader returns a value outside this interval because this can cause geometry to be clipped.

mental ray 3.1.2 and later allows the displacement shader to store a motion vector in . This vector will be interpreted as the motion of the displaced point relative to the original point on the undisplaced base surface. This allows motion blurring of the displacement, if the displacement changes rapidly between frames. This requires that motion blurring is enabled, and that the object has motion vectors or motion transformations (the displacement motion is added to the motion of the underlying surface).

mental ray 3.3 and later make first derivatives available in the state for displacement shaders. Also, the result pointer passed to displacement shaders when displacing subdivision surfaces now points to cleared memory; this is useful for displacement shader chains where each shader adds to the result of the previous shader.