Table of Contents

Shaders

Shaders are written in SDSL, an advanced high-level shader language that supports OOP concepts and multiple inheritance. This allows to write short and nice looking shader code.

Here is a step by step guide to get you started:

Prepare an editor

vvvv does not come with a build-in shader editor. See Editing Shaders for different options.

Start from a Template

Use the built-in Sharder Wizard (as of version 5.0)

  • Quad -> New -> Shader File
  • Choose one of the templates
  • Specify a name for the new shader
  • In the Open on Create pulldown you can choose:
    • Solution: This is the best option, assuming you have Visual Studio installed with the Stride Extension as explained in Editing Shaders
    • Open the .sdsl file: If you don't have Visual Studio installed, you can also simply edit the .sdsl files with any text editor
    • Open Folder: In case you don't want to edit the file at this point, you can also just see where it is located by having the explorer opened, pointing to it
  • Press Create
    • This will create the new shader file on disk, reference the VL.Stride package with your current document (if it isn't already) and open the shader

Create the shader node

Open the NodeBrowser and find the shader by the name you gave it.

Now anytime you save a change in your shader file, the node will be updated accordingly.

Further details

Scope

Any .vl document that has VL.Stride set as a dependency will pick up shader files that are placed next to it in special folder called "shaders". Multiple .vl documents can share the same shaders folder.

Note

Shader files share a global scope, two files with the same name are not allowed, even if they are referenced by two different .vl documents.

Special Suffixes

If a shader file ends with one of the pre-defined suffixes, the shader will be converted into a VL node.

_ShaderFX

A node that just represents "a piece of code" that can be used to compose larger shaders. This is the most flexible type of node, it can work together with all other shader node types.

_DrawFX

A node that can be used to draw geometry.

_ComputeFX

A node that represents a compute shader to work with arbitrary data on the GPU.

_TextureFX

Specialized nodes to process textures. See more in the chapter TextureFX.

Core Concepts

Includes and Static Calls

You can use the #include directive just as you would in HLSL. But often you'll not need it because you can call a static function of any shader that is in scope (e.g in the same directory, or both in the /shaders folder next to any .vl document that is loaded). Static functions are functions that don't use any stream variables or class variables, like shader inputs. See also Static Calls in the Stride documentation.

If you have a file MyUtils.sdsl like this:

shader MyUtils
{
    float4 Invert(float4 col)
    {
        col.rgb = 1 - col.rgb;
        return col;
    }
};

You can call its static functions in another file like so:

shader MyFx_TextureFX : FilterBase
{
    float4 Filter(float4 tex0col)
    {
        return MyUtils.Invert(tex0col);
    }
};

Inheritance

The main purpose of inherance is re-using existing shader code. You can think of it like importing or including the code of another shader into your own shader.

For examples, see Inheritance in the Stride documentation.

To understand the shader inheritance hierachy better, you can use the Stride.ShaderExplorer to get an overview and browse the shaders.

Composition

Compostion allows a shader A to use other shader B like a variable and call functions of it. The main feature is, that the other shaders C or D can be used as composition if they inhertit from the shader class B, that is expected as composition variable in shader A. The fact that you can use different implementations (shaders that inherit from B) as the composition, allows for polymorphism known as interfaces in OOP languages.

For examples, see Composition in the Stride documentation.

Streams

SDSL has a convenient way to pass parameters across the different stages of your shader. Simply declare a variable as stream variable and write and read to it in any shader stage. The SDSL compiler will generate the input and output structs for each shader stage.

For examples, see Automatic shader stage input/output in the Stride documentation.