Loops
Iteration constructs in BWSL including range-based loops, eval unrolling, and skip.
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 provides a variety of loop constructs designed for shader programming, from familiar C-style loops to GPU-friendly range and unrolled forms.
C-Style For Loop
The traditional for loop works as expected:
for (int i = 0; i < 10; i++) {
doThing(i);
}
Range-Based Loops
Exclusive Range
Use .. for an exclusive end bound:
for (i in 0..10) {
doThing(i);
}
Inclusive Range
Use ..= for an inclusive end bound:
for (i in 0..=9) {
doThing(i);
}
Step Size with by
for (i in 0..100 by 4) {
processVector(i);
}
Multi-Variable Iteration
Use foreach to iterate over multiple ranges simultaneously:
foreach (x in 0..width, y in 0..height) {
processPixel(x, y);
}
This expands to nested iteration over all combinations.
Collection Iteration
Explicit Element Variable
for (vertex in vertices) {
transform(vertex);
}
Implicit Iterator
When you omit the element variable, use the reserved it keyword:
for (lights) {
skip if (it.intensity < EPSILON);
accumLight += calculateLight(it);
}
Simple Loop
When you don't need an index, use loop with a count:
loop (8) {
result = hash(result);
}
Loop Until
For post-condition loops, use loop with until:
loop {
marchRay();
steps++;
} until (steps >= MAX_STEPS);
The loop body executes at least once before the condition is checked.
Compile-Time Unrolling
Eval For
eval for (i in 0..4) {
output[i] = input[i] * 2.0;
}
Eval Loop
eval loop (8) {
result = hash(result);
}
Use eval loops when the iteration count is small and known at compile time. This removes loop overhead and enables further folding.
Inside Eval Blocks
for and loop can also be used inside eval { ... } blocks, where all control flow is compile-time. This allows mixing compile-time variables with loop-generated runtime statements:
eval {
eval int total = 0;
for (i in 0..4) {
total = total + i;
sum += float(i);
}
sum += float(total);
}
See Eval Blocks for full details.
Conditional Loop Control
Skip
BWSL uses skip instead of continue:
for (int i = 0; i < 10; i = i + 1) {
skip if (i % 2 == 0);
sum = sum + float(i);
}
Break If
break if is the matching conditional form for early loop exit:
for (int i = 0; i < 100; i = i + 1) {
sum = sum + float(i);
break if (sum > limit);
}
Loop Summary
| Construct | Description |
|---|---|
for (int i = 0; i < n; i++) | C-style loop with explicit counter |
for (i in 0..n) | Range loop, exclusive end |
for (i in 0..=n) | Range loop, inclusive end |
for (i in 0..n by k) | Range loop with custom step |
foreach (x in a..b, y in c..d) | Multi-variable nested iteration |
for (item in collection) | Collection iteration |
for (collection) | Collection iteration with implicit it |
loop (n) | Simple counted loop |
loop { } until (cond) | Post-condition loop |
skip if (cond) | Skip current iteration |
break if (cond) | Exit the loop early |
eval for / eval loop | Compile-time unrolled loops |
eval { for ... } | Compile-time loops inside eval blocks |
See Also
- Eval — Compile-time evaluation, eval blocks, and code folding
- Language Overview - BWSL syntax and concepts