Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

This section contains some more advanced RenderMan© concepts. One should be familiar with the basics of shader writing before reading this section.

As explained in Integration with Softimage, 3Delight for Softimage automatically translates Softimage shaders to compiled RenderMan© shaders. This means that no shader programming is necessary to use 3Delight for Softimage. However, it is logical to provide Softimage users with the added flexibility of using RenderMan© shaders, if needed. The following sections explain how to connect RenderMan© shaders and how to write shaders that are tightly integrated into Softimage.

Table of Contents
styletriangle
separatorpipe

RenderMan Shaders In The Render Tree

Anchor
RenderMan Shaders in the RenderTree
RenderMan Shaders in the RenderTree

It is possible to import custom RenderMan© shader nodes to be used along the standard Softimage nodes in the Render Tree. The imported RenderMan© shader must contain a "surface" method and be compiled using the shaderdl utility. To load the shader into Softimage you must use the RendermanShaderImport script command, as in:

RendermanShaderImport("full\\path\\to\\sdl")

The new node will appear in the 3Delight category of the Preset Manager of the Render Tree.

It is possible for the shader writer to provide additional information with regards to the UI that will be used to show the different shader parameters (such as parameter ranges, grouping, etc.). Usually, this is done through SPDL files but in this instance it is 3Delight for Softimage who builds the SPDL automatically from the compiled shader. To specify path where SPDL will be created you must use second argument of  RendermanShaderImport:

RendermanShaderImport("full\\path\\to\\sdl", "spdl\\directory")

The mechanism through which the shader writer can define such UI elements is called "shader annotations". An annotation is added using the #pragma preprocessor directive. Its general form is:

Code Block
#pragma annotation <shader_param_name> "annotation[;annotation;...];"
One such shader annotation is very handy and allows for grouping logically related parameters. The grouping syntax is:
Code Block
#pragma annotation "grouping" "<group>/[<subgroup>/...]<parameter name>;"
As an example, the following annotation will create a group labeled `Hair Color' and put the `tipcolor' parameter in it.
Code Block
#pragma annotation "grouping" "hairColor/tipcolor;"
It is possible to define any number of group levels; for instance:
Code Block
#pragma annotation "grouping" "hair/hairColor/tipcolor;"
would create a 'Hair' group, then create a 'Hair Color' group inside the 'Hair' group, and finally insert the 'tipcolor' parameter there. The parameters will appear in the order they are annotated. 

It is possible to specify presets in the shader using annotation. A preset is a collection of parameter settings. Following example specifies a preset with name `Bright' and parameter `i_F' with value `0.5':

 

Code Block
#pragma annotation preset:Bright "i_F=0.5;"

Other accepted annotations are listed in the table below below.

AnnotationDescription
label=<label text>Specifies a label for the parameter. When no label annotation is supplied, the parameter's label is the parameter name itself.
hide=<true/parameter_name>When true, the parameter will not be visible in the user interface. It's also possible to specify a checkbox parameter. If this checkbox parameter is disabled, the current parameter will not be visible in the UI.
insensitive=<parameter_name>Specifies parameter that makes the current parameter insensitive.
disable=<true/false>When true, the parameter will not be generated.
value=<value>Specifies default value of the parameter.
min=<value>
max=<value>
Specifies min and max values for the parameter.
hint=<hint text>Specifies description of the parameter.
type=<type>Specifies the type of parameter to create. The supported types are:

 

The following illustrates how parameter annotations can be constructed:

Code Block
#pragma annotation F "label=Value;"
#pragma annotation C "label=Color;"
#pragma annotation i_F "label=Value;"
#pragma annotation i_C "label=Color;"
#pragma annotation i_F "default=0.5;"
#pragma annotation i_C "default=0.75 0.5 0.0;"
#pragma annotation F "min=-1;max=1;"
#pragma annotation i_F "min=-1;max=1;"

#pragma annotation grouping "Shader's Parameters/F;"
#pragma annotation grouping "Shader's Parameters/C;"
#pragma annotation grouping "Method's Parameters/i_F;"
#pragma annotation grouping "Method's Parameters/i_C;"

#pragma annotation preset:<Default> "none"
#pragma annotation preset:Yellow "i_F=0.75;"
#pragma annotation preset:Yellow "i_C=1 0 0;"
#pragma annotation preset:Yellow "F=0.75;"
#pragma annotation preset:Yellow "C=0 1 0;"
#pragma annotation preset:Black "i_F=0;F=0;"

class coshadertest(
    float F = 0.5;
    color C = 1;)
{    
    public void surface( output color Ci, Oi; float i_F = 1; color i_C = 1;)
    {    
        Ci = F*C + i_F*i_C;
        Oi = 1;
    }
}

Connecting RenderMan Shaders

Info
titleImportant

This sections show how to connect RenderMan© shaders using a special object property. This method will be deprecated so users should use the method described in RenderMan Shaders in the RenderTree.

Connecting a RenderMan© shader is a three step process:

  1. Select the object to which the shader will be applied. Note that it is impossible to connect RenderMan© shaders to clusters since the RenderMan© standard has no support for such elements.
  2. Get a RenderMan© Shaders Property by going to Render -> Property -> 3Delight -> Shaders.
  3. Select the surface, displacement, volume or light shader tab and specify a shader path.

Please note the following important details:

  • A shader property can be inserted anywhere in the scene hierarchy. For example, it is possible to put a RenderMan© shader property in the Scene_Root and that property will be applied to all objects in the scene. This is the main reason of using properties to connect RenderMan© shaders.
  • It is possible to connect a RenderMan© displacement shader, leaving the surface shader empty, and this will effectively use an Softimage material for the surface and a RenderMan© shader for the displacement.

Accessing Softimage Vertex Properties

All Softimage vertex properties (such as vertex colors and UV coordinates) are available to shader writers. Accessing a vertex property is as simple as naming it in the parameters list of the shader.

Info
titleNote

If there is 3Delight attributes attached to geometry, make sure that Export Vertex Properties is 'on'. This parameter is on by default, as explained in 3Delight Attributes.

The following listing shows how to access the Vertex_Color vertex property.

Code Block
surface test(
    varying float Vertex_Color[4] = 0; )
{
    /* Put the color in the surface color */
    Ci = color( Vertex_Color[0], Vertex_Color[1], Vertex_Color[2] );
}

Two noteworthy details about example above:

    • We use an array of 4 scalars to pass colors since those can also contain the alpha. Also note that if you export Tangents they will end up as color properties since those are encoded as a 4-tuple.
    • The varying keyword is needed in front of the parameter since vertex colours vary across the surface.

The following example shows how to access a UVW Softimage property named Texture_Projection.

Code Block
surface test(
    string texturename = "";
    varying float Texture_Projection[3] = 0; )
{
    /* Access a texture using the given UVs */
    Ci = texture( texturename,
        Texture_Projection[0], Texture_Projection[1] );
}

Note that we are using a float[3] instead of a point in the previous example to declare the parameter. This is needed because a point would have been transformed by the transformation matrix applied to the underlying object; passing an array of floats bypasses this "problem".

Accessing Softimage Render Channels

All Softimage render channels are easily accessed by naming them as output varying shader parameters. The names are the same as in the Softimage interface: 'Diffuse' for the diffuse channel, 'Specular' for the specular channel, 'Ambient' for the ambient channel and so on. The following example shows an example shader that sets some of Softimage render channels.

Code Block
surface renderchannels(
    output varying color Specular = 0; 
    output varying color Diffuse = 0;
    output varying float Depth = 0; )
{
    /* This will set the Diffuse/Specular render channels in Softimage */
    Specular = noise( P );
    Diffuse = diffuse( N ); 

    /* Store the depth, in Softimage infinity is set to 0. */
    Depth = depth(P);
    if( Depth > 1e36 )
        Depth = 0;

    /* Put some different color pattern in the color */
    Ci = cellnoise( P * 2 );
    Ci *= Oi;
}

Accessing store-in render channels is similarly easy: the store-in has to be declared as parameter of the shader, with the correct type.

Writing Shaders for Softimage Curves

Anchor
Writing Shaders for Softimage Curves
Writing Shaders for Softimage Curves

As explained in Features Summary3Delight for Softimage can render Softimage curves of any shape and of any degree. Since Softimage does not allow connecting a material to such geometric primitives, the only option for shading is to assign a RenderMan© shader. A few remarks:

    • 3Delight for Softimage exports curves' length with each curve using the softimage_curve_length variable so shader writers can have access to it by declaring it as a parameter of the shader.
    • RenderMan© curves vary in `u' across their width and in `v' across their length.
    • Curves knot vector is normalize between 0 and 1 so `v' varies between 0 and 1.

Next listing gives a simple example of such a renderman shader. Note the presence of the softimage_curve_length variable that is available to shader writers and automatically passed as a primvar to all curve primitives.

Code Block
/* 
  A simple shader that demonstrates how to cut a curve at a specific
  length. This example shows how to:
    -- access curve's length
    -- set the opacity using an anti-aliased step function
*/
surface curve_cutoff(
  float softimage_curve_length = 0; /* This is set by 3Delight for Softimage */ 
  float cutoff = 0; )
{
  /* compute distance from root */
  float current_length = v * softimage_curve_length;

  float f = filterstep( current_length, cutoff ); 

  /* Opacity becomes 0 after the cutoff */
  Oi = f;

  /* Set the color to white and modulate by opacity as usual in
     RenderMan shaders */
  Ci = 1 * Oi;
}

Accessing Reference Geometry

Reference geometry can be output as the usual Pref and Nref RenderMan© primvars by enabling reference geometry output in Geometry. The following example illustrates how to access the reference geometry from inside a shader.

 

Code Block
surface prefaccess(
    varying point Pref = 0;
    varying normal Nref = normal(0, 0, 1); )
{
    Ci = diffuse( Nref ) * noise( Pref );
}

Note that exporting reference geometry will double the size of the object so this feature should be enabled only when strictly necessary.

Writing "Cluster Aware" Shaders

It is possible to access clusters' sort order property from inside a RenderMan© shader as shown in the example below. This is an easy way for a TD to create clusters and write particular code for each one of them.

Info
titleNote

To export the cluster sort order, it is necessary to attach 3Delight attributes to geometry and switch the Export Cluster Sort Order property to 'on'. Refer to 3Delight Attributes.

Code Block
surface test(
    uniform float softimage_cluster_sort_order = 0; )
{
    /* Just put the sort order as a gray scale value */
    Ci = softimage_cluster_sort_order / 255;
}

 

Note that a uniform variable is enough here since the sort order of each cluster doesn't vary across one single polygon.