State Variables

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 shader state, or simply called 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.

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, which s 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. The 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 the parent shader. 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 copy used by that ray remains available after the trace call returns. This means, if a 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 the label from state→child→label to state→label after mi_trace_transparent has returned.

Note Only the most recent child state is retained; thus state→child→child is undefined.

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 may set variables in the state of the parent by following the parent pointer. 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 any previous call. The state can not be used to pass information from one primary (camera) ray to the next. Static variables in the shader may be used for this purpose, but can pose problems on multi-processor shared-memory machines where the same shader may be executed simultaneously but still share the static variables. mental ray provides locking facilities to synchronize access to such variables and to protect critical sections supposed to be run only once at any time.

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.

The next sections provide 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 page.

The state data structure (type miState), and everything else needed to write shaders, is defined in shader.h header file, which must be included by shader source files. It is recommended to actually use the name state for the state parameter that is passed as a formal parameter to the function because some macros provided in the shader.h header file rely on this name, for example the mi_eval_* family of functions.

Copyright © 1986, 2013 NVIDIA Corporation