jrMan Renderer

Ken Camann

 

Before Reading…

 

If you see boxes, question marks, or other odd symbols appearing extraneously at the end of many sentences, this is because this website refuses to serve pages in the character encoding that they are requesting.  In Firefox, choose View->Character Encoding->Western (ISO-8859-1).  In Explorer, right click in the window and from the context menu choose Encoding->Western European (Windows).

 

Overview

 

The renderer I picked, jrMan, is an open source version of the Reyes rendering architecture written in the Java programming language.  The source code is made available under the GPL license, but binaries can also be downloaded from the webpage. There is very little documentation, but this is not actually a serious problem.  Almost everything about a RenderMan rendering session, from the positioning of the geometry to the size and name of the output image file, can be described completely by a scene description text file (called a .RIB file, which is discussed below).  Because the scene description and rendering options are encoded in an independent format, there is very little for jrMan to do except parse the file and render it correctly.  Thus jrMan itself has very little documentation.  Because it is written in Java, it should run anywhere a Java virtual machine is installed.  The current version, 0.4, requires Java 1.4.2 (or newer) to run.

 

Features

 

The main goal of the project is not to produce a feature complete implementation of RenderMan, but to provide well-written, easy to follow source code for a Reyes-style implementation of the RenderMan standard.  As a result, some features present in many RenderMan implementations are missing.  The readme.txt file gives a complete list of both the supported and unsupported parts of the specification.  Since the unsupported feature list is much shorter, I will list them here.

 

Features which are not yet supported:

 

 

Note that shaders are implemented; it is only the compiler that is not.  This affects the performance of the renderer, but all shaders should still work in interpreted mode.  Further note that polygons and “general polygons” are not the same thing; I am not sure exactly what this means, but I believe they use the term as a synonym for what are usually called complex polygons, which are polygons whose sides intersect and are therefore neither convex nor concave.  Of course, simple polygons are supported.

 

Method of Rendering

 

It is important to note the difference between the RenderMan specification and a particular RenderMan renderer.  The RenderMan Interface Specification, also called RISpec, defines the communication protocol between modeling programs and rendering programs.  In short, it describes what kind of commands the renderer must understand (and to an extent also what features it must support) but does not specify how the renderer should render its scene.  As a result, you may find one RenderMan implementation which use ray tracing and another that uses scan conversion.  The Reyes algorithm is a specific way of rendering data defined by the RISpec, namely the micropolygon algorithm described in class.  This is what jrMan uses.  Note that Pixar’s implementation of Reyes has been modified to include a ray-tracing backend for certain effects, a feature that is not in jrMan.  This explains the lack of several features, for example motion blur.  The latest RISpec can be found here, and a slightly older HTML browsable version is here.  Note that it defines two bindings for its API, commands issued as C function calls to a C runtime library, and commands encoded as statements in a text file.  These text files are called RenderMan Interface Bytestream files, or RIB files.  jrMan parses these files and renders the scenes described in them using the Reyes algorithm.

 

Using jrMan

 

Because most of the work done by jrMan is determined by the .RIB file contents, the only real input it takes are a few optional command line arguments (there are only 5 of these) and a .RIB file list.  Even so, it also provides a GUI to aid in adding many .RIB files to a rendering queue and to provide an interface for setting options.  Below is a screen shot of the GUI:

 

 

Creating scenes

 

As mentioned, scene description is done separately from jrMan and is entirely determined by the .RIB file.  The RISpec is far too complicated to describe here; there are entire books which describe the scene description and shader languages.  Information about some of these books and other resources can be found in jrMan’s readme.txt file.  I have also found a good tutorial for a different RenderMan renderer, BMRT, the Blue Moon Ray Tracer.  This program does not use the Reyes algorithm, but understands the same .RIB file format.  While some later parts of the tutorial apply only to BRMT, the beginning is an introduction to RIB file structure and commands, and should work on any RenderMan compliant renderer.  It is the main resource I used to learn how to create simple .RIB files.

 

A simple scene

 

I created the following scene by hand in notepad, the Windows text editor.  I did not create the models by hand; their geometry is included by referencing other .RIB files which are included with jrMan.  I do not provide links to them since they come with jrMan anyway, and are very large because they are ASCII encodings of complex models.

 

 

It is obviously quite difficult to define a scene by hand, and this is not what people usually do.  Usually RenderMan is integrated directly into modeling/scene creation software, using the C runtime library bindings for RISpec to interact with the renderer from inside the program.  Other programs can also output .RIB data.  For example, JPatch is patch-based modeler which can output geometry in .RIB format.

 

Speed

 

The above image was rendered in about 20 seconds.  jrMan is much more dependant on shader complexity than it is on geometry.  For example, the following image containing a huge number of sphere primitives renders in only 49 seconds

 

 

whereas this image with only 9 spheres took 2 minutes and 34 seconds, because of the procedural noise surface and displacement shaders.

 

 

The reason for this dramatic slowdown is most likely because jrMan does not have a shader language compiler capable of creating native java code from the shader descriptions, and must instead interpret its shaders.  This is always a slower strategy than compilation.  While a look at the source code reveals that they are working on a compiler, there were 4 years in between the previous jrMan release and the current one.  It is intended mostly as a learning tool for understanding the programming behind the Reyes algorithm, so one should not “count on” this feature being available in the short term (and perhaps ever).

 

My thoughts

 

I liked this renderer, and if you have an efficient way of create .RIB files it is very easy to use.  Despite being written in Java, it is quite fast given the image quality is it capable of producing, and includes many example scenes and a few models.  Its main use is as a learning tool, so I briefly looked at the code (mostly the primitive and rendering classes) and it is very well written and designed.  Unlike many similar projects, the real work of the entire render isn’t crammed into one giant 350k source file.  The work is logically spread around in many different places, each one of them easy to digest, the hallmark of good object oriented design.

 

On the other hand, the thing I really dislike about jrMan is actually something I dislike about Reyes in general.  It is difficult and awkward to create the most important effect in rendering: shadows.  As you can see, my image does not look very impressive at all, but it actually does contain sophisticated lighting.  You cannot see this though, because a lack of shadowing takes away most of the “depth” in any scene.  From the jrMan website, here is the same bicycle with a shadowing effect:

 

 

Shadowing is supposed to be done with shadow mapping, where the .RIB file first renders the z buffer into a file from the light’s perspective, then loads data from it as a shadow map.  It is somewhat frustrating to get working, especially if you have multiple lights, because the learning curve (in terms of new RIB syntax/commands) to learn is high.  One nice thing about ray tracers on the other hand is that they “just work”.  While they are very slow, they can solve most problems (aliasing, hard shadows) just by shooting more rays.  This method is not very clever and a somewhat inefficient way to solve the problem, but it does not require the user to do additional work and generates physically correct output “for free” without resorting to tricks.