next up previous contents
Next: 3.5 Shader Parameter Declarations Up: 3. Using and Writing Previous: 3.3 Shader Type Overview

Subsections

3.4 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 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. It is recommended to call the state parameter that shaders receive as a formal parameter state because some macros provided in the mi_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 mi_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 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 below. The first table lists all state variables that remain unchanged for the duration of the frame:

3.4.1 Frame

 

type name content
int version shader interface version
miTag camera_inst tag of camera instance
miCamera * camera camera information
miRc_options * options general rendering options

  The camera data structure pointed to by camera has the following fields. None of these may be written to by a shader.

 

type name content
miBoolean orthographic orthographic rendering
float focal focal length of the camera
float aperture aperture of the camera
float aspect aspect ratio y$ \over$x
miRange clip Z clipping distances
int x_resolution image width in pixels
int y_resolution image height in pixels
int window.xl left image margin
int window.yl bottom image margin
int window.xh right image margin
int window.yh top image margin
miTag volume camera volume (atmosphere)
miTag environment camera environment shader
miTag lens lens shader or lens shader list
miTag output output shader or output shader list
int frame frame number
float frame_time frame time in seconds
float x_offset2.1 x offset of image in pixels
float y_offset2.1 y offset of image in pixels

  The option data structure pointed to by option has the following format. The option structure may not be written to by shaders.

 

type name content
miBoolean trace ray tracing turned on?
miBoolean scanline scanline mode turned on?
miBoolean motion motion blur turned on?
char shadow no, normal, segmented, sorted
char filter nonlocal sampling filter
char acceleration ray tracing algorithm
char face front, back, or both faces
char field odd or even fields, or off
int reflection_depth max reflection trace depth
int refraction_depth max refraction trace depth
int trace_depth max combined trace depth
int photon_reflection_depth max photon reflection trace depth
int photon_refraction_depth max photon refraction trace depth
int photon_trace_depth max combined photon trace depth
miBoolean samplelock noise animation locking on/off
miBoolean caustic caustics on/off
miBoolean globillum2.1 global illumination on/off
miBoolean finalgather2.1 final gather on/off
miPointer image [ ] frame buffers for output shaders

The following parameters are in the state- >camera structure:

The following parameters are in the state- >options structure:

3.4.2 Image Samples

 The state variables in the next table describe an eye (primary) ray. There is one eye ray for every sample that contributes to a pixel in the output image. If a material shader that evaluates a material hit  by a primary ray casts secondary reflection, refraction, transparency, light, or shadow rays, all shaders called as a consequence will inherit these variables unmodified:

 

type name content
miScalar raster_x X coordinate of image pixel
miScalar raster_y Y coordinate of image pixel
miFunction * shader current shader
miLock global_lock lock shared by all shaders
short thread current thread

3.4.3 Rays

Whenever a ray is cast the following state variables are set to describe the ray:

 

type name content
miState * parent state of parent shader
miState * child state of child shader
miRay_type type type of ray: reflect, light...
miCBoolean scanline from scanline algorithm
void * cache RC intersection cache
miVector org start point of the ray
miVector dir direction of the ray
float time shutter interval time
miTag volume volume shader of primitive
miTag environment environment shader
int reflection_level current reflection ray depth
int refraction_level current refraction ray depth

=4cm6cm

miPHOTON_TRANSPARENT
is a photon transmitted directly (ie., without refraction) through a surface.

3.4.4 Intersection

 The variables in the next table are closely related to the previous. They describe the intersection of the ray with an object, and give information about that object and how it was hit.

 

type name content
miTag refraction_volume volume shader for refraction
miUint label object label for label file
miTag instance instance of object
miTag light_instance instance of light
miScalar [4] bary barycentric coordinates
miVector point intersection (ray end) point
miVector normal interpolated normal at point
miVector normal_geom geometry normal at point
miCBoolean inv_normal true if normals were inverted
miScalar dot_nd dot prod of normal and dir
double dist length of the ray
void * pri identifies hit box
int pri_idx identifies hit primitive in box
double shadow_tol safe zone to prevent self-shadows
miScalar ior index of refraction of medium
miScalar ior_in index of r. of previous medium

3.4.5 Textures, Motion, Derivatives

The following table is an extension to the previous. These variables give information about the intersection point for texture mapping. They are defined when the ray has hit a textured object:

 

type name content
miVector * tex_list list of texture coordinates
miVector * bump_x_list list of X bump basis vectors
miVector * bump_y_list list of Y bump basis vectors
miVector tex texture coord (tex shaders)
miVector motion interpolated motion vector
miVector * derivs[5] list of surface derivatives

3.4.6 User Fields

Finally, the user field allows a shader to store a pointer to an arbitrary data structure in the shader. Subsequent shaders called as a result of operations done by this shader (such as casting a reflection ray or evaluating a light or a texture) inherit the pointer and can read and write this shader's local data. Sub-shaders can also find other parent's user data by following state parent pointers, see above. With this method, extra parameters can be provided to and extra return values received from sub-shaders.

However, once the shader that has set the user pointer returns, the user pointer is lost. Its purpose is to pass information to sub-shaders down the call graph, not to pass information from one invocation of a shader to the next (for example, to the next primary ray). This implies that it is not a good idea to use  mi_mem_allocate to obtain the pointer because by definition this could result in millions of allocations, which is inefficient. Long-term shader user data should be stored in state - > shader - > user.p instead, typically allocated in the  init shader and released in the  exit shader.

The user variables are initialized to 0.

 

type name content
void * user user data pointer
int user_size user data size (optional)

The shader pointer can be used to access the shader parameters, as state- >parameters. This is redundant for the current shader because this pointer is also passed as the third shader argument, but it can be used to find a parent shader's parameters.

3.4.7 State Variables by Shader Type

 The following table describes which state variables are available in which types of shaders:

G  geometry shader  
D  displacement shader  
P  photon shader and  photon volume shader  
E  photon emitter shader  
Le  lens shader  
M  material shader and  texture shader  
T  texture shader  
V  volume shader  
Lg  light shader  
S  shadow shader  
Cs  contour store shader  
C  contour contrast shader and  contour shader  
O  output shader  

In the following table,

In the case of the options and camera variables, the shader may write neither the pointer nor any field of the options and camera structures. Note that during rendering (between the rendering and rendering finished messages), the camera and the options may differ from the scene file specifications because  phenomenon requirements and conflict detection may make adjustments. For example, a lens shader might have requested ray tracing to be turned off even though it was turned on in the scene file. In this case, shaders called during rendering would see a trace flag that is off, and other shaders such as geometry or displacement shaders do not.

variable G D P E Le M V Lg S Cs C O
version R R R R R R R R R R R R
camera_inst R R R R R R R R R R R R
camera R R R R R R R R R R R R
options R R R R R R R R R R R R
global_lock1 - rw rw rw rw rw rw rw rw rw rw -
raster_x - - - - R R R R R R - -
raster_y - - - - R R R R R R - R
parent - - R R R R R R R R - -
type R R R R R R R R R R - R
scanline - - - - r r r r r r - -
inv_normal - - r - r r r r - r - -

variable G D P E Le M V Lg S Cs C O
reflection_level - - rw rw rw rw rw rw rw rw - -
refraction_level - - rw rw rw rw rw rw rw rw - -
org - - rw rw rw rw rw rw rw rw - -
dir - - rw rw rw rw rw rw - rw - -
dist - - rw rw rw rw rw rw rw rw - R
time - - R R R R R R R R - -
ior x x x x x x x x x x x x
ior_in x x x x x x x x x x x x
material - r r r - r r r r r - -
volume - - rw rw rw rw rw rw rw rw - -
environment - - - - rw rw rw - - rw - -
refraction_volume - - rw rw - rw rw - - rw - -
label - r r r rw rw rw rw rw rw - -
instance R R R - R R R R R R - -
light_instance - - - R - - R2 R R - - -
pri3 - - r - rw rw rw rw rw rw - -
pri_idx - - r - r r r r r r - -

variable G D P E Le M V Lg S Cs C O
bary[4] - - r - r r r r r r - -
point - r r - rw rw rw rw rw rw - -
normal - r r - rw rw rw rw rw rw - -
normal_geom - - r - rw rw rw rw rw rw - -
dot_nd - - r - rw rw rw rw - rw - -
shadow_tol - - r - r r r r r r r -
tex_list - rw rw - rw rw rw rw rw rw - -
bump_x_list - - rw - rw rw rw rw rw rw - -
bump_y_list - - rw - rw rw rw rw rw rw - -
motion - - rw rw rw rw rw rw rw rw - -
derivs4 - - rw - rw rw rw rw rw rw - -
tex x x x x x x x x x x x x
shader R R R R R R R R R R R R
child - - R R R R R R R R - -
thread R R R R R R R R R R R R
user x x x x x x x x x x x x
user_size x x x x x x x x x x x x

  1 global_lock is accessed with   mi_lock and mi_unlock only.
  2 If state - > type is miRAY_SHADOW
  3 Set to 0 to cast rays from empty space. Do not set to other values.
  4 If the object contains surface derivatives

See page [*] for a similar table listing available shader interface functions.


next up previous contents
Next: 3.5 Shader Parameter Declarations Up: 3. Using and Writing Previous: 3.3 Shader Type Overview
Copyright 2000 by mental images