JavaScript Runtime Linking
Runtime linking enables custom shaders adapted to the user’s application environment:
- Tune shaders based on runtime checks of GPU capabilities
- Customize shaders according on web application settings
- Augment shaders with frameworks that dynamically generate shader fragments,
- Extend the linker itself with wesl-js extensions
The link()
API offers options for runtime control of WESL shader transpilation.
#requestWeslDevice for Source Mapped Errors
The wesl library includes requestWeslDevice()
which can be optionally used
in place of WebGPU’s GPUAdapter.requestDevice()
for improved error reporting.
Each WebGPU implementation analyzes WGSL
to find user errors or safety violations.
WESL is transpiled into WGSL,
and so it’s handy to see any errors WGSL in terms of the original WESL.
requestWeslDevice()
returns a WeslDevice,
an extended WebGPU GPUDevice
.
A WESLDevice captures compilation errors from WebGPU and
attaches the WESL source.
A WeslDevice is as a GPUDevice
and can be used everywhere a GPUDevice
is used.
#Conditions
To set a condition for use in @if
conditional translation,
pass a conditions
option to link()
with boolean values for the conditions.
Unset conditions are presumed falsy.
/// main.ts
import appWesl from "../shaders/app.wesl?link";
link({...appWesl, conditions: { MOBILE: true }});
/// app.wesl
@if(MOBILE) var size = 8;
#Runtime Constants
To inject constants from JavaScript/TypeScript for WESL shader compilation,
pass a constants
option to link()
with string or numeric values for the constants.
WESL shaders can use the constants by importing from the constants
virtual module.
/// main.ts
link({..., constants: { NumLights: 7 }});
/// app.wesl
var<private> lights: array<vec3f, constants::NumLights>;
#Virtual Modules
To use a function that generates WESL/WGSL shader code from JavaScript at runtime,
use the virtualLibs
option.
Pass a record with the name of the virtual module as a key,
and the generating function as a value.
/// main.ts
link({..., virtualLibs: { MyCustom: () => "fn custom() {}" }});
/// app.wesl
import MyCustom::custom;
fn example() {
custom();
}
#Custom Extensions
To plug in a custom extension that extends the linker itself with a WeslJsPlugin,
use the config
option.
/// main.ts
link({..., config: { plugins: bindingStructsPlugin() }});
#Further Details
See LinkParams for further details on runtime linking options.