Getting Started
Learn how to install BWSL and write your first shader.
Turn the guide into code
Take the key idea from this page into the playground and validate it in a real shader instead of leaving it as theory.
Open PlaygroundWelcome to BWSL (Brawl Shading Language) - a modern shader language and compiler for game rendering. It lets you describe shader code, pipeline stages, shader-visible resources, shader variant space, and cross-platform outputs from one source file.
Most BWSL files follow the same shape:
- Declare a
pipeline. - List vertex
attributesand shaderresources. - Add one or more
passblocks. - Write
vertex,fragment, orcomputestage code. - Optionally declare variants that specialize the pipeline for different materials, vertex layouts, quality levels, or platform choices.
- Compile to SPIR-V, plus optional Metal, HLSL, GLSL, or GLSL ES output.
Why BWSL?
Traditional shader languages like GLSL and HLSL are powerful, but engine-facing shader code often ends up split across source files, reflection metadata, platform variants, and build scripts. BWSL keeps the common pieces close together:
- First-class shader variants for compile-time specialization without duplicating whole shader files
- Enum-backed configuration so variant choices can be named, constrained, and reflected for tools
- Pipeline-first structure for graphics and compute passes
- Source-declared resources so uniforms, buffers, textures, and images are visible to the compiler
- Strong typing across scalars, vectors, matrices, arrays, structs, enums, and pointers
- Compile-time
evalblocks for controlled shader generation and specialization patterns - Cross-platform output through SPIR-V, Metal, HLSL, GLSL, and GLSL ES
- Editor-friendly WASM builds for playgrounds, tools, and autocomplete
Variants are the main reason to use BWSL instead of treating shader sources as plain text templates. A pipeline can declare the legal options once, constrain invalid combinations with rules, then compile only the selected path for each material or platform permutation.
Quick Example
Here's a small lit material. The resources block declares values the host application must provide before drawing:
pipeline BasicLit {
enum LightingMode {
Unlit
Lambert
}
attributes {
position: float3
normal: float3
}
resources {
modelViewProjection: mat4
normalMatrix: mat3
}
variants {
lighting: LightingMode = LightingMode::Lambert;
}
pass "Main" {
use attributes { position, normal }
use resources { modelViewProjection, normalMatrix }
vertex {
output.position = resources.modelViewProjection * float4(attributes.position, 1.0);
output.normal = normalize(resources.normalMatrix * attributes.normal);
}
fragment {
float3 n = normalize(input.normal);
float3 lightDir = normalize(float3(1.0, 1.0, 1.0));
float diffuse = variants.lighting == LightingMode::Unlit
? 1.0
: saturate(dot(n, lightDir));
output.color = float4(float3(diffuse), 1.0);
}
}
}
BWSL always emits SPIR-V. Add output flags such as -metal, -hlsl, -glsl, or -gles when you also need backend source code.
bwslc basic-lit.bwsl -o build/shaders -gles
Compile a specific variant by passing -variant values:
bwslc basic-lit.bwsl -o build/shaders -gles -variant lighting=Unlit
See Shader Variants, Enums, and Eval for the pieces that make this style scale beyond a single example.
Next Steps
Ready to dive in?
Start with Installation if you want to build the compiler locally. Jump to Quick Start if you already have bwslc available and want to compile a shader immediately.
- Installation - Set up BWSL in your project
- Quick Start - Create your first shader
- Integration - Wire BWSL into your build or engine