PhotoRealistic RenderMan is more efficient at rendering some types of models than others. The renderer has been optimized for some features, and consequently other features are less efficient. Modelers which take advantage of this knowledge will get their models rendered more quickly, with no loss of generality or features.
PhotoRealistic RenderMan is a complete implementation of the RenderMan Interface Specification. Thus, it will accept any RenderMan model description and generate the correct image (excepting, of course, for any bugs or memory limits). This doesn't mean, however, that it will generate any image quickly. Like any program, PhotoRealistic RenderMan performs best when its inputs fall into certain classes or when they refrain from using certain expensive features. This note will help you understand how to structure your RenderMan model description so that it takes advantage of the features that PhotoRealistic RenderMan has optimized, particularly when there is a choice between an optimized and an unoptimized description of the same thing. Application Note 3, How to Render Quickly Using PhotoRealistic RenderMan, explains how to use speed-versus-quality knobs to optimize the rendering speed of an individual image once the model description for that image is fixed.
It would seem on the surface that the geometric model is unchangeable. The modeling primitives are known by the modeler, after all, and those are the ones it wants rendered. This is not quite correct, however, because RenderMan supports a rich set of geometric primitives which can double for each other under certain circumstances. Knowing the situations in which certain primitives can be used will help generate models that are much more efficient to render.
The single most important thing a modeler can do to optimize its geometric model for PhotoRealistic RenderMan is use curved surface primitives to model curved surfaces. This is not a trite comment. Historically, modelers and renderers have shared the characteristic of processing polygonal data almost exclusively. Since all curved surfaces were tessellated into polygons by the renderers anyway, it was as efficient (or more efficient) for modelers to control the tessellation by giving the renderer purely polygonal data in the first place. The disadvantages (computation of Phong-interpolated normals, straight-line silhouettes, difficulty of approximating the curve to the right level of detail) were well known, but common to all systems and so were accepted.
PhotoRealistic RenderMan does not fit into this model, however. PhotoRealistic RenderMan accepts and processes curved surfaces directly, and very efficiently. A single sphere primitive will render faster than 30 polygons approximating a sphere, and significantly faster than 1000 polygons approximating a sphere. The curved surface descriptions are more memory efficient (both core and disk) than polygonal approximations of the curves. Moreover, the shading normals of curved surfaces are always correct without resorting to interpolation, its silhouettes are smooth, and the surface is approximated at exactly the right level of detail.
Seven types of quadric primitives (sphere, cylinder, cone, disk, hyperboloid, paraboloid and torus), bicubic patches and non-uniform rational B-spline surfaces are all handled directly by PhotoRealistic RenderMan. Other common modeling surfaces, such as surfaces of revolution, ruled and lofted surfaces, 3-D mathematical functions, etc., are easily converted to curved surface representations, often with no more effort than converting them to polygonal representations.
PhotoRealistic RenderMan is designed and optimized to handle rectangular regions, and one of the results is that a triangle is rendered at the same speed as a rectangle which is twice the size. Looked at another way, triangles render at half the speed of rectangles. This has significant impact on models which contain a large number of triangles, such as polygonal tessellations of curved surfaces. This speed disadvantage will be addressed in future versions of PhotoRealistic RenderMan, but for the moment it is a very good idea to avoid triangles wherever possible. For example, polygonal tessellations often use triangles for convenience, and because polygon-based renderers handled them quite well. Equivalent quadrilateral tessellations are often just as easy to produce, and will be much more efficient with PhotoRealistic RenderMan.
Similarly, two adjacent triangles can often be joined along their common edge to form a quadrilateral, as long as the resulting quadrilateral is convex. If this is done throughout a model, the speed of rendering can often as much as double. When two triangles are joined in this way, the new primitive is often not planar. Although the RenderMan Interface Specification states that polygon primitives must be planar, PhotoRealistic RenderMan will accept and correctly render quadrilaterals that are only slightly non-planar by replacing them with bilinear patches. This will generate a curved (ruled) surface, which is a hidden benefit if the polygon is, in fact, part of an approximation of a curved surface.
Meshes and Polyhedra
It is very rare for an object in the real world to be modeled by a single patch or polygon. Usually there are large numbers of patches or polygons, and they are quite often connected in some regular pattern. Patches are often parts of spline surfaces, with an underlying rectangular grid. Polygons are often parts of polyhedra, and share most of their vertices with other polygons. RenderMan has compact, efficient versions of patch and polygon primitives for these situations known as PatchMesh and PointsPolygons.
These aggregate primitives have the major advantage that vertices used by multiple primitives are only specified once, and then shared. Since the redundant vertices are only stored in RIB files once, read out of RIB files once, and transformed, projected and bounded once, a large amount of storage space and execution time is saved.
If very complex models are being used more than once in an image, or the same complex model is being used repeatedly in multiple frames, it can often be very beneficial to place the geometric primitives for that model in a RenderMan object. This entire model can then be referred to by its identification tag, rather than re-specifying all of the geometric data for every use. For example, the patch meshes which make up the body of a car might be made into an object. Then images of automobile showrooms or animations of driving can be made by transforming and instancing the car object into each position of each frame. This has the obvious advantages of significantly cutting down the amount of data which flows through the RenderMan Interface and is stored in RIB files.
There are severe limitations on what can be put in an object, however. The most restrictive limitation is that only geometric primitives can be placed in the object block. Attributes are inherited from the graphics state at the time the object is instantiated, and thus all of the primitives in the block have identical attributes. There are no restrictions, however, on primitive vertex variables, and these can sometimes be used to get around this problem. No transformations are permitted inside the object, either. This means that the primitives must be defined relative to some local object coordinate system, which effectively eliminates the use of quadric surfaces. Obviously, the primitives cannot change shape once they are inside the object (the vertices cannot move), so flexible primitives are not appropriate for treatment as objects. Objects are automatically deleted when the frame block or world block which contains their definition is ended. Objects created outside of all frame and world blocks will not be deleted until RiEnd.
Photorealistic RenderMan fully supports the Solid Modeling optional capability of RenderMan. However, the algorithms used in Photorealistic RenderMan were not designed with efficient solid modeling as one of the primary goals, and as such, it can be very expensive. In particular, negative spaces are handled in a brute force manner, which can lead to significant rendering costs (in both memory and execution time) if these spaces are not carefully planned.
Negative spaces should be as tight and form-fitting as possible. For example, negative cylinders which cut holes in objects should be carefully placed and scaled so that they do not extend far outside the volume of the positive space. In situations where geometric relationships make it more natural to use corners of large negative objects to subtract small bits from positive objects, it is almost always advantageous for the modeler to clip the large negative object and build an impromptu cap out of patches or polygons rather than allow the negative object to extend far from the positive object. Negative spaces can usually be rendered with larger than normal shading rates, since they are invisible.
Avoid negative spaces entirely if there are other alternatives. Clipped quadrics such as hemispheres and truncated cones should always be rendered with partially swept quadric surfaces and disks, and should never be rendered as full quadrics and subtractive cubes. Similar tricks can be used on truncated surfaces of revolution.
Some attributes can be used to help speed rendering by telling the renderer that certain computations are unnecessary. These have to be used with care, however, because lying to the renderer about this will cause incorrect pictures to be generated. PhotoRealistic RenderMan also contains a relatively complex system for keeping track of the shaders which are used on each primitive, and a little forethought can help this facility avoid extraneous work as well.
Most models contain objects that enclose space. That is, objects which have a distinct interior with no holes to the outside; for example, a sphere or a cube. Unlike a sheet of paper or an open cylinder, it is easy to recognize that on such closed objects, it is impossible to see the interior surface. Renderers often try to take advantage of this fact by completely discarding the parts of that object where the interior surface faces the viewer (e.g., the back wall of the cube). This process is often called backface culling, and is enabled in RenderMan by setting the RiSides(1) flag.
Quite often the modeler knows that a particular object is closed, even though the renderer cannot tell that by looking at the individual primitives. With backface culling enabled, one half of the primitives can be completely thrown away with no further processing. This will double the rendering speed. Therefore, the modeler should take care to set RiSides(1) whenever it can. However, it should not be set if the interior or back faces can be seen, for example, through a transparent front surface.
Some of the lights in a scene will strike every object in the scene. For example, ambient light and most distant lights will illuminate at least one side of everything. Other lights are very specific. Spot lights are aimed at individual objects in the scene, and the intensity of point lights fall off to essentially zero after some distance. However, it takes almost as long to discover that a certain light will have no effect on an object as it does do calculate how much effect it actually has. For this reason, RenderMan supports the concept of the current light list.
The light list gives the modeler the ability to indicate to PhotoRealistic RenderMan which lights can illuminate which objects. This list is changed by RiIlluminate which turns lights off and on. For example, a spotlight which illuminates only the floor can be turned off for the walls, the paintings on the walls, and the huge kinetic sculpture in the front yard. PhotoRealistic RenderMan can completely ignore that light for everything but the floor. If the model has a large number of lights, this can amount to substantial savings in execution time. However, it obviously requires some knowledge about the locality of the light, such as that it is inside a closed room, or it is a dim light on a single object.
If you have a model where many primitives use the same shader, but each primitive has slightly different values for the instance variables of the shader, you would typically have an alternating sequence of RiSurface calls and RiPolygon calls, for example. Each shader would be slightly different, and would be used exactly once. In PhotoRealistic RenderMan this means there will be large numbers of shader definitions in the system, each slightly different, each taking up memory.
Another way to approach this problem is to use a single shader with none of the variable parameters set, followed by all of the primitives with the interesting shading parameters set in the parameter lists of the primitives. The variables on primitives can be varying or uniform; in this case they will most likely be uniform. This approach will take significantly less memory at some minor cost in execution speed. If you are close to (or over) memory limits, and are paging, this is a very valuable trade.
When using displacement shaders, take some care to ensure that the displacement bounds are set correctly. Displacement bounds are specified in object-space units by default, however displacement shaders are often written to displace using camera-space units. These lengths are usually quite different, and unless the bound is tight, displacements can become needlessly expensive. If the displacement bound is too large, then PhotoRealistic RenderMan will do far too much work processing the primitive, and use lots of memory storing the pieces that were done far too early. It's important that the units for displacement bounds are correct and consistent. See Application Note 12, Using Displacement Shaders, for more information on designing and using displacement shaders.
PhotoRealistic RenderMan, like all programs, has certain features it executes quickly and efficiently, and certain features which it executes slowly or clumsily. Because PhotoRealistic RenderMan implements a standard interface, it probably has more of the latter than the average program (which would usually simply throw away any features that didn't run fast enough). Modelers can chose to take advantage of knowledge about which of the standardized RenderMan functionality that PhotoRealistic RenderMan does best. These sophisticated modelers will get better rendering performance than the naive applications which use whichever piece of RenderMan functionality suites their fancy that day. To get the best performance out of PhotoRealistic RenderMan, modelers should:
After the RenderMan model is built efficiently, there are other tricks described in Application Note 3, How To Render Quickly Using PhotoRealistic RenderMan, which help speed up renderings of any model. Modelers should incorporate those tricks as well, in order to get the best possible performance out of PhotoRealistic RenderMan.
Pixar Animation Studios