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