Getting Started3 min read

Getting Started

Learn how to install BWSL and write your first shader.

Reading Time
3 min
Word Count
383
Sections
3
Try It Live

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 Playground

Welcome 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:

  1. Declare a pipeline.
  2. List vertex attributes and shader resources.
  3. Add one or more pass blocks.
  4. Write vertex, fragment, or compute stage code.
  5. Optionally declare variants that specialize the pipeline for different materials, vertex layouts, quality levels, or platform choices.
  6. 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 eval blocks 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:

bwsl
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.

bash
bwslc basic-lit.bwsl -o build/shaders -gles

Compile a specific variant by passing -variant values:

bash
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.