Skip to content

Generator CLI

TypeGPU Generator (tgpu-gen) is a command-line interface for the TypeGPU code generator. It provides a way for a highly automated migration process and is a great tool for existing WebGPU projects that want to start taking advantage of type-safe TypeGPU features.

Installation

Using npm:

Terminal window
npm install -g tgpu-gen

Feature overview

  • Generate TypeGPU definitions from WGSL shaders
  • Continuously watch for changes in WGSL files and update the generated definitions
  • Specify input and output using glob patterns
  • Choose the output extension and CommonJS or ES module format

Example

Let’s assume the following directory structure:

  • DirectorycomputeBoids
    • Directoryshaders
      • updateSprites.wgsl
      • sprite.wgsl
    • main.ts

This is a simple project that contains two WGSL shaders (updateSprites.wgsl and sprite.wgsl) and a TypeScript file (main.ts). The example WGSL shaders can be found on the WebGPU Samples repository.

Here are the contents of the shader files:

Click to see the content
struct Particle {
pos : vec2f,
vel : vec2f,
}
struct SimParams {
deltaT : f32,
rule1Distance : f32,
rule2Distance : f32,
rule3Distance : f32,
rule1Scale : f32,
rule2Scale : f32,
rule3Scale : f32,
}
struct Particles {
particles : array<Particle>,
}
@binding(0) @group(0) var<uniform> params : SimParams;
@binding(1) @group(0) var<storage, read> particlesA : Particles;
@binding(2) @group(0) var<storage, read_write> particlesB : Particles;
// https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3u) {
var index = GlobalInvocationID.x;
var vPos = particlesA.particles[index].pos;
var vVel = particlesA.particles[index].vel;
var cMass = vec2(0.0);
var cVel = vec2(0.0);
var colVel = vec2(0.0);
var cMassCount = 0u;
var cVelCount = 0u;
var pos : vec2f;
var vel : vec2f;
for (var i = 0u; i < arrayLength(&particlesA.particles); i++) {
if (i == index) {
continue;
}
pos = particlesA.particles[i].pos.xy;
vel = particlesA.particles[i].vel.xy;
if (distance(pos, vPos) < params.rule1Distance) {
cMass += pos;
cMassCount++;
}
if (distance(pos, vPos) < params.rule2Distance) {
colVel -= pos - vPos;
}
if (distance(pos, vPos) < params.rule3Distance) {
cVel += vel;
cVelCount++;
}
}
if (cMassCount > 0) {
cMass = (cMass / vec2(f32(cMassCount))) - vPos;
}
if (cVelCount > 0) {
cVel /= f32(cVelCount);
}
vVel += (cMass * params.rule1Scale) + (colVel * params.rule2Scale) + (cVel * params.rule3Scale);
// clamp velocity for a more pleasing simulation
vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1);
// kinematic update
vPos = vPos + (vVel * params.deltaT);
// Wrap around boundary
if (vPos.x < -1.0) {
vPos.x = 1.0;
}
if (vPos.x > 1.0) {
vPos.x = -1.0;
}
if (vPos.y < -1.0) {
vPos.y = 1.0;
}
if (vPos.y > 1.0) {
vPos.y = -1.0;
}
// Write back
particlesB.particles[index].pos = vPos;
particlesB.particles[index].vel = vVel;
}

If we wanted to leverage TypeGPU’s type-safe features with these shaders, we could manually create the necessary definitions. However, maintaining these handcrafted definitions in sync with the shaders can be both tedious and prone to errors. Fortunately, we don’t have to do that; we can use the TypeGPU Generator CLI to automatically generate the required TypeScript definitions for us.

Assuming that we are inside the project directory (computeBoids folder), we can run the following command to generate the TypeScript definitions for the shaders:

Terminal window
tgpu-gen "shaders/*.wgsl" -o "definitions/*.ts"

This command will generate the following files:

  • DirectorycomputeBoids
    • Directoryshaders
      • updateSprites.wgsl
      • sprite.wgsl
    • Directory
      definitions
      • updateSprites.ts
      • sprite.ts

The generated TypeScript definitions look like this:

Click to see the content
/* generated via tgpu-gen by TypeGPU */
import tgpu from 'typegpu';
import * as d from 'typegpu/data';
/* structs */
export const Particle = d.struct({
pos: d.vec2f,
vel: d.vec2f,
});
export const SimParams = d.struct({
deltaT: d.f32,
rule1Distance: d.f32,
rule2Distance: d.f32,
rule3Distance: d.f32,
rule1Scale: d.f32,
rule2Scale: d.f32,
rule3Scale: d.f32,
});
export const Particles = (arrayLength: number) => d.struct({
particles: d.arrayOf(Particle, arrayLength),
});
/* bindGroupLayouts */
export const layout0 = tgpu.bindGroupLayout({
params: {
uniform: SimParams,
},
particlesA: {
storage: Particles,
access: 'readonly',
},
particlesB: {
storage: Particles,
access: 'mutable',
},
});

These definitions can now be used in our TypeScript code to interact with the shaders in a type-safe manner. If we wanted to tinker with the shaders, but still have the updated definitions, we could use the --watch flag to keep the definitions up-to-date. For specific usage details, check out the following Usage section.

Usage

This section will cover the most common use cases of the TypeGPU Generator CLI and provide short examples.

Generate TypeGPU definitions for WGSL shader files

To generate TypeGPU definitions from a single WGSL shader file, run:

Terminal window
tgpu-gen path/to/shader.wgsl

This will generate a TypeScript file with the TypeGPU definitions in the same directory as the shader. By default, the generated file will have the same name as the shader, with the .ts extension.

  • Directorypath/to
    • shader.wgsl
    • shader.ts

TypeGPU Generator CLI supports glob patterns for specifying input paths. The following command will generate TypeGPU definitions for all WGSL files inside a given directory:

Terminal window
tgpu-gen "path/to/*.wgsl"

The generated TypeScript files will have the same names as the shaders, with the .ts extension.

  • Directorypath/to
    • shader1.wgsl
    • shader1.ts
    • shader2.wgsl
    • shader2.ts
    • Directoryexample
      • shader3.wgsl

To specify a recursive search, use the ** pattern:

Terminal window
tgpu-gen "path/to/**/*.wgsl"

This will generate TypeGPU definitions for all WGSL files inside the path/to directory and its subdirectories.

  • Directorypath/to
    • shader1.wgsl
    • shader1.ts
    • Directoryexample
      • shader2.wgsl
      • shader2.ts

Specify the output path with the --output option

By default, the generated TypeScript files are placed in the same directory as the input shaders. You can specify a different output path using the --output option:

Terminal window
tgpu-gen "path/to/shader.wgsl" --output "different/path/output.ts"

This will generate the TypeGPU definitions in the different/path directory with the output.ts filename.

  • Directorypath/to
    • shader.wgsl
  • Directory
    different/path
    • output.ts

It also supports glob patterns for specifying the output path:

Terminal window
tgpu-gen "path/to/*.wgsl" --output "output/*.ts"

This will generate the TypeGPU definitions in the output directory with the same names as the shaders, but with the .ts extension.

  • Directorypath/to
    • shader1.wgsl
    • shader2.wgsl
    • Directoryexample
      • shader3.wgsl
  • Directory
    output
    • shader1.ts
    • shader2.ts

You can also use the -o shorthand for the --output option:

Terminal window
tgpu-gen "path/to/shader.wgsl" -o "different/path/output.ts"

Supported extensions and module formats

By default, the generated TypeScript files use the .ts extension and the ES module format. You can specify a different extension by just providing the extension in the output path:

Terminal window
tgpu-gen "path/to/shader.wgsl" -o "different/path/output.js"

This will generate the TypeGPU definitions in the different/path directory with the output.js filename. The supported extensions are:

  • 1

    .js

  • 2

    .cjs

  • 3

    .mjs

  • 4

    .ts

  • 5

    .cts

  • 6

    .mts

  • Using the --keep and --overwrite options

    When generating TypeGPU definitions, if the output file already exists, the script will fail and not overwrite the existing file. You can use the --keep option to skip the generation of the file if it already exists:

    Terminal window
    tgpu-gen "path/to/*.wgsl" --output "output/*.ts" --keep

    This will skip the generation of the TypeGPU definitions for shaders that already have a corresponding TypeScript file in the output directory.

    If you want to overwrite the existing files, you can use the --overwrite option:

    Terminal window
    tgpu-gen "path/to/*.wgsl" --output "output/*.ts" --overwrite

    This will overwrite the existing TypeScript files with the new TypeGPU definitions.

    Watch mode

    TypeGPU Generator CLI supports a watch mode that continuously monitors the input files for changes and updates the generated definitions. To enable the watch mode, use the --watch (or -w) option:

    Terminal window
    tgpu-gen "path/to/*.wgsl" --output "output/*.ts" --watch

    This will generate the TypeGPU definitions for all WGSL files inside the path/to directory and its subdirectories and continuously monitor them for changes. By default, the watch mode will overwrite the existing files when changes are detected after the initial generation. You can also use the --keep and --overwrite options in the watch mode. They will only affect the initial generation.

    Getting help with the Generator CLI

    To get a quick overview of the generator, its arguments and options, run:

    Terminal window
    tgpu-gen --help

    You can also use the -h shorthand for the --help option.