Syntax
Functions in WGSL are declared using the fn keyword. Each function must explicitly specify its parameters and return type if it yields a value.
Function Signature Template
A user-defined function has the following structure:
fn name(parameters) -> return_type { body }
- name is the unique identifier of the function (e.g.,
average). - parameters is a comma-separated list of inputs in the form
identifier : type. - return_type is the explicit type of the value the function returns.
- body is the enclosed block of statements executing the subroutine.
Zero Implicit Coercion (Strict Type Matching)
WGSL enforces strict typing with absolutely no implicit type conversion. When calling a function, the arguments you pass must exactly match the declared types of the parameters.
Strict Type Matching
If a parameter is declared as f32, passing an integer literal like 5 or an i32 variable will result in a compile-time error. You must explicitly cast the value: e.g., 5.0 or f32(my_int).
Implicit Parameter Immutability (Read-Only)
All function parameters in WGSL are implicitly read-only. You cannot re-assign or modify the value of a parameter variable within the function body. If you need a mutable copy, you must explicitly declare a local variable using var and copy the parameter into it.
fn square_and_add(val : f32) -> f32 {
// val = val * val; // COMPILE ERROR: cannot assign to parameter 'val'
var local_val = val;
local_val = local_val * local_val; // OK
return local_val + 1.0;
}
GPU-Specific Type Restrictions
To maintain deterministic execution on GPU hardware, WGSL places strict restrictions on what types can be passed to or returned from user-defined functions:
- No Textures or Samplers as Parameters: Unlike GLSL or HLSL, you cannot pass texture or sampler variables as parameters into user-defined functions. They must instead be accessed as global variables.
- Constructible Return Types Only: A user-defined function can only return constructible types (such as scalars, vectors, matrices, arrays, and structs). Pointers, textures, and samplers are not constructible and cannot be returned.
Declaring Void Functions (No Return Value)
If a function does not return a value, the arrow -> and return type are completely omitted from the signature:
Example: Function returning nothing
Declaring Returning Functions
Functions that return a value specify the type after the parameter list and must terminate all code paths with a matching return statement:
Use the playground to see these functions compile and return values in real-time.
/*
* Copyright ©2026 Michael R. Bernstein. All new modifications licensed under Apache 2.0.
* Upstream lineage ©2023 governed by original BSD 3-Clause. See README.md.
*/
// WGSL Syntax Demonstration
// 1. A function with no parameters and no return value (void function)
fn do_nothing() {
// Body is empty, or performs state modifications
}
// 2. A function with an input parameter and no return value
fn eat_an_i32(my_param : i32) {
// Parameter 'my_param' is read-only inside this scope
}
// 3. A function with no parameters that returns an 'i32' value
fn give_me_a_number() -> i32 {
return 42;
}
// 4. A function with multiple parameters that returns a 'f32' value
// Notice the literal '2.0' - division must match types strictly!
fn average(a : f32, b : f32) -> f32 {
return (a + b) / 2.0;
}