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:
|
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:
|
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 |
|
input Definition of a block input |
|
output Definition of a block 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.
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:
- 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.
- Change the names of the variables, inputs and outputs where this makes sense. This is necessary if the variables might get redefined otherwise.
- 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.