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, that 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-2010 by mental images GmbH