Auxiliary Functions

mi_lookup_color_texture
    miBoolean mi_lookup_color_texture(
        miColor         *color,
        miState         *state,
        miTag           tag,
        miVector        *coord)

tag is assumed to be a texture as taken from a color texture parameter of a shader. This function checks whether the tag refers to a shader (procedural texture) or an image, depending on which type of color texture statement was used in the .mi file. If tag is a shader, coord is stored in state→tex, the referenced texture shader is called, and its return value is returned. If tag is an image, coord is brought into the range (0..1, 0..1) by removing the integer part, the image is looked up at the resulting 2D coordinate, and miTRUE is returned. If the texture is marked with the filter keyword, multi-level pyramid filtering is performed, a procedure related to classical mip-map textures. In both cases, the color resulting from the lookup is stored in * color.

mi_lookup_filter_color_texture
    typedef struct {
        miScalar        eccmax;
        miScalar        max_minor;
        miScalar        circle_radius;
        miBoolean       bilinear;
        miScalar        spare[10];
    } miTexfilter;

    miBoolean mi_lookup_filter_color_texture(
        miColor         *color,
        miState         *state,
        miTag           tag,
        miTexfilter     *paras,
        miMatrix        ST)

This function provides higher quality filtering than the multi-level pyramid filtering of mi_lookup_color_texture described above using a transformation ST which transforms the coordinate system centered in the current raster position in screen space to texture space. The functions mi_texture_filter_project and mi_texture_filter_transform are provided for helping to calculate this transformation matrix.

This function expects that tag does not refer to a texture shader, that is, it works only on texture images. It will return miFALSE when used with incorrect parameters or if a projection failed.

In the filtering algorithm a circle around the current raster position is projected to an ellipse in texture space, and returns the average color of all texture pixels inside the ellipse. If the texture defined by tag is a pyramid texture, multi-level lookup of the texture pixels is performed to speed up the filtering. In the algorithm the level calculation is based on the minor radius of the ellipse.

The filtering can be controlled by choosing different values in paras. If paras is a null, default values for medium filter quality are used.

The eccmax field in miTexfilter specifies the maximum allowed eccentricity of the ellipse. It must be equal to or greater than 1.0. The eccentricity is defined by the ratio of the major and minor radius. Under severe projective distortion the ellipse can have a very large eccentricity and too many texture pixels would be covered by the elliptical area, resulting in long rendering times. In order to limit the filtering time in these cases, the eccentricity threshold can be specified. If the eccentricity is greater than this value, the minor radius of the ellipse is made larger allowing for a potentially higher level in the texture image pyramid since the level calculation is based on the minor radius.

In this calculation a level is selected where the minor radius of the ellipse has a maximum length of max_minor texture pixels. In each successive level in the image pyramid the radius is divided by two, and there are fewer pixels inside the elliptical area. The useful range for eccmax is approximately 10 to 30, higher values will result in better antialiasing. For max_minor the range should be 3 to 8. Higher values result in better antialiasing.

The size of the projected screen-space circle can be modified with the circle_radius parameter. Larger values will result in more blurring since the elliptical area is also made larger. Smaller values will increase the aliasing. The useful range for this field is 0.4 to 1.0.

When a magnification area is detected, that is, an area in which the pixels are not compressed (the elliptical area is smaller than a texture pixel), bilinear texture pixel interpolation can be switched on by setting the bilinear field to miTRUE, which results in a more blurry image.

See elliptical texture filtering for an example.

mi_lookup_scalar_texture
    miBoolean mi_lookup_scalar_texture(
        miScalar        *scalar,
        miState         *state,
        miTag           tag,
        miVector        *coord)

This function is equivalent to mi_lookup_color_texture, except that tag is assumed to refer to a scalar texture shader or scalar image, as defined in the .mi file with a scalar texture statement, and a scalar is looked up returned in * scalar. Filtering of scalar textures (enabled with filter scalar texture statements) is supported.

mi_lookup_vector_texture
    miBoolean mi_lookup_vector_texture(
        miVector        *vector,
        miState         *state,
        miTag           tag,
        miVector        *coord)

This function is also equivalent to mi_lookup_color_texture, except that tag is assumed to refer to a vector texture shader or vector image, as defined in the .mi file with a vector texture statement, and a vector is looked up returned in * vector. Vector textures cannot be filtered.

mi_texture_filter_project
    miBoolean mi_texture_filter_project(
        miVector        p[3],
        miVector        t[3],
        miState *const  state,
        miScalar        disc_r,
        miUint          space)

This function helps in calculating the screen to texture space transformation matrix required by mi_lookup_filter_color_texture. It projects three points including the current raster position onto the current intersection primitive (state→pri) plane and calculates the texture coordinates in the intersections. If state→pri is null, or if the projection fails, miFALSE is returned.

This function assumes that the current intersected object has a texture space associated and uses space as an index into the texture space. The three screen space points are returned in p, the corresponding two dimensional texture space points are put into t. The first point in the array is always the central raster position (0,0), the others are inside a disc with radius of disc_r from this central position. Note that the points are relative to the central position, absolute screen space coordinates are not used. The value of disc_r should be set to 0.5 in most cases, since the full pixel is projected to texture space. However, when there are highly curved objects in the scene, a smaller value can effectively remove projection problems where the projected points are far outside the hit triangle primitive.

mi_texture_filter_transform
    miBoolean mi_texture_filter_transform(
        miMatrix        ST,
        miVector        p[3],
        miVector        t[3])

This function helps in calculating the screen to texture space transformation matrix required by mi_lookup_filter_color_texture. The three two dimensional screen space points in p and the corresponding three two dimensional texture space points form a linear equation which is solved for the transformation matrix. See elliptical texture filtering for an example. This function returns miFALSE if the linear equation mentioned above has no solution.

mi_luminance
    miScalar mi_luminance(
        miState         *state,
        miColor         *color);

Return the luminance of color, by multiplying each RGB component by a factor (default 1 ⁄ 3;) and adding the results. The factors can be changed with the luminance weight statement, or the luminance_weight field in the miOptions structure. The purpose of having a single function to do this calculation is to make luminance calculations in shaders consistent across all shaders, and making the weight easily changeable in one central place. This is for shaders only; mental ray does not calculate luminances or use the weights in any way.

mi_tri_vectors
    miBoolean mi_tri_vectors(
        miState         *state,
        int             which,
        int             ntex,
        miVector        **a,
        miVector        **b,
        miVector        **c)

All the information in the state pertains to the interpolated intersection point in a triangle. This function can be used to obtain information about the uninterpolated triangle vertices. Together with the barycentric coordinates in the state, parameters retrieved with mi_tri_vectors may be interpolated differently by the shader. The which argument is a character that controls which triple of vectors is to be retrieved:

which vector
'p' the points in space
'n' the normal vectors
'm' the motion vectors
't' the texture coordinates of texture space ntex
'u' the U bump basis vectors
'v' the V bump basis vectors
'U' the first surface derivative in U (d P du)
'V' the first surface derivative in U (d P dv)
'X' the second surface derivative d² P du²
'Y' the second surface derivative d² P dv²
'Z' the second surface derivative d² P du dv
'*' the user vectors

A pointer to the vectors is stored in *a, *b, and *c. The shader may not modify these vectors. They are stored in the space used when the scene was created (either object space or camera space depending on state→options→render_space; the original data is accessed without implicit transformation to internal space. If the requested triple is not available, miFALSE is returned. This function relies on state→pri; it only works if the shader has not modified this variable, as some ray-marching volume shaders do.

This function may not be called in displacement shaders because triangles do not yet exist at that stage. Displacement displaces vertices, not triangles; triangles are built from final vertices later. It also may not be called for hair objects, because hair is not based on triangles. (mental ray 3.2 and later detect this case and return miFALSE for hair objects.)

mi_texture_interpolate
    miBoolean mi_texture_interpolate(
        miState         *state,
        miUint          space,
        miScalar        *result)

This function interpolates the current intersection state→pri texture coordinates, using the barycentric coordinates from the state. The texture space index is given with space. The coordinates are written to the array result which must be allocated large enough according to the dimension of the texture space. This function is needed only for geometry with texture coordinates that have more or fewer than three dimensions. Standard 3D texture coordinates should be read from state→tes_list. Non-3D texture coordinates are supported only for subdivision surfaces and raw primitive lists. Use the miQ_TEXTURE_DIM mode of mi_query to find the dimension of a texture coordinate.

mi_raster_unit
    miBoolean mi_raster_unit(
        miState         *state,
        miVector        *x,
        miVector        *y)

Transforms a pair of X and Y unit vectors in raster space to the current object space. In other words, the returned x and y vectors specify the size of a pixel in object space. This information is useful for selecting filter parameters in the shader, such as bump map precisions or texture lookups. This function assumes a pinhole camera. The orientation of the surface at the current shading point is not taken into account.

mi_shaderstate_set
    miBoolean mi_shaderstate_set(
        miState         *state,
        const char      *key,
        void            *value,
        int             valsize,
        int             lifetime)

Store a data block *value under the name key. The data block can be retrieved by key with mi_shaderstate_get later. Shorter keys are slightly faster to hash and compare. valsize is the size of the value block to store. A copy of * value is made. If a data item with the same key exists, it is replaced with the new one. If value or valsize are null, an existing data item with the same key is deleted and none is created. The lifetime controls when the data item is deleted: at the end of the current eye ray if lifetime is miSS_LIFETIME_EYERAY, or at some later point, but no later than the end of the rectangle, if it is miSS_LIFETIME_RECT. The latter is slightly faster. In any case, data items are separate for each host, thread, and rectangle.

Data items stored with this mechanisms are intended for communication between shaders called during evaluation of a single eye ray, both upstream and downstream. For example, a material shader may set a data item to be picked up by any later light shader, or by the root lens shader. It is a replacement for state→user, which works only downstream and causes conflicts if more than one data item is needed. The mechanism is only available in eye ray context during rendering, but not in geometry, output, displacement, or other shaders that do not get called as a consequence of an eye ray. As a special case, use in lightmap shaders is supported.

Note that transparency in rasterizer mode (formerly called Rapid Motion) is not performed by casting rays that could carry shader state, but by compositing at a later stage. For this reason it is not possible to transport shader state through a call to mi_trace_transparency In rasterizer mode.

mi_shaderstate_get
    void *mi_shaderstate_get(
        struct miState  *state,
        const char      *key,
        int             *valsize)

Look up a data element previously stored with mi_shaderstate_set, under the same key, and return a pointer to the stored value. Also return the size of the stored value in *valsize, unless valsize is a null pointer. If no data element is found, a null pointer is returned and valsize is undefined.

mi_shaderstate_enumerate
    void mi_shaderstate_enumerate(
        miState         *state,
        miBoolean       (*cb)(void *arg, char *key, void *val, int vsz, int l),
        void            *arg)

The callback cb is called for each known item, with the opaque arg pointer, key, value, value size, and lifetime. If cb is a null pointer, the list is printed using mi_info. This function is intended for debugging only; the implied linear search is inefficient. Callback mode is useful to interpret the contents of the value pointer; mi_info merely prints an address.

mi_fb_put
    miBoolean mi_fb_put(
        miState         *state,
        int             fb,
        void            *data)

Store data into the sample so that it gets filtered and stored in user frame buffer fb later 1. The type of the data to copy from * data is determined by the frame buffer type as defined in the options block. The frame buffer number fb must be a number equal to or greater than 0, corresponding to the fb n number in the frame buffer statements. If this frame buffer was not defined, this function has no effect and returns miFALSE. The data is stored in the current sample (i.e., the current location for which the primary ray was cast), and is filtered to create frame buffer pixels after all samples in the region have been taken. There is no way to store user frame buffer data in arbitrary locations with this function. It should be called for all samples and all defined user frame buffers to avoid leaving holes; if user frame buffer data is left undefined in a sample because mi_fb_put was not called, the data defaults to zero and is filtered as such.

Output shaders may not use this function because there is no notion of "samples" during output shading; instead, they must use the standard mi_img_put_* functions with an offset of miRC_IMAGE_USER + fb. Final gathering, light mapping, displacement, and geometry shaders may not use mi_fb_put and mi_fb_get because the frame buffers are only available during frame rendering. In previous versions of mental ray, the data type of a frame buffer was stored in state→options→images_info.

mi_fb_get
    miBoolean mi_fb_get(
        miState         *state,
        int             fb,
        void            *data)

Retrieve data from user frame buffer fb 1. The type of the data copied to * data is determined by the frame buffer type as defined in the options block. It will never be larger than 16 bytes (the size of a miColor). The frame buffer number fb must be in the range 0...7. If this frame buffer was not defined, this function returns miFALSE, and no data is stored. This function is intended to let shaders retrieve data that may have been stored by shaders called in later ray generations, but like mi_fb_put it is limited to the current sample. Again, output shaders may not use this function because there is no notion of "samples" during output shading; instead, they must use the standard mi_img_get_* functions with an offset of miRC_IMAGE_USER + fb.

mi_output_image_open
    miImg_image *mi_output_image_open(
        miState         *state,
        miUint          idx)

Returns an image pointer for a frame buffer index. idx is one of the miRC_IMAGE_RGBA, miRC_IMAGE_USER etc. constants. May only be called from output shaders. Versions prior to 3.4 could obtain the output image from a static array in the state, which is no longer available in mental ray. This means that older output shaders need to be rewritten for mental ray.

mi_output_image_close
    void mi_output_image_close(
        miState         *state,
        miUint          idx)

Closes an opened frame buffer image that has been opened with mi_output_image_open. idx is one of the miRC_IMAGE_RGBA, miRC_IMAGE_USER etc constants. May only be called from output shaders.

mi_geoshader_add_result
    miBoolean mi_geoshader_add_result(
        miTag           *result,
        const miTag     item)

This function should be called from geometry shaders for adding a scene element to the result. If result or item are null, miFALSE is returned. If result refers to a null tag, an instance group is created and returned in result. If result is non-null but does not refer to an instance group, an instance group is created, the result element is put into this group and the group is returned in result. Now that this function has enforced that an instance group element is always returned, the item element is put into the returned group. See page geoshaderex for an example.

mi_geoshader_tesselate
    miBoolean mi_geoshader_tesselate(
        miState         *state,
        miTag           *leaves,
        miTag           source)

This function should be called from geometry shaders only. It builds a list of instances that describes the object, instance group, or instance source. If source contains more than one object, there will be multiple instances in the leaves list. The leaves argument is set to the tag of the first instance; the others are chained to one another with the next field in each instance. The last instance in the list has a null next field.

The tessellation function also tessellates the geometry described by each instance, and attaches the triangles resulting from the tessellation to the boxes field of the instance. Triangles are stored in boxes, which are data structures consisting of a header, a vector list, a vertex list, and a triangle list. In mental ray 2.x, boxes have a maximum size; if an object does not fit into one box, more are generated and chained using the next_box tag in each box.

mi_geoshader_tesselate_end
    miBoolean mi_geoshader_tesselate_end(
        miTag           leaves)

Release all memory allocated by mi_geoshader_tesselate. This function releases all instances and boxes attached to the instance chain leaves, which was created by mi_geoshader_tesselate. Multiple instance lists can exist at the same time; it is not necessary to release one before creating the next but since memory demands may be substantial if the tessellated geometry is large, it is recommended to not keep instance lists longer than necessary.

mi_geoshader_echo_tag
    typedef struct {
        miBoolean       prefer_approx_polygons; /* triangles from polygons */
        miBoolean       prefer_approx_faces;    /* triangles from surfaces */
        miBoolean       ascii_output;           /* non-binary output */
        miBoolean       verbatim_textures;      /* dump textures verbatim ? */
        miBoolean       norendercommand;        /* disable rendercmd echo? */
        miUint          explode_objects;        /* write objects to subfiles */
        miTag           leaf_insts;             /* for prefer_approx_* lookup*/
        miBoolean       nolinkcommand;          /* don't echo link statements*/
        miUint          dont_echo;              /* EO_* bitmap: omit these */
        miUint          dont_recurse;           /* EO_* bitmap: no prereqs */
    } miEchoOptions;

    miBoolean mi_geoshader_echo_tag(
        FILE            *fp,
        miTag           tag,
        miEchoOptions   *eopt)

This function exists for debugging geometry shaders. It echos a .mi scene fragment, anchored at tag, to the stdio file fp. The options should be cleared with memset or similar, and then initialized (the structure occasionally grows; this way recompilation will suffice). The prefer_approx_polygons, prefer_approx_faces, norendercommand, and nolinkcommand must be miFALSE (0). ascii_output prints geometry vectors as ASCII numbers instead of the default binary vectors. verbatim_textures includes texture files in the echoed scene, instead of referencing them by file name. explode_objects, if nonzero, causes all objects with more than the given number of vectors to be echoed to independent subfiles; this is not generally useful for debugging. The dont_echo and dont_recurse bitmaps of miEO_ bits allow excluding certain scene element types. In a geometry shader it may be useful to set dont_recurse to ∼0 to suppress echo of all tags that tag is referencing. See the command-line option -echo (appendix A) for more details.

mi_string_substitute
    char *mi_string_substitute(
        char            *newname,
        char            *name,
        long            size)

This function performs substitutions on the file path name, and returns the substituted path in newname, which must point to a char buffer of sufficient size ( miPATHSIZE is recommended). The size of the buffer must be passed as size to prevent buffer overruns. Substitutions are taken from the MI_RAY_SUBSTITUTE environment variable, the mental ray registry mechanism, and the (obsolete) Softimage Linktab mechanism. For details on the first two refer to [Driemeyer 01]. The value of newname is returned.

mi_volume_num_shaders
    miInteger mi_volume_num_shaders(
        miState         *state)

In autovolume mode, volume shaders can use this function to determine the number of overlapping volumes whose volume shaders have the same (highest) volume level as the current volume shader. This is the length of the list of volume shaders to call. Refer to the autovolume section on page autovolshd for more information on autovolumes. mental ray also supports autovolume mode for photon emitters, so photon shaders can determine which photon volumes a photon passes through.

mi_volume_cur_shader
    miInteger mi_volume_cur_shader(
        miState         *state)

In autovolume mode, volume shaders can use this function to determine their own position in the list of volume shaders to call. The first volume shader gets number 0.

mi_volume_tags
    miTag *mi_volume_tags(
        miState         *state)

In autovolume mode, volume shaders can use this function to retrieve the list of volume shader tags scheduled for being called for this ray segment. The length of the list can be obtained by calling mi_volume_num_shaders.

mi_volume_instances
    miTag *mi_volume_instances(
        miState         *state)

This function is a companion function to mi_volume_tags. It returns a constant pointer to the leaf instances through which the current ray is traveling. The n-th instance tag in the returned array corresponds to the n-th volume shader tag in the array returned by mi_volume_tags. A volume shader could use this function to store the instance it is associated with to state→instance (which otherwise holds the instance of the hit primitive) to enable correct object transformations from the vector_to_object and point_from_object family. The instance tag can also be used to obtain instance-specific user data.

mi_volume_user_color
    miColor *mi_volume_user_color(
        miState         *state)

In autovolume mode, volume shaders can use this function to store an arbitrary color value. This is useful for communication between different volume shaders in the list. For example, the first volume shader can initialize this value, and the last can return it.

mi_opacity_set
    void mi_opacity_set(
        miState         *state,
        miColor         *color)
  

This function has an effect in the rasterizer rendering mode (formerly called Rapid Motion) only. Since the rasterizer handles transparency in a separate shading sample combination pass and not inside the material shader, the shader cannot normally create matte objects by returning a transparent color regardless of other objects behind the shaded surface. The shading sample combination phase would fill in the obscured objects. In this case, the shader may use mi_opacity_set to explicitly set the opacity to be used for combining instead oif the result alpha. As a bonus, the opacity may be set for R, G, B, and A separately, instead of using the result alpha for all components. The color is saved along with the result color returned by the shader until the combination phase.

mi_opacity_get
    miBoolean mi_opacity_get(
        miState         *state,
        miColor         *color)
  

After mi_opacity_set has been called at any point for the current surface shading point and all its secondary rays, it remains in effect until the rasterizer (formerly called Rapid Motion) shades the next surface point. It is saved along with the returned color until shading sample combination. Since any of the shaders of a Phenomenon can call mi_opacity_set, the companion function mi_opacity_get can be used to retrieve the opacity color last set. This is also useful in volume shaders that need to control matte opacity. The function returns miFALSE if mi_opacity_set has not been called for the current shading point yet; in this case color is undefined.

1 This function is kept for backwards compatibility, new shaders should use the new C++ shader interface to refer to new frame buffers by name.

Copyright © 1986-2009 by mental images GmbH