RIS Attributes

RIS Attributes

Attributes

Attributes are parameters in the graphics state that may change while geometric primitives are being defined. Standard attributes are described in two tables: Shading Attributes, and Geometry Attributes. Attributes can be explicitly saved and restored with RiResource. RiAttributeBegin/RiAttributeEnd blocks implicitly do a save and restore.

The documentation includes an attributes index that summarizes the attributes available in PRMan. Note that some of the defaults listed can be overridden by configuration files.


Implementation-specific Attributes

Rendering programs may have additional implementation-specific attributes that control parameters that affect primitive appearance or interpretation. These are all set by the following procedure. In addition, a user can specify graphics state attributes by pre-pending the string "user" onto the attribute name. While these attributes are not expected to have any meaning to a renderer, user attributes should not be ignored. Rather, they must be tracked according to standard attribute scoping rules and made available to shaders via the attribute function.

RiAttribute ( RtToken name, ...parameterlist... );

Set the parameters of the attribute name, using the values specified in the token-value list parameterlist.

RIB BINDING

Attribute name parameterlist

EXAMPLE

Attribute "bound" "displacement" [2.0]

SEE ALSO

RiAttributeBegin

Typical implementation-specific attributes
Attribute name/param Type Default Description
"displacementbound" "sphere" [s] float 0 Amount to pad bounding box for
"displacementbound" "coordinatesystem" [c] string "object" The name of the coordinate system that the displacement bound is measured in.
"identifier" "name" [n] string "" The name of the object (helpful for reporting errors).
"trimcurve" "sense" [n] string "inside" If "inside", trim the interior of Trim Curve regions. If "outside", trim the exterior of the trim region.

RiAttributeBegin ()
RiAttributeEnd ()

Push and pop the current set of attributes. Pushing attributes also pushes the current transformation. Pushing and popping of attributes must be properly nested with respect to various begin-end constructs.

RIB BINDING

AttributeBegin -
AttributeEnd -

EXAMPLE

RiAttributeBegin ();

SEE ALSO

RiFrameBegin, RiTransformBegin, RiWorldBegin


Shading

The process of shading is described in detail in the RenderMan Shading Language section of the documentation. The complete list of attributes related to shading are enumerated in the table below.

The graphics state maintains a list of attributes related to shading. Associated with the shading state are a current color and a current opacity.

All geometric primitives use the current surface shader for computing the color (shading) of their surfaces and the current atmosphere shader for computing the attenuation of light towards the viewer. The graphics state also contains a current list of light sources that are used to illuminate the geometric primitive. Finally, there is a current area light source. Geometric primitives can be added to a list of primitives defining this light source.

Shading Attributes
Shading Attribute Type Default Description
Color color color "rgb" (1,1,1) The reflective color of the object.
Opacity color color "rgb" (1,1,1) The opacity of the object.
Texture Coordinates 8 floats (0,0)(1,0),(0,1),(1,1) The texture coordinates (s, t) at the 4 corners of a parametric primitive.
Light Sources shader list n/a A list of light source shaders that illuminate subsequent primitives.
Area Light Source shader n/a An area light source that is being defined.
Effective Shading Rate float 1.0 Minimum rate of surface shading.
Shading Interpolation token "constant" How the results of shading are interpolated across a polygon.
Matte Surface Flag boolean false A flag indicating the surfaces of the subsequent primitives are opaque to the rendering program, but transparent on output.

Texture coordinates

The Shading Language allows precalculated images to be accessed by a set of two-dimensional texture coordinates. This general process is referred to as texture mapping. Texture access in the Shading Language is very general since the coordinates are allowed to be any legal expression. However, the texture function often uses default texture coordinates related to the surface parameters.

All the parametric geometric primitives have surface parameters (u,v) that can be used as their texture coordinates (s,t). Surface parameters for different primitives are normally defined to lie in the range 0 to 1. This defines a unit square in parameter space. The Geometric Primitives section defines the position on each surface primitive that the corners of this unit square lie. The texture coordinates at each corner of this unit square are given by providing a corresponding set of (s,t) values. This correspondence uniquely defines a 3x3 homogeneous two-dimensional mapping from parameter space to texture space. Special cases of this mapping occur when the transformation reduces to a scale and an offset, which is often used to piece patches together, or to an affine transformation, which is used to map a collection of triangles onto a common planar texture.

The graphics state maintains a current set of texture coordinates. The correspondence between these texture coordinates and the corners of the unit square is given by the following table.

Surface Parameters
(u,v)
Texture Coordinates
(s,t)
(0,0) (s1,t1)
(1,0) (s2,t2)
(0,1) (s3,t3)
(1,1) (s4,t4)

By default, the texture coordinates at each corner are the same as the surface parameters (s=u, t=v). Note that texture coordinates can also be explicitly attached to geometric primitives. Note also that polygonal primitives are not parametric, and the current set of texture coordinates do not apply to them.

RiTextureCoordinates (RtFloat s1, RtFloat t1, RtFloat s2, RtFloat t2,
                        RtFloat s3, RtFloat t3, RtFloat s4, RtFloat t4 )

Set the current set of texture coordinates to the values passed as arguments according to the above table.

RIB BINDING

TextureCoordinates s1 t1 s2 t2 s3 t3 s4 t4
TextureCoordinates [s1 t1 s2 t2 s3 t3 s4 t4]

EXAMPLE

RiTextureCoordinates (0.0,0.0,  2.0,-0.5, -0.5,1.75,  3.0,3.0);

SEE ALSO

texture() and bump() in the Shading Language

Light sources

The graphics state maintains a current light source list. The lights in this list illuminate subsequent surfaces. By making this list an attribute different light sources can be used to illuminate different surfaces. Light sources can be added to this list by turning them on and removed from this list by turning them off. Note that popping to a previous graphics state also has the effect of returning the current light list to its previous value. Initially the graphics state does not contain any lights.

An area light source is defined by a shader and a collection of geometric primitives. The association between the shader and the geometric primitives is done by having the graphics state maintain a single current area light source. Each time a primitive is defined it is added to the list of primitives that define the current area light source. An area light source may be turned on and off just like other light sources.

The RenderMan Interface includes four standard types of light sources: "ambientlight", "pointlight", "distantlight", and "spotlight". The definition of these light sources are given in the Standard RenderMan Interface Shaders section of the Example Shaders page. The parameters controlling these light sources are given in the table below.

Standard Light Source Shader Parameters
Light Source Parameter Type Default Description
ambientlight
intensity
lightcolor
float
color
1.0
color "rgb" (1,1,1)
Light intensity
Light color
distantlight
intensity
lightcolor
from
to
float
color
point
point
1.0
color "rgb" (1,1,1)
point "shader"(0,0,0)
point "shader"(0,0,1)
Light intensity
Light color
Light position
Light direction is from-to
pointlight
intensity
lightcolor
from
float
color
point
1.0
color "rgb" (1,1,1)
point "shader"(0,0,0)
Light intensity
Light color
Light position
spotlight
intensity
lightcolor
from
to
coneangle
conedeltaangle
beamdistribution
float
color
point
point
float
float
float
1.0
color "rgb" (1,1,1)
point "shader"(0,0,0)
point "shader"(0,0,1)
radians(30)
radians(5)
2.0
Light intensity
Light color
Light position
Light direction is from-to
Light cone angle
Light soft edge angle
Light beam distribution
RtLightHandle RiLightSource (RtToken shadername, ...parameterlist... )

shadername is the name of a light source shader. This procedure creates a non-area light, turns it on, and adds it to the current light source list. An RtLightHandle value is returned that can be used to turn the light off or on again.

RIB BINDING

LightSource name handle ...parameterlist...

The handle is a unique light identification number or string that is provided by the RIB client to the RIB server. Both client and server maintain independent mappings between the handle and their corresponding RtLightHandles. When specified as a number it must be in the range 0 to 65535.

EXAMPLE

LightSource "spotlight" 2 "coneangle" [5]
LightSource "ambientlight" 3 "lightcolor" [.5 0 0] "intensity" [.6]
LightSource "blacklight" "a-unique-string-handle" "lightcolor" [.5 0 0] "intensity" [.6]

In order to override the string handle selected, RiLightSource recognizes the special string __handleid parameter, which may be passed in via the parameter list. The value of this parameter will be used to override the handleid that appears in the RIB binding, e.g.:

RtString id = "mylight";
RiLightSource("spotlight", "__handleid", &id);

Integer sequence numbers are supported and are equivalent to their string representations. Thus, the following RIB statements are equivalent:

LightSource 57 "spotlight"
LightSource "57" "spotlight"

SEE ALSO

RiAreaLightSource, RiIlluminate, RiFrameEnd, RiWorldEnd


RtLightHandle RiAreaLightSource ( RtToken shadername, ...parameterlist... )

shadername is the name of a light source shader. This procedure creates an area light and makes it the current area light source. Each subsequent geometric primitive is added to the list of surfaces that define the area light. RiAttributeEnd ends the assembly of the area light source.

The light is also turned on and added to the current light source list. An RtLightHandle value is returned which can be used to turn the light off or on again.

If the Area Light Source capability is not supported by a particular implementation, this subroutine is equivalent to RiLightSource.

RIB BINDING

AreaLightSource name handle parameterlist

The handle is a unique light identification number or string that is provided by the RIB client to the RIB server. Both client and server maintain independent mappings between the handle and their corresponding RtLightHandles. When specified as a number it must be in the range 0 to 65535.

EXAMPLE

RtFloat decay = .5, intensity = .6;
RtColor color = {.5,0,0};

RiAreaLightSource ( "finite", "decayexponent", (RtPointer)&decay, RI_NULL);
RiAreaLightSource ("ambientlight", "lightcolor", (RtPointer) color, "intensity",
                    (RtPointer)&intensity, RI_NULL);

SEE ALSO

RiFrameEnd, RiLightSource, RiIlluminate, RiWorldEnd


RiIlluminate ( RtLightHandle light, RtBoolean onoff )

If onoff is RI_TRUE and the light source referred to by the RtLightHandle is not currently in the current light source list, add it to the list. If onoff is RI_FALSE and the light source referred to by the RtLightHandle is currently in the current light source list, remove it from the list. Note that popping the graphics state restores the onoff value of all lights to their previous values.

RIB BINDING

Illuminate handle onoff

The handle is the integer or string light handle defined in a LightSource or AreaLightSource request.

EXAMPLE

LightSource "main" 3
Illuminate 3 0

SEE ALSO

RiAttributeEnd, RiAreaLightSource, RiLightSource

Displacement shading

The graphics state maintains a current displacement shader. Displacement shaders are procedures that can be used to modify geometry before the lighting stage.The RenderMan Interface includes one standard displacement shader: bumpy. The definition of this displacement shader is given in the Standard RenderMan Interface Shaders section of the Example Shaders page. The parameters controlling this displacement are listed in the table below.

RiDisplacement ( RtToken shadername, ...parameterlist... )

Set the current displacement shader to the named shader. shadername is the name of a displacement shader.

If a particular implementation does not support the Displacements capability, displacement shaders can only change the normal vectors to generate bump mapping, and the surface geometry itself is not modified (see Displacement Shaders).

RIB BINDING

Displacement shadername ...parameterlist...

EXAMPLE

RiDisplacement ("displaceit", RI NULL);
Standard Displacement Shader Parameters
Shader Name Parameter Type Default Description
bumpy
amplitude
texturename
float
string
1.0
""
Bump scaling factor
Displacement map name
Displacement Bounds

This is a control that increases the sizes of calculated bounding boxes on primitives in order to account for the effects of displacement mapping. The size is specified by identifying a single floating-point value which is the radius of a sphere which is guaranteed to contain the maximum possible displacement, and the name of the coordinate system in which this sphere resides. This value should be as tight as possible. It is extremely inefficient, both in terms of memory usage and calculation time, to specify a bounding sphere which is larger than the actual displacement. Therefore, this sphere should be as small as possible without permitting points on the object to displace farther than the sphere's radius.

The coordinate system identified can be:

  • any of the standard coordinate systems ("screen", "camera", "world", "object")
  • "surface" or "displacement", which specifies the shader space of the appropriate shader on this object
  • "shader", which is identical to "displacement" if there is a displacement shader on this object, or to "surface" if there is not
  • "current", which is the Shading Language current space (identical to "camera" in PRMan)
  • "null", which specifies the coordinate system at the time of the RiAttribute call
  • any user-defined coordinate system created with RiCoordinateSystem

The default coordinate system is "object" space.

RtString c[1] = "world";
RtFloat d = 3.5;
RiAttribute("displacementbound", "coordinatesystem", (RtPointer)c,
               "sphere", (RtPointer)&d, RI_NULL);

In version 3.8, the coordinate system may be specified by supplying a transformation matrix. The parameterlist name for this version of the call is "transform", and the value is a single transformation matrix. The semantics of this transformation matrix is parallel to passing a transformation matrix to a shader and transforming a point through it. In other words,

Attribute "displacementbound"
        "sphere" [2]
        "coordinatesystem" ["world"]

is to

dispmag = sphereradius * ntransform("world", Nf);

as

Attribute "displacementbound"
        "sphere" [2]
        "transform" [...mx...]

is to

dispmag = sphereradius * ntransform(mx, Nf);

Co-shaders

In addition to the light list described in the Light sources section above, the graphics state maintains a list of co-shaders. Co-shaders are not directly executed by the renderer, but can be called by other shaders (like co-routines), as described in the Shader Objects and Co-Shaders application note. As with lights, popping to a previous graphics state returns the current co-shader list to its previous value.

RiShader ( RtToken shadername, RtToken handlename, ...parameterlist... )

shadername is the name of a shader definition. The handlename is used as a key when calling this co-shader from another shader.

RIB BINDING

Shader shadername handlename parameterlist

EXAMPLE

RtFloat Ks = 0.0;

RiShader ("rust", "rustlayer", "Ks", (RtPointer)&Ks, RI_NULL);

SEE ALSO

RiLightSource

Shading Rate

In RIS, ShadingRate controls the tessellation rate, not the shading frequency. The shading frequency is controlled by the path tracer's "maxsamples" settings. ShadingRate should be set to a numerically high value on area lights (e.g. 100) unless your area lights have high curvature or high frequencies in the emission.

RiShadingRate ( RtFloat size )

Set the current shading rate to tessellation size.

RIB EXAMPLES

ShadingRate 10.0

Attribute "Ri" "float ShadingRate" [10.0]

Attribute "shade" "float shadingrate" [10.0]

SEE ALSO

RiGeometricApproximation

Relative Shading Rate
Attribute "shade" "relativeshadingrate" [float]
                  "resetrelativeshadingrate" [float]

Attribute "shade" "relativeshadingrate" sets the value of the relative shading rate equal to the relativeshadingrate value multiplied by any other relativeshadingrate values in the Attribute stack. It can also be passed two float values wherein the first value is the relativeshadingrate and the second is a multiplier on the shading rate in Z, for volumes, equivalent to setting the depthrelativeshadingrate attribute. As with the shadingrate attribute, "relativeshadingrate" has a float[2] variant that allows users to set the standard and the volume (depth) relative shading rate independently.

Attribute "shade" "resetrelativeshadingrate" resets the relativeshadingrate to the given value.

The final ShadingRate used on an object will be the accumulated relativeshadingrate multiplied by the actual shadingrate.

Relative Pixel Variance
Attribute "shade" "relativepixelvariance" [float]
Attribute "shade" "relativepixelvariance" sets the value of the relative pixel variance equal to the relativepixelvariance value multiplied by any other pixelvariance value. This allows users to change the rendered quality relative to the main pixel variance quality threshold. Keep in mind that extreme values may create artifacts or "halos" around objects where their pixel variance thresholds are very different. This option is also only effective for objects seen by camera rays and not (indirectly) reflected or refracted in other objects.
images/relpixvar.jpg

"Relative Pixel Variance applied to red teapot"

Shading Interpolation

Shading calculations are performed at discrete positions on surface elements or in screen space (at a frequency determined by the shading rate). The results can then either be interpolated or constant over some region of the screen or the interior of a surface element corresponding to one shading sample. This is controlled by the following procedure:

RiShadingInterpolation ( RtToken type )

This function controls how values are interpolated between shading samples (usually across a polygon). If type is "constant" the color and opacity of all the pixels inside the polygon are the same. This is often referred to as flat or facetted shading. If type is "smooth" the color and opacity of all the pixels between shaded values are interpolated from the calculated values. This is often referred to as Gouraud shading.

RIB BINDING

ShadingInterpolation "constant"
ShadingInterpolation "smooth"

EXAMPLE

ShadingInterpolation "smooth"

Matte Objects

Matte objects are the functional equivalent of three-dimensional hold-out mattes. Matte objects are not shaded and are set to be completely opaque so that they hide objects behind them. However, regions in the output image where a matte object is visible are treated as transparent.

RiMatte ( RtBoolean onoff )

Indicates whether subsequent primitives are matte objects.

RIB BINDING

Matte onoff

EXAMPLE

RiMatte (RI_TRUE);

SEE ALSO

RiDisplayChannel

Derivatives and Normals

Attribute "derivatives" "centered"    [1]
Attribute "derivatives" "extrapolate"    [1]

Derivatives and normals are calculated using a technique that eliminates or reduces several shading artifacts.

  • Derivatives are symmetric with respect to the (u,v) parameterization. This eliminates the shading artifacts that would sometimes occur when adjacent patches in a subdivision surface had different orientations.
  • Derivatives are more robust near degeneracies (such as sphere poles).
  • Second derivatives are more accurate, which should reduce or eliminate grid artifacts when using reflection maps.
  • Note

    These changes only take effect when smooth shading is enabled (via ShadingInterpolation "smooth"). When constant shading is used (the default setting), derivatives and normals are unchanged from previous releases. Smooth shading and centered derivatives are highly recommended in order to minimize rendering artifacts.

    If desired, centered/extrapolated derivatives can be turned off as follows:

    Attribute "derivatives" "centered"    [0]
    Attribute "derivatives" "extrapolate"    [0]
    

Ray Tracing

Attribute "trace" "int maxdiffusedepth" [1] "int maxspeculardepth" [2]
these attributes limit the number of bounces (diffuse or specular) for indirect illuminance relative to the associated primitive. To resolve the interaction between per-primitive values when different objects have different values of these attributes, we pass the current max down the ray tree and calculate maxdiffusedepth = MIN(parent.maxdiffusedepth, parent.diffusedepth + object.maxdiffusedepth) - and similar for maxspeculardepth.
Attribute "trace" "int displacements" [0]
controls whether true displacements appear in ray-traced results. When 0 (off), the displacement will be disregarded for the purposes of ray-primitive intersection tests, but shading will take the displacements into account effectively resulting in a bump-mapped appearance. When 1, the surface will be displaced before ray-primitive intersection tests. New for PRMan 16.0: When 2, the surface will only be displaced when near the ray origin or when the ray differential is narrow.
Attribute "trace" "bias" [.01]
this bias value affects transmission/shadow rays as well as trace/environment rays. It is an offset applied to the ray origin, moving it slightly away from the surface launch point in the ray direction. This offset can prevent blotchy artifacts resulting from the ray immediately finding an intersection with the surface it just left.
Attribute "trace" "autobias" [1]
with this attribute on, an appropriate bias value is automatically computed and it is no longer necessary to set trace bias. In fact, the "trace bias" value is ignored. In the rare case where an explicit trace bias setting is preferable, turn "trace" "autobias" off (i.e. set it to 0).
Attribute "trace" "int samplemotion" [0]
controls whether motion blurred objects appear in ray-traced results. When 0, the motion blur of other objects hit by rays launched from the object with this attribute will be ignored. When non-zero, motion blur will be taken into account by rays launched from an object with this attribute.
Attribute "trace" "int decimationrate" [1]
similar to the decimationrate option, the attribute specifies the tessellation decimation for ray tracing. With values 2 or higher, the surface tessellation used for ray tracing will be coarser than the surface tessellation ("dicing") used for Reyes rendering of directly visible surfaces. This means faster ray-surface hit tests. The number of grids in the fine geometry cache will decrease with higher values of decimationrate (since each grid is smaller), leading to better cache performance in complex scenes. The most useful values are 1, 2, 4, and 16. The default value of the attribute is the corresponding option value, which defaults to 1 (i.e. no decimation). If both the option and attribute are set, the attribute value is used. The attribute value must be at least as high as the option value. (When the decimationrate option is set, we change the relative sizes of the three tessellation caches; with the decimationrate attribute this isn't possible.) Values smaller than 1 are clamped to 1 (i.e. no decimation). Values of 16 or higher means that all rays are traced against fully simplified geometry: a single quad or triangle per micropolygon grid.
Attribute "trace" "string shadow|reflect|transmitsubset" ["<group-membership>"]
PxrPathTracer supports group subsets and flags for shadowsubset, reflectsubset, and transmitsubset. When a set is applied to geometry, it participates in the specified lightpath. For example: Objects that are part of a shadowsubset will cast shadows on objects using the shadowsubset trace setting. Other objects without this membership are excluded.
Attribute "trace" "int intersectpriority" [0]
dictates a priority used when ray tracing overlapping materials. The default value is 0, indicating that the surface will not participate in priority calculations (and will also trump other priority calculations in the immediate vicinity). When using PRMan in RIS mode, rays launched from closed geometry that asserts a non-zero priority into the interior of that same surface will miss any other nested interior geometry with a lower, non-zero priority; however, the renderer will track whether the ray entered or exited these lower priority surfaces (a false intersection). If the ray subsequently hits an object of equal or higher priority (a true intersection), any intervening false intersections will be used to correctly figure out the current index of refraction for the outside surface associated with the true intersection. For more details, please see the paper "Simple Nested Dielectrics in Ray Traced Images", by Charles M. Schmidt and Brian Budge.

Lighting

Attribute "lighting" "string subset" [""]
The subset of lights with which to perform direct lighting in RIS mode. The string may be a group-selecting expression like trace subset.
Attribute "lighting" "string exludesubset" [""]
The subset of lights to exclude from consideration for direct lighting in RIS mode. The string may be a group-selecting expression like trace subset.

Shading Frequency

Attribute "shade" "string frequency" ["motionsegment"]

Attribute "shade" "frequency" sets the frequency of shading execution for multi-segment motion blurred geometry. The default frequency is "motionsegment": the shader is executed at the beginning of every motion segment. In this mode, the primitive variables bound to the shader are sourced directly from each segment.

When the frequency is set to "frame", the shader is executed only once for the frame. In this mode, the primvars bound to the shader are sourced only from the first motion segment; all other primvars are ignored. Note that the dPdtime variable in the shading language remains a scalar vector, not an array. Hence, the renderer will compute a dPdtime that takes into account only the first and last motion samples. If a displacement shader chooses to output dPdtime, it will not have an affect on the interior motion samples, and they will be linearly interpolated to match the specified motion.

"Frame" frequency can lead to more efficient rendering due to reduced shading and reduced memory overhead, but may be inappropriate for situations where primitive variables are themselves motion blurred, or shading scenarios which demand a higher frequency of shading for accuracy. Also, in some cases of extreme motion blur, objects with "frame" frequency may be less efficient to bound, leading to higher hiding costs.

Index of Refraction

Attribute "shade" "float indexofrefraction" [1.0]
In conjunction with Attribute "trace" "intersectpriority", attaching this attribute to nested dielectric surfaces allows Bxdfs to correctly figure out the correct value for the outside index of refraction associated with the current surface (via GetBuiltinVar(k_outsideIOR)). The default value is 1.0 (air).

Geometry

Geometry Attributes
Attribute Type Default Description
Object-to-World transform identity Transformation from object or model coordinates to world coordinates.
Bound 6 floats infinite Subsequent geometric primitives lie inside this box.
Detail Range 4 floats (0,0,infinity,infinity) Current range of detail. If the current detail is in this range, geometric primitives are rendered.
Geometric Approximation token value n/a The metric used to determine the accuracy of a geometric surface approximation.
Cubic Basis Matrices 2 matrices Bezier, Bezier Basis matrices for bicubic patches. There is a separate basis matrix for both the u and the v directions.
Cubic Basis Steps 2 ints 3, 3 Patchmesh basis increments.
Trim Curves n/a n/a A list of trim curves that bound NURBS.
Orientation token "outside" Whether primitives are defined in a left-handed or right-handed coordinate system.
Number of Sides integer 2 Whether subsequent surfaces are considered to have one or two sides.
Displacement shader "null" A displacement shader that specifies small changes in surface geometry.

Bound

The graphics state maintains a bounding box called the current bound. The rendering program may clip or cull primitives to this bound.

RiBound ( RtBound bound )

This procedure sets the current bound to bound. The bounding box bound is specified in the current object coordinate system. Subsequent output primitives should all lie within this bounding box. This allows the efficient specification of a bounding box for a collection of output primitives.

RIB BINDING

Bound xmin xmax ymin ymax zmin zmax
Bound [xmin xmax ymin ymax zmin zmax]

EXAMPLE

Bound [0 0.5 0 0.5 0.9 1]

SEE ALSO

RiDetail

Detail

The graphics state maintains a relative detail, a current detail, and a current detail range. The current detail is used to select between multiple representations of objects each characterized by a different range of detail. The current detail range is given by 4 values. These four numbers define transition ranges between this range of detail and the neighboring representations. If the current detail lies inside the current detail range, geometric primitives comprising this representation will be drawn.

Suppose there are two object definitions, foo1 and foo2, for an object. The first contains more detail and the second less. These are communicated to the rendering program using the following sequence of calls:

RiDetail( bound );
RiDetailRange( 0., 0., 10., 20. );
    RiObjectInstance( foo1 );
RiDetailRange( 10., 20., RI_INFINITY, RI_INFINITY );
    RiObjectInstance( foo2 );

The current detail is set by RiDetail. The detail ranges indicate that object foo1 will be drawn when the current detail is below 10 (thus it is the low detail detail representation) and that object foo2 will be drawn when the current detail is above 20 (thus it is the high detail representation). If the current detail is between 10 and 20, the rendering program will provide a smooth transition between the low and high detail representations.

RiDetail ( RtBound bound )

Set the current bound to bound. The bounding box bound is specified in the current coordinate system. The current detail is set to the area of this bounding box as projected into the raster coordinate system, times the relative detail. Before computing the raster area, any portion of the bounding box behind the near clipping plane is flattened onto the near clipping plane; this does not happen at the edges of the display or the far clipping plane. The raster area outside the field of view is computed so that if the camera zooms in on an object the detail will increase smoothly. Detail is expressed in raster coordinates so that increasing the resolution of the output image will increase the detail.

RIB BINDING

Detail minx maxx miny maxy minz maxz
Detail [minx maxx miny maxy minz maxz]

EXAMPLE

RtBound box = { 10.0, 20.0, 42.0, 69.0, 0.0, 1.0 };

RiDetail (box);

SEE ALSO

RiBound, RiDetailRange, RiRelativeDetail

RiDetailRange ( RtFloat minvisible, RtFloat lowertransition,
                RtFloat uppertransition, RtFloat maxvisible )

Set the current detail range. Primitives are never drawn if the current detail is less than minvisible or greater than maxvisible. Primitives are always drawn if the* current detail* is between lowertransition and uppertransition. All these numbers should be non-negative and satisfy the following ordering:

minvisible <=; lowertransition <=; uppertransition <=; maxvisible.

If the Detail capability is not supported by a particular implementation, all object representations which include RI_INFINITY in their detail ranges are rendered.

RIB BINDING

DetailRange minvisible lowertransition uppertransition maxvisible
DetailRange [minvisible lowertransition uppertransition maxvisible]

EXAMPLE

DetailRange [0 0 10 20]

SEE ALSO

RiDetail, RiRelativeDetail

Level of Detail

Reyes only feature

Attribute "instance" "int singlelod" [-1]

Controls whether only a single level of detail of the master will be created. By default, when the raytrace hider is used, only a single representation of each master is created (this behavior was introduced in PRMan 19). When the stochastic hider is used, multiple representations will be created.

Useful values are -1, 0, and 1. When set to -1 (the default value) the behavior is automatically contingent on choice of hider: the raytrace hider sets it to 1, 0 otherwise. A value of 1 forces only a single LOD for instances. This is redundant with dice strategies that are view-independent (i.e. it has no effect). A value of 0 enables the previous behavior, allowing for multiple LODs.

Geometric Approximation

Geometric primitives are typically approximated by using small surface elements or polygons. The size of these surface elements affects the accuracy of the geometry since large surface elements may introduce straight edges at the silhouettes of curved surfaces or cause particular points on a surface to be projected to the wrong point in the final image.

RiGeometricApproximation ( RtToken type, RtFloat value )

The predefined geometric approximation is "flatness." Flatness is expressed as a distance from the true surface to the approximated surface in pixels. Flatness is sometimes called chordal deviation.

Two special geometric approximation types are available with RiGeometricApproximation to provide a processing/quality tradeoff for motion-blurred objects whose motion can be large in screen space - motionfactor - or for objects blurred due to Depth of Field - focusfactor.

motionfactor will cause the renderer to check the length of the motion blur on the screen for all motion-blurred objects and if the distance is large, raise the effective shading rate value of the blurred objects. Since the objects will be blurred across the screen, fine shading detail would be lost anyway. This can save large amounts of processing if many objects in the scene have large blurs. A motionfactor factor value of 0.0 will turn this feature off. Values greater than 1.0 will cause motion-blurred objects to have their effective shading rate raised even higher. RiGeometricApproximation specifies an attribute and as such, motionfactor should be scoped within the current RiAttributeBegin-RiAttributeEnd block.

focusfactor adjusts the dicing rate for objects blurred due to RiDepthOfField. If focusfactor is not set (the default value is -1), then the motionfactor value, if set, continues to affect the adjustment of dicing rate for both motion blur and depth blur. If focusfactor is set (to a value greater than or equal to 0), then the motionfactor value only affects the motion blur adjustment, and focusfactor only affects the depth blur adjustment. A value of 0.0 will cause the renderer to use the default shading rate; values greater than 1.0 will cause objects to have their effective shading increased.

As of PRMan 18, these are available as Attributes, via the "Ri" namespace.

RIB BINDING

GeometricApproximation type value

RIB EXAMPLE

Attribute "Ri" "float focusfactor" [2.5]

SEE ALSO

RiShadingRate

Orientation and Sides

The handedness of a coordinate system is referred to as its orientation. The initial "camera" coordinate system is left-handed: x points right, y point up, and z points in. Transformations, however, can flip the orientation of the current coordinate system. An example of a transformation that does not preserve orientation is a reflection. (More generally, a transformation does not preserve orientation if its Jacobian is negative.)

Similarly, geometric primitives have an orientation, which determines whether their surface normals are defined using a right-handed or left-handed rule in their object coordinate system. Defining the orientation of a primitive to be opposite that of the object coordinate system causes the primitive to be turned inside-out. If a primitive is inside-out, its normal will be computed so that it points in the opposite direction. This has implications for culling, shading, and solids (see the section on Solids and Spacial Set Operations). The outside surface of a primitive is the side from which the normal points outward; the inside surface is the opposite side. The interior of a solid is the volume that is adjacent to the inside surface and the exterior is the region adjacent to the outside. This is discussed further in the section on Geometric Primitives.

The current orientation of primitives is maintained as part of the graphics state independent of the orientation of the current coordinate system. The current orientation is initially set to match the orientation of the initial coordinate system, and always flips whenever the orientation of the current coordinate system flips. It can also be modified directly with RiOrientation and RiReverseOrientation. If the current orientation is not the same as the orientation of the current coordinate system, geometric primitives are turned inside out, and their normals are automatically flipped.

RiOrientation ( RtToken orientation )

This procedure sets the current orientation to be either "outside" (to match the current coordinate system), "inside" (to be the inverse of the current coordinate system), "lh" (for explicit left-handed orientation) or "rh" (for explicit right-handed orientation).

RIB BINDING

Orientation orientation

EXAMPLE

Orientation "lh"

SEE ALSO

RiReverseOrientation


RiReverseOrientation ()

Causes the current orientation to be toggled. If the orientation was right-handed it is now left-handed, and vice versa.

RIB BINDING

ReverseOrientation -

EXAMPLE

RiReverseOrientation ();

SEE ALSO

RiOrientation

Sides

Objects can be two-sided or one-sided. Both the inside and the outside surface of two-sided objects are visible, whereas only the outside surface of a one-sided object is visible. If the outside of a one-sided surface faces the viewer, the surface is said to be frontfacing, and if the outside surface faces away from the viewer, the surface is backfacing. Normally closed surfaces should be defined as one-sided and open surfaces should be defined as two-sided. The major exception to this rule is transparent closed objects, where both the inside and the outside are visible.

RiSides ( RtInt sides )

If sides is 2, subsequent surfaces are considered two-sided and both the inside and the outside of the surface will be visible. If sides is 1, subsequent surfaces are considered one-sided and only the outside of the surface will be visible.

RIB BINDING

Sides sides

EXAMPLE

Sides 1

SEE ALSO

RiOrientation

One-sided Primitives

Attribute "sides" "backfacetolerance" [0]

The renderer culls one-sided primitives that are backfacing. A primitive is considered backfacing if the primitive's surface normals all point more than 90 degrees away from the viewing vector. Backface culling is guaranteed to occur and to be exact; no transparency artifacts as described above will occur; the threshhold for backface culling of one-sided primitives prior to shading can be adjusted with the sides:backfacetolerance attribute. The backface culling tolerance angle is a floating-point number, measured in degrees, that specifies the angle that the primitive must exceed, beyond the "silhouette normal", before it may be culled prior to shading. The default value is 0 degrees.

For example:

Attribute "sides" "backfacetolerance" [20]

will cause the renderer to not cull backfacing objects until their surface normals point more than 110 degrees away from the viewing vector. Note that this does not affect the fact that by the end of the rendering pipeline, backface culling is exact and occurs at 90 degrees.

Named Primitives

Attribute "identifier" "string name" [s]

It is occasionally useful to give names to individual primitives. For example, when a primitive has incorrect motion blur parameters it can be desirable to know which primitive is causing the problem. This can be done using the attribute identifier with the parameter name, as in:

RtString name[1] = { "Gigi" };
RiAttribute("identifier", "name", (RtPointer)name, RI_NULL);

All defined primitives will have this name until the graphics stack is popped (with RiAttributeEnd) or another such RiAttribute call is made. The error message would then contain a reference to a specific primitive name instead of the mysterious <unnamed>.

Attribute "identifier" "string lpegroup"

controls grouping of objects for LPE outputs. This is useful when a specific set of objects and/or their contribution is needed in an ouput AOV.

For example:

LPE: C<RD'crate'><L.>

would capture illumination from the identified "crate" group into an LPE output.

Trim Curve Sense

Attribute "trimcurve" "string sense" [inside]

The sense of Trim Curves can now be reversed using an attribute. The sense can be set to either inside or outside. The default is inside. When the sense is set to outside, all portions of the surface inside the Trim Curve, those drawn in the default case, will not be drawn, and those portions outside the Trim Curve, those not drawn in the default case, will be drawn. Since Trim Curves are attributes themselves, this allows one to use a single Trim Curve to define areas of different shading on the same NURBS surface by repeating the patch with a different sense of the same Trim Curve. The following example shows how to set the Trim Curve sense in a C program.

RtString sense[1] = "outside";
RiAttribute("trimcurve", "sense", (RtPointer) sense, RI_NULL);

Visibility

Attribute "visibility" "int camera" [1]
controls the visibility of subsequent primitives to the camera. By default all primitives are visible.
Attribute "visibility" "int diffuse" [0]
controls the visibility of the current primitive to diffuse rays. These are rays cast by gather, occlusion, and indirectdiffuse.
Attribute "visibility" "int specular" [0]
controls the visibility of the current primitive to specular rays. These are rays cast by gather, trace, and environment.
Attribute "visibility" "int indirect" [1]
sets all the indirect transport modes at once. Note that this is the preferred visibility state when using PRMan's RIS mode, as there can be both diffuse and specular contributions via the indirect (even if diffuse was sampled, there may be some specular contribution). It is on, [1], by default in RIS mode only.
Attribute "visibility" "int transmission" [1]
controls the visibility of primitives to transmission (shadow) rays.
Attribute "visibility" "int midpoint" [0]
controls the visibility of the current primitive to the midpoint depth filter. Options that have midpoint visibility but no camera visibility are considered visible when the midpoint depthfilter is active, and take part in the two surface hider computation, but only as the second surface. Such objects can be considered "shadow receivers", but will not be "shadow casters".

Grouping

Attribute "grouping" "string membership" ["name_spec"]

controls the group membership of subsequent primitives. A single primitive can be a member of several groups. Membership is used to precisely control trace relationships between objects. Ray-tracing shaders on one object can limit their ray intersections to members of specific groups by using the optional "subset" parameter of the tracing operators. The name_spec supports relative and absolute specification:

  • "name"
  • list,of,names" or "list of names"
  • +additional,names"
  • -without,names"

In addition, starting with PRMan 13.5, the special value "*" may be specified for name_spec. Primitives with this membership will be hit-testable by any ray, no matter what the subset of that ray, or even if the ray doesn't specify a subset.

Culling

Attribute "cull" "backfacing"    [1]
                 "hidden"    [1]
PRMan supports two attributes for culling. When the "cull" "backfacing" attribute is turned off, surfaces are shaded even if they have Sides 1 and their back side is facing the camera. When the "cull" "hidden" attribute is turned off, surfaces are shaded even if they are behind other surfaces. These attributes are convenient to force shading to happen, for example for baking ambient occlusion or indirect illumination. For regular rendering, these attributes should be left at their default value (1) so that surfaces that do not contribute to an image are culled before wasting time shading them.

Dicing

Dicing Strategy & Camera
Attribute "dice" "string strategy" ["planarprojection"]
                 "string referencecamera" ["worldcamera"]
                 "float worlddistancelength" [-1]

PRMan 12.0 added support for specifying the camera and strategy to use during dicing. These are chosen via the "strategy" and "referencecamera" parameters of Attribute "dice". There are two camera based strategies: "planarprojection" and "sphericalprojection". The "planarprojection" strategy has been used in all previous releases of PRMan: dicing rate is determined using the screen space coordinates of a primitive projected onto a plane. The "sphericalprojection" strategy uses the coordinates of a primitive projected onto a sphere. The parameters of the sphere are taken from the state of the standard camera. The radius is set to the distance to the near clipping plane, and the size of a pixel is set to match the current projection. Both strategies can utilize nonraster-oriented dicing metrics.

In addition to any camera definition named by a RiCamera declaration, two built-in reference cameras can be specified for dicing - the camera state at FrameBegin, named by "framecamera", and the state of the camera at WorldBegin, named by "worldcamera" or "camera". In order to guarantee that the frame and world cameras have unique world to eye transformations, Identity must be called after FrameBegin. To setup the frame camera as your dicing camera:

Define dicing camera
FrameBegin
Identity
Define viewing camera
WorldBegin
WorldEnd
FrameEnd

As of PRMan 16.0 there is support for a third dicing strategy: "worlddistance". Here, the dicing rate is determined using distances measured in world space units compared to the current ShadingRate. With this strategy, the dicing camera is ignored. PRMan 19.0 introduced a new attribute, "worlddistancelength" that can be used with this dicing strategy if set to a value greater than zero.

Attribute "dice" "string offscreenstrategy" ["viewfrustumdistance"]

PRMan 16.2 added support for specifying the dicing strategy to use for objects outside the viewing frustum. There are three off-screen strategies: "clamped", "sphericalprojection", and "viewfrustumdistance".

The "clamped" off-screen strategy has been used in all previous releases of PRMan: objects outside the viewing frustum are never split and their dicing rates are clamped to sqrt(maxgridsize)-1. This can give very coarse off-screen tessellation and shading which can sometimes be visible in reflections and refractions.

The "sphericalprojection" off-screen strategy means that objects outside the viewing frustum are split and diced using the sphericalprojection oracle as if they were inside the viewing frustum. This can give large memory use in the "ray acceleration" and "traceable prims" categories.

The "viewfrustumdistance" off-screen strategy means that objects outside the viewing frustum are split less and diced coarser the farther away from the viewing frustum they are. This strategy first computes dicing rates using the spherical projection and then reduces those dicing rates according to the distance to the viewing frustum. (The offscreenmultiplier, set with Option "dice" "float offscreenmultiplier" [f], can be used to scale this effect.) This strategy is a good middle ground between "clamped" and "sphericalprojection": reflections of off-screen geometry are free from visible tessellation and shading artifacts, and the memory overhead is low. This is the new default.

Nonraster-Oriented Dicing
Attribute "dice" "rasterorient" [1]
PRMan's default dicing criteria is the screen-oriented raster space (i.e. Attribute "dice" "rasterorient" [1]). Turning this attribute off, by setting it to 0, enables nonraster-oriented dicing, a mode of dicing that computes micropolygon sizes using an unoriented raster space metric rather than the standard screen-aligned raster metric. This is useful in situations where it is important that the dicing rate on an object doesn't change due to camera orientation. For example, it can help in situations where objects that are viewed edge on result in large micropolygons (but small in screen space), which are then displaced leading to micropolygons that are large in screen space.
Watertight Dicing
Attribute "dice" "watertight"
The watertight tessellation primarily aims to eliminate a major source of pinhole artifacts in objects by eliminating T-junctions that arise due to the use of regular rectangular dicing on adjacent faces. This attribute is added in PRMan 20.12 onward.
Binary Dicing
Attribute "dice" "int binary" [0]

This is a flag that indicates whether the lowest level patches must be diced into a grid of micropolygons with power-of-two dimensions. This attribute is typically used to prevent patch cracking on high-curvature patches. This attribute is deprecated in PRMan 20.2 onward.

RtInt flag = 1;
RiAttribute("dice", "binary", (RtPointer)&flag, RI_NULL);
Curve Dicing
Attribute "dice" "hair" [0]

This Attribute, specifically used for RiCurves geometry, makes thin hair-like curves much cheaper to shade, and more memory efficient when dealing with long hair which spans multiple buckets. When it is enabled by setting to 1 (it is disabled by default), Du() of any quantity is 0, with the trivial exception of Du(u) = 1. In other words, derivatives across the width of the curve are ill-defined. Because of this, this attribute should only be used for curves which are truly hair-like (very thin in screen space).

See the RiCurves Primitive application note for additional details and recommendations.

Attribute "dice" "int preservecv" [0]
The preservecv attribute is used to guarantee that a curve's CVs are fully represented in the grid, ensuring an adequate dice rate for any curvature. The default value is 0, or "off". Note that this attribute only affects RiCurves.
Attribute "dice" "int roundcurve" [1]

Enabling this dicing mode (it is off - [0] - by default) will have the following effects for RiCurves that do not have user supplied normals:

  • If Attribute "dice" "int hair" is set to 0, the grids generated have a cylindrical cross section, and the value of N will be computed accordingly.
  • If Attribute "dice" "int hair" is set to 1, the grids generated for RiCurves will be unaffected.
  • Rays fired from the geometry have their launch origins set as though the grid had a cylindrical cross section. If only one ray is fired, or the samplebase parameter is set to 0, the ray(s) will simply be offset by the width of the hair in the direction of the ray launch. Otherwise the ray origin will be jittered across the cylindrical surface of the curve.
  • During ray tracing, the RiCurve will be hit tested as though it had a cylindrical cross section. (With roundcurve set to 0, the RiCurve is always oriented toward the camera, even if normals are not supplied.) The normals returned by these hit tested ray traced curves will reflect the cylindrical cross section. Depending on the scene there may be significant performance differences incurred by ray tracing curves with roundcurve enabled.

See the RiCurves Primitive application note for additional details and recommendations.

Instance Dicing
Attribute "dice" "string instancestrategy" ["worlddistance"]
                 "float instanceworlddistancelength" [1e30]
PRMan 19 introduced two attributes for controlling tessellation to tune instancing performance. These attributes can be used to control how finely object masters are tessellated - "instancestrategy" determines the dicing strategy for object instancing (the default is now "worlddistance") and "instanceworlddistancelength" sets the worlddistance length. Users should note that the default for "instanceworlddistancelength" - 1e30 - is large and may need to be lowered if you see under-tessellation artifacts, or, in the case of patches, NURBs and curves partially or completely disappearing geometry. In that case you may need to try setting it to a similar order of magnitude as the scene or object size.
Pretessellation
Attribute "dice" "int pretessellate" [1]
enables "pre-tessellating" subdivision surfaces into polygons on the fly (in RIS mode only) for improved memory performance. This can also be set via rendermn.ini with /prman/dice/pretessellate 1 or via a corresponding Option. It is on - 1 - by default.

Stochastic Transparency

Attribute "curve" "int stochasticshadows" [1]
Enables stochastic transparency for shadow rays on curves. This can also be set via a corresponding Option or in the rendermn.ini with /prman/curve/stochasticshadows [1]. The Attribute takes precedence over the Option, which in turn takes precedence over the rendermn.ini setting. It is on ([1]) by default.

Procedural Attributes

Attribute "procedural" "string attributes" [""]

The "procedural" "string attributes" attribute is used by any subsequent procedural primitive. The value of the attribute is used as a look up for a saved resource, of type "attributes". If found, the saved attribute state will override the graphics state for the procedural primitive, without affecting the inherited graphics state of the contents of the procedural primitive. One use of this attribute is to control the visibility of a procedural, without interfering with the visibility of the procedural's contents, which normally would inherit the graphics state previously defined.

For example, suppose it is required for the contents of an archived RIB file to inherit no raytrace visibility (the contents of said RIB file may of course turn on raytracing visibility where it sees fits). One could simply do this:

Attribute "visibility" "int diffuse" [0] "int specular" [0] "int camera" [1]
ReadArchive "archive.rib"

This breaks when it comes to a Procedural DelayedReadArchive:

Attribute "visibility" "int diffuse" [0] "int specular" [0] "int camera" [1]
Procedural "DelayedReadArchive" [ "archive.rib" ] [ ]

In this situation, the procedural never gets cracked by ray tracing, even if its contents actually have diffuse/specular 1. Here, we clearly have a disconnect between the desire to specify the visibility of a procedural, and the inherited default visibility of its contents. By using Attribute "procedural" "string attributes", the desired situation can be expressed as follows:

Attribute "visibility" "int diffuse" [1] "int specular" [1] "int camera" [1]
Resource "supervisibility" "attributes" "string operation" "save"
Attribute "procedural" "string attributes" "supervisibility"
Attribute "visibility" "int diffuse" [0] "int specular" [0] "int camera" [1]
Procedural "DelayedReadArchive" [ "archive.rib" ] [ ]
  • Important

    Be aware that the saved attribute state includes the current transform state. Since the entirety of the saved attribute state overrides the graphics state for the procedural primitive, this means that the saved transform state will be the one applied to the procedural's bounding box (but not its contents). If the saved transform state is different from the current transform state, this will require transformation of the bounding box from the current transform state to the saved transform state. For example, suppose that we have the following procedural which has been modified by a translation.

    Translate 0 0 5
    Procedural "DelayedReadArchive" ["archive.rib"] [0 1 0 1 0 1]
    

    If we save the attribute state prior to the translation, and use that saved attribute with the procedural, the bounding box will need to be adjusted:

    Resource "mystate" "attributes" "string operation" "save"
    Translate 0 0 5
    Attribute "procedural" "string attributes" "mystate"
    Procedural "DelayedReadArchive" ["archive.rib"] [0 1 0 1 5 6]
    
Attribute "procedural" "int reentrant" [1]
Prior to PRMan 15, all procedural primitive geometry was run serially and could not be run simultaneously in multiple threads. Attribute "procedural" "int reentrant" [1] will cause any subsequent procedural to not lock the global mutex. Note that this requires that the procedural be thread safe. The default value of this attribute is 0, i.e. all procedurals remain locked. The default value can be overridden by a rendermn.ini flag: /prman/procedural/reentrant can be set to true or false, and this value will dictate the default value of Attribute "procedural" "reentrant" if not otherwise set.
  • Important

    In order to support this change, we now require some changes to the scope of certain values that were once considered conceptually global:

    • any type declarations (made with RiDeclare), shader handles, and inline archives made by a Procedural will now only be visible to geometry and shaders created by that Procedural or its children (which may themselves also be Procedurals).
    • Procedural execution will incur an implicit ResourceBegin and ResourceEnd. Without this change, the semantics would be highly order-dependent, requiring "first execution must create".

    Additionally, Rif Plugins that operate on re-entrant procedurals must be re-entrant as well.

Note that multiple invocations of the same RunProgram will still spawn only a single RunProgram. As RunPrograms are generally written to respond to ordered input, this means that simultaneous execution of the same RunProgram by multiple threads will still incur a lock: a thread will lock before writing to the pipe, and will release the lock after reading from the pipe.
Attribute "procedural" "int unloadable" [1]
The "procedural" "int unloadable" attribute is used by any subsequent procedural primitive in conjunction with the procedural memory limit option. By default, the renderer assumes that all procedurals can be unloaded from memory. If a procedural must remain persistent, setting the value of the unloadable attribute to 0 will prevent the renderer from unloading the procedural even if the procedural memory limit has been reached.
Attribute "procedural" "int immediatesubdivide" [1]
The "procedural" "int immediatesubivide" attribute is used by RiProcedural to compel a procedural to immediately subdivide (behavior supported via the __immediatesubdivide meta-parameter in RiProcedural2). This attribute is "special" in that it is not inherited into sub-procedural contexts - meaning parent immediate-subdivide procedurals don't accidentally trigger immediate-subdivide children. A value of 0 (the default) disables, 1 enables, and 2 forces all child procedurals to crack immediately.

User-Specified Attributes

Attribute "user" "uniform string myattribute" [ "foo" ]

PRMan (subsequent to version 10.0) supports the use of arbitrarily defined token/value pairs for the user attribute. These token/value pairs may be arbitrarily defined and set, and then queried with the attribute shadeop or via the RxAttribute mechanism. Like other attributes, all token/value pairs associated with this attribute will be pushed and popped on the graphics stack with each RiAttributeBegin and RiAttributeEnd call.

RtString myattribute = "foo";
RiAttribute("user", "uniform string myattribute", (RtPointer)&myattribute, RI_NULL);
Attribute "user" "float maxtextureresolution" [1024]
Clamps texture resolution, preventing the texture lookup from going deeper than the 1k mip level (by default).