next up previous contents
Next: Miscellaneous Tools Up: Blue Moon Rendering Tools Previous: Photo-realistic rendering with rendrib

Subsections

Shaders and Textures

If you are using rendrib, you are probably already used to one aspect of working with the RenderMan Interface: specifying scenes. In other words, using the procedural interface (the C library calls) or using RIB (the ASCII archival format).

There is another aspect to using the RenderMan Interface: writing your own shaders. You've already used some of the ``standard'' shaders such as "matte", "metal", "plastic", and so on. Part of the real power of the RenderMan interface is the ability to write your own shaders to control the appearance of your objects.

Shaders control the appearance of objects. There are several types of shaders:

Surface shaders
describe the appearance of surfaces and how they react to the lights that shine on them.
Displacement shaders
describe how surfaces wrinkle or bump.
Light shaders
describe the directions, amounts, and colors of illumination distributed by a light source in the scene.
Volume shaders
describe how light is affected as it passes through a participating medium such as smoke or haze.
Imager shaders
describe color transformations made to final pixel values before they are output.

The RenderMan interface specifies that there are several standard shaders available. Standard surface shaders include "constant", "matte", "metal", "plastic", "shiny", and "paintedplastic". Standard light source shaders are "ambientlight", "distantlight", "pointlight", and "spotlight". Standard volume shaders are "depthcue" and "fog". The only standard displacement shader is "bumpy", and there are no standard transformation or imager shaders.

Compiling interpreted shaders with slc

Once you have written a shader, save it in a file whose name ends with the extension .sl. To compile it, do the following:

	slc myshader.sl

This will result either in a compiled shading language object file called myshader.slc, or you will get error messages. Hopefully, the error message will direct you to the line in your file on which the error occurred, and some clue as to the type of error. slc only can compile one .sl file at a time.

The slc program takes the following command line arguments:


-Ipath

Just like a C compiler, the -I switch, followed immediately by a directory name (without a space between -I and the path), will add that path to the list of directories which will be searched for any files that are requested by any #include directives inside your shader source. Multiple directories may be specified by using multiple -I switches.


-Dsymbol
-Dsymbol=val

Just like a C compiler, the -D switch, followed immediately by a symbol name (and possibly with an initial value), will define a proprocessor macro symbol. This allows you to have conditional compilation based on defined symbols using the #if and #ifdef statements in your shader source code files. The slc program automatically defines the symbol BMRT.


-o name

Specifies an alternate filename for the resulting .slc file. Without this switch, the output file is derived from the name of your shader.


-q

Quiet mode, only reports errors without any chit-chat.


-v

Verbose mode, lots of extra chit-chat.


-x

Encrypts the resulting .slc file.


-arch

Just print out the architecture name (e.g., sgi_m3, linux, etc.).


-dso

On some platforms, this will compile your shader to a machine-code DSO file. See the following section for details.

IMPORTANT NOTE: slc uses the C preprocessor (cpp). This executable is usually kept in the /lib directory, so that's where slc looks for it. Therefore, if you keep it someplace else (or, like on Windoze, it doesn't normally exist at all), you need to have this directory in your execution PATH or slc will not be able to run properly.

Since .sl files are passed through the C preprocessor, you can use the #include directive, just as you would for C language source code. You can also give an explicit path for include files using the -I command line option to slc (just like you would for the C compiler). You can also use #ifdef and other C preprocessor directives in a shader. A variable named BMRT is defined, so you can do something like #ifdef BMRT.

The output of slc is an ASCII file for a sort of ``assembly language'' for a virtual machine. When rendrib renders your frame and needs a particular shader, this assembly code is read, converted to bytecodes, and interpreted to execute your shader. Because the slc's output is ASCII and is for a virtual machine, it is completely machine-independent. In other words, you can compile your shader on one platform, and use that .slc file on any other platform. But, like any other interpreted bytecode, even though BMRT's interpreter is fairly efficient, it is not as efficient as compiled machine code.

Compiling .sl files to DSO's

On some platforms (specifically Linux, SGI, and Sun), slc is also capable of compiling programs to native machine code (by first translating into C++ and then invoking the system's C++ compiler), and dynamically loading the code and executing it directly when the shader is needed by rendrib. Some complex shaders can run significantly faster (translating into overall rendering speedups of between 10-50%) if you compile your shaders into DSO's.

You can do this with the -dso flag:

	slc -dso myshader.sl

This will create a file called myshader.ARCH.slc, where ARCH is the code name of the platform (such as linux, sgi_m3, etc.).

There are several very important limitations and caveats to remember when using DSO's:

Using slctell to list shader arguments

The slctell program reports the type of a shader and its parameter names and default values. Usage is simple: just give the shader name on the command line. For example,

	slctell plastic

reports:

	surface "shaders/plastic.slc"
	    "Ka" "uniform float"
	                Default value: 1
	    "Kd" "uniform float"
	                Default value: 0.5
	    "Ks" "uniform float"
	                Default value: 0.5
	    "roughness" "uniform float"
	                Default value: 0.1
	    "specularcolor" "uniform color"
	                Default value: "rgb" [1 1 1]

The slctell program should correctly report shader information for both interpreted and compiled DSO shaders. Note, however, that in either case, slctell can only report the default values for parameters that are given defaults by simple assignment. In other words, if a constant (or a named space point) is used as the default value, slctell will report it correctly, but if the default is the result of a function, complex computation, or involves a graphics state variable, there is no way that slctell will correctly report the default value.

Making tiled TIFF files with mkmip

BMRT has always used TIFF files for stored image textures (as opposed to PRMan, which requires you to convert to a proprietary texture format). Though BMRT accepts regular scanline (or strip) oriented TIFF files, it is able to perform certain optimizations if the TIFF files you supply happen to be tile-oriented. In particular, BMRT is able to significantly reduce the memory needed for texture mapping with tiled TIFF files.

The mkmip program converts scanline TIFF files into multiresolution, tiled TIFF files. The mkmip program will also convert zfiles into shadow maps (tiled float TIFFs) and will combine six views into a cube face environment map. Command line usage is:

where options include:


-smode wrapmode
-tmode wrapmode
-mode wrapmode

where wrapmode is one of: periodic, black, or clamp. This specifies the behavior of the texture when outside the [0,1] lookup range. Note that -smode and -tmode specify wrapping behavior separately for the s and t directions, while -mode specifies both at the same time. The default behavior is black.


-resize option

Controls the resizing of non-square and non-power-of-two textures when being converted to MIP-maps. The option may be any of: up, down, round, up-, down-, round-. The up, down, and round indicates that the texture should be resized to the next highest power of two, the next lowest power of two, of the ``nearest'' power of two, respectively. For each option, the trailing dash indicates that the texture coordinates should always range from 0 to 1, regardless of the aspect ratio of the original texture. Absence of the dash indicates that the texture should encode its original aspect ratio and adjust the texture coordinates appropriately at texture lookup time. I think that the option that gives the most intuitive use is up-. The default is up.


-fov fovangle

for envcube only, specifies the field of view of the faces.

Note: rendrib specifically wants TIFF files as texture and environment maps. The files can be 8, 16, or 32 bits per channel, but cannot be palette color files. Single channel greyscale is okay, as are 3 channel RGB or 4 channel RGBA files. Ordinary scanline TIFF is fine, but if you use the mkmip program to pre-process the textures into multiresolution tiled TIFF, your rendering will be much more efficient.


next up previous contents
Next: Miscellaneous Tools Up: Blue Moon Rendering Tools Previous: Photo-realistic rendering with rendrib
Larry Gritz
2000-04-14