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.
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.
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.
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.
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.
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.
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.
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.)
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.
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.
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.
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.
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.
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
.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
[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-2008 by mental images GmbH