Every shader needs to access information about the current state of mental ray, and information about the intersection that led to the shader call. This information is stored in a single structure known as the state. Not all information in the state is of interest or defined for all shaders; for example, lens shaders are called before an intersection is done and hence have no information such as the intersection point or the normal there. See page statevartable for a table of which variable is available in which type of shader.
It is recommended to call the state parameter that shaders receive as a formal parameter state because some macros provided in the shader.h include file that require access to the state rely on this name (namely, the typed mi_eval_* variants). The state, and everything else needed to write shaders, is defined in shader.h, which must be included by all shader source files.
Before a shader is called, mental ray prepares a new state structure that provides global information to the shader. This state may be the same data structure that was used in the previous call (this is the case for shaders that modify another shader's result, like lens, shadow, and volume shaders); or it may be a new state structure that is a copy of the calling shader's state with some state variables changed (this is done if a secondary ray is cast with one of the tracing functions provided by mental ray). For example, if a material shader that is using state A casts a reflected ray, which hits another object and causes that object's material shader to be called with state B, state B will be a copy of state A except for the ray and intersection information, which will be different in states A and B. State A is said to be the parent of state B. The state contains a parent pointer that allows sub-shader to access the state of parent shaders. If a volume shader is called after the material shader, the volume shader modifies the color calculated by the material shader, and gets the same state as the material shader, instead of a fresh copy.
The state also contains a child pointer that, together
with the parent pointer, forms a double-linked list of states.
After a shader casts a ray, the state used by the ray remains
available after the trace call returns. This means that if trace
call returns true, the shader has full access to the intersection
information, label value, and all other state variables used by the
child shader. For example, the shader for a completely transparent
object may decide to copy state→child→label
to state→label
after mi_trace_transparency
returns. Only the most recent discarded child state is retained;
state→child→child
is undefined.
This means that it is possible to pass information from one shader to another in the call tree for a primary ray, by one of two methods: either the parent (the caller) changes its own state that will be inherited by the child, or the child follows the parent pointer. The state contains a user pointer that a parent can store the address of a local data structure in, for passing it to sub-shaders. Since every sub-shader inherits this pointer, it may access information provided by its parent. A typical application of this are inside/outside calculations performed by material shaders to find out whether the ray is inside a closed object to base the interpretation of parameters such as the index of refraction on.
Note that the state can be used to pass information from one shader to sub-shaders that are lower in the call tree. Care must be taken not to destroy information in the state because some shaders (shadow, volume, and the first eye shader) re-use the state from the previous call. In particular, the state cannot be used to pass information from one primary (camera) ray to the next. Static variables can be used in the shader for this purpose, but care must be taken to avoid multiple access on multiprocessor shared-memory machines. On such a machine, all processors share the same set of static variables, and every change by one processor becomes immediately visible to all other processors, which may be executing the same shader at the same time. Locking facilities are available in mental ray to protect critical sections that may execute only once at any time.
Here is a complete list of state variables usable by shaders. Variables not listed here are for internal use only and should not be accessed or modified by shaders. Some variables are available only in some types of shaders; see the "State Variables by Shader Type" section on page statevartable. The first table lists all state variables that remain unchanged for the duration of the frame:
Copyright © 1986-2008 by mental images GmbH