HelloRenderMan Programs

Just to be clear, this is not an introduction to Python programming. Nor is it an introduction to 3D graphics and RenderMan. This is about two useful Python programs for creating 3D graphics with Pixar RenderMan.

If you are a 3D artist but don't know anything about programming, or a programmer but don't know anything about 3D graphics, I hope you will dive in anyway. Python is an excellent language for beginning programming, with too many books and online tutorials to list here. The RenderMan API is also excellent introduction to 3D graphics, and you can find tutorials online at Pixar.

If you prefer books, at the time of writing (2023) there are none that are ideal for beginners because RenderMan 21 replaced the original shading language by the Open Shading Language so older tutorials and examples often no longer work. Two books, if you can find them, are still very useful for explaining the structure and geometric primitives of the RenderMan API, and as an introduction to the concepts of 3D shaders.

The RenderMan Companion by Steve Upstill, 1990. The first book, so both introduction and reference to the C language programming API, original RenderMan Shading Language, and original rendering pipeline. It is still a good introduction for programmers with some 3D knowledge, and as a reference to the C and now Python API.

Rendering for Beginners by Saty Raghavachary, 2005. This is an introduction to 3D graphics by writing RenderMan RIB files and shaders. Better for RenderMan/3D beginners and covers the new geometric primitives such as subdivision-surfaces that are not in the Companion, but since these are old style RIB files and original shading language the examples won't work with current day RenderMan until modified or rewritten.

1. Downloading

A current version of Python programs and example code are at my personal web site.

You should end up with a directory/folder with at least these files in it:

The download includes all the web pages, so you can work offline if you like.

2. Is this switched on?

Note: all the commands here were copied from my Linux workstation. If you're on a Mac, /home/hugh/ would instead be /Users/hugh/. On Windows PowerShell it will be \Users\hugh\ and forward slashes should be replaced by backslashes.

First step after downloading is to ensure everything is working. The download includes a simple RenderMan RIB file which should display a green teapot:

/home/hugh% cd HelloRenderMan/code
/home/hugh/HelloRenderMan/code% prman -progress teapot.rib

If that worked, render the teapot again but this time cyan and from Python:

/home/hugh/HelloRenderMan/code% python teapot.py

If you don't see teapots, something is wrong with your RenderMan and/or Python configuration. Work through the RenderMan and Python Command Line Setup guide and try again.

3. Coding with rmwatch

Developing in Python is already fast because there's no compilation or linking required. But I'm lazy, so rmwatch.py is designed to make the development process even faster.

From a terminal window, change into the HelloRenderMan/code directory. Type this command:

/home/hugh/HelloRenderMan/code% python rmwatch.py teapot.py

As before, you'll see the teapot rendered in a preview window. But notice that the rmwatch.py program doesn't finish. Leave it running, and don't close the render window.

Now start your editor and open teapot.py. (If you are using emacs or vi or similar, you'll need to open another terminal window - don't background rmwatch.py.) About line 40 in the render() function look for this just before drawing the teapot:

Ri.Rotate(-90, 1, 0, 0)

This puts the teapot into an upright orientation. Change the -90 angle to -135 or -45 or something and save. Within a second or so the original render window should close and a new one open, with the teapot at the new angle.

4. Animation

Have a look at the code in teapot.py. The "main" control code is function render(), which takes a a dictionary of arguments. One of these is a frame number which defaults to 1.

This is meant to be a spinning teapot, so about line 43 in render() there is a rotation by frame * 2. The frame number when run either directly or from rmwatch.py is 1, but this is easily changed. Add a new at about line 35, just after # Camera setup:

frame = 20

The teapot will change rotation. Try a few other frame values, but remember you must delete this line before doing a batch render. If you forget, every single frame will be identical.

rmwatch.py can watch more than one file and re-run the main program when any of them change. Useful files to watch include RIB archives, texture maps, or shaders.

(Since there are different frame rates across TV and film and stereo, basing values on just the frame number is usually not a great idea. The extra **args to render() can be used to pass additional parameters. This is just a deliberately simplified example.)

Time to render the entire sequence. To stop rmwatch.py, just press Control-C. Because it isn't the editor, there is nothing that needs saving.

5. Batch rendering with rmframes

The second Python program is rmframes.py. In the terminal type:

/home/hugh/HelloRenderMan/code% python rmframes.py teapot.py 150

This will chug away for a while and create numbered TIFF files in /tmp/teapot/ on Linux or MacOSX, in \Users\YOU\Pictures\RenderMan\teapot\ on MS Windows.

Once it has finished the following command should produce an MPEG-4 file playable by most applications. (Thank you StackOverflow user VC.One for incantation details.) Replace DIR by the location of the numbered TIFF files for your system.

ffmpeg -i DIR/teapot%03d.tiff -c:v libx264 -preset slow -crf 20 -pix_fmt yuv420p -r 30 teapot.mp4

Other than input and output file names, the argument you are most likely to change is -r 30 which is the frames per second in the output movie.

Have a look at the code for rmframes.py. There's an -out pattern command line option to generate frames into a different directory or with different names if you want. There's also a configFrame() function which sets the resolution and any other global rendering parameters. And the program does a certain amount of housekeeping for you, such as deleting any frames left over from a previous run.

Notes

You know how to use rmwatch.py and rmwatch.py. I hope you have found this useful.

Python programmers may be asking why rmwatch.py and rmframes.py are run through the Python interpreter, not as stand-alone programs. The answer is that they'll work fine under Linux and MacOS, but under MS Windows the import path changes for some reason I don't understand. If you're not using Windows, go for it.

These programs only work together by following a few rules about program behaviour and the render() function. Of course, these are just my ideas of how things should work. Everything is Open Source meaning you are free to make copies, change things, give your modified copies to other people, and generally do what you like. And if you have a better idea, please tell me about it at the email address below.

At the end of the teapot program is a standard Python if __name__ == "__main__" for when teapot.py is run directly instead of through rmwatch or being imported by another program. For this special case the main code must create an interface object, configure Begin-Display-Format-FrameBegin, render frame number 1, and clean up again. It's not necessary to put this code into every Python RenderMan file, but I think it is nice to have.


Suggestions, mistakes, other feedback?

Any and all feedback about this gratefully accepted.
hugo.fisher at gmail

Copyright 2022- H Fisher, Canberra. Released under Creative Commons Attribution-NonCommercial-ShareAlike license.