Shared code
Code that several shaders use, such as noise functions, lighting helpers or data structures, goes into shared code: a static class or a struct marked with [ShaderCode].
using Ahilevich.ShaderScript;
[ShaderCode]
public static class Waves
{
public const float DefaultFrequency = 4;
public static float Sine(float x, float frequency, float time)
{
return math.sin(x * frequency + time);
}
public static float Sum(float2 position, float time)
{
return Sine(position.x, DefaultFrequency, time) + Sine(position.y, DefaultFrequency * 1.7f, time) * 0.5f;
}
}
// In any shader:
OUT.positionOS.y += Waves.Sum(IN.positionOS.xz, Time.y) * WaveHeight;
Create shared code with Assets > Create > Shader Script > Shared Code for a static class, or Shared Struct for a struct.
How it's used
- Any shader, and any other
[ShaderCode]type, can use shared code, as in C#. - Each shader includes only the shared code it actually uses, so a large library of functions doesn't make shaders bigger.
- When shared code changes, every shader that uses it is updated.
- The shared type must be in the same assembly as the shaders that use it: Shader Script translates source code while an assembly compiles, and can't see the source of other assemblies.
A class or struct that isn't marked with [ShaderCode] can't be used in shader code: calling it is reported as an error that suggests adding the attribute.
What shared code can contain
Shared code is either a static class, for functions and constants, or a struct, for a data type with its own methods. A [ShaderCode] class must be declared static: other classes aren't supported.
| Feature | Static class | Struct |
|---|---|---|
| Static methods | ✓ | ✓ |
| Instance methods | — | ✓ |
const fields |
✓ | ✓ |
| Instance fields | — | ✓, without initial values |
Other static fields, static readonly too |
✗ | ✗ |
| Constructors | ✗ | ✗ |
| Properties and indexers | ✗ | ✗ |
| Operators and events | ✗ | ✗ |
| Generic methods | ✗ | ✗ |
| Nested types | ✗ | ✗ |
✓ supported, ✗ not supported, — not possible in a static class in C#.
Type and member names can't contain underscores.
What shared code can use
Shared code can use everything that doesn't belong to a particular shader: the shader types, math, ShaderApi, ShaderLib, textures passed as parameters, enums and other shared types.
What belongs to a shader isn't available in shared code: its material properties, the built-in variables such as Time, and the input and output structures such as FragmentInput. Pass the values you need as parameters:
[ShaderCode]
public static class Surface
{
public static float3 Detail(Texture2D detailMap, float2 uv, float strength)
{
return detailMap.Sample(uv).rgb * strength;
}
}
// In a shader:
float3 detail = Surface.Detail(DetailMap, uv, DetailStrength);