Skip to main content

Crate wesl_quote

Crate wesl_quote 

Source
Expand description

§Write shaders inline with the quote_module macro

This crate provides the quote_*! macros which let one write WGSL shaders directly in source code. This is experimental work.

Writing shaders inline in Rust code has a few advantages:

  • Like quote, it supports local variable injection. This can be used e.g. to customize a shader module at runtime.
  • The module is parsed at build-time, and syntax errors will be reported at the right location in the macro invocation.
  • WGSL and Rust have a similar syntax. Your Rust syntax highlighter will also highlight injected WGSL code.
use wesl::syntax::*; // this is necessary for the quote_module macro

// this i64 value is computed at runtime and injected into the shader.
let num_iterations = 8i64;

// the following variable has type `TranslationUnit`.
let module = quote_module! {
    @fragment
    fn fs_main(@location(0) in_color: vec4<f32>) -> @location(0) vec4<f32> {
        for (let i = 0; i < #num_iterations; i++) {
            // ...
        }
        return in_color;
    }
};

One can inject variables into the following places by prefixing the name with a # symbol:

An interpolation is either a bare #ident (in expression position) or an explicit marker of the form #marker@ident. The marker selects the syntactic location to inject into:

MarkerInjected typeIndirectly supported injection type with Into
#decl@identGlobalDeclarationDeclaration TypeAlias Struct Function ConstAssert
#mem@identStructMember
#attr@identAttributeBuiltinValue InterpolateAttribute WorkgroupSizeAttribute TypeConstraint CustomAttribute
#expr@ident or bare #identExpressionLiteralExpression ParenthesizedExpression NamedComponentExpression IndexingExpression UnaryExpression BinaryExpression FunctionCallExpression TypeOrIdentifierExpression and transitively: bool i64 (AbstractInt) f64 (AbstractFloat) i32 u32 f32 Ident
#stmt@identStatementCompoundStatement AssignmentStatement IncrementStatement DecrementStatement IfStatement SwitchStatement LoopStatement ForStatement WhileStatement BreakStatement ContinueStatement ReturnStatement DiscardStatement FunctionCallStatement ConstAssertStatement DeclarationStatement
use wesl::syntax::*; // this is necessary for the quote_module macro

let inject_struct = Struct::new(Ident::new("mystruct".to_string()));
let inject_func = Function::new(Ident::new("myfunc".to_string()));
let inject_stmt = Statement::Void;
let inject_expr = 1f32;
let module = quote_module! {
    struct #inject_struct { dummy: u32 } // structs cannot be empty
    fn #inject_func() {}
    fn foo() {
        #stmt@inject_stmt
        let x: f32 = #expr@inject_expr;
    }
};

Macros§

quote_declaration
quote_directive
quote_expression
quote_import
quote_literal
quote_module
quote_statement