Texture Map Utilities
Errors
Archive Files
Inline Archives
Conditional Evaluation
The format of the various texture map files is implementation dependent. However, there are standard utilities that convert image files into texture map files.
During two-dimensional texture access, texture coordinates (s, t) are mapped onto the texture such that s=0 maps to xmin, s=1 maps to xmax+1, t=0 maps to ymin, and t=1 maps to ymax+1. To be precise, all accesses to the half-open interval [0,1) in s and t will lie within the picture data.
A wrapmode describes how the texture is accessed if the texture
coordinates are outside the unit square (less than zero, or greater than or
equal to one). The swrap and twrap strings specify the
wrapping behavior of the s and t coordinates. The standard
wrapping behavior for s and t, "black," is to
return the value zero for all accesses outside the unit square. (Thus an RGBa
texture will be transparent black, zero on all four channels.) The keyword "periodic
"
indicates that values of s (or t) outside [0,1) will be
mapped into [0,1) by subtracting the largest integer less than or equal to the
coordinate (the floor of the coordinate). This will wrap the value 1 back to
0, the value 1.25 to 0.25, and the value -0.1 to 0.9. The result will be to
repeat the texture as a tile that fills texture space in the s (or t) direction.
The keyword "clamp
" indicates that values of s
(or t) outside [0,1) will be mapped into [0,1) by clamping them
at their minimum and maximum values. All values below zero will be clamped
to zero and all values greater than or equal to one will be clamped to a
value slightly less than one (at the last texture pixel).
Textures are often prefiltered so that subsequent antialiasing calculations can be done more quickly at run-time. This is controlled by giving a filterfunc, which is the same as the filterfunc used in RiPixelFilter, and an swidth and twidth.
Surface textures are used to modify the properties of a surface, such as color and opacity. A surface texture is accessed using the surface texture coordinates (see the section on Texture coordinates) or any other two-dimensional coordinates computed by a user-defined shader. A surface texture consists of one or more channels. A single channel or a group of n channels (usually an RGB color) can be accessed using the texture function of the Shading Language. The texture function requires the name of a texture file containing the texture.
RiMakeTexture( char *picturename, char *texturename, RtToken swrap, RtToken twrap, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...parameterlist... )
Convert an image in a standard picture file whose name is picturename into a texture file whose name is texturename. All channels of the picture file will be converted (in order) to texture channels. The storage format of the texture file and the precision of stored texture channels are implementation-dependent.
The picture file used as input is not changed or otherwise affected by RiMakeTexture.
RIB BINDING MakeTexture picturename texturename swrap twrap filter swidth twidth ...parameterlist...
The filter parameter should be one of "box," "triangle," "catmull-rom," "b-spline," "gaussian" and "sinc." These correspond to the predefined filter functions described in RiPixelFilter.
EXAMPLE RiMakeTexture("globe.pic," "globe.tx," "periodic," "clamp," RiGaussianFilter, 2.0, 2.0, RI_NULL); SEE ALSO RiTextureCoordinates, texture() in the Shading Language
Environment maps are images representing the color of an environment in a particular direction. An environment map is accessed using a point representing direction; this direction is often the direction of a mirror reflection and hence environment maps are often referred to as reflection maps. However, any direction can be computed by a user-defined shader. An environment map image consists of one or more channels. A single channel or a group of n channels (usually an RGB color) can be accessed using the environment function in the Shading Language. Environment maps can be input in two formats. The first is as a single latitude-longitude image. Environment maps in this form are fairly easy to create using a paint system. The second format is a set of six cube face projections. Environment maps in this form are naturally created by the rendering program.
RiMakeLatLongEnvironment( char *picturename, char *texturename, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...parameterlist... );
Convert an image in a standard picture file representing a latitude-longitude map whose name is picturename into an environment map whose name is texturename. The storage format of the texture file and the precision of stored texture channels are implementation-dependent.
This image has longitude equal to 0 degrees at the left, and 360 degrees at the right. The latitude at the bottom is -90 degrees and at the top is 90 degrees. The bottom of the picture is at the south pole and the top the north pole. The direction in space corresponding to each of the points on the image is given by:
Notice that latitude-longitude environment maps are sensitive to the handedness of the coordinate system in which they will be accessed. Environment maps which are intended to be accessed in a right-handed coordinate system will, if displayed, appear as a mirror image of those intended to be accessed in a left-handed coordinate system.
RIB BINDING MakeLatLongEnvironment picturename texturename filter swidth twidth parameterlistThe filter parameter should be one of "box," "triangle," "catmull-rom," "b-spline," "gaussian" and "sinc." These correspond to the predefined filter functions described with RiPixelFilter.
EXAMPLE MakeLatLongEnvironment "long.pic" "long.tx""catmull-rom" 3 3 SEE ALSO RiMakeCubeFaceEnvironment, environment() in the Shading Language
RiMakeCubeFaceEnvironment( char *px, char *nx, char *py, char *ny, char *pz, char *nz, char *texturename, RtFloat fov, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...parameterlist... );
Convert six images in standard picture files representing six viewing directions into an environment map whose name is texturename. The image pz (nz) is the image as viewed in the positive (negative) z direction. The remaining images are those viewed along the positive and negative x and y directions. The storage format of the texture file and the precision of stored texture channels are implementation-dependent.
Each image is normally produced by a rendering program by placing the eye at the center of the environment (usually the origin) and generating a picture in each of the six directions. These pictures are the projection of the environment onto a set of cube faces. Each face is usually assumed to be unit distance from the eye point. Cube face environment maps should be generated with the following orientations:
Image Forward Axis Up Axis Right Axis px +X +Y -Z nx -X +Y +Z py +Y -Z +X ny -Y +Z +X pz +Z +Y +X nz -Z +Y -X Notice that cube face environment maps are sensitive to the handedness of the coordinate system in which they will be accessed. Environment maps which are intended to be accessed in a right-handed coordinate system will, if displayed, appear as a mirror image of those intended to be accessed in a left-handed coordinate system.
The fov is the full horizontal field of view used to generate these images. A value of 90 degrees will cause the cube face edges to meet exactly. Using a slightly larger value will cause the cube faces to intersect. Having a slight overlap helps remove artifacts along the seams where the different pictures are joined.
RIB BINDING MakeCubeFaceEnvironment px nx py ny pz nz texturename fov filter swidth twidth parameterlist
The filter parameter should be one of "box," "triangle," "catmull-rom," "b-spline," "gaussian" and "sinc." These correspond to the predefined filter functions described with RiPixelFilter.
EXAMPLE RiMakeCubeFaceEnvironment("foo.x," "foo.nx," "foo.y," "foo.ny," "foo.z," "foo.nz," "foo.env," 95.0, RiTriangleFilter, 2.0, 2.0, RI_NULL); SEE ALSO RiMakeLatLongEnvironment, environment() in the Shading Language
Shadow maps are depth buffer images from a particular view. They are generally used in light source shaders to cast shadows onto objects. A shadow map is accessed by point in the camera coordinate system corresponding to that view. This point must be computed in the shader. A shadow map texture can be accessed using the shadow function of the Shading Language. The shadow function requires the name of a texture file containing the texture.
RiMakeShadow( char *picturename, char *texturename, char *parameterlist )
Create a depth image file named picturename into a shadow map whose name is texturename. The storage format of the shadow map texture file and the precision of stored texture channels are implementation-dependent.
RIB BINDING MakeShadow picturename texturename parameterlist EXAMPLE MakeShadow "shadow.pic" "shadow.tex" SEE ALSO shadow() in the Shading Language
Brick maps are 3D textures stored in a tiled MIP map representation. A brick map texture can be accessed using the texture3d function of the Shading Language. The texture3d function requires the name of a brick map file containing the texture.
RiMakeBrickMap( int n, char **ptcnames, char *bkmname, char *parameterlist )
Create a brick map file named bkmname from a list of n point cloud files in ptcnames. The storage format of the brick map file is implementation-dependent.
RIB BINDING MakeBrickMap ptcname(s) bkmname parameterlist EXAMPLES MakeBrickMap "sphere.ptc" "sphere.bkm" MakeBrickMap ["sphere.ptc" "box.ptc"] "spherebox.bkm" "maxerror" 0.002 SEE ALSO texture3d() in the Shading Language
There are times when external commands must be synchronized with various stages of multi-pass rendering. This can be accomplished with RiSystem, which executes an arbitrary command expressed as a single string at the time the RiSystem call is encountered. As with other commands responsible for managing external resources, RiSystem is only valid outside the RI World scope.
RiSystem(char *cmd)
Execute an arbitrary command in the same environment as the current rendering pass. Some implementations will perform standard shell substitutions for meta characters. Errors occuring during the command execution are interpreted as severe and will terminate the current rendering context.
RIB BINDING System cmdstring EXAMPLES System "/usr/bin/env" System "ptfilter -f ssdiffusion -material ketchup in.ptc out.ptc"
RenderMan Interface procedures do not return error status codes. Instead, the user may specify an error handling routine that will be called whenever an error is encountered.
RiErrorHandler( RtFunc handler )
This procedure sets the error handling procedure invoked by the renderer when an error is detected. Error handling procedures have the following form:
RtVoid handler( RtInt code, RtInt severity, char *message )code indicates the type of error, and severity indicates how serious the error is. Values for code and severity are defined in <ri.h>. The message is a character string containing an error message formatted by the renderer which can be printed or displayed, as the handler desires.
The following standard error handlers are defined:
RtVoid RiErrorIgnore; RtVoid RiErrorPrint; RtVoid RiErrorAbort; RtInt RiLastError;If RiErrorIgnore is specified, all errors are ignored and no diagnostic messages are generated. If RiErrorPrint is specified, a diagnostic message is generated for each error. The rendering system will attempt to ignore the erroneous information and continue rendering. If RiErrorAbort is specified, the first error will cause a diagnostic message to be generated and the rendering system will immediately terminate. Each of the standard error handlers saves the last error code in the global variable RiLastError. This procedure can be called outside an RiBegin-RiEnd block.
RIB BINDING ErrorHandler "ignore" ErrorHandler "print" ErrorHandler "abort"
If "
ignore
," "abort
" is specified, the equivalent predefined error handling procedure will be invoked in the RIB server. Notice that the RIB parser process may detect RIB stream syntax errors which make it impossible to correctly parse a request. In this case, the error procedure will be invoked and the parser will do its best to resynchronize the input stream by scanning for the next recognizable token.
EXAMPLE
ErrorHandler "ignore
"
One important use of the RIB protocol is to store a scene description in an archive file for rendering at a later time or in a remote location from the modeling application. Appendix D, RenderMan Interface Bytestream Conventions, outlines structuring conventions to make these archives as portable and useful as possible.
RiArchiveRecord( RtToken type, char *format [, arg ...] )
This call writes a user data record (data which is outside the scope of the requests described in the rest of Part I of this document) into a RIB archive file or stream. type is either "
comment
", "structure
", or "verbatim
". "comment
" begins the user data record with a RIB comment marker and terminates it with a newline. "structure
" begins the user data record with a RIB structuring convention preface and terminates it with a newline. "verbatim
" writes user data record as-is, without any prefacing comment markers; a trailing newline will be added if the string does not already end with one. The user data record itself is supplied as aprintf()
format string with optional arguments. It is an error to embed newline characters in the format or any of its string arguments.
RiReadArchive( RtToken name, RtVoid (*callback)(RtToken, char*,...), ...parameterlist...)
This function will read the named file. Each RIB command in the archive will be parsed and executed exactly as if it had been called by the application program directly, or been in-line in the calling RIB file, as the case may be. This is essentially a RIB-file include mechanism. In the C API version, the callback parameter is a function which will be called for any RIB user data record or structure comment which is found in the file. This routine has the same prototype as RiArchiveRecord, and allows the application routine to notice user data records and then execute special behavior based on them as the file is being read into the renderer. If a NULL value is passed for callback, comments and structures in the RIB file will simply be ignored.
RIB BINDING ReadArchive filename
EXAMPLE ReadArchive "sodacan.rib"
SEE ALSO RiArchiveRecord
Inline archives represent a means to describe and instance arbitrary RIB sequences in a RIB stream. This generality makes in-line archives superior in terms of expressiveness to the deprecated retained geometry feature (RiObjectBegin/End). In conjunction with conditional evaluation, inline archives are an important tool for RIB generators. Renderers should make no assumptions and impose no limits on the size and nesting of inline archives.
RtArchiveHandle RiArchiveBegin ( RtToken archivename, ...parameterlist...) RiArchiveEnd()
These requests bound the definition of an in-line archive. Inline archives can be instantiated with RiReadArchive, but only within the RI context in which they were defined.
RIB BINDING ArchiveBegin archivename ...parameterlist... ArchiveEnd
EXAMPLE ArchiveBegin "mysphere" Sphere 1 -1 1 360 ArchiveEnd ReadArchive "mysphere"
SEE ALSO RiReadArchive
RiIfBegin (RtToken expression) RiElseIf (RtToken expression) RiElse RiIfEnd
These calls form the basis of a simple conditional evaluation mechanism and allow RIB archives with be constructed with a degree of context sensitivity. RIB archives allow chunks of "frozen" geometry or scene state to be stored and then accessed from a higher level driver RIB file. The archive can be reused in multiple parts of the same frame or across multiple frames. For example, an object whose shape remains the same across many frames might be placed in an archive, it's position and orientation might be animated by specifying a different transformation matrix in each per-frame driver file before referencing the object's archive. This modularity has many benefits, including the potentially large savings in per-frame RIB generation time when the archived object is very complex.
However, there are certain important situations for which it would be useful to write out a single archive once, but then allow certain aspects of the archive to change based on the current context in which it has been instantiated, as defined by the driver file.
For example, the archive might select entirely different surface shaders depending on which "rendering pass" is active. The driver file might define the current pass with a user Attribute setting:
Attribute "user" "string renderpass" ["shadow"] Procedural "DelayedReadArchive" ["archive.rib"] [0 1 0 1 0 1]Then, the archive can use the conditional evaluation calls to decide which shaders to apply:
AttributeBegin IfBegin "$user:renderpass == 'shadow'" Surface "null" ElseIf "$user:renderpass == 'beauty'" Surface "rmarble" Else Surface "plastic" IfEnd Sphere 1.0 -1.0 1.0 360.0 AttributeEnd
Expression syntax: The conditional expressions evaluated by IfBegin and ElseIf are similar to those found in C and many scripting languages. The entire expression evalutes to a numeric result, and if the result is non-zero then the associated branch of the If-Else block becomes active. The expression operators work on values which are string or numeric literals, or renderer state variables. A typical set of arithmatic, relational, and logical operators are provided, plus a few additional functions:
State Variables | look up Attribute and Option values |
$name |
Arithmetic | take numbers, return numbers |
+ - * / ** |
Bit Mask
|
bit-wise integer And, Or, Xor |
& | ^ |
Relational
|
take numbers or strings;
return 1 if the relation holds, 0 if it doesn't; strings are compared using strcmp() |
== != < <= >= > |
String Match
|
glob-style matching, the pattern
can contain '*' and '?' wildcards. |
string =~ pattern |
Logical
|
treats non-zero as true,
zero as false;
return 1 if the logical assertion holds, 0 if it doesn't |
&& || ! |
Grouping |
(subexpression) 'string literal' |
|
Variable Existence
|
returns 1 if the state variable exists,
0 if it doesn't |
defined(name) |
Concatenation | combines strings |
concat(string , string) |
Computed Variable Names | look up name given by subexpression |
$(subexpression) |
State variable names are looked up by searching the Attribute stack, then the Options, then RendererInfo. The search can be restricted by prepending an additional "namespace" qualifier:
$Frame --> finds the Option (current frame number) $limits:eyesplits --> finds the Attribute $Attribute:limits:eyesplits --> also finds the Attribute $Option:limits:eyesplits --> finds the Option
Traditional static archives will continue to be the right choice in most situations. With proper archive "factoring" the creator of the driver file can select appropriate archives as needed and hardcode their names in the driver. Conditional evaluation becomes useful when factoring isn't possible or when it can help reduce the number of required archives
RIB BINDING
EXAMPLE
Using Computed Variable Names (i.e. $(subexpression)) in a conditional rib statement. The use of computed variable names is similar to evaluating expressions created from the contents of other variables (like performing 'eval' or 'expr' from some shells).
prman x.rib main.rib ---> renders a yellow matte sphere
prman y.rib main.rib ---> renders a magenta plastic sphere
x.rib
Attribute "user" "string abc" ["x"]
y.rib
Attribute "user" "string abc" ["y"]
main.rib
##RenderMan RIBversion 3.03FrameBegin 1Format 128 128 1Display "/tmp/t.tif" "tiff" "rgba"Projection "perspective" "fov" [45]WorldBeginLightSource "distantlight" 1 "from" [1 1 -1]Attribute "user" "float x1" [11]Attribute "user" "float x2" [12]Attribute "user" "float y1" [101]Attribute "user" "float y2" [102]AttributeBeginAttribute "identifier" "name" ["mysphere"]Translate 0 0 2.75IfBegin "$($abc$Frame) > 100"Color 1 0 1Surface "plastic"ElseColor 1 1 0Surface "matte"IfEndSphere 1.0 -1.0 1.0 360.0AttributeEndWorldEndFrameEnd
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of Pixar. The information in this publication is furnished for informational use only, is subject to change without notice and should not be construed as a commitment by Pixar. Pixar assumes no responsibility or liability for any errors or inaccuracies that may appear in this publication.
Pixar Animation Studios
|