wgsl.runLearn WGSL
English Türkçe

Chapter 04

Control Flow & Functions

WGSL functions look compact, but the compiler is strict about return paths, loop structure, and where control flow can diverge across invocations. Treat each branch as something validation must reason about.

Functions are typed contracts

Parameters and return values are explicit. Helper functions cannot secretly access entry-point builtins; pass the values they need.

helper functionexplicit input and output
fn wave(i : u32, scale : f32) -> f32 {
  return sin(f32(i) * scale);
}

@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id : vec3u) {
  data[id.x] = wave(id.x, 0.0625);
}

Branches can be data-dependent

Ordinary arithmetic can branch per invocation. Operations that need uniform control flow, such as some derivative and subgroup paths, require more care. Studio diagnostics are the fastest way to see which rule was hit.

branchingper invocation
fn classify(x : f32) -> f32 {
  if (x < 0.0) {
    return -1.0;
  }
  return 1.0;
}

Loops should expose their exit

Keep loop bounds easy to read when a pass touches buffers. A good loop says which index moves, which bound stops it, and which buffer location is affected.

bounded loopreadable exit
fn sum4(base : u32) -> f32 {
  var total = 0.0;
  for (var k = 0u; k < 4u; k = k + 1u) {
    total = total + data[base + k];
  }
  return total;
}