RenderMan 3.9 Release Notes
PhotoRealistic RenderMan 3.9
Release Notes
Pixar
April 2001
Introduction
These release notes describe significant changes and enhancements to the RenderMan Toolkit for the 3.9 release over the 3.8 release. In successive sections, we cover
- Blobby Implicit Surfaces
PRMan now has the ability to render blobby implicit surfaces. - Speed and Memory Optimizations
Several parts of the renderer have been optimized, and are much faster compared to 3.8. - Soft Shadow Optimizations
Soft shadows are now two to three times faster. - Improved NURBS Primitive
The NURBS primitive has been rewritten, improving accuracy, stability, and speed. - Improved Curves Primitive
Uniform RiCurves parameters are now bound per curve, rather than per segment. Bounding boxes have also been tightened for speed improvements. - Control Over Triangular Subdivision for Subdivision Surfaces
A new tag has been added which controls the subdivision rule for triangular faces in subdivision surfaces. - Centered Derivatives and Normals
Derivatives and normals are calculated by a new method that will eliminate or reduce several shading artifacts (when used in conjunction with シェーディングInterpolation "smooth"). - Internal Crack Elimination
PRMan now guarantees that individual geometric primitives will not crack, even under extreme displacement. This eliminates the need for most binary dicing. - Binary Dicing Optimizations
Binary dicing has been optimized and is no longer a significant performance penalty. Overall rendering times on scenes that use binary dicing have been reduced by 25-40%, in addition to the other speedups mentioned in these notes. - Accumulated Opacity
Culling
The hider can now cull geometry behind layers of transparent geometry, saving time in scenes with a large number of semi-transparent layered objects. - Fractional Mattes Matte objects may now be partially transparent.
- Compressed Zfiles The zfile driver now supports gzip compression.
- Extended Statistics Output Statistics output from the renderer has been extended.
- Motion Blur Improvements Improvements have been made to motion blurring to reduce artifacts and to improve accuracy.
- シェーディング Language DSO Shadeops Improvements Several improvements have been made to DSO shadeops.
- DSO Interface to Noise PRMan now provides a DSO-accessible interface to its own implementation of noise.
- シェーディング Language Additions Additions have been made to the shading language.
- Directory Mapping (3.9.2) Directory mappings can be specified for all absolute path name references.
- Miscellaneous Changes and
Bug Fixes
Lastly, many parts of the release have had small changes and bug fixes. - Bug Fixes since 3.9.0.0
Fixes in the renderer between 3.9.0.0 and 3.9.2.
Blobby Implicit Surfaces
The new Blobby surface type implements free-form self-blending implicit-function surfaces in the style of Jim Blinn's blobby molecules, Nishimura et al.'s Metaballs and Wyvill, McPheeters and Wyvill's soft objects. Blobby surfaces may be composed of spherical and sausage-like line-segment primitives with extremely flexible control over blending. The surface type also provides for repulsion to avoid intersection with irregular ground planes, represented by prman-produced Z-files.
Blobbies may be shaded much like ordinary parametric primitives, with the caveat that they have no u and v parameters. Nevertheless, they may be given vertex values, by attaching scalar values or reference coordinate fields to primitive sub-objects that will be blended appropriately by prman. Motion-blur, depth-of-field and all of prman's other advanced sampling features also work as expected.
In the Renderman C binding, blobby implicits are specified by:
void RiBlobby(
RtInt nleaf,
RtInt ncode, RtInt code[],
RtInt nflt, RtFloat flt[],
RtInt nstr, RtString str[],
...);
In a RIB stream, the syntax is:
Blobby nleaf [ code ] [ floats ] [ strings ] parameterlist
The code array is a sequence of machine language-like instructions describing the object's primitive blob fields and the operations that combine them. Floating point parameters of the primitive fields are stored in the floats array. File names of the z-files of repellers are in the strings array. The integer nleaf is the number of primitive blobs in object, also the number of items in each varying or vertex parameter.
Each instruction has a numeric opcode followed by a number of operands. Instructions specifying primitive fields start at 1000. They are:
| Opcode | Operands | Operation |
|---|---|---|
| 1000 | float | constant |
| 1001 | float | ellipsoid |
| 1002 | float | segment blob |
| 1003 | string, float | repelling ground plane |
For all four of these operators, the operands are indices into the appropriate arrays.
- For opcode 1000 (constant) the operand indexes a single floating-point number in the floats array. The index of the first item in the array is zero.
- For opcode 1001 (ellipsoid) the operand indexes the first of 16 floats describing a 4x4 matrix that transforms the unit sphere into the ellipsoidal bump in object space.
- The operand of opcode 1002 (segment blob) indexes 23 floats that give the endpoints and radius of the segment and a 4x4 matrix that transforms the segment into object space.
- Opcode 1003 (repelling ground plane) takes two indices. The first gives the index of the name of a z-file in the strings array. The second indexes the first of 4 float parameters of the repeller's repulsion contour.
There are several more opcodes that compute composite fields by combining the results of previous instructions in various ways. Every instruction in the code array has a number, starting with zero for the first instruction, that when used as an operand refers to its result. The combining opcodes are:
| Opcode | Operands | Operation |
|---|---|---|
| 0 | count, ... | add |
| 1 | count, ... | multiply |
| 2 | count, ... | maximum |
| 3 | count, ... | minimum |
| 4 | subtrahend, minuend | subtract |
| 5 | dividend, divisor | divide |
| 6 | negand | negate |
| 7 | idempotentate | identity |
Add, multiply, maximum and minimum all take variable numbers of arguments. The first argument is the number of operands, and the rest are indices of results computed by previous instructions. The identity operator does nothing useful, and is only included for the convenience of programs that automatically generate Renderman input.
More details on usage can be found in AppNote #31.
Speed and Memory Optimizations
The texture system has been optimized and is more than twice as fast as PRMan 3.8. Shadow maps, noise, arrays, and parsing are also substantially faster. In combination with other speedups mentioned below, these changes have reduced the overall rendering time by approximately 30-40% for the very large scenes rendered here at Pixar. In addition, for some large scenes memory usage has been reduced by over 50%.
Soft Shadow Changes
The usage of soft shadows is now two to three times faster than PRMan 3.8. There have also been minor changes in the format of minmax soft shadow texture files. テクスチャ files generated from previous versions of the renderer may not work, and will need to be regenerated from the z files via txmake or RiMakeShadow.
Improved NURBS Primitive
The NURBS primitive has been almost entirely rewritten, resulting in better accuracy and significant speedups on scenes with NURBS geometry modelled with a large number of control points. In addition, shading rates are now guaranteed more stringently than before. Various bugs related to vertex variables have also been fixed.
Improved Curves Primitive
Curves now have improved dicing behaviour and tighter bounding boxes, resulting in a significant reduction in overall shading time. As a result, and as a means of making RiCurves parameters more generally useful, uniform RiCurves parameters are now bound per curve rather than per segment.
The renderer currently attempts to be backward-compatible with regards to curve uniforms. Per-segment uniform curve parameters are accepted, and forced to to be compatible with the uniform semantics by using the data associated with first segment on each curve. A warning message will be issued if the conversion results in a loss of data (i.e., if the per-segment data varies along a curve).
Control Over Triangular Subdivision for Subdivision Surfaces
Added new tag "smoothtriangles" for subdivision meshes. This tag takes one integer value that should be set to either 1 (on) or 0 (off), the default being off. When on, the tag specifies that a special subdivision rule be applied to all triangular faces; this rule was empirically determined to make triangles subdivide more smoothly. However, it was recently shown that this rule breaks the nice property that two separate meshes can be joined seamlessly by overlapping their boundaries; i.e. when there are triangles at either boundary, it is impossible to join the meshes seamlessly. The tag introduced is meant to overstep the problem by allowing the user to turn off the offending subdivision rule. The syntax is:
SubdivisionMesh "catmull-clark" ... ["smoothtriangles"] [1 0] [0] []
Centered Derivatives and Normals
Derivatives and normals are calculated using a new technique, which will eliminate or reduce several shading artifacts.
- Derivatives are now 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.
The new technique will change surface normals slightly, and may give bumpy surfaces a softer appearance.
Note: These changes only take effect when smooth shading is enabled (via シェーディングInterpolation "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 derivatives can be turned off as follows:
Attribute "derivatives" "centered" [0]
Internal Crack Elimination
PRMan now eliminates all cracks within single primitives, even when large displacements are used. This has been implemented for all surface types except polygons and implicits. It is controlled by the following attribute (turned on by default):
Attribute "stitch" "enable" [1]
Cracks may still occur between separate primitives (for example, between two adjacent bicubic patches). As in previous releases, such cracks may be reduced by turning on binary dicing:
Attribute "dice" "binary" [1]
Binary Dicing Optimizations
Binary dicing has been optimized, reducing overall rendering times by 25-40% on scenes that use this feature. It is no longer a significant performance penalty and can be turned on by default.
Accumulated Opacity Culling
There is a new hider option to extend occlusion culling to account for layers of transparent visible points. This "opacity culling" can result in a significant time and memory savings in scenes with a large number of semi-transparent, layered objects (e.g., hair).
The essential idea is to consider a stack of sampled geometries as being fully opaque if its accumulated opacity is large enough. To specify just how small "large enough" is, there is a new "limits" option:
Option "limits" "othreshold" [rthresh gthresh bthresh]
A stack of visible points whose accumulated opacity is greater (in each channel) than the specified limit will be considered fully opaque by the hider, and objects behind the stack will be culled.
By default, opacity culling is enabled, with the default opacity threshold being [0.996 0.996 0.996].
Fractional Mattes
PRMan now supports the concept of fractional mattes, allowing semi-transparent hold out objects. The opacity of the matte object is now used to determine how much of the geometry behind it is rendered as black and transparent. More details on usage can be found in AppNote #29.Compressed Zfiles
The zfile display driver now supports gzip compression. This can be enabled by adding the parameter "zcompression" with value "zip" to the RiDisplay parameter list:
Display "ri.zfile" "zfile" "z" "zcompression" ["zip"]
Because the tiff display driver also interprets the "compression" parameter, you can separately enable compression for the zfile when rendering with the "rgbaz" mode:
Display "ri.tif" "tiff" "rgbaz" "compression" ["lzw"] "zcompression" ["zip"]
Extended Statistics Output
Statistics output now includes a table summarizing memory use. Current memory use, percentage of current memory, and peak memory use are reported for each of a number of categories; the current memory statistics are primarily useful when generated mid-frame (e.g. by killing prman with a SIGHUP).
More information on using statistics can be found in AppNote #30.
Motion Blur Improvements
Changes have been made to jittering which eliminate the artifacts occuring when using PixelSamples which were powers of two (ie: "PixelSamples 4 4"). In addition, the "stamping" artifacts which resulted from using both motion blur and depth of field (at all PixelSamples settings) have been reduced.
In addition, when using multi-segment motion blur, coordinate system transformations which take place inside shaders are now correctly updated over each segment of time.
シェーディング Language DSO Shadeops Improvements
Several improvements have been made to シェーディング Language DSO shadeops:- Polymorphism based on return type
Just like the built-in noise() function invokes a different variety depending on how you cast or assign it, you may now have the same flexibility with your DSO shadeops. Previously, you could have several variants of a shadeop distinguished by the types of the arguments passed to the function, but not by the return type.
- Multiple DSO shadeops in one DSO
Previously, all variants of a function, say sqr(), had to be stored in a file sqr.so. You couldn't combine shadeops of other names in the same .so file, which is handy if you want them to share common data.
In PRMan 3.9, rather than looking specifically at the <name>.so file, the shader compiler will search all .so files in your include path until it finds one (of any name) with the shadeop table for your function. Because the name of the .so file no longer matters, you can create .so file libraries containing an arbitrary collection of DSO shadeops.
- Shared initializer/cleanup for DSO shadeops in the same .so file
If multiple DSO shadeops in the same .so file all use the same named initializer routine, then the initializer will be called only the first time that any of those shadeops is invoked. Upon further calls to any of the shadeops which share an initializer, they will all be passed pointers to the data block returned by the first initializer. In other words, all of the shadeops which share the same initializer will also share the same per-thread data store.
- New arguments to DSO shadeop initializer routines
Previously, DSO shadeop initializer routines were passed no arguments. Now they are passed two: an integer signifying a unique integer ID for the thread, and a void* which is a blind handle to a texturing context for the thread. If your shadeop method routines will need this data, you should stash it somewhere in the data that you allocate and return from the initializer routine.
Previously compiled routines should continue to operate with no problems. New routines should use the new shadeop.h and declare these two parameters. They are not required to use the parameters in any way.
The intended use of the texture context pointer is that it will be required to pass in to a future API entry point which will allow your DSO shadeops to request filtered texture lookups. (This may be introduced in future releases of PRMan.)
- More helpful error messages when DSO functions do not match
The error reporting for DSO function matching has been significantly beefed up. You can now expect to see error messages from DSO mismatches carefully explaining which argument choices were available and which you apparently were asking for. For example:
>nshader testsqr.sl "testsqr.sl", line 12: ERROR: DSO "s.so" had several ambiguous versions of sqr() matching your arguments. Choices were: vector sqr (vector) float sqr (vector) Your call was:sqr (vector) "testsqr.sl", line 15: ERROR: DSO "s.so" had no version of sqr() matching your arguments. Choices were: float sqr (float) point sqr (point) vector sqr (vector) float sqr (vector) normal sqr (normal) color sqr (color) Your call was: matrix sqr (matrix) testsqr: ERRORS -- NOT COMPILED.
DSO Interface to Noise
PRMan now allows DSOs access to the internal implementation of noise, including the nonperiodic, periodic, and cellular varieties. These are accessed via Rx functions, prototyped in the "rx.h" header file:
extern RtStatus RxNoise(int inDimension, float *in,
int outDimension, float *out);
extern RtStatus RxPNoise(int inDimension, float *in, float *period,
int outDimension, float *out);
extern RtStatus RxCellNoise(int inDimension, float *in,
int outDimension, float *out);
These functions take as input an array of floats in with dimensionality specified in inDimension (which can be 1 to 4). The output noise values is placed in out, which has dimensionality specified in outDimension. The period parameter for RxPNoise should be nonzero for periodic noise.
シェーディング Language Additions
- Uniform テクスチャ Lookups
The renderer now supports "uniform texture lookups". In the past, the texture shadeops (texture, shadow, environment) didn't allow uniform arguments, and the return type was always varying. Now, the compiler allows a uniform return type from a texture shadeop if and only if all the arguments are uniform. In this case, only one texture lookup is done per grid.
- Polymorphic User Functions
Like built-in functions (such as noise) and DSO functions, users are now allowed to write SL functions which are polymorphic. In other words, you may write multiple functions with the same name, but which take different arguments, and the compiler will correctly use the right function under the right circumstances.
- Matrix Component Access
The comp and setcomp functions have been extended to access and set individual floating point components of matrices:
float comp (matrix m; float row, column) void setcomp (matrix m; float row, column; float newvalue)
Directory Mapping
In 3.9.2, a new Option was added which allows the renderer to apply translations to the absolute paths used to look up resources such as shaders and texture maps. More information can be found in section 4.16 of the User Manual.
Miscellaneous Changes
There is now a searchpath mechanism for procedural primitive DSOs, specified via:
Option "searchpath" "procedural" [ pathstring ]
As usual, the default searchpath is "."
The sloargs library now allows you to query whether a shader parameter has output storage class.
The renderer now provides the standard parameter "PixelAspectRatio" to display drivers.
Some parts of the renderer now use double-precision floating point arithmetic, to avoid round-off error.
The 4096-character restriction on token length in RIB files has been removed. This allows for very long resource searchpaths.
Starting with the 3.9.1 release, the official location for the prman executable is now $RMANTREE/bin/prman. The old paths $RMANTREE/prman/bin/prman and $RMANTREE/etc/prman are now deprecated, and are now symbolic links to the new location; if you rely on this path in your scripts, please update them to use the new location.
Similarly, in 3.9.1 the confidence test $RMANTREE/prman/etc/setup has been moved to $RMANTREE/etc/setup, and the library $RMANTREE/prman/lib/libprman.a has been moved to $RMANTREE/lib; $RMANTREE/prman/lib/libprman.a is now a symbolic link to $RMANTREE/lib/libprman.a.
Bug Fixes
- The calculation of derivatives of constant and uniform variable derivatives (ie via calculatenormal) now returns the correct value of zero instead of dumping core.
- Illuminance loops with light category specifiers now work for the negative case.
- Fixed a subdivision surface motion blur bug triggered when shutter times differed from motion times (blur was greater than expected).
- The zbuffer hider has now been fixed.
- Fixed a bug in trim curves where whole trimmed patches would disappear if rendered at high shading rates.
- Fixed bug that kept arrays of colors in vertex vectors from working.
- The four dimensional version of the pnoise shadeop now works correctly.
- txmake and RiMakeテクスチャ now handle byte swapped zfiles correctly.
- The paint hider is now officially deprecated; it will no longer work correctly.
- Opacity culling now works correctly, and is enabled by default. There are also some new statistics output for opacity culling.
- The tga (Targa) display driver now works correctly.
- (Alpha/Linux/NT) The renderer now correctly handles data send to display drivers when dealing with differing bit depths.
- (NT) PRMan and shader now correctly handle wild card expansions (i.e. prman *.rib)
- (NT) PRMan is now built using more aggressive compiler optimizations, resulting in better performance
- (NT) dspysrvr.exe no longer locks the input RIB file, preventing applications from deleting or updating the file
- (NT) Problems with the display driver when spawning a prman.exe process from a GUI application have been fixed
- (NT) Precision problems related to large floating point values have been fixed
- (NT) netrender no longer hangs when given the -progress flag
- (NT) Removed a short delay which sometimes occured just before rendering to disk
- Option "searchpath" "display" now works correctly
- Fixed a problem where netrender occasionally stopped at 99% when using multiple CPUs
- RiDetail no longer crashes the renderer when shutter time is greater than 1.0
- The version string reported by render -version is now 3 numbers (3.9.1) and not 4
- netrender now supports the ability of alfserver running in nrm mode to kill prman processes on the server side
- rendermn.ini now includes $(RATTREE)/lib/shaders as part of the default shader path
- Linking with libprman.a no longer requires linking with -lmalloc. Libprman.a also is no longer linked with its own memory allocation system, preventing conflicting malloc definitions
- Blobby implicit surfaces now correctly motion blur in the face of mismatched shutter and motion block times
- The sloargs library no longer crashes when initializing an array of matrices with an incomplete constant array list
- (NT) RunProgram RiProcedurals now work correctly
- (NT) DSO RiProcedurals are now able to access Ri interface calls from the renderer correctly; this will require linking against the new prman.lib import library
- (NT, Linux, Alpha) The texture cache is no longer flushed (causing a possible performance hit) when the renderer uses extremely large filter widths
- The rib client library (and catrib) handle the output of embedded newlines correctly
- Using dPdtime as an arbitrary output mode now works correctly
- Netrender now consistently returns a valid exit code when the remote rendering host fails
- (NT, Linux) txmake no longer fails on MayaIFF input images
- (NT) The renderer now returns a license immediately when aborting a render to the framebuffer
- (Linux, Windows) Z data produced when rendering rgbaz through the TIFF driver was incorrected byte swapped
- (NT) 5 channel images rendered through netrender were not being byte swapped correctly
- (NT) SGI format images (.rgb) extension were not being rendered correctly by the sgif driver, nor were they read correctly by sho or txmake
- (NT) Maya IFF images were not being correctly handled by txmake
- sloargs library handled constant initialization of matrix arguments incorrectly
- Bounding boxes for segment RiBlobbys was sometimes computed incorrectly. This could lead to dropping of buckets containing the blob
- User vertex variables attached to RiBlobbys was not transformed into current space by the time the shader is called
- mpoint user vertex data was not transformed correctly
- Bounding boxes for motion blurred RiBlobbys was occasionally going to infinity, leading to eyesplitting problems
- RiBlobby now handles illconditioned primitive blob matrices much better, preventing "Negative discriminant set to zero" messages and dropping out of the blob
- (Linux) PRMan is no longer built against its own implementation of malloc. This prevents a problem with allocating more than 900 MB of memory; you may need to ensure the version of malloc in your glibc does not also have the same bug (versions prior to 2.1.3 as well as 2.1.3 RPMs from RedHat may be affected)
- The handling of the eye plane has been improved for certain marginal cases of geometry very close to the camera.
- Object's with displacement bounds which push behind the camera are better handled.
- The shader compiler no longer creates invalid compiled shader files in cases where division by zero is attempted during constant folding.
