11.1. RenderMan RIB export

The module cgkit.ribexport contains the class RIBExporter that exports the current scene as RIB and creates shaders from the materials and light sources used in the scene.

To use the exporter you can simply use the save() command and pass a file name with suffix .rib. The plugin supports the following options that can be passed to the save() command:

Option Default Description
camera None Camera object to be used
output None Output image file name or output specs
output_framebuffer True Framebuffer output?
bake False Activate texture baking mode
bakemodel None Determines the model to bake
bakestvar "st" Variable name of the bake texture coordinates

camera specifies the camera object to be used for rendering the scene. If None is specified the first camera found in the scene is used.

output is the output image file name or a list of output specifiers. Each specifier is a 4-tuple (filename, type, mode, params) containing the parameters for a RiDisplay() call. The additional parameters must be given as a dictionary. output can also be None in which case no RiDisplay() call is made.

output_framebuffer is a flag that specifies if a framebuffer display should be opened in addition to writing the output image file to disk. This flag is only used when output is a string.

If bake is True the exported scene will bake a texture map instead of producing a final image.

bakemodel is either the name of a WorldObject or a WorldObject itself. The texture will be baked for the specified model. This parameter doesn’t have to be specified if there is only one mesh in the scene.

bakestvar is the name of the primitive variable that holds the texture coordinates that should be used for baking.

The plugin uses the following global options:

Option Default Description
displaymode "rgb" Display mode
displaytype "file" Display type
output None Output image file name or output specs (see above)
resolution (640,480) Output image resolution
pixelsamples (2,2) Number of pixel samples
shadingrate 1.0 Shading rate
pixelfilter None Pixel filter setting
tiles None Render the image in tiles
rib None Additional global RIB requests

displaymode is the mode string for the RiDisplay() call and determines what data is written to the output. Usually you might want to switch between “rgb” (default) and “rgba”.

output is the image output name or a list of output specifiers (see above).

resolution is either a 2-tuple (width, height) or a 3-tuple (width, height, pixel aspect) specifying the outpout image resolution.

pixelsamples is a 2-tuple containing the pixel samples setting.

shadingrate contains the shading rate setting.

pixelfilter is a 2-tuple (filter, (xwidth, ywidth)) that sets the pixel filter to use. If None is passed the default pixel filter of the renderer is used. Example: (“gaussian”, (2,2))

tiles contains two sequences that defines the positions where the image is split. The first sequence contains the x positions and the second sequence the y positions where a split should occur. Each value lies between 0 and 1, so for example tiles=((0.5,), (0.5,)) will render the image in four equal tiles. The tiles can than be stitched together using the stitch module.

rib is a string containing additional RIB requests that are written in front of the frames.

It is possible to attach user RIB requests to an object simply by adding a string attribute called rib. When present this string will be written right before the geometry calls. For example, this can be used to set attributes that are specific to a particular renderer:

s = Sphere(...)
s.rib = 'Attribute "visibility" "transmission" "opaque"'

For an object to be exported as RIB it has to use a geometry that supports the IGeometry protocol. Materials must support the IMaterial protocol and light sources the ILightSource protocol. For details on these protocols see the sub sections below. If there is an object that does not support one of these protocols an adapter can be written that implements the protocol on behalf of the original object.

The remainder of this section is meant to be read by developers who want to extend the functionality of the exporter either by implementing adapter classes for existing classes or by implementing new geometries, materials or light sources that natively support the respective protocol.

11.1.1. The IGeometry protocol

Every GeomObject that supports the IGeometry protocol can be exported as RIB. If the geometry does not support the protocol it will be ignored.

The IGeometry protocol only specifies the presence of one method:

IGeometry.render(matid)

Creates Ri geometry requests for the geometry that has the material with id matid assigned to it. The geometry should be created in the local coordinate system of the GeomObject. The primitive variables should also be exported. The method can assume that there is already an enclosing RiAttributeBegin()/RiAttributeEnd() block around the call.

Here is an example of an adapter class that implements the IGeometry protocol for the SphereGeom (which knows nothing about RenderMan):

import protocols
from ri import *

# Adapter class that implements the IGeometry protocol on behalf of the SphereGeom class
class SphereAdapter:

    protocols.advise(instancesProvide=[IGeometry], asAdapterForTypes=[SphereGeom])

    def __init__(self, spheregeom, proto):
        self.geom = spheregeom

    def render(self, matid):
        # A sphere can only have one single material
     if matid==0:
            r = self.geom.radius
            RiSphere(r, -r, r, 360)

11.1.2. The IMaterial protocol

A material that supports the IMaterial protocol will be mapped to a surface shader, displacement shader and interior shader. To support the IMaterial protocol the following methods have to be implemented:

IMaterial.createPasses()

Returns a list of RenderPass objects necessary for this material instance. These passes may be used to create environment maps, for example. If no extra passes are required an empty list has to be returned.

IMaterial.preProcess(exporter)

This method is called before the image is rendered and can be used to create or copy image maps or do other initializations that have to be done before the actual rendering starts. The exporter instance is provided as argument to the method (for example, to find out where image maps are stored).

IMaterial.color()

Return the color (as a 3-sequence of floats) for the RiColor() call. If no color is required the method may return None in which case no Color call is made.

IMaterial.opacity()

Return the opacity (as a 3-sequence of floats) for the RiOpacity() call. If no opacity is required the method may return None in which case no Opacity call is made.

IMaterial.surfaceShaderName()

Return the name of the surface shader for this material. The exporter may still modify this name to make it unique among all generated shaders.

IMaterial.surfaceShaderSource()

Return the RenderMan Shading Language source code for the surface shader. Instead of the shader name the generated source code should contain the variable $SHADERNAME that will be substituted with the actual name of the shader. The method may also return None if no shader should be created. In this case, the name returned by surfaceShaderName() is assumed to be the name of an existing shader.

IMaterial.surfaceShaderParams(passes)

Returns a dictionary that contains the shader parameters that should be used for the surface shader. The key is the name of the parameter (including inline declarations) and the value is the actual parameter value at the current time. The passes argument contains the list of passes as generated by createPasses(). This list can be used to obtain the actual name of an environment map, for example.

IMaterial.surfaceShaderTransform()

Return a mat4 containing the transformation that should be applied to the shader.

IMaterial.displacementShaderName()

Return the name of the displacement shader for this material. The exporter may still modify this name to make it unique among all generated shaders. You can also return None if no displacement shader is required.

IMaterial.displacementShaderSource()

Return the RenderMan Shading Language source code for the displacement shader. Instead of the shader name the generated source code should contain the variable $SHADERNAME that will be substituted with the actual name of the shader. The method may also return None if no shader should be created. In this case, the name returned by displacementShaderName() is assumed to be the name of an existing shader.

IMaterial.displacementShaderParams(passes)

Returns a dictionary that contains the shader parameters that should be used for the displacement shader. The key is the name of the parameter (including inline declarations) and the value is the actual parameter value at the current time. The passes argument contains the list of passes as generated by createPasses().

IMaterial.displacementShaderTransform()

Return a mat4 containing the transformation that should be applied to the shader.

IMaterial.displacementBound()

Returns a tuple (coordinate system, distance) that specifies the maximum displacement. The distance is the maximum amount that a surface point is displaced and is given in the specified coordinate system.

IMaterial.interiorShaderName()

Return the name of the interior shader for this material. The exporter may still modify this name to make it unique among all generated shaders. You can also return None if no interior shader is required.

IMaterial.interiorShaderSource()

Return the RenderMan Shading Language source code for the interior shader. Instead of the shader name the generated source code should contain the variable $SHADERNAME that will be substituted with the actual name of the shader. The method may also return None if no shader should be created. In this case, the name returned by displacementShaderName() is assumed to be the name of an existing shader.

IMaterial.interiorShaderParams(passes)

Returns a dictionary that contains the shader parameters that should be used for the interior shader. The key is the name of the parameter (including inline declarations) and the value is the actual parameter value at the current time. The passes argument contains the list of passes as generated by createPasses().

IMaterial.interiorShaderTransform()

Return a mat4 containing the transformation that should be applied to the shader.

11.1.3. The ILightSource protocol

Every world object that supports the ILightSource protocol will be used as light source to illuminate the scene. In order to support the ILightSource protocol the following four methods have to be implemented:

ILightSource.createPasses()

Returns a list of RenderPass objects necessary for this light source instance. Usually the light sources will make use of the ShadowPass pass. If no extra passes are required an empty list has to be returned.

ILightSource.shaderName()

Return the name of the light source shader for this light source. The exporter may still modify this name to make it unique among all generated shaders.

ILightSource.shaderSource()

Return the RenderMan Shading Language source code for this light source. Instead of the shader name the generated source code should contain the variable $SHADERNAME that will be substituted with the actual name of the shader. The method may also return None if no shader should be created. In this case, the name returned by shaderName() is assumed to be the name of an existing shader.

ILightSource.shaderParams(passes)

Returns a dictionary that contains the shader parameters that should be used for this light source instance. The key is the name of the parameter (including inline declarations) and the value is the actual parameter value at the current time. The passes argument contains the list of passes as generated by createPasses(). This list can be used to obtain the actual name of a shadow map, for example.

11.1.4. RenderPass — Base class for all passes

The creation of an image may take several render passes where shadow maps, environment maps and eventually the final image are created. The number of passes is dependent on the number and types of light sources and the materials used in the scene. Every render pass is represented by a class that is derived from the RenderPass class.

An actual pass has to implement the doPass() method where it has to output a frame block that generates one or more output files. To do the scene export it can use the methods from the exporter.

class RenderPass(output, owner=None)

output is a list of tuples (name, type, mode, params) that each defines the output to create in this pass. Each tuple contains the parameters necessary for a RiDisplay() call. name is the name of the output file, type is the output type (such as “file” or “zfile”), mode specifies what information will be stored in the file (RI_RGB, RI_RGBA, ...) and params is a dictionary with extra parameters.

Every RenderPass instance has an attribute exporter that will contain a reference to the exporter. So the pass object may use the exporter methods to output the scene.

RenderPass.done()

Check if this pass is already done or not. This method is used when shader parameters have to be determined. The output of a pass may only be used once the pass is done and the output really exists (for example, you cannot use a shadow map until it was created).

RenderPass.doPass(framenr)

This method has to be overwritten in derived classes where the actual frame block is generated. framenr is the frame number to use for the RiFrameBegin() call.

RenderPass.realFilename(filename)

Translate the logical file name filename into a real file name. A ValueError exception is generated if filename is not a logical file name of this pass.

RenderPass.getFilenameTable()

Return the filename translation table. The return value is a dictionary that maps logical file names to real file names.

RenderPass.setFilenameTable(tab)

Set an updated filename table. This method is used to set the updated file name table where no name clashes occur with other passes.

RenderPass.initDisplays()

This method calls RiDisplay() for all specified outputs. This is a helper method that can be used in doPass().

11.1.5. ImagePass — Creates the final image pass

class ImagePass(output, cam)

11.1.6. ShadowPass — Creates a shadow map

class ShadowPass(output, light, fov, resolution)

11.1.7. RIBExporter — The exporter class

Besides the usual methods that every exporter must implement this exporter has the following helper methods that have to be used by RenderPass objects:

RIBExporter.isExportable(wobj)
RIBExporter.applyViewTransform(V)

Applies the view transformation V (given as a mat4). This method corresponds to a RiConcatTransform() call. It outputs the view transformation V (which transforms from world to camera coordinates) as a RenderMan transformation. The handedness of the scene is taken into account.

RIBExporter.applyLightSource(lgt)

Apply the light source lgt which must be a light source world object. This method corresponds to a RiLightSource() call.

RIBExporter.applyTransformation(T, linearvel=None, angularvel=None)

Apply the transformation T (given as a mat4). This method corresponds to a RiConcatTransform() call. It outputs T as a RenderMan transformation. If a linear or angular velocity is given an motion block is written to enable motion blur.

RIBExporter.applyMaterial(mat)

Apply the material mat which must be a Material object. This method corresponds to the calls RiColor(), RiOpacity(), RiSurface(), RiDisplacement() and RiInterior().

RIBExporter.applyGeometry(geom)

Apply the geometry geom which must be a GeomObject.

RIBExporter.writeShader(name, source)

Write a shader source file and return the name of the shader. Usually, you don’t have to call this method yourself as it is called by the above applyXyz()-methods.