workbench / live
hologram.bwslstarfield · 1 pipeline · 3 variants
BWSL
variants
IR
GPU
brawl shading language·v0.1

BWSL

For graphics code that has outgrown a single shader file.

Declare the pipeline once. Express permutations as typed variants. Compile to SPIR-V, GLSL, HLSL, or Metal — clean, specialized, no preprocessor sprawl.

variants
typed
compile-time
targets
4
spv · glsl · hlsl · msl
runtime
wasm
+ native cli

One pipeline. Specialized at compile time.

Declare the variant space once. Branch on it like normal code. The compiler emits the exact shader paths the GPU will see — sphere, vortex, helix — with the dead code stripped out.

And it scales the way shipping renderers need. A handful of declarations describes a whole shader family — Morphing Shapes turns seven lines of variant syntax into 80 legal shaders, each compiled on demand. Nothing precompiled, nothing wasted.

7 lines80 legal shaders0 dead code
particles.bwsl
Dead code eliminated
65float3 spherePos = float3(
66 sinPhi * cosTheta,
67 cosPhi,
68 sinPhi * sinTheta
69) * baseRadius;
70
71// Add swirl motion
72float swirlAngle = resources.time * 0.5 + t * 6.28318;
73float swirlRadius = 0.1 * sin(resources.time * 2.0 + id * 0.1);
74spherePos.x += cos(swirlAngle) * swirlRadius;
75spherePos.z += sin(swirlAngle) * swirlRadius;
76
77float3 particlePos = spherePos;
78
79if (variants.shape == ParticleShape::Vortex) {
80 float vortexTurn = t * 24.0 + resources.time * 1.2 + id * 0.013;
81 float vortexHeight = (t - 0.5) * 2.6;
82 float vortexRadius = 0.18 + t * 1.05;
83 vortexRadius += 0.12 * sin(resources.time * 2.0 + id * 0.17);
84
85 particlePos = float3(
86 cos(vortexTurn) * vortexRadius,
87 vortexHeight,
88 sin(vortexTurn) * vortexRadius
89 );
90 particlePos.xz += float2(cos(theta), sin(theta)) * 0.08 * sin(resources.time + id * 0.09);
91} else if (variants.shape == ParticleShape::Helix) {
92 float helixTurn = t * 25.13274123 + resources.time * 0.95;
93 float helixAxis = (t - 0.5) * 2.1;
94 float strandPhase = fract(id * 0.5) < 0.5 ? 0.0 : 3.14159265;
95 float helixRadius = 0.32 + 0.05 * sin(t * 12.56637 + resources.time * 1.4);
96
97 particlePos = float3(
98 helixAxis,
99 cos(helixTurn + strandPhase) * helixRadius,
100 sin(helixTurn + strandPhase) * helixRadius
101 );
102 particlePos.y += 0.04 * sin(resources.time * 2.0 + id * 0.05);
103}

Built for the way shader code actually grows.

Six things you stop hand-rolling the moment passes, resources, and variants become first-class language constructs.

Tame Variant Sprawl

Declare axes once, branch normally, and let the compiler generate the exact shader paths.

Pipeline-First Design

Passes, targets, and render state live beside the shader code that uses them.

Type-Safe Bindings

Validate uniforms, structs, and resource layouts at compile time, not runtime.

Cross-Platform Output

Target SPIR-V, GLSL, HLSL, and Metal Shading Language from a single codebase.

Modern Ergonomics

Use modules, imports, and compile-time evaluation without sacrificing GPU-level control.

Rich Standard Library

Drop-in helpers for math, color, noise, PBR, and post-processing.

Five concepts. One language.

Start with variants, then layer in modules, layouts, pipelines, and compile-time eval — each one earns its keep.

Variantsvariants.bwsl
pipeline Particles {
enum ParticleShape {
Sphere
Vortex
Helix
}
variants {
shape: ParticleShape = ParticleShape::Sphere;
}
pass "MainPass" {
vertex {
float3 particlePos = spherePos;
if (variants.shape == ParticleShape::Vortex) {
particlePos = vortexPosition(...);
} else if (variants.shape == ParticleShape::Helix) {
particlePos = helixPosition(...);
}
}
}
}

Built in the open. Licensed for production.

Why BWSL Exists

BWSL started as a fix for one specific pain: managing shader variants. The first plan was modest — Metal with a little extra metadata to keep permutations sane. But solving variants properly meant a real type system, compile-time specialization, and rules the compiler could check. One thing led to another, and it grew into a language of its own.

That origin is why pipelines, resources, and variants are native concepts rather than bolted-on conventions — and why the compiler ships as a fast native CLI for Windows, macOS, and Linux, alongside the WASM build that powers this playground.

Permissive License

Use BWSL anywhere: personal experiments, open-source engines, or commercial AAA titles. The Apache 2.0 license gives you the freedom and legal protection to build with confidence.

The compiler, standard library, and playground are entirely open source and available on GitHub.

License summary
  • Commercial and private use
  • Modification and distribution
  • Express patent grant from contributors
  • License and copyright notice required
  • Changes must be documented

Stop juggling shader strings.
Write the pipeline.

The language guide takes 10 minutes. The playground takes zero install.

compiles toSPV · GLSL · HLSL · MSL