Functions
Function declaration, shader entry points, generics, and scoping in BWSL.
Pressure-test the syntax
Take the concept from this page into the playground and deliberately break a pass, binding, or type signature to see how the compiler responds.
Try a Live EditBWSL functions use the :: declaration form and support overloading, pass-local helpers, module-qualified calls, and stage-returning helper functions.
Function Declaration
Functions are declared with typed parameters and an explicit return type after ->:
add :: (int a, int b) -> int {
return a + b;
}
calculateNormal :: (float3 p0, float3 p1, float3 p2) -> float3 {
float3 edge1 = p1 - p0;
float3 edge2 = p2 - p0;
return normalize(cross(edge1, edge2));
}
The general form is:
functionName :: (Type arg1, Type arg2, ...) -> ReturnType {
// body
}
Function Calls
Call functions with positional arguments:
int result = add(5, 3);
float3 normal = calculateNormal(v0, v1, v2);
The current parser surface uses positional calls only.
Overloading
Multiple functions can share a name as long as their parameter lists differ:
square :: (float x) -> float {
return x * x;
}
square :: (float3 x) -> float3 {
return x * x;
}
Shader Entry Points
BWSL can package shader stages into helper functions that return vertex_function, fragment_function, or compute_function.
Vertex and Fragment Helpers
vertexMain :: () -> vertex_function {
vertex {
output.position = float4(attributes.position, 1.0);
output.uv = attributes.texcoord;
}
}
fragmentMain :: () -> fragment_function {
fragment {
output.color = float4(input.uv, 0.0, 1.0);
}
}
Use them in a pass with stage assignment:
pass "Main" {
use attributes { position, texcoord }
vertex = vertexMain()
fragment = fragmentMain()
}
Compute Helpers
clearPass :: () -> compute_function {
compute "Main" [64, 1, 1] {
uint idx = input.global_id.x;
if (idx >= 1024u) {
return;
}
// resources.output[idx] = 0.0;
}
}
Function Scope
Functions can live at pipeline scope, pass scope, or module scope.
Pipeline Scope
Pipeline-scoped helpers are visible to every pass in the pipeline:
pipeline MyPipeline {
luma :: (float3 color) -> float {
return dot(color, float3(0.299, 0.587, 0.114));
}
pass "Forward" {
fragment {
float v = luma(float3(1.0, 0.8, 0.2));
output.color = float4(v, v, v, 1.0);
}
}
}
Pass Scope
Helpers declared inside a pass stay inside that pass:
pipeline MyPipeline {
pass "SpecialEffect" {
wobble :: (float2 uv, float t) -> float2 {
return uv + sin(uv.y * 10.0 + t) * 0.01;
}
fragment {
float2 distorted = wobble(input.uv, 1.0);
output.color = float4(distorted, 0.0, 1.0);
}
}
}
Module Scope
Functions defined in modules are accessed using the :: namespace operator:
module Math {
square :: (float x) -> float {
return x * x;
}
}
pipeline MyPipeline {
import Math
pass "Main" {
fragment {
float v = Math::square(0.5);
output.color = float4(v, v, v, 1.0);
}
}
}
Constraint-Based Functions
BWSL's active generic system is constraint-based:
constraint FloatVectors = float2 | float3 | float4;
scale :: (FloatVectors v, float s) -> FloatVectors {
return v * s;
}
Constrained functions can dispatch on the resolved concrete type:
componentSum :: (FloatVectors v) -> float {
float2: v.x + v.y
float3: v.x + v.y + v.z
float4: v.x + v.y + v.z + v.w
}
Angle-bracket syntax such as foo<T> and where clauses are not part of the current supported surface. See Generics for the constraint-based form.
Function Summary
| Feature | Syntax |
|---|---|
| Declaration | name :: (params) -> ReturnType { } |
| Positional call | func(a, b, c) |
| Overload | name :: (float x) -> ... and name :: (float3 x) -> ... |
| Vertex helper | name :: () -> vertex_function { vertex { } } |
| Fragment helper | name :: () -> fragment_function { fragment { } } |
| Compute helper | name :: () -> compute_function { compute "Main" [X, Y, Z] { } } |
| Type constraint | constraint Name = Type1 | Type2; |
| Constrained parameter | (ConstraintName param) |
| Module function | moduleName::functionName() |
See Also
- Generics - Type constraints and generic functions
- Modules - Organizing code into reusable modules
- Shader I/O - Input and output in shader stages
- Language Overview - BWSL syntax and concepts