Introduction

Curves can be used to render large numbers of thin strands of geometry very efficiently, making this primitive particularly well-suited for modeling fur, hair, and blades of grass. This geometry type is an approximate representation, designed to render more efficiently in both time and memory compared to an equivalent surface of circular cross section. The trade-off is that when viewing curve geometry up close, there can sometimes be geometric artifacts; these artifacts tend to not be perceptible as the curves become more distant from the camera. RenderMan supports both flat (ribbon-like) and round (tube-like) curves, and it is possible to choose from a variety of basis functions.

Parameters

Width

The width of a curve can vary over the length of the curve. It is possible to specify a constant width that applies to all curve strands in the primitive, or widths can be specified to be different on a per-curve strand, per-vertex, or per-segment basis.

Basis

Given a set of control points that the user supplies as vertices, which composes the hull of the curve, the basis function determines how the actual rendered curve appears. For example, some basis functions, such as the Catmull-Rom basis, guarantee that the rendered curve will pass through all interior, non-endpoint control vertices, whereas others, such as B-spline, typically do not pass exactly through any of the control vertices. Each basis function has different trade-offs in terms of smoothness, controllability and ease-of-use.

 

Mode

RenderMan supports both flat (ribbon-like) curves and round (tube-like) curves, demonstrated in the images below.

 

 

Opacity

Like all geometry in RenderMan, if the BxDF attached to a curves primitive computes presence, this will control whether the curves are present on screen and to what percent. There is also an optimization implemented for round curves where if the opacity is specified in the "Os" primitive variable, then a more efficient code path is taken when computing shadowing which avoids the need to run any BxDFs. This optimization can be controlled via the "curve" "int stochasticshadows" [0|1] option or attribute; by default the more efficient shadowing code path is enabled. 

Minimum Width

An option can be used to specify the minimum width for curves. When specified, this artificially widens curves so that they are at least as wide as the specified minimum width (measured in pixels), with a corresponding decrease in presence. The effect is that the curve looks about the same when rendered, except that the high spatial frequency geometry is now band-limited thus minimizing aliasing artifacts, which just means that fewer camera samples are needed in order to anti-alias the curve (and thus fewer rays need to be traced, resulting in faster performance). Useful values for minimum hair width range from 0.1 to 1.0.

 

        Option "hair" "float minwidth" [0] (default: 0)

 

                  hair:minwidth = 1.0 with 64 samples per pixel                                            hair:minwidth = 0.2 with 64 samples per pixel

 

Notice in the example images above that the render with hair:minwidth=1.0 has converged after 2.5 minutes using only 64 samples-per-pixel, whereas visual inspection reveals that the render with hair:minwidth=0.2 (also rendered using 64 samples-per-pixel) still has some areas with not-fully-converged aliasing artifacts after the same 2.5 minutes of rendering (which do ultimately resolve with more samples). On the other hand, the hair:minwidth=1.0 setting has introduced a very small (but perceptible) amount of bias in the render (that is, it is very slightly smoother in a few areas), although the introduced bias is not visually objectionable.

 

Best Practices

When rendering hair or fur, it is recommended that: