SDSL Shaders for vvvv gamma / Stride
What Is SDSL
SDSL (Stride Shading Language) is Stride's shader language — a superset of HLSL with four key additions:
classes with inheritance, multiple inheritance (mixins), the
system for automatic inter-stage data flow, and
for clean method replacement. Shaders are defined in
files.
Streams System
Streams replace manual VS_INPUT/VS_OUTPUT structs. Declare once, access everywhere:
hlsl
stream float4 MyData : TEXCOORD5; // Declare a custom stream variable
// In vertex shader:
streams.MyData = float4(1, 0, 0, 1); // Write
// In pixel shader:
float4 d = streams.MyData; // Read (auto-interpolated)
Key built-in streams:
- (SV_Position) — clip-space position
- (SV_Target0) — pixel shader output
- (float4) — object-space position
- (TEXCOORD0) — texture coordinates
- — world-space normal
Base Shader Hierarchy
Stride Core (available in both Stride and vvvv)
| Shader | Provides |
|---|
| VSMain/PSMain entry points |
| Texture0-9, Sampler, PointSampler, LinearSampler, TexCoord |
| World, View, Projection, WorldViewProjection matrices |
| Position, PositionWS, DepthVS |
| meshNormal, normalWS, tangentToWorld |
| CSMain entry, Compute() hook, thread groups |
| Interface returning float4 via Compute() |
| Interface returning void via Compute() |
| Time, TimeStep (cbuffer PerFrame) |
vvvv-Only (NOT available in plain Stride)
| Shader | Inherits | Use For |
|---|
| ShaderBase, PositionStream4, NormalStream, Transformation | DrawFX base |
| TextureFX | Pixel-processing texture effects |
| TextureFX | Blending textures |
| ImageEffectShader, Camera, ShaderUtils | Texture effect base |
Important:
already includes Transformation, NormalStream, and PositionStream4. Do NOT re-inherit them.
File Naming → Auto Node Generation
vvvv automatically creates nodes from shaders based on filename suffix:
| Suffix | Node Type | Description |
|---|
| TextureFX | Image processing effects |
| DrawFX | Drawing/rendering shaders |
| ComputeFX | Compute shaders |
| ShaderFX | General shader effects |
Example:
automatically creates a "MyBlur" TextureFX node.
Basic TextureFX Structure
hlsl
shader MyEffect_TextureFX : FilterBase
{
float Intensity = 1.0;
float4 Filter(float4 tex0col)
{
return tex0col * Intensity;
}
};
Note the semicolon after the closing brace — this is required.
Syntax Rules
For critical SDSL syntax rules (
scope, semicolons,
, variable initialization, common mistakes, branch divergence), see
syntax-rules.md.
Keywords
| Keyword | Purpose |
|---|
| Defines a shader class |
| Required when overriding parent methods |
| Access parent implementation |
| Ensures member defined once across compositions |
| Member accessible at every shader stage |
| Static methods callable without inheritance |
| Declare a composition slot for shader mixins |
| Force separate instance of a composed shader |
| Method without body (child must implement) |
Inheritance & Mixins
hlsl
// Single inheritance
shader Child : Parent
{
override float4 Filter(float4 tex0col)
{
return base.Filter(tex0col) * 0.5;
}
};
// Multiple inheritance (mixins)
shader MyShader : FilterBase, ColorUtils, MathUtils
{
float4 Filter(float4 tex0col)
{
float3 linear = ColorUtils.GammaToLinear(tex0col.rgb);
return float4(linear, tex0col.a);
}
};
// Static function calls (no inheritance needed)
float3 result = ColorUtils.LinearToGamma(col.rgb);
Enum Binding — C# Enum in Shaders
hlsl
[EnumType("MyNamespace.BlendMode, MyAssembly")]
int Mode = 0;
csharp
namespace MyNamespace;
public enum BlendMode
{
Normal = 0,
Add = 1,
Multiply = 2,
Screen = 3
}
Requirements:
- The enum DLL must be pre-compiled (not from dynamic csproj)
- Assembly name is the project name
- vvvv must be restarted after enum DLL changes
GPU Best Practices
Protect Against Math Errors
hlsl
float3 safeLog = log2(max(x, 1e-10)); // Avoid log2(0)
float3 safe = x / max(y, 0.0001); // Avoid div by zero
float3 safePow = pow(max(x, 0.0), gamma); // Avoid pow(negative)
Texture Sampling
hlsl
// In TextureFX, tex0col is already sampled from Texture0
float4 Filter(float4 tex0col)
{
// Sample additional textures:
float4 tex1 = Texture1.Sample(Texturex1Sampler, streams.TexCoord);
return lerp(tex0col, tex1, 0.5);
}
ShaderFX / ComputeColor Pattern
Composable shader nodes using
keyword:
hlsl
shader MyTonemap_ShaderFX : ComputeColor, TonemapOperators
{
compose ComputeColor ColorIn;
[EnumType("MyNamespace.TonemapOp, MyAssembly")]
int Operator = 1;
float Exposure = 0.0;
override float4 Compute()
{
float4 color = ColorIn.Compute();
color.rgb *= exp2(Exposure);
color.rgb = ApplyTonemap(color.rgb, Operator);
return color;
}
};
In vvvv patching, connect a ShaderFX node to a TextureFX's
input to chain processing.
Mixin Composition — Virtual Method Dispatch
Base shader with a virtual method, overridden by dynamically composed mixins:
hlsl
// Base shader declares the virtual method
shader ColorProcessorBase
{
float4 ProcessColor(float4 inPixel) { return inPixel; }
};
// Host shader uses composition
shader ColorTransform_TextureFX : TextureFX
{
stage compose ColorProcessorBase Processor;
stage override float4 Shading()
{
float4 col = Texture0.SampleLevel(PointSampler, streams.TexCoord, 0);
return Processor.ProcessColor(col);
}
};
Template / Generic Shaders
hlsl
// Declaration with type parameter
shader ComputeColorWave<float Frequency> : ComputeColor, Texturing
{
override float4 Compute()
{
return float4(sin(streams.TexCoord.x * Frequency), 0, 0, 1);
}
};
// Instantiation via inheritance
shader MyEffect : ComputeColorWave<2.0f> { };
Supported template parameter types:
,
,
,
,
,
,
.
Composition Arrays
Multiple composed shaders of the same type:
hlsl
compose ComputeColor lights[];
override float4 Compute()
{
float4 total = 0;
foreach (var light in lights)
total += light.Compute();
return total;
}
Shared Struct Types Across Shaders
Define once, use in emit/simulate/draw pipeline:
hlsl
shader ParticleTypes
{
struct Particle { float3 Position; float3 Velocity; float Life; };
};
shader Emit_ComputeFX : ComputeShaderBase, ParticleTypes { /* fills buffer */ };
shader Simulate_ComputeFX : ComputeShaderBase, ParticleTypes { /* physics */ };
shader Draw_DrawFX : VS_PS_Base, ParticleTypes { /* renders */ };
For detailed SDSL syntax rules, see syntax-rules.md.