You've probably already used some of the ``standard'' shaders such as "matte", "metal", "plastic", and so on. Part of the real power of BMRT is the ability to write your own shaders to control the appearance of your objects. There are several types of shaders:
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".
Once you have written a shader, save it in a file whose name ends with the extension .sl. To compile it, do the following:
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:
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.
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.
Specifies an alternate filename for the resulting .slc file. Without this switch, the output file is derived from the name of your shader.
Quiet mode, only reports errors without any chit-chat.
Verbose mode, lots of extra chit-chat.
Encrypts the resulting .slc file.
Just print out the architecture name (e.g., sgi_m3, linux, etc.).
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). On Unix-like operating systems, this executable is usually kept in the /lib directory, so that's where slc looks for it. If it can't find it there (or, like on Windows, it doesn't normally exist at all), slc will look for it in $BMRTHOME/bin. So you will need to set the environment variable BMRTHOME to point to the directory in which you have installed BMRT.
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.
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 (or -dll on Windows):
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, intelnt, sgi_m3, etc.).
There are several very important limitations and caveats to remember when using DSO's:
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,
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.
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:
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.
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. The option that probably gives the most intuitive use is up-. The default is up.
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.