Complete guide to installing and using WGSL utility functions in your WebGPU projects
wgsl-fns is a JavaScript library that provides WGSL (WebGPU Shading Language) utility functions as string constants. This allows you to easily include pre-written, tested functions in your WebGPU shaders without having to write them from scratch.
Install wgsl-fns using npm, yarn, or pnpm:
npm install wgsl-fnsEach WGSL function is exported as a string constant:
import { elasticWave, smoothStep, noise2D } from 'wgsl-fns'; console.log(elasticWave); // Output: fn elasticWave(x: f32, amplitude: f32, frequency: f32, decay: f32, phase: f32) -> f32 { ... }
Use getFns() to combine multiple functions into a single string:
import { getFns } from 'wgsl-fns'; const shaderCode = getFns(['elasticWave', 'smoothStep', 'noise2D']); console.log(shaderCode); // Output: Combined string with all three functions
Access all functions through the default export object:
import wgslFns from 'wgsl-fns'; console.log(wgslFns.elasticWave); console.log(Object.keys(wgslFns)); // List all available functions
Some functions depend on other functions. The getFns() function automatically includes all required dependencies in the correct order:
import { getFns } from 'wgsl-fns'; // This automatically includes noise2D and hash22 dependencies const shaderCode = getFns(['fbm']); console.log(shaderCode); // Output includes: hash22, noise2D, and fbm functions
Dependencies are resolved automatically, so you don't need to worry about the order or manually including prerequisite functions.
wgsl-fns includes complete TypeScript definitions for better development experience:
import { elasticWave, getFns, WgslFunction } from 'wgsl-fns'; // Type-safe function imports const waveFunction: string = elasticWave; // Type-safe function names for getFns const shaderCode: string = getFns(['elasticWave', 'smoothStep']); // Access to type definitions const functions: WgslFunction[] = [ { name: 'elasticWave', code: elasticWave } ];
Here's a complete example showing how to use wgsl-fns functions in a WebGPU compute shader:
import { getFns } from 'wgsl-fns'; // Get the WGSL functions we need const wgslFunctions = getFns(['noise2D', 'smoothStep', 'elasticWave']); // Create the complete shader code const shaderCode = ` ${wgslFunctions} @group(0) @binding(0) var<storage, read_write> output: array<f32>; @compute @workgroup_size(8, 8) fn main(@builtin(global_invocation_id) global_id: vec3<u32>) { let coords = vec2<f32>(f32(global_id.x), f32(global_id.y)); let time = 0.0; // You'd pass this as a uniform // Use the imported functions let noiseValue = noise2D(coords * 0.01); let wave = elasticWave(coords.x * 0.01, 1.0, 2.0, 0.5, time); let smoothed = smoothStep(0.0, 1.0, noiseValue + wave); let index = global_id.y * 256u + global_id.x; output[index] = smoothed; }`; // Create WebGPU shader module const shaderModule = device.createShaderModule({ code: shaderCode });
import { getFns } from 'wgsl-fns'; const fragmentShaderCode = ` ${getFns(['fbm', 'hsv2rgb', 'rotate2D'])} @group(0) @binding(0) var<uniform> time: f32; @fragment fn main(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f32> { let uv = fragCoord.xy / 512.0; // Assuming 512x512 canvas // Create animated noise let rotatedUV = rotate2D(uv - 0.5, time * 0.5) + 0.5; let noise = fbm(rotatedUV * 4.0 + time * 0.1); // Convert to color let hue = noise * 360.0; let color = hsv2rgb(vec3<f32>(hue, 0.8, 0.9)); return vec4<f32>(color, 1.0); }`;
Combines multiple WGSL functions into a single string with automatic dependency resolution.
Parameters:
functionNames (string[]): Array of function names to includeReturns: string - Combined WGSL code with all functions and dependencies
Each function is exported as a named export containing the WGSL code as a string.
// All functions are available as named exports import { elasticWave, smoothStep, noise2D, fbm, hsv2rgb, rotate2D, // ... and many more } from 'wgsl-fns';
The getFns() function includes built-in error handling for invalid function names:
import { getFns } from 'wgsl-fns'; try { const shaderCode = getFns(['validFunction', 'invalidFunction']); } catch (error) { console.error('Function not found:', error.message); // Output: "Function 'invalidFunction' not found. Available functions: [list]" }