home << prev next >> contents  


RC Functions

These are the functions supplied by the render modules of mental ray, 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.

    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. The allowed origin and direction values are restricted when using the ray classification2.1 rendering algorithm (not recommended, it exists only for backwards compatibility). 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 and , respectively, overwriting the previous values.

    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, in mental ray 3.4 and higher, 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.

    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, in mental ray 3.4 and higher, 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→cameravolume 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.



    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 in mental ray 3.2, 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. In mental ray 3.4 this function returns miFALSE and a transparent black color if the hit object has disabled transparency receiving.

In rasterizer mode (formerly called Rapid Motion), 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 nonstandard compositing, or evaluates environments if mi_trace_transparent returns false, it must be modified to work properly in rasterizer mode. A shader can detect rasterizer mode by testing whether .

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

continues the current ray, in the same direction. Unlike other trace calls, is not set to but remains unchanged, 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 . 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.

    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.

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

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 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 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;
                  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. Also note that mental ray 3.1 finds objects regardless of flags, while mental ray 3.2 finds only objects that have the trace flag set.

If the start point of the ray is changed by modifying before calling mi_trace_probe, should be set to 0, and restored after mi_trace_probe returns. 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.

Until mental ray 3.2, a probe ray can hit all onbjects, but beginning with mental ray 3.2 it sees only objects that have the trace flag set. The reason for this is that visible-only objects no longer 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.

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

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 [17]. 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. In mental ray 3.1.2 or later, shaders that operate on a surface such as material shaders may clear instead, which disables the backside light test but preserves the information on the current surface for mi_query and self-shadowing tests. ( 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 global light list obtained from mi_query.

This function works with light groups introduced in mental ray 3.3.

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

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 mental ray 1.9 only, do not use it for new projects.

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

computes shadows for the given light ray by casting shadow rays. This function 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, in mental ray 3.4 and higher, if the hit object has shadow receiving disabled.

    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.

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

3.4 allows a shadow shader to continue tracing the exact same shadow segment that triggered this shadow shader, thus 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.

    miBoolean mi_ray_offset(
        miState   *state,
        double    *offset)

All rays cast from this point on will begin a little distance away from , 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.

    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 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.

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

This function accepts a list of light source instances, 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. 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.

This function works with light groups introduced in mental ray 3.3.

    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. 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.

This function works with light groups introduced in mental ray 3.3.

    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 */

3.1 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.

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

3.1 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.

    miBoolean mi_compute_irradiance(
        miColor   *result,
        miState   *state)

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

    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.

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


    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 */

        /* 3.5 extensions */
        miUint     finalgather_points;    /* #fg points for interpolation */
        miScalar   importance;            /* importance factor */ 

        /* this structure may be extended in the future */
    } miIrrad_options;

This function basically subsumes mi_compute_irradiance and mi_compute_irradiance_backside functions under a common interface and additionally allows overriding quality parameters for final gathering and photons on a per-call basis.

mi_compute_avg_radiance (result, state, 'f', NULL) returns the same result as mi_compute_irradiance (result, state) divided by . In other words, mi_compute_irradiance's result is exactly times brighter than mi_compute_avg_radiance. There is a similar relationship between mi_compute_avg_radiance (result, state, 'b', NULL) (note the 'b') 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 intialized before this struct is passed to mi_compute_avg_radiance. A macro miIRRAD_DEFAULT may be used to initialize the structure with defaults from , and a subset of the sturcture fields can be modified explicitely after that.

The importance3.5 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 explicitely given size fields allows two-way compatibility.

    miBoolean mi_compute_volume_irradiance(
        miColor   *result,
        miState   *state)

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

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

This function is supported in mental ray 2.1.43 and later. mi_compute_directional_irradiance 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 is given in the figure below for r = 1.0, 0.0, and .

    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, , and must be initialized before calling mi_finalgather_store. For best quality, 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.

[17] mental ray 3.3 and later leave dir and dot_nl undefined when returning miFALSE. Previous versions set it to 0.0.

home << prev next >> contents  


Copyright © 1986-2007 by mental images GmbH