Skip to content

Migrating to 0.12

TypeGPU 0.12 removes several APIs that were deprecated in previous releases. This guide covers the required changes, as well as behavioral changes in companion packages.

The default export is still available, but the named export is now recommended. It improves tree-shaking and keeps all TypeGPU imports consistent.

import tgpu, { d, std } from 'typegpu';
import { tgpu, d, std } from 'typegpu';

The deprecated .value alias has been removed from TypeGPU resources. Use .$ to access their GPU-side value.

This applies to buffers created with createUniform, createReadonly and createMutable, as well as constants, variables, slots, accessors, lazy values, textures, samplers, raw code snippets and bind group layouts.

const time = root.createUniform(d.f32);
const scale = tgpu.const(d.f32, 2);
const main = () => {
'use gpu';
return time.value * scale.value;
return time.$ * scale.$;
};

The deprecated layout.bound object has been removed. Layout entries are accessed directly through layout.$.

const layout = tgpu.bindGroupLayout({
size: { uniform: d.vec2u },
});
const getSize = () => {
'use gpu';
return layout.bound.size.$;
return layout.$.size;
};

Plain strings are no longer treated as raw shader expressions when passed through slots or other resolvable APIs. Use a typed TypeGPU value instead. Strings can still be used for comptime branching when they do not become part of the generated shader.

const colorSlot = tgpu.slot<string>('vec3f(1, 0, 0)');
const colorSlot = tgpu.slot<d.v3f>(d.vec3f(1, 0, 0));
const getColor = tgpu.fn([], d.vec3f)`() {
return colorSlot;
}`.$uses({ colorSlot });
const green = getColor.with(colorSlot, 'vec3f(0, 1, 0)');
const green = getColor.with(colorSlot, d.vec3f(0, 1, 0));

For intentional raw WGSL integration, use tgpu['~unstable'].rawCodeSnippet(...) or tgpu['~unstable'].declare(...) so that the expression’s type and dependencies are explicit.

The deprecated withVertex(...).withFragment(...).createPipeline() and withCompute(...).createPipeline() APIs have been removed. Pass the stages and their configuration directly to createRenderPipeline or createComputePipeline.

const renderPipeline = root
.withVertex(vertex, { position: vertexLayout.attrib })
.withFragment(fragment, { format: 'rgba8unorm' })
.createPipeline();
const renderPipeline = root.createRenderPipeline({
vertex,
fragment,
attribs: { position: vertexLayout.attrib },
targets: { format: 'rgba8unorm' },
});
const computePipeline = root
.withCompute(compute)
.createPipeline();
const computePipeline = root.createComputePipeline({ compute });

The old string-based texture layout descriptors have been removed. Use texture data schemas instead.

const layout = tgpu.bindGroupLayout({
sampled: { texture: 'float', viewDimension: '2d' },
sampled: { texture: d.texture2d(d.f32) },
output: {
storageTexture: 'rgba8unorm',
access: 'writeonly',
viewDimension: '2d',
},
output: { storageTexture: d.textureStorage2d('rgba8unorm', 'write-only') },
frame: { externalTexture: {} },
frame: { externalTexture: d.textureExternal() },
});

For sampled float textures that cannot be used with a filtering sampler, keep the schema as d.texture2d(d.f32) and add sampleType: 'unfilterable-float' to the layout entry.

Writing an image source to a texture now requires the texture to have the 'render' usage. If the source and texture dimensions differ, pass { fit: 'stretch' } to opt into resampling; otherwise, .write() throws instead of resizing implicitly.

const texture = root.createTexture({
size: [256, 256],
format: 'rgba8unorm',
}).$usage('sampled');
}).$usage('sampled', 'render');
texture.write(image);
texture.write(image, { fit: 'stretch' });

If the image already has the same dimensions as the texture, no fit option is needed, but the 'render' usage is still required. Writes from an ArrayBuffer, typed array or DataView are unchanged.

Runtime expressions now reject JavaScript truthiness and comparisons that WGSL cannot represent directly:

  • &&, || and unary ! require boolean operands.
  • <, <=, > and >= require numeric scalar operands.
  • === and !== require numeric or boolean scalar operands.

Convert numeric values explicitly with d.bool, and use the component-wise helpers from std for vectors.

const check = tgpu.fn([d.u32, d.bool, d.vec3f, d.vec3f])((count, enabled, a, b) => {
'use gpu';
const isEmpty = !count;
const isVisible = count && enabled;
const compared = a < b;
const isEmpty = !d.bool(count);
const isVisible = d.bool(count) && enabled;
const compared = std.lt(a, b);
});

The d.bool constructor itself now accepts only booleans and numeric scalars. std.not accepts booleans and boolean vectors; use d.bool(value) before negating a numeric scalar.

Runtime ternaries also reject struct, array, vector or matrix branches that alias existing values, because WGSL’s select returns a copy while JavaScript would keep a reference. Copy the branches explicitly or use an if/else statement.

const position = enabled ? boid.position : boid.velocity;
const position = enabled
? d.vec3f(boid.position)
: d.vec3f(boid.velocity);

The experimental callback-based beginRenderPass and beginRenderBundleEncoder APIs have been replaced by explicit encoder objects.

root['~unstable'].beginRenderPass(
{ colorAttachments: [{ view: context }] },
(pass) => {
scenePipeline.with(pass).draw(sceneVertexCount);
overlayPipeline.with(pass).draw(overlayVertexCount);
},
);
const encoder = root['~unstable'].createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: { view: context },
});
scenePipeline.with(pass).draw(sceneVertexCount);
overlayPipeline.with(pass).draw(overlayVertexCount);
pass.end();
encoder.submit();

For render bundles, replace beginRenderBundleEncoder(descriptor, callback) with createRenderBundleEncoder(descriptor), record commands on the returned encoder, and call .finish() yourself.

root.createUniform(...), root.createReadonly(...), root.createMutable(...) and buffer.as(...) now return the same kind of object, called a buffer binding. As a result, bindings can be passed directly to matching bind group entries.

const size = root.createUniform(d.vec2u, d.vec2u(800, 600));
const layout = tgpu.bindGroupLayout({
size: { uniform: d.vec2u },
});
root.createBindGroup(layout, { size });

The TgpuBufferUniform, TgpuBufferReadonly and TgpuBufferMutable type aliases are deprecated. Replace them with TgpuUniform, TgpuReadonly and TgpuMutable respectively. isBufferShorthand is also deprecated in favor of isBufferBinding.

If you inspect resourceType at runtime, note that a value returned from buffer.as(...) now reports 'uniform', 'readonly' or 'mutable' instead of 'buffer-usage'. Prefer the isUniformBinding, isReadonlyBinding and isMutableBinding type guards.

root['~unstable'].flush() was deprecated and had no effect. Remove the call. Direct pipeline executions submit their work immediately, while the new command encoder API submits work when you call encoder.submit().

The unstable root option for a custom shader generator now accepts a class, so that TypeGPU can create a fresh generator for every resolution.

const root = await tgpu.init({
shaderGenerator: new CustomGenerator(),
});
const root = await tgpu.init({
unstable_shaderGeneratorClass: CustomGenerator,
});

This only affects tgpu.init and tgpu.initFromDevice. The tgpu.resolve option remains unstable_shaderGenerator and still accepts an instance.

When react-native-worklets is installed, @typegpu/react now runs useFrame callbacks on the UI thread. Mark every callback with the 'worklet' directive.

useFrame(({ elapsedSeconds }) => {
'worklet';
time.write(elapsedSeconds);
pipeline.withColorAttachment({ view: ctxRef.current }).draw(3);
});

If you want to keep frame callbacks on the RN thread, opt out for that subtree instead:

<Root disableWorklets>
<App />
</Root>

Refer to the React Native Worklets guide for Babel setup and the rules around transferring TypeGPU resources.

New pseudo-random number generator in @typegpu/noise

Section titled “New pseudo-random number generator in @typegpu/noise”

Along with @typegpu/noise v0.12.0, a more robust and efficient pseudo-random number generator became the default: Xoroshiro64**, introduced by David Blackman and Sebastiano Vigna in “Scrambled Linear Pseudorandom Number Generators”.

This changes the sequence returned by randf for the same seed. If your app depends on the previous implementation’s exact behavior, you can use the following code to keep using the legacy generator:

import {
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
,
import d
d
,
import std
std
} from 'typegpu';
import {
const randf: {
seed: typeof randSeed;
seed2: typeof randSeed2;
seed3: typeof randSeed3;
seed4: typeof randSeed4;
sample: typeof randFloat01;
sampleExclusive: typeof randUniformExclusive;
normal: typeof randNormal;
exponential: typeof randExponential;
cauchy: typeof randCauchy;
bernoulli: typeof randBernoulli;
... 7 more ...;
onUnitSphere: typeof randOnUnitSphere;
}
randf
,
const randomGeneratorSlot: TgpuSlot<StatefulGenerator>
randomGeneratorSlot
,
const randomGeneratorShell: TgpuFnShell<[], d.F32>
randomGeneratorShell
,
type
(alias) interface StatefulGenerator
import StatefulGenerator
StatefulGenerator
,
} from '@typegpu/noise';
/**
* Incorporated from https://www.cg.tuwien.ac.at/research/publications/2023/PETER-2023-PSW/PETER-2023-PSW-.pdf
* "Particle System in WebGPU" by Benedikt Peter
*/
const
const BPETER11: StatefulGenerator

Incorporated from https://www.cg.tuwien.ac.at/research/publications/2023/PETER-2023-PSW/PETER-2023-PSW-.pdf "Particle System in WebGPU" by Benedikt Peter

BPETER11
:
(alias) interface StatefulGenerator
import StatefulGenerator
StatefulGenerator
= (() => {
const
const seed: TgpuVar<"private", d.Vec2f>
seed
=
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
privateVar: <d.Vec2f>(dataType: d.Vec2f, initialValue?: d.v2f | undefined) => TgpuVar<"private", d.Vec2f>

Defines a variable scoped to each entry function (private).

@paramdataType The schema of the held data's type

@paraminitialValue If not provided, the variable will be initialized to the dataType's "zero-value".

privateVar
(
import d
d
.
const vec2f: d.Vec2f
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
);
return {
StatefulGenerator.seed?: ((seed: number) => void) | undefined
seed
:
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
fn: <[d.F32]>(argTypes: [d.F32], returnType?: undefined) => TgpuFnShell<[d.F32], d.Void> (+2 overloads)
fn
([
import d
d
.
const f32: d.F32
export f32

A schema that represents a 32-bit float value. (equivalent to f32 in WGSL)

Can also be called to cast a value to an f32.

@example const value = f32(); // 0

@example const value = f32(1.23); // 1.23

@example const value = f32(true); // 1

f32
])((
value: number
value
) => {
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
=
import d
d
.
function vec2f(x: number, y: number): d.v2f (+3 overloads)
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
(
value: number
value
, 0);
}),
StatefulGenerator.seed2?: ((seed: d.v2f) => void) | undefined
seed2
:
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
fn: <[d.Vec2f]>(argTypes: [d.Vec2f], returnType?: undefined) => TgpuFnShell<[d.Vec2f], d.Void> (+2 overloads)
fn
([
import d
d
.
const vec2f: d.Vec2f
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
])((
value: d.v2f
value
) => {
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
=
import d
d
.
function vec2f(v: AnyNumericVec2Instance): d.v2f (+3 overloads)
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
(
value: d.v2f
value
);
}),
StatefulGenerator.seed3?: ((seed: d.v3f) => void) | undefined
seed3
:
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
fn: <[d.Vec3f]>(argTypes: [d.Vec3f], returnType?: undefined) => TgpuFnShell<[d.Vec3f], d.Void> (+2 overloads)
fn
([
import d
d
.
const vec3f: d.Vec3f
export vec3f

Schema representing vec3f - a vector with 3 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec3f(); // (0.0, 0.0, 0.0) const vector = d.vec3f(1); // (1.0, 1.0, 1.0) const vector = d.vec3f(1, 2, 3.5); // (1.0, 2.0, 3.5)

@example const buffer = root.createBuffer(d.vec3f, d.vec3f(0, 1, 2)); // buffer holding a d.vec3f value, with an initial value of vec3f(0, 1, 2);

vec3f
])((
value: d.v3f
value
) => {
'use gpu';
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
=
value: d.v3f
value
.
xy: d.v2f
xy
+
import d
d
.
function vec2f(xy: number): d.v2f (+3 overloads)
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
(
value: d.v3f
value
.
v3f.z: number
z
);
}),
StatefulGenerator.seed4?: ((seed: d.v4f) => void) | undefined
seed4
:
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
fn: <[d.Vec4f]>(argTypes: [d.Vec4f], returnType?: undefined) => TgpuFnShell<[d.Vec4f], d.Void> (+2 overloads)
fn
([
import d
d
.
const vec4f: d.Vec4f
export vec4f

Schema representing vec4f - a vector with 4 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec4f(); // (0.0, 0.0, 0.0, 0.0) const vector = d.vec4f(1); // (1.0, 1.0, 1.0, 1.0) const vector = d.vec4f(1, 2, 3, 4.5); // (1.0, 2.0, 3.0, 4.5)

@example const buffer = root.createBuffer(d.vec4f, d.vec4f(0, 1, 2, 3)); // buffer holding a d.vec4f value, with an initial value of vec4f(0, 1, 2, 3);

vec4f
])((
value: d.v4f
value
) => {
'use gpu';
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
=
value: d.v4f
value
.
xy: d.v2f
xy
+
value: d.v4f
value
.
zw: d.v2f
zw
;
}),
StatefulGenerator.sample: () => number
sample
:
randomGeneratorShell<() => number>(implementation: () => number): TgpuFn<() => d.F32> (+2 overloads)
randomGeneratorShell
(() => {
'use gpu';
const
const a: number
a
=
import std
std
.
dot<d.v2f>(lhs: d.v2f, rhs: d.v2f): number
export dot
dot
(
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
,
import d
d
.
function vec2f(x: number, y: number): d.v2f (+3 overloads)
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
(23.14077926, 232.61690225));
const
const b: number
b
=
import std
std
.
dot<d.v2f>(lhs: d.v2f, rhs: d.v2f): number
export dot
dot
(
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
,
import d
d
.
function vec2f(x: number, y: number): d.v2f (+3 overloads)
export vec2f

Schema representing vec2f - a vector with 2 elements of type f32. Also a constructor function for this vector value.

@example const vector = d.vec2f(); // (0.0, 0.0) const vector = d.vec2f(1); // (1.0, 1.0) const vector = d.vec2f(0.5, 0.1); // (0.5, 0.1)

@example const buffer = root.createBuffer(d.vec2f, d.vec2f(0, 1)); // buffer holding a d.vec2f value, with an initial value of vec2f(0, 1);

vec2f
(54.47856553, 345.84153136));
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
.
v2f.x: number
x
=
import std
std
.
function fract(value: number): number (+1 overload)
export fract
fract
(
import std
std
.
function cos(value: number): number (+1 overload)
export cos
cos
(
const a: number
a
) * 136.8168);
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
.
v2f.y: number
y
=
import std
std
.
function fract(value: number): number (+1 overload)
export fract
fract
(
import std
std
.
function cos(value: number): number (+1 overload)
export cos
cos
(
const b: number
b
) * 534.7645);
return
const seed: TgpuVar<"private", d.Vec2f>
seed
.
TgpuVar<"private", Vec2f>.$: d.v2f
$
.
v2f.y: number
y
;
}).
TgpuNamable.$name(label: string): TgpuFn<() => d.F32>
$name
('sample'),
};
})();
const
const root: TgpuRoot
root
= await
const tgpu: {
const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant;
fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn;
comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime;
resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve;
resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext;
init: typeof import("node_modules/typegpu/src/core/root/init").init;
initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice;
slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot;
lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy;
... 10 more ...;
'~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");
}

@moduletypegpu

tgpu
.
init: (options?: InitOptions) => Promise<TgpuRoot>

Requests a new GPU device and creates a root around it. If a specific device should be used instead, use

@seeinitFromDevice. *

@example

When given no options, the function will ask the browser for a suitable GPU device.

const root = await tgpu.init();

@example

If there are specific options that should be used when requesting a device, you can pass those in.

const adapterOptions: GPURequestAdapterOptions = ...;
const deviceDescriptor: GPUDeviceDescriptor = ...;
const root = await tgpu.init({ adapter: adapterOptions, device: deviceDescriptor });

init
();
const
const pipeline: TgpuGuardedComputePipeline<[]>
pipeline
=
const root: TgpuRoot
root
.
Withable<WithBinding>.with<StatefulGenerator>(slot: TgpuSlot<StatefulGenerator>, value: Eventual<StatefulGenerator>): WithBinding (+2 overloads)
with
(
const randomGeneratorSlot: TgpuSlot<StatefulGenerator>
randomGeneratorSlot
,
const BPETER11: StatefulGenerator

Incorporated from https://www.cg.tuwien.ac.at/research/publications/2023/PETER-2023-PSW/PETER-2023-PSW-.pdf "Particle System in WebGPU" by Benedikt Peter

BPETER11
)
.
WithBinding.createGuardedComputePipeline<[]>(callback: () => void): TgpuGuardedComputePipeline<[]>

Creates a compute pipeline that executes the given callback in an exact number of threads. This is different from createComputePipeline() in that it does a bounds check on the thread id, where as regular pipelines do not and work in units of workgroups.

@paramcallback A function converted to WGSL and executed on the GPU. It can accept up to 3 parameters (x, y, z) which correspond to the global invocation ID of the executing thread.

@example

If no parameters are provided, the callback will be executed once, in a single thread.

const fooPipeline = root
.createGuardedComputePipeline(() => {
'use gpu';
console.log('Hello, GPU!');
});
fooPipeline.dispatchThreads();
// [GPU] Hello, GPU!

@example

One parameter means n-threads will be executed in parallel.

const fooPipeline = root
.createGuardedComputePipeline((x) => {
'use gpu';
if (x % 16 === 0) {
// Logging every 16th thread
console.log('I am the', x, 'thread');
}
});
// executing 512 threads
fooPipeline.dispatchThreads(512);
// [GPU] I am the 256 thread
// [GPU] I am the 272 thread
// ... (30 hidden logs)
// [GPU] I am the 16 thread
// [GPU] I am the 240 thread

createGuardedComputePipeline
(() => {
'use gpu';
const
const value: number
value
=
const randf: {
seed: typeof randSeed;
seed2: typeof randSeed2;
seed3: typeof randSeed3;
seed4: typeof randSeed4;
sample: typeof randFloat01;
sampleExclusive: typeof randUniformExclusive;
normal: typeof randNormal;
exponential: typeof randExponential;
cauchy: typeof randCauchy;
bernoulli: typeof randBernoulli;
... 7 more ...;
onUnitSphere: typeof randOnUnitSphere;
}
randf
.
sample: () => number

Returns a random f32 value in [0, 1) range.

sample
();
});