Rendering Functions

These are the functions supplied by the render modules of mental ray, called RC*. All following trace functions return miTRUE if any subsequent call of a shader returned miTRUE to indicate presence of illumination. Otherwise no illumination is present and miFALSE is returned. All trace functions derive the state of the ray to be cast from the given state of the parent ray. This state becomes the "child state" that is passed to subsequent shaders that are called by the trace function. The state is always copied, and the given state is not modified except for the state fields label, point, normal, dist and motion. These fields are copied from the child state so that the lens shader can access them in the state modified by mi_trace_eye. After the trace function returns, the caller may examine the child state (but not the grandchild, which is gone if it ever existed). Volume shaders get the same state as the previous (material) shader. Note that all point and direction vectors passed as arguments to tracing functions must be in internal space.

mi_trace_eye
miBoolean mi_trace_eye(
    miColor         *result,
    miState         *state,
    miVector        *origin,
    miVector        *direction)

casts an eye ray from origin in direction, or calls the next lens shader. If scanline rendering is turned on and state→scanline is not zero, origin and direction must be the same as in the initial call of mi_trace_eye, and the lens shader may not modify them. Lens shaders that depend on modifying ray origin and direction should be declared with the trace on option. Origin and direction must be given in internal space. This function may be used only in lens shaders. Note that mi_trace_eye stores origin and direction in state→org and state→dir, respectively, overwriting the previous values.

mi_trace_reflection
miBoolean mi_trace_reflection(
    miColor         *result,
    miState         *state,
    miVector        *direction)

casts a reflection ray from state→point to direction. It returns miFALSE if the trace depth has been exhausted or if the hit object has disabled reflection receiving. If no intersection is found, the optional environment shader is called. The direction must be given in internal space. This function may be used only in shaders called during image rendering, but not in displacement, geometry, photon, or output shaders.

mi_trace_refraction
miBoolean mi_trace_refraction(
    miColor         *result,
    miState         *state,
    miVector        *direction)

casts a refraction ray from state→point to direction. It returns miFALSE if the trace depth has been exhausted or if the hit object has disabled refraction receiving. If no intersection is found, the optional environment shader is called. Before this functions casts the refraction ray, after copying the state, it copies state→refraction_volume to state→volume because the ray is now assumed to be "inside" the object, so the volume shader that describes the inside should be used to modify the ray while traveling inside the object. It is the caller's responsibility to set state→refraction_volume to the camera's volume shader state→camera→volume or some other volume shader if it determines that the ray is now leaving the object. The direction must be given in internal space.

If ray tracing has been disabled, mi_trace_refraction cannot modify the ray direction and operates like mi_trace_transparent. This function may be used only in shaders called during image rendering, but not in displacement, geometry, photon, or output shaders.

For rendering with the rasterizer, please see the discussion in the rasterizer section.

mi_trace_transparent
miBoolean mi_trace_transparent(
    miColor         *result,
    miState         *state)

Does the same as mi_trace_refraction with dir == state→dir (that is, no change in the ray direction) but may be executed faster if the parent ray is an eye ray. It also works when ray tracing is turned off, and considers visible as well as trace objects. If the ray direction does not change (because no index of refraction or similar modification is applied), it is more efficient to cast a transparency ray than a refraction ray. Like mi_trace_refraction, this function copies the refraction volume shader to the volume shader because the ray is now assumed to be inside the object. This function may be used only in shaders called during image rendering, but not in displacement, geometry, photon, or output shaders. The function returns miFALSE and a transparent black color if the hit object has disabled transparency receiving.

In rasterizer mode mi_trace_transparent always returns miFALSE and a transparent black color if no ray has been traced yet. Since the rasterizer separates shading from compositing, there is no object behind the current surface at the time the material shader is called. The object behind will be shaded at some other time, and both results are composited long after the material shaders have returned. As long as the shader uses standard linear composition for mi_trace_transparent results, returning black gives exactly the same result regardless of whether rasterizer mode is in effect or not, the composition just happens later. However, if the shader performs non-standard compositing, or evaluates environments if mi_trace_transparent returns false, it must be modified to work properly with the rasterizer. Shaders can detect if the rasterizer is enabled by testing state→options→scanline == miRENDER_FH_RAST (or state→options→scanline == 'r' which is identical). In case rasterizer and ray tracing are both turned on, state→scanline may be checked to determine if the current intersection was found by the rasterizer (state→scanline != 0) or ray tracing (state→scanline == 0).

mi_trace_continue
miBoolean mi_trace_continue(
    miColor * const result,
    miState * const state)

Continues to trace the current ray in the same direction. Unlike other trace calls, state→origin is not set to state→point but remains unchanged, state→type remains unchanged, and no new state is created. There are no trace depth checks. Effectively, this call pretends to the next intersection that the current intersection never happened, although the shader that calls mi_trace_continue does have the option to manipulate the state and returned color. Care should be taken because the state is not copied, so the next intersection will have operated on state instead of state→child, state→child is left undefined. This function can be used to control object visibility based on more complex criteria than the object visible flag.

Unlike mi_trace_transparent, which will ignore the intersections happening very close to the origin of the transparency ray, mi_trace_continue guarantees that if there is another triangle coplanar to the hit triangle, then the other triangle will also be hit. The order with which the multiple coplanar triangles are hit is undefined.

mi_trace_environment
miBoolean mi_trace_environment(
    miColor         *result,
    miState         *state,
    miVector        *direction)

casts a ray into the environment. The trace depth is not incremented or checked. The environment shader in the state is called to compute the color to be returned. The direction must be given in internal space.

mi_trace_probe
miBoolean mi_trace_probe(
    miState         *state,
    miVector        *direction,
    miVector        *org)

Cast a ray into the scene just to check for intersections.

Casts a ray into the scene, starting at org with the direction direction, both in internal space coordinates. If nothing is hit, miFALSE is returned. If the ray hits another object, miTRUE is returned and state→child is set to the state that the material shader of the hit object would have seen. However, unlike all other mi_trace_* functions, no shader is called. Note, that the state state→child does not itself have a state, so it cannot be used to call a material shader at the hit object directly. This requires setting up an artificial "grandchild" state:

if (mi_trace_probe(state, &dir, &org)) {
        miState grandchild;
        state->child->child = &grandchild;
/* no texture, bump, or derivative vectors ! */
        if (mi_call_material(&result, state->child))
                /* use the result */
}

This sequence works roughly like mi_trace_reflection, except that no ray levels are tested, no environment is sampled, and no volume shaders are called. Note that mi_trace_probe will always return miFALSE if ray tracing is disabled.

If the start point of the ray is changed by modifying state→origin before calling mi_trace_probe, then state→pri should be set to 0, and restored after mi_trace_probe returns. state→pri is used to prevent self-intersections, which is not useful if the start point was modified and/or the probe ray begins in empty space.

Note, that the state→child data returned from mi_trace_probe may be incomplete, it does not contain any interpolated vectors for tex_list, bump_x_list, bump_y_list, and derivs.

Note, that probe rays hit only objects that have any of the trace flags set. The reason for this is that visible-only objects don't need to be put into the ray tracing acceleration structures (like the BSP tree), which supports the model of separating high-resolution visible geometry from low-resolution trace geometry. This model is also supported by approximation flags and ray offsets.

mi_trace_probe_x
miBoolean mi_trace_probe_x(
    miState         *state,
    miVector        *direction,
    miVector        *org,
    miUint          flags)

Cast a ray into the scene just to check for intersections with objects carrying certain flags.

Works exactly like mi_trace_probe, with the additional feature of respecting the object flags of the hit primitive. The flags argument allows to pass any combination of trace flags from the enumeration miTrace_flags. This function is typically more efficient to find specific objects than tracing a regular probe ray and checking the flags on the hit primitive afterwards.

mi_sample_light
miBoolean mi_sample_light(
    miColor         *result,
    miVector        *dir,
    miScalar        *dot_nl,
    miState         *state,
    miTag           light_inst,
    miInteger       *samples)

This function casts a light ray from the light source to the intersection point, causing the light source's light shader to be called. The light shader may then calculate shadows by casting a shadow ray to the intersection point. This may cause shadow shaders of occluding objects to be called, and will also cause the volume shader of the state to be called, if there is one. Before the light is sampled, the direction from the current intersection point in the state to the light and the dot product of this direction and the normal in the state are calculated and returned in dir and dot_nl if these pointers are nonzero. The direction is returned in internal space. The light instance to sample must be given in light_inst. samples must point to an integer that is initialized to 0. mi_sample_light must be called in a loop until it returns miFALSE. *samples will then contain the total number of light samples taken; it may be larger than 1 for area light sources.

For every call in the loop, a different dir and dot_nl is returned because the rays go to different points on the area light source. The caller is expected to use these variables, the returned color, and other variables such as diffuse and specular colors from the shader parameters to compute a color. These colors are accumulated until mi_sample_light returns miFALSE and the loop terminates (leaving dir and dot_nl undefined when returning miFALSE). The caller then divides the accumulated color by the number of samples ( *samples) if it is greater than 0, effectively averaging all the intermediate results. See page mtlshaderex for an example of a shader using mi_sample_light.

When casting light rays with mi_sample_light, mental ray may check whether the primitive's normal is pointing away from the light and ignore the light in this case. For this reason some shaders, such as ray marching volume shaders, should assign 0 to state→pri first, and restore it before returning. All mi_query modes that return information on the intersected surface, such as miQ_PRI_BBOX_MIN/MAX, miQ_NUM_TEXTURES, miQ_GEO_LABEL, and miQ_GEO_DATA, do not work if pri has been modified. Shaders that operate on a surface such as material shaders may clear state→normal instead, which disables the backside light test but preserves the information on the current surface for mi_query and self-shadowing tests. (state→pri is an identifier for the intersected "primitive" of the surface.)

Light instance tags to call this function with can be found either in shader parameters of type light or array light, or in the instance light list retrieved with mi_instance_lightlist, or in the global light list obtained from mi_query.

This function works with light groups.

mi_trace_light
miBoolean mi_trace_light(
    miColor         *result,
    miVector        *dir,
    miScalar        *dot_nl,
    miState         *state,
    miTag           light_inst)

This function is a simpler variation of mi_sample_light that does not keep a sample counter, and is not called in a loop. It is equivalent to mi_sample_light except for area light sources. Area light sources must be sampled multiple times with different directions, which is not supported accurately by this function because it can only return a single direction and dot_nl. This function is provided for backwards compatibility with previous versions of mental ray, and should not be used for new projects.

mi_trace_shadow
miBoolean mi_trace_shadow(
    miColor * const result,
    miState * const state)

This function computes shadows for the given light ray by casting shadow rays. It is normally called from a light shader to take occluding objects that prevent some or all of the light emitted by the light source to reach the illuminated point (whose material shader has probably called the light shader). The result color is modified by the shadow shaders that are called if occluding objects are found. Note that light shaders can improve performance by tracing shadow rays only if the contribution from the light is greater than some threshold, for example because distance or angle attenuation has left so little of the light color (less than 1 ⁄ 256, for example) that applying shadow occlusion to this value is not going to make any difference. This function returns miFALSE if full occlusion is detected, that is, result is black or if the hit object has shadow receiving disabled.

mi_trace_shadow_seg
miBoolean mi_trace_shadow_seg(
    miColor * const result,
    miState * const state)

recursively calls the shadow shader for the next shadow segment and returns its result, or the result of the light shader if there is no more shadow intersection. It does nothing if shadow segments are turned off. It is used by shadow shaders only; light shaders always use mi_trace_shadow. See the introduction to shader types and the shadow shader explanation for details on shadow modes. This function returns miFALSE if full occlusion is detected, that is, result is black.

mi_continue_shadow_seg
miBoolean mi_continue_shadow_seg(
    miColor * const result,
    miState * const state)

This function allows a shadow shader to continue tracing the exact same shadow segment that triggered this shadow shader, which is effectively ignoring the corresponding occluder. In other words, it allows to ignore occluders on a per shadow segment basis. The next shadow shader will be called as if the previous intersection never existed. mi_continue_shadow_seg leaves the state unchanged from the perspective of the next shadow shader. Like mi_trace_shadow_seg, this function must be called by shadow shaders only. It returns miFALSE if full occlusion is detected, that is, result is black.

mi_ray_offset
miBoolean mi_ray_offset(
    miState   *state,
    double    *offset)

All rays cast from this point on will begin a little distance away from state→point, defined by *offset. Objects closer than this distance will not be hit by the ray. This is useful if there are low-resolution shadow or trace standins (possibly created by approximation flags) that are some distance away: if the rays ignore very nearby other objects, they cannot hit the low-resolution version, which avoids self-shadowing or self-reflection, especially self-reflection caused by final gathering. The old *offset value is returned, and should be restored before the shader returns; it should be used to bracket functions like mi_trace_reflection or mi_compute_irradiance.

mi_ray_falloff
miBoolean mi_ray_falloff(
    miState   *state,
    double    *start,
    double    *stop)

All rays and photons cast within this shader call from now on will reach a maximum distance of *stop, measured from state→point when the ray or photon tracing function or mi_compute_irradiance is called. The maximum distance is applied to every single ray or photon segment; lengths are not accumulated. Objects farther away will not be hit; instead, the environment will be returned (unless cleared in the state by the shader). The *start parameter defines a falloff distance; objects at a distance between *start and *stop will fade from the object color to the environment color (or black if none), to avoid hard edges in animations. This function is useful to limit the reach of rays, especially finalgather rays, to keep computation local and not fill the geometry cache with distant objects that do not matter much anyway. The old start and stop values are returned, and should be restored before the shader returns. This function takes precedence over falloffs in the options and objects.

mi_inclusive_lightlist
miBoolean mi_inclusive_lightlist(
    int       *n_lights,
    miTag     **lights,
    miState   *state)

This function accepts a list of light source instances or light groups, and returns a modified list that includes all other instances of the instanced lights as well. If a light is instanced three times in the scene, and one (or more) of them appears in *lights, then *lights will contain all three after this call. Light groups are expanded to return the individual instances. n_lights points to an integer containing the original list size, and lights points to a pointer to the original list. After the function returns, the integer holds the new list length, and the pointer points to a new list. Both the integer and the pointer should be on the stack and should be initialized from the shader parameters using mi_eval to avoid overwriting the actual shader parameters, which should remain intact for the next shader call. The returned list should not be written to by the shader.

The new list is a copy of the global light list (see mi_query) with only those lights that match the passed original list included. The returned list remains valid until the next call to mi_inclusive_lightlist or mi_exclusive_lightlist. Note that this function involves a loop over all lights, and may be a good candidate for calling once in the init shader instead of once every time the shader is called, if *lights is known to be constant during the frame.

mi_exclusive_lightlist
miBoolean mi_exclusive_lightlist(
    int       *n_lights,
    miTag     **lights,
    miState   *state)

This function is similar to the previous, but returns all global light instances except those whose instanced light match a light instanced in the given list, or is contained in a given light group. Both functions return mutually exclusive lists when called with the same argument list. n_lights points to an integer containing the original list size, and lights points to a pointer to the original list. After the function returns, the integer holds the new list length, and the pointer points to a new list. Both the integer and the pointer should be on the stack and should be initialized from the shader parameters using mi_eval to avoid overwriting the actual shader parameters, which should remain intact for the next shader call.

The new list is a copy of the global light list (see mi_query) with the matches with the original list removed. This function is slightly slower than the previous. The returned list remains valid until the next call to mi_inclusive_lightlist or mi_exclusive_lightlist.

mi_instance_lightlist
miBoolean mi_instance_lightlist(
    int       *n_lights,
    miTag     **lights,
    miState   *state)

This function returns the expanded instance lights for the current geometry instance state→instance as specified in the scene description (see Instance Light List). This function does not expect any input lights, both n_lights and lights are out parameters. The integer n_lights points to will contain the array size of the returned light list, and lights will point to the array content. If the state instance has not inherited a light list, this functions fills the returned array with all lights present in the scene. In plain-C shaders this function can be used as an alternative to light iterators, and enables sharing of the same shader even on objects with different light sets.

mi_lightprofile_value
miScalar mi_lightprofile_value(
    void      *vlp,     /* opaque pointer to light profile */
    miScalar  phi,      /* horizontal angle */
    miScalar  costheta, /* cos of vertical angle */
    miVector  *pos,     /* sampling position on light */
    miBoolean rel)      /* return pure or relative value */

This function supports direct access to light profile data for photon emitter shaders. For a given light profile, identified by the opaque pointer vlp and obtained by mi_db_accessing the tag from the lightprofile parameter, this routine returns a light intensity. This intensity is either relative (normalized to a factor in the range 0…1) if rel is miTRUE, or the raw values from the vendor-supplied profile file (Candelas in the case of IES and Candelas per 1000 Lumen flux in the case of Eulumdat) if rel is miFALSE. The phi and costheta arguments define the horizontal angle and the cosine of the vertical angle, respectively, as defined by the light profile. This function is intended for light emitter shaders that operate directly with angles; light shaders should use mi_lightprofile_sample.

mi_lightprofile_sample
miScalar mi_lightprofile_sample(
    miState   *state,
    miTag     light_profile,
    miBoolean rel)

This is a variant of mi_lightprofile_value with a simplified interface suitable for light shaders. The vlp pointer is derived from accessing light_profile, and phi, costheta, and pos are derived from the direction and point variables of state. The rel flag is passed through.

mi_compute_irradiance
miBoolean mi_compute_irradiance(
    miColor   *result,
    miState   *state)

This function computes the irradiance corresponding to indirect diffuse illumination at the intersection point given in state→point. It is used in material shaders to add indirect illumination such as caustics or color bleeding. If state→pri is zero, miFALSE is returned. The mi_compute_irradiance function, if called to evaluate irradiance from final gathering, will return the average of all alphas from finalgather rays. This allows a simple form of ambient occlusion mapping. The final gather receive mode must be enabled in order to compute final gather contributions with this function.

mi_compute_irradiance_backside
miBoolean mi_compute_irradiance_backside(
    miColor   *result,
    miState   *state)

This function is equivalent to mi_compute_irradiance, except that it computes the irradiance on the back side of the surface, as defined by the surface normal.

mi_compute_avg_radiance
typedef struct miIrrad_options {
    int        size;                  /* size of the structure */
                                        /* finalgather part... */
    int        finalgather_rays;      /* no. rays in final gather */
    miScalar   finalgather_maxradius; /* maxdist for finalgather */
    miScalar   finalgather_minradius; /* mindist for finalgather */
    miCBoolean finalgather_view;      /* radii in raster pixels? */
    miUchar    finalgather_filter;    /* finalgather ray filter */
    miUchar    padding1[2];           /* padding */
                                        /* globillum part... */
    int        globillum_accuracy;    /* no. GI photons in estimation */
    miScalar   globillum_radius;      /* maxdist for GI photons */
					/* caustics part... */
    int        caustic_accuracy;      /* no. caustic photons in est. */
    miScalar   caustic_radius;        /* maxdist for caustic photons */
                                        /* extensions... */
    miUint     finalgather_points;    /* #fg points for interpolation */
    miScalar   importance;            /* importance factor */ 
    /* this structure may be extended in the future */
} miIrrad_options;


miBoolean mi_compute_avg_radiance(
    miColor                *result,
    miState                *state,
    miUchar                 face,           /* 'f' front, 'b' back  */
    struct miIrrad_options *irrad_options); /* options to overwrite */

This function is a generalization of the mi_compute_irradiance and mi_compute_irradiance_backside functions with a common interface. Additionally, it allows to override quality parameters for final gathering and photons on a per-call basis.

The function
mi_compute_avg_radiance (result, state, 'f', NULL) returns the same result as
mi_compute_irradiance (result, state) divided by π.
In other words, the color result of mi_compute_irradiance is exactly π times brighter than that of mi_compute_avg_radiance.
There is a similar relationship between
mi_compute_avg_radiance (result, state, 'b', NULL) and
mi_compute_irradiance_backside (result, state).

For overriding finalgather and/or photon quality settings, a non-NULL pointer to a properly setup miIrrad_options struct must be passed in as fourth argument. All fields must be initialized before this struct is passed to mi_compute_avg_radiance. A macro miIRRAD_DEFAULT may be used to initialize the structure with defaults from state→options, and a subset of the structure fields can be modified explicitly after that.

The importance factor may be used by a shader to hint mental ray kernel to use more of fewer finalgather rays for a specific finalgather point. For example, a shader may pass the intensity of the diffuse component to make mental ray trace more finalgather rays in the bright part of the scene and less in the dark part. For a semi-transparent glass, a shader may use the transparency as importance in order to reduce the number finalgather rays used for computing finalgather points behind the glass. If importance is not set, mental ray computes the default one based on the current reflection and refraction level.

Note that miIrrad_options may be extended in the future versions, but explicitly given size fields allows two-way compatibility.

mi_compute_volume_irradiance
miBoolean mi_compute_volume_irradiance(
    miColor   *result,
    miState   *state)

This function computes the irradiance corresponding to indirect diffuse illumination at the point given in state state→point. It is used in volume shaders to add indirect illumination such as multiply scattered light or volume caustics.

mi_compute_directional_irradiance
miBoolean mi_compute_directional_irradiance(
    miColor   *result,
    miState   *state,
    miScalar  r,
    miScalar  g1,
    miScalar  g2)

This function is a generalization of mi_compute_volume_irradiance that calculates the volume irradiance obtained when the forward or backward scattering directions (measured with respect to the light ray direction) are preferred over sideways scattering. The parameters g1 and g2 are used to quantify two independent instances of these. Values between 0 and 1 specify forward scattering, while values between -1 and 0 specify backward scattering. A value of 0 indicates no preference, that is, diffuse scattering. The blending parameter r specifies to what extent the two choices should be (linearly) superimposed. For r = 0 only the choice with preferences specified by g2 contributes, while for r = 1 only the choice with preferences specified by g1 contributes. Commonly a positive choice for g1 is combined with a negative g2 and vice versa. Purely diffuse volume scattering may be computed more efficiently with mi_compute_volume_irradiance. An example polar diagram of irradiance dependent on the angle between scattering direction and light direction for values g1 = −g2 = 0.5 is given in the figure below for r = 1.0, 0.0, and 0.5.

mi_finalgather_store
typedef enum miFinalgather_store_mode {
    miFG_STORE_COMPUTE  = 1,
    miFG_STORE_SET      = 2
} miFinalgather_store_mode;


miBoolean mi_finalgather_store(
    miColor   *color,
    miState   *state,
    int       mode)

Creates a new finalgather point with the irradiance value color. Normally final gather points are created automatically based on accuracy settings, either during preprocessing, or during rendering when an irradiance is computed for a point with no nearby preexisting finalgather points. This function stores a point energy color explicitly, regardless of accuracy settings. The color value is either computed by mi_finalgather_store if mode is miFG_STORE_COMPUTE, using a procedure similar to mi_compute_irradiance, or the value specified by the caller is used directly if mode is miFG_STORE_SET.

If the mode is miFG_STORE_SET, then state→point, state→normal, and state→dist must be initialized before calling mi_finalgather_store. For best quality, state→dist should contain the distance to the closest object, but if this is not known or too expensive to probe, it may be left unchanged in the state.

This function is useful for setting finalgather points in places where they would not normally be seen by preprocessing, such as the back sides of objects. This is especially useful for lightmap shaders because light maps that compute irradiances would otherwise look better on parts of the object seen by the camera. For example, the light map shader might use mi_finalgather_store in compute mode to place finalgather points on vertices, for later lookup in output mode.

mi_ambient_occlusion
typedef struct miAmboccl_options {
    int           size;           /* size of the structure            */
                                    /* ao compute quality...            */
    int           rays;           /* number of rays to shoot          */
    miVector      axis;           /* the axis for the cone            */
    miScalar      spread;         /* cosine of the spread angle       */
    miScalar      spread_exp;     /* the exponent of the cosine distr */
    miScalar      mindist;        /* near clipping distance           */
    miScalar      maxdist;        /* far clipping distance            */
                                    /* ao lookup quality...             */
    int           cache_points;   /* number of ao points for lookup   */
} miAmboccl_options;


miScalar mi_ambient_occlusion(
    miState                       *state,
struct miAmboccl_options      *amboccl_options,
miVector                      *bent_normal);   /* opt. bent normal */

This function computes the amount of occlusion by surrounding objects at the intersection point state→point if ambient occlusion is enabled in mental ray, which is the default. This is typically a faster and less expensive method to simulate the effects of global illumination. The return value is the extent to which the area above a point is covered by geometry, ranging from 0 for no coverage to 1 for fully covered. It may be used in material shaders to scale the contribution from ambient lighting, or create effects like contact shadows.

The occlusion value is computed by tracing a number of rays into the hemisphere above the surface point and testing to what extent this region is blocked. No material shaders are called during these trace calls, hence no shading effects are considered for occlusion (in contrast to final gathering, for example).

The ambient occlusion algorithm supports a caching mechanism similar to final gathering, where occlusion values are pre-computed for distinct points only and stored in a 3d map data structure, for fast look-up and interpolation during final rendering. By default the cache is disabled in mental ray, which results in ambient occlusion calculations performed only on demand from shaders without any caching. The caching can be enabled with a scene option or on the mental ray command line. This will trigger computations for ambient occlusion before rendering starts, and independent of actual calls to this function in shaders.

The function supports additional parameters to control the ambient occlusion computation for the particular call. Passing a NULL pointer for the amboccl_options will enforce to use the ambient occlusion options and defaults set in the scene or from the mental ray command line. Passing a valid pointer to a miAmboccl_options structure, on the other hand, requires to initialize all fields before this structure is provided to the funtion mi_ambient_occlusion. The macro miAMBOCCL_DEFAULT should be used to fill the structure with reasonable values first, and then individual fields may be modified explicitly. Note, the macro needs to be called for every shading point, since it refers to state variables. The fields have the following meanings:

size
the size of the structure for the current version of mental ray, supporting future extensions without breaking binary compatibility. This value should never be changed.
rays
the number of probe rays to cast when computing the ambient occlusion value at the current shading point. If set to 0 or a negative value then mental ray will use the global scene setting provided with the options or on the command line, or the default 256 otherwise. The miAMBOCCL_DEFAULT macro sets the value of this field to -1, hence refers to the scene setting or default.
axis
the center direction of the sampling cone in world space, around which the rays are shot to compute the ambient occlusion value. It may be set to any world space direction, for instance to the normal before bump mapping. The miAMBOCCL_DEFAULT macro sets the value of this field to the current state→normal.
spread
the cosine of the angle between the axis and the extension of the cone within the rays are shot. A value of 0.0 means an angle of 90 degrees (the maximum spread, or hemisphere), values approaching 1.0 cause narrower angle, and 1.0 corresponds to 0 degrees. The miAMBOCCL_DEFAULT macro sets the value of this field to a negative out-of-range value, forcing mental ray to use the default 0.0 (full coverage).
spread_exp
exponent to be used for the weighting of the samples. A value of 1 causes Lambertian distribution, which is the default. The miAMBOCCL_DEFAULT macro sets the value to 1.
This is currently not fully implemented, values other than the default have no effect.
min_dist
max_dist
set near and far distances. This can be used to exclude contribution from geometry residing outside a given distance range, to localize the effect and accelerate the computation. By default no limiting range is active. Using a finite maximum distance also enables linear fading of the occlusion value between the minimum and the maximum distance. With infinite maximum distance no fading can be performed. The miAMBOCCL_DEFAULT macro sets the value of these fields to -1, disabling any distance limitations (distance range: 0.0 to infinity).
cache_points
the number of ambient occlusion cache points that should be used for interpolation if the cache was enabled (see above), ignored otherwise. If set to a negative out-of-range value then mental ray will use the scene setting provided with the options or on the command line, or the default 64 otherwise. If set to 0, then mental ray will ignore the cache if present. The miAMBOCCL_DEFAULT macro sets the value of this field to -1.

The bent_normal parameter will return an additional direction vector if a valid pointer is given. It provides the direction into the unoccluded part of the hemisphere. This may be used for special shading effects or acceleration purposes. It is determined as follows: during casting of the rays, the directions of unoccluded probe rays are accumulated to produce an average at the end, called the bent normal. If the current surface point is completely unoccluded, this average vector is coincidental with the original axis (or normal in the default case). If it's partially occluded, then the resulting vector can be regarded as a bending of the normal into the average direction of the unoccluded part of the hemisphere. This may be used in shaders to produce a specular highlight, or to concentrate sampling of the environment around the bent normal instead of the normal. The mental ray base shader mib_fast_occlusion provides an example implementation.

Copyright © 1986, 2015 NVIDIA ARC GmbH. All rights reserved.