Creating Custom Sler Blocks

Contents

What is a Block?
Creating the Block's XML Definition
Converting SL Code to a Sler Template
Adding Blocks to Sler
Contributing

What is a Block?

A block is a visual component that creates a particular portion of the final shader's SL code.

Each block is defined by a pair of files:

*.xml FILE *.sl FILE
MEANING An XML file that describes the following:
  • Regular SL variables that define the block's inputs and outputs. Inputs and outputs are used for directing data between blocks.
  • Additional internal variables that need to be replaced so that they don't get redefined by other blocks in the same shader in case those blocks use the same names.
A fragment of SL code with some markup. The code does its bit of shading work.
SYNTAX Regular XML; see the table below for details. The same as in a regular SL file, but with the following differences:
  • This file does not include the shader's beginning (for example: surface MyShader(color mycolor = 1){) and ending (the closing curly brace at the end: }).
  • All variables, inputs and outputs must be enclosed in parentheses and preceded by a dollar sign $, as follows: $(variable_name).
  • Regular variables and outputs must be defined according to Shading Language rules, but inputs must not. This is because an input gets the name of the variable from whatever output of another block is connected to it. To handle situations where nothing is connected to the input, you must specify the default value when defining the input in the XML file. This is done with the default parameter of the input tag; see the table below for details.

Creating the Block's XML Definition

In this exercise, convert the predefined plastic shader into a Sler block. The shader code comes from the Pixie distribution:

/*      plastic surface shader
 *
 *      Pixie is:

 *      (c) Copyright 1999-2003 Okan Arikan. All rights reserved.
 */

surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1;
                 color specularcolor = 1;) {
        normal Nf = faceforward (normalize(N),I);
        Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,-normalize(I),roughness);
        Oi = Os;
        Ci *= Oi;
}

The shader's input variables are its parameters. The outputs for any surface shader are Oi and Ci. You can add other outputs if you want—for that, create corresponding tags in the XML definition.

Note that the names Oi and Ci have no special meaning in the XML file. They are as good as any other name and can even be changed—in fact, you will rename these variables in the course of the exercise.

In addition, the shader uses an internal variable Nf. A variable with the same name is likely to occur in other blocks, so you need to make sure it doesn't get redefined along the way as the data flows between blocks. To avoid redefinition, declare it explicitly in the XML definition so that its name is replaced with something that contains the shader name like plastic0_Nf when the resulting shader is generated.

You will also add two input variables inColor and inOpacity, which will be used instead of Cs and Os. The outputs Ci and Oi will be renamed outColor and outOpacity, respectively.

Now that you know the names of your internal variables, you can create an XML file with the block definition. The following is the listing of the plastic.xml file located in Sler's blocks directory.

<block name="plastic" 
       category="shaders, surface" description="Standard plastic shader"
       tested="False">
 <input name="inColor" type="color" default="1" description="Input color" />
 <input name="inOpacity" type="color" default="1" description="Input opacity" />
 <input name="specColor" type="color" default="1" description="Specular color" />
 <input name="Ka" type="float" default="1" description="Ambient power" />
 <input name="Kd" type="float" default="0.5" description="Diffuse power" />
 <input name="Ks" type="float" default="0.5" description="Specular power" />
 <input name="Roughness" type="float" default="0.1" description="Roughness of specular light" />
 <output name="outColor" type="color" description="Output color" />
 <output name="outOpacity" type="color" description="Output opacity" />
 <var name="Nf" />
 <template file="plastic.sl"/>
 <preview function="surface" module="sler.util.preview"
          color="outColor" opacity="outOpacity"/>
</block>

The definition uses the following tags:

TAGS PARAMETERS AND DETAILS
block
Top-level tag
  • name
    Name of the block in Sler
  • category
    Comma-separated list of categories in which this block is included
  • description
    Description of the block
  • tested
    Whether or not this block has been tested and found safe to use
input
Definition of a block input
  • name
    Name of the input
  • type
    The Shading Language type of the variable
  • default
    Default value of the input in case no output value is directed into it
  • description
    Description of the input
output
Definition of a block output
  • name
    Name of the output
  • type
    The Shading Language type of the variable
  • description
    Description of the output
var
Definition of an internal variable in the block
name
Name of the variable; the type of the variable does not need definition, because that is done by the SL code fragment
template
Location of the SL template
file
Path to the block's SL template file; this path is relative to the current XML file
preview
Block preview configuration

This tag contains preview mode settings. You can have multiple preview tags if you want to be able to preview the block in multiple ways. At least one of the tags must have its name parameter set to "default" to define its default preview mode. If two or more preview tags have identical names, the last one overrides the previous ones.

A block may also have no preview mode. This is common for such blocks as PI, sin, cos and so on.

  • name
    Name of the preview mode; this name is used when you select the preview mode in the block properties (not implemented yet)
  • function
    Name of the function that performs all the steps of the preview (generates the RIB code, passes it through the renderer and prepares the image for display in the windowing system)
  • module
    Python module that contains the specified function. The predefined preview mode functions are located in the sler.util.preview module. You can specify a different module as long as Python knows where to find it.

You can also supply custom parameters named them after the arguments that your function expects. For example, if your function's expected argument is strength, add this parameter: strength="1.0" (for a fixed value) or strength="f1" (where "f1" is the name of one of the block's outputs; the output value will be redirected to the function). Custom parameters are passed to the preview function as a dictionary.

The predefined surface function expects the color and opacity parameters. However, you can omit these parameters—then default color and opacity values are used. Another predefined function is displacement, which creates previews for displacement shaders and expects the point and normal parameters. It can optionally process the surface attribute, which specified the name of the surface shader to be used in the displacement preview. If you omit this parameter, plastic is used.

Converting SL Code to a Sler Template

To perform the conversion:

  1. Remove the beginning and ending of the original shader or function. That is, everything up to and including the opening curly brace, and then the closing curly brace. Leave only the shader logic.
  2. Change the names of the variables, inputs and outputs where this makes sense. This is necessary if the variables might get redefined otherwise.
  3. Enclose these names in parentheses preceded by a dollar sign. For example, Nf becomes $(Nf).

The following is the predefined plastic block template used in Sler:

/* Plastic shader begin (taken from Pixie) */

/*      plastic surface shader
 *

 *      Pixie is:

 *      (c) Copyright 1999-2003 Okan Arikan. All rights reserved.
 */

normal $(Nf) = faceforward(normalize(N), I);

color $(outColor) = $(inColor) * ($(Ka) * ambient() +
        $(Kd) * diffuse($(Nf))) + $(specColor) * $(Ks) *
        specular($(Nf), -normalize(I), $(Roughness));
color $(outOpacity) = $(inOpacity);
$(outColor) *= $(outOpacity);
/* Plastic shader end */

Now the template is ready to be used in the shader generator.

Adding Blocks to Sler

To load your custom block into Sler, put both of its files into the blocks directory located in the root directory of your Sler installation.

Currently, Sler can only load valid XML, and will at best fail to start if there is an error in the markup. On the contrary, errors in the SL template do not affect the program's stability, but the resulting code might not be processed by the shader compiler you are using. What you get depends on how the compiler goes about the error.

Contributing

If you have created a useful block that you would like to share, please send it to qewerty@gmail.com, and it might be included in a future Sler distribution.

Copyright © 2007 RIBKit Team.
RenderMan is registered trademark of Pixar.