Short Contents

5.3 Geometric Primitives

3Delight supports the entire set of geometric primitives defined by the RenderMan standard. Since the primitives are explained in great detail in the RenderMan specification, the following chapters give only a brief description and some useful implementation details.

5.3.1 Subdivision Surfaces

Catmull-Clark subdivision surfaces are supported by 3Delight(20). All standard tags are recognized:

"hole"
A per-face value, tagging faces that are considered as holes. The parameter is an array of integers listing the indices of the hole faces.
"corner"
A per-vertex value, tagging vertices that are considered semi-sharp. The tag should be specified with an array of integers, giving the indices of the vertices as well as an array of floating point values giving their sharpness. Corners are smooth at sharpness 0.0 and grow sharper as the value is increased.
"crease"
A per-edge value, tagging edges that are considered as semi-sharp. This tag is specified with an array of integers, indicating the list of vertices that form an edge chain. An array of floating point values specifies the sharpness value for each edge in the chain.
"interpolateboundary"
A per-surface value, specifying that boundary edges and vertices are infinitely sharp. This tag takes an optional integer parameter with the following possible values:

  • 0 - No interpolation, the default behavior.
  • 1 - Full interpolation: infinitely sharp creases are added to boundary edges and infinitely sharp corners are added to boundary vertices of valence 2. This is the behavior obtained when the tag is specified without a parameter.
  • 2 - Interpolation of edges only: infinitely sharp creases are added to boundary edges.
"facevaryinginterpolateboundary"
A per-surface value which allows using either true facevarying (set to 0) or a facevertex-like version (set to 1) which smooths out the boundaries. The default value is 1 and can be changed in `rendermn.ini' with the "/3delight/subdivisionmesh/facevaryinginterpolateboundary" key.

The following are 3Delight specific extensions:

"smoothcreasecorners"
This tag requires a single integer parameter with a value of 0 or 1 indicating whether or not the surface uses enhanced subdivision rules on vertices where more than two creased edges meet. With a value of 0, such a configuration uses the conventional rules which treat the vertex as a sharp corner. With a value of 1, the vertex is subdivided using an extended crease vertex subdivision rule which yields a smooth crease. Note that sharp corners can still be explicitly requested using the "corner" tag.

Unlike other rendering packages, 3Delight does not attempt to tesselate the entire subdivision surface into many small polygons (thus taking a large amount of memory); instead, a lazy and adaptive process is used to generate only those portions of the surface that are needed for some specific bucket.

All standard variable types are supported: constant, uniform, varying, vertex, facevarying and facevertex. facevertex is used exactly as facevarying but interpolates the variables according to surface's subdivision rules. This eliminates many distortion artifacts due to bilinear interpolation in facevaryings.

5.3.2 Parametric Patches

All parametric patches are supported:

RiPatch
Specifies a single bicubic or bilinear patch. All standard basis matrices are supported: "bezier", "bspline", "catmull-rom" and "hermite".
RiPatchMesh
Specifies a rectangular mesh of bilinear or bicubic patches. As with RiPatch, all basis matrices are supported. It is recommanded to use RiPatchMesh instead of RiPatch when specifying connected surfaces since this is more efficient and more suited to 3Delight's crack elimination algorithm.
RiNuPatch
Specfies a NURBS surface. Trimming is supported.

The following variable types are allowed for parametric patches: constant, uniform, varying, vertex and facevarying.

5.3.3 Curves

Both `linear' and `cubic' curves are supported. Attaching a normal to the curve geometry modifies the curve's orientation depending on the normal's direction; this can be used to render features such as grass. The following variables are supported: constant, uniform, varying, vertex and facevarying.

Note

uniforms are specified per curve and not per curve segment as was the case in old versions.

5.3.4 Polygons

All polygonal primitives are supported, this includes: RiPolygon, RiGeneralPolygon, RiPointsPolygons and RiPointsGeneralPolygons. All polygonal primitives support the following variable types: constant, uniform, varying, vertex and facevarying.

Note

vertex and varying interpolation over a polygon is ill-defined since it depends on how the polygon is tesselated by the renderer.

5.3.5 Points

Points are supported in 3Delight through the standard RenderMan RiPoints primitive. Points' size is controlled using either "width" or "constantwidth" variable (RI_WIDTH or RI_CONSTANTWIDTH in the API). The way 3Delight renders points is selectable during primitive declaration using the "uniform string type" variable which can take one of the following values: `particle', `blobby', `patch', `sphere' or `disk'.

"particle"
The default mode is to render points using a lightweight primitive, suitable for clouds of tiny particles (such as clouds of dust, stars, etc ...). Particles are rendered as circles using a specialized algorithm which is suitable for such small primitives.
Note

Displacement and volume shaders, as well as output variables, are not supported for lightweight particles.

"blobby"
Renders the particles as "blobbies" (implicit surfaces). In this case, the energy field radius is defined by width or constantwidth. Particles created as blobbies will blend together smoothly and will also blend all primitive variables.
"sphere"
"disk"
"patch"
Points are rendered using the RiSphere, RiDisk or RiPatch primitive, respectively. This is useful when shading over the surface of the particle is important. It is also more efficient to use this feature to declare large groups of spheres, disks and patches instead of declaring each primitive individually. It is not recommended to use these high level primitives for small, particle-like, points.
Note

Since spheres are two sided primitives, they will render differently from disks, patches and particles when the material is not fully opaque and RiSides is set to `2'.

When using the `patch' particle type, two additional variables are understood by 3Delight:
"constant|varying float patchaspectratio"
Controls the "aspect ratio" of the patch. This is defined as width / height and will only modify the patch's height (the width being specified by width or constantwidth). When constant, the aspect ratio applies to all particles; varying aspect ratio gives one value per particle.
"constant|varying float patchrotation"
Gives the rotation, in degrees, of the patch around its center.
Additionally, width, constantwidth, patchaspectratio and patchrotation are correctly motion blurred.

EXAMPLE

WorldBegin

  Translate 0 0 10
  Color 1 1 1
  
  AttributeBegin
    Rotate -30 0 1 0
    Rotate 60 1 0 0
    Scale 0.3 0.3 0.3
    # Render some points using the 'sphere' primitive ...
    Points
      "P" [ -3 2 1 3 2 1 -3 0 1 -1 0 1 1 0 1 3 0 1
            -1 -4 1 1 -4 1 -3 2 -1
             3 2 -1 -3 0 -1 -1 0 -1 1 0 -1 3 0 -1 -1 -4 -1 1 -4 -1 ]
      "constantwidth" [0.2]
      "uniform string type" "sphere"
  AttributeEnd
WorldEnd
Listing 5.1: Using sphere-shaped RiPoints.

5.3.6 Implicit Surfaces (Blobbies)

RiBlobby is implemented. It supports spheres and segments(21). All standard operators are supported, including: add, subtract, min, max, multiply, divide and negate. Variables specified to RiBlobby are interpolated over the resulting isoparametric surface by blending. Note that vertex and varying variables are specified per node; uniform variables are specified for the entire primitive.

3Delight uses an adaptive algorithm to render implicit surfaces, meaning that only small parts of the primitive are tessellated at a given time. Tessellation resolution is controlled by RiShadingRate and should be decreased if very small implicit surfaces (in raster space) are rendered. In addition, setting RiShadingInterpolation to `smooth' (the default) greatly improves the rendering quality of implicit surfaces.

5.3.7 Quadrics

All six quadrics (plus the torus) are supported. This includes: RiSphere, RiDisk, RiHyperboloid, RiParaboloid, RiCone, RiCylinder and RiTorus. Each of these primitives accept the following variable types: constant, uniform, varying and vertex. Note that vertex variables behave exactly as varyings on quadrics.

5.3.8 Procedural Primitives

Procedural primitives from the C binding using RiProcedural are supported. Built-in procedures for the RIB binding (RiProcDelayedReadArchive, RiProcRunProgram and RiProcDynamicLoad) are also fully supported.

The following two RIB bindings were added to provide functionality equivalent to calling RiProcRunProgram or RiProcDynamicLoad directly from a C program:

ProcDynamicLoad [ "dsoname" "dsodata" ] detail
ProcRunProgram [ "progname" "progdata" ] detail

They invoke the corresponding procedural immediately when encountered in a RIB. Unlike their counterparts used through the Procedural RIB binding, they can be used to alter the current attribute and transform stacks. Note that the corresponding binding for RiProcDelayedReadArchive is simply ReadArchive.

3Delight also supports a RiProceduralV C API which allows the following parameters to be specified:

"string instancekey"
Setting this makes 3Delight handle procedurals for which it has the same value as instances of the same geometry. This means the procedural may be expanded only once and its output reused internally. This can improve both performance and memory use.

Limitations

Procedural primitives cannot be used inside a RiMotionBegin/RiMotionEnd block. They can still be subject to transformation motion blur as well as contain motion blocks themselves. When a procedural primitive contains a motion block, it is the user's responsability to take it into account when providing the renderer with a bounding box for the procedural primitive.

Procedural primitives cannot be used inside a RiObjectBegin/RiObjectEnd block. They can however contain such a block and use objects declared before themselves (with the caveats mentioned below).

The following parts of the graphics state are not saved and restored for procedural primitives:

  1. Named coordinate systems created with RiCoordinateSystem
  2. Retained geometry objects (RiObjectBegin/RiObjectEnd)

This means that declaring one of the above, inside a procedural primitive, may affect the graphics state for later procedural primitives. Likewise, a declaration made after the procedural primitive declaration (but before it was needed by the renderer) may affect it. It is therefore necessary to declare the required elements before the procedural primitives that require them and not to replace them until after the end of world block, when rendering is complete. It also wise to avoid using these declarations inside the procedural primitive itself. This behavior is subject to change in future releases depending on user feedback about it. Contact us at info@3delight.com if these features are important to you.

5.3.9 Object Instances

Object instancing is supported with the RiObjectBegin/RiObjectEnd and RiObjectInstance APIs. 3Delight also supports a RiObjectBeginV API which allows the following parameters to be specified:

"string __handleid"
This specifies the handle 3Delight should use for the object. RtObjectHandle and RtString are actually equivalent in 3Delight.
"string scope"
This specifies at which scope the object should be inserted. The default is "local" which is wherever RiObjectBegin is called. Other possible values are "world" which makes the object available for the entire render and "global" which makes the object available until RiEnd. These two require that the handle be specified with "__handleid". Their purpose is to allow a procedural primitive to generate objects lazily and reuse them in other instances of the procedural. Note that this will require some synchronization in the procedural's code.

5.3.10 Constructive Solid Geometry

CSG is fully supported. This includes all defined operations on solids: `union', `difference' and `intersection'. One limitation of the CSG algorithm is that primitives spanning the eye plane might give incorrect results when used in a CSG tree.

As an extension, 3Delight allows putting procedural primitives inside any kind of solid block. This behaves as if the content of the procedural was immediately expanded except if the procedural is the first element in a `difference' block. In that case, the procedural will act as an implicit `union' block.

3Delight 10.0. Copyright 2000-2011 The 3Delight Team. All Rights Reserved.