The RenderMan RIB Specification is an API developed by Pixar to describe three dimensional scenes. It includes the RenderMan Shading Language.
It is a technical specification for a standard communications protocol between modeling programs and rendering programs capable of producing photorealistic-quality images. In this way, it is similar to PostScript but for describing 3D scenes rather than 2D page layouts.
Selecting a RenderMan installation
Note:
CityEngine does not write the RIB files itself, but makes use of any installed Renderman package (examples are prman, air, 3delight, aqsis, pixie, etc.). Ensure you are using the 64bit version.Please set the path to the corresponding shared library in Edit > Preferences > Export > RenderMan > RenderMan Library .
Examples for common RIB output libraries are listed in the following table (the library extensions are .so/.dylib/.dll for Linux/OS X/Windows). These libraries are usually found in the lib subdirectory:
Renderer | Library (w/o extension) |
---|---|
PRMan (>= 14) | libprman-xx.x |
3Delight | lib3delight |
Air | airdlink |
Aqsis | libaqsis_ri2rib |
Pixie | libri |
Export settings
In addition to the general export options, RIB has the following options:
Include Camera Data | If enabled, CityEngine will export additional RIB statements to the primary rib file (current camera position of "Perspective" camera and default lights) to make the exported rib files directly renderable without the need for additional tools. |
Write Compressed Files | If enabled, CityEngine will instruct the RIB library to write to compressed/binary rib files (not available with every renderman package). |
CGA Mapping to RIB
This section explains the mapping of the CityEngine geometry and material data to the RIB elements.
The implementation of the RIB exporter in the CityEngine follows the RIB specification version 3.2. The specification is freely available at http://www.pixar.com.
Geometry
All meshes are translated using the RiPointsGeneralPolygons API call. All non-empty texture coordinate channels are appended using custom attributes and the numbering of the texture channel is preserved. For example, a single mesh translates into RIB like this:
PointsGeneralPolygons [ ... ] [ ... ] [ ... ]
"P" [ ... ]
"facevarying normal N" [ ... ]
"st" [ ... ]
"facevarying float [2] uv1" [ ... ]
"facevarying float [2] uv2" [ ... ]
"facevarying float [2] uv3" [ ... ]
"facevarying float [2] uv4" [ ... ]
"facevarying float [2] uv5" [ ... ]
Any of the N, st, uv1, .., uv6 attributes are optional, depending on the settings of the export options and presence of texture coordinates in the mesh.
Material/Shader
CityEngine includes a template RSL shader with a lighting model similar to phong. Upon export the shader is renamed and copied into the target folder, which is handy for quick visualisation tests. The following shader implementation is used:
surface DefaultCityEngineShader
(
color diffuseColor = color(1.0, 1.0, 1.0);
color ambientColor = color(0.0, 0.0, 0.0);
color specularColor = color(0.0, 0.0, 0.0);
float shininess = 1.0;
float reflectivity = 0.0;
string diffuseMap = "";
string diffuseMap1 = "";
string specularMap = "";
string opacityMap = "";
string bumpMap = "";
string normalMap = "";
float diffuseMapScale[2] = { 1, 1 };
float diffuseMap1Scale[2] = { 1, 1 };
float specularMapScale[2] = { 1, 1 };
float opacityMapScale[2] = { 1, 1 };
float bumpMapScale[2] = { 1, 1 };
float normalMapScale[2] = { 1, 1 };
float diffuseMapTranslate[2] = { 0, 0 };
float diffuseMap1Translate[2] = { 0, 0 };
float specularMapTranslate[2] = { 0, 0 };
float opacityMapTranslate[2] = { 0, 0 };
float bumpMapTranslate[2] = { 0, 0 };
float normalMapTranslate[2] = { 0, 0 };
float diffuseMapRotate = 0.0;
float diffuseMap1Rotate = 0.0;
float specularMapRotate = 0.0;
float opacityMapRotate = 0.0;
float bumpMapRotate = 0.0;
float normalMapRotate = 0.0;
varying float uv1[2] = { 0, 0 };
varying float uv2[2] = { 0, 0 };
varying float uv3[2] = { 0, 0 };
varying float uv4[2] = { 0, 0 };
varying float uv5[2] = { 0, 0 };
)
{
// helper variables for texture uv transformation
float rotPivot[2] = { 0.5, -0.5 };
point p1 = point(rotPivot[0], 0, rotPivot[1]);
point p2 = point(rotPivot[0], 1, rotPivot[1]);
// light independent color (useful to debug)
float Kg = 0.0;
color globalColor = color(1, 1, 1);
// some magic intensity scalings to make it look good :)
float Ka = 0.3;
float Kd = 0.6;
float Ks = 0.1;
// initialize texture color
color tex = color(1, 1, 1);
// please note:
// this example shader only uses texture layer 0 and 2 and does not apply uv rotation
if (diffuseMap != "")
{
float u = (s - diffuseMapTranslate[0]) * diffuseMapScale[0];
float v = (t - diffuseMapTranslate[1]) * diffuseMapScale[1];
tex *= color texture(diffuseMap, u, v);
}
if (diffuseMap1 != "")
{
float u = (uv2[0] - diffuseMap1Translate[0]) * diffuseMap1Scale[0];
float v = (uv2[1] - diffuseMap1Translate[1]) * diffuseMap1Scale[1];
tex *= color texture(diffuseMap1, u, v);
}
/* compute shading variables */
normal Nf = faceforward(normalize(N), I);
vector V = -normalize(I);
/*
* now add it all together
*/
Oi = Os;
Ci = Os * (Cs * tex * ( Kg * globalColor +
Ka * ambientColor * ambient() +
Kd * diffuseColor * diffuse(Nf) ) +
Ks * specularColor * phong(Nf, V, shininess) );
}