WESL Logo

Authoring Shaders

Learning WGSL

We recommend these resources to learn how to write WGSL shaders:

Learning WESL Extensions

WESL currently provides these functionalities:

Import Statements

Import statements are placed at the top of your file. All they do is add a declaration present in another file to the scope.

import sdf::primitives::box;         // import function `box` in module `primitives` in package `sdf`.
import package::bindings::mySampler; // import declaration `mySampler` from file `bindings.wesl` located at the root of this package.
import super::util;                  // import the entire sibling module `./util.wesl`.
import package::animals::{           // you can nest imports with `{ }`.
    bird,
    mammals::{ dog, cat }
};

Qualified names

In addition to import statements, you can write directly the path to a declaration at the usage site.

import package::math;

fn main() {
    package::my_mod::my_submod::my_fn(); // import statement not required.
    let x = math::constants::PI;         // module `math` was imported, you can access its declarations with a qualified name.
}

Shader entrypoints and co.

We recommend putting shader entrypoints and pipeline overridable constants in the root module. This ensures that they do not get mangled.

@if attribute

The @if(condition) attribute makes the following element optionally included in the final shader, depending on the condition. The condition is made of feature flags which are set when you invoke the linker (wesl-js or wesl-rs).

@if(debug_mode && !raytracing_disabled) // attributes on top-level declarations 
var<private> debug_count_iterations: i32 = 0;

@if(is_2d)
alias point = vec2f;
@if(!is_2d) // the @else block is in discussion, meanwhile just negate the if condition.
alias point = vec3f;

struct Line {
    start_point: point, end_point: point,
    @if(colored) color: vec4f, // attributes on struct members
}

fn fibonacci(n: u32) {
    @if(use_lookup_table) { // attributes on blocks `{ }`
        const lut = array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144);
        return lut[n];
    }
    // ...
}

The condition is a boolean expression containing: feature names, && (and), || (or), ! (not), true and false.

You can place attributes on declarations (functions, structs, variables, etc.), statements, struct members and function parameters.

Next Steps

Visit the Reference page for the complete documentation of WESL Extensions.