Skip to content

Resolve

Defining shader schemas and objects in JS/TS has lots of benefits, but having to keep them in sync with the corresponding WGSL code is hard to maintain. The tgpu.resolve API takes in TypeGPU resources (and optionally a WGSL template) and generates a ready-to-use WGSL bundle containing all transitive dependencies of the passed in objects.

The first tgpu.resolve overload takes in an array of items to resolve, and an optional argument with options. Here’s a simple example:

const
const Boid: d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>
Boid
=
import d
d
.
struct<{
size: d.F32;
color: d.Vec4f;
}>(props: {
size: d.F32;
color: d.Vec4f;
}): d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>
export struct

Creates a struct schema that can be used to construct GPU buffers. Ensures proper alignment and padding of properties (as opposed to a d.unstruct schema). The order of members matches the passed in properties object.

@example const CircleStruct = d.struct({ radius: d.f32, pos: d.vec3f });

@paramprops Record with string keys and TgpuData values, each entry describing one struct member.

struct
({
size: d.F32
size
:
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
,
color: d.Vec4f
color
:
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
,
});
const
const UnrelatedStruct: d.WgslStruct<{
id: d.U32;
}>
UnrelatedStruct
=
import d
d
.
struct<{
id: d.U32;
}>(props: {
id: d.U32;
}): d.WgslStruct<{
id: d.U32;
}>
export struct

Creates a struct schema that can be used to construct GPU buffers. Ensures proper alignment and padding of properties (as opposed to a d.unstruct schema). The order of members matches the passed in properties object.

@example const CircleStruct = d.struct({ radius: d.f32, pos: d.vec3f });

@paramprops Record with string keys and TgpuData values, each entry describing one struct member.

struct
({
id: d.U32
id
:
import d
d
.
const u32: d.U32
export u32

A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)

Can also be called to cast a value to an u32 in accordance with WGSL casting rules.

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

@example const value = u32(7); // 7

@example const value = u32(3.14); // 3

@example const value = u32(-1); // 4294967295

@example const value = u32(-3.1); // 0

u32
});
const
const createSmallBoid: TgpuFn<() => d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>
createSmallBoid
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
fn: <[], d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>(argTypes: [], returnType: d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>) => TgpuFnShell<[], d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>> (+1 overload)
fn
([],
const Boid: d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>
Boid
)(() => {
return
const Boid: d.WgslStruct
(props: {
size: number;
color: d.v4f;
}) => {
size: number;
color: d.v4f;
} (+1 overload)
Boid
({
size: number
size
: 1,
color: d.v4f
color
:
import d
d
.
function vec4f(x: number, y: number, z: number, w: number): d.v4f (+9 overloads)
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
(0, 1, 0, 1) });
});
const
const createBigBoid: TgpuFn<() => d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>
createBigBoid
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
fn: <[], d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>(argTypes: [], returnType: d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>) => TgpuFnShell<[], d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>> (+1 overload)
fn
([],
const Boid: d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>
Boid
)(() => {
return
const Boid: d.WgslStruct
(props: {
size: number;
color: d.v4f;
}) => {
size: number;
color: d.v4f;
} (+1 overload)
Boid
({
size: number
size
: 10,
color: d.v4f
color
:
import d
d
.
function vec4f(x: number, y: number, z: number, w: number): d.v4f (+9 overloads)
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
(1, 0, 0, 1) });
});
const
const resolved: string
resolved
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolve: (items: ResolvableObject[], options?: TgpuResolveOptions) => string (+1 overload)

A shorthand for calling tgpu.resolveWithContext(...).code.

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const resolved = tgpu.resolve([Gradient]);
console.log(resolved);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const code = tgpu.resolve({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolve
([
const createSmallBoid: TgpuFn<() => d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>
createSmallBoid
,
const createBigBoid: TgpuFn<() => d.WgslStruct<{
size: d.F32;
color: d.Vec4f;
}>>
createBigBoid
]);

Resolved WGSL shader code is as follows:

struct Boid_1 {
size: f32,
color: vec4f,
}
fn createSmallBoid_0() -> Boid_1 {
return Boid_1(1f, vec4f(0, 1, 0, 1));
}
fn createBigBoid_2() -> Boid_1 {
return Boid_1(10f, vec4f(1, 0, 0, 1));
}

As you may note, the resolved WGSL code contains exactly the set of definitions required for the objects passed in the argument to be valid.

You can also resolve other resources, like consts, buffers, textures, entry point functions or even entire pipelines. Here’s an example with a pipeline:

const
const root: TgpuRoot
root
= await
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
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 dataMutable: TgpuMutable<d.WgslArray<d.U32>>
dataMutable
=
const root: TgpuRoot
root
.
TgpuRoot.createMutable<d.WgslArray<d.U32>>(typeSchema: d.WgslArray<d.U32>, initial?: number[] | undefined): TgpuMutable<d.WgslArray<d.U32>> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader. Can be mutated in-place on the GPU. For a general-purpose buffer, use

TgpuRoot.createBuffer

.

@paramtypeSchema The type of data that this buffer will hold.

@paraminitial The initial value of the buffer. (optional)

createMutable
(
import d
d
.
arrayOf<d.U32>(elementType: d.U32, elementCount: number): d.WgslArray<d.U32> (+1 overload)
export arrayOf

Creates an array schema that can be used to construct gpu buffers. Describes arrays with fixed-size length, storing elements of the same type.

@example

const LENGTH = 3; const array = d.arrayOf(d.u32, LENGTH);

If elementCount is not specified, a partially applied function is returned.

@example const array = d.arrayOf(d.vec3f); // ^? (n: number) => WgslArray<d.Vec3f>

@paramelementType The type of elements in the array.

@paramelementCount The number of elements in the array.

arrayOf
(
import d
d
.
const u32: d.U32
export u32

A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)

Can also be called to cast a value to an u32 in accordance with WGSL casting rules.

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

@example const value = u32(7); // 7

@example const value = u32(3.14); // 3

@example const value = u32(-1); // 4294967295

@example const value = u32(-3.1); // 0

u32
, 8), [1, 2, 3, 4, 5, 6, 7, 8]);
const
const computeMain: TgpuComputeFn<{
gid: d.BuiltinGlobalInvocationId;
}>
computeMain
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
['~unstable'].
computeFn: <{
gid: d.BuiltinGlobalInvocationId;
}>(options: {
in: {
gid: d.BuiltinGlobalInvocationId;
};
workgroupSize: number[];
}) => TgpuComputeFnShell<{
gid: d.BuiltinGlobalInvocationId;
}> (+1 overload)
computeFn
({
workgroupSize: number[]
workgroupSize
: [1],
in: {
gid: d.BuiltinGlobalInvocationId;
}
in
: {
gid: d.BuiltinGlobalInvocationId
gid
:
import d
d
.
const builtin: {
readonly vertexIndex: d.BuiltinVertexIndex;
readonly instanceIndex: d.BuiltinInstanceIndex;
readonly position: d.BuiltinPosition;
readonly clipDistances: d.BuiltinClipDistances;
readonly frontFacing: d.BuiltinFrontFacing;
readonly fragDepth: d.BuiltinFragDepth;
readonly sampleIndex: d.BuiltinSampleIndex;
readonly sampleMask: d.BuiltinSampleMask;
readonly localInvocationId: d.BuiltinLocalInvocationId;
readonly localInvocationIndex: d.BuiltinLocalInvocationIndex;
readonly globalInvocationId: d.BuiltinGlobalInvocationId;
readonly workgroupId: d.BuiltinWorkgroupId;
readonly numWorkgroups: d.BuiltinNumWorkgroups;
readonly subgroupInvocationId: BuiltinSubgroupInvocationId;
readonly subgroupSize: BuiltinSubgroupSize;
}
export builtin
builtin
.
globalInvocationId: d.BuiltinGlobalInvocationId
globalInvocationId
},
})((
input: {
gid: d.v3u;
}
input
) => {
const
const index: number
index
=
input: {
gid: d.v3u;
}
input
.
gid: d.v3u
gid
.
v3u.x: number
x
;
const dataMutable: TgpuMutable<d.WgslArray<d.U32>>
dataMutable
.
TgpuMutable<WgslArray<U32>>.$: number[]
$
[
const index: number
index
] *= 2;
});
const
const multiplyPipeline: TgpuComputePipeline
multiplyPipeline
=
const root: TgpuRoot
root
['~unstable']
.
withCompute<{
gid: d.BuiltinGlobalInvocationId;
}>(entryFn: TgpuComputeFn<{
gid: d.BuiltinGlobalInvocationId;
}>): WithCompute
withCompute
(
const computeMain: TgpuComputeFn<{
gid: d.BuiltinGlobalInvocationId;
}>
computeMain
)
.
WithCompute.createPipeline(): TgpuComputePipeline
createPipeline
();
const
const resolved: string
resolved
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolve: (items: ResolvableObject[], options?: TgpuResolveOptions) => string (+1 overload)

A shorthand for calling tgpu.resolveWithContext(...).code.

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const resolved = tgpu.resolve([Gradient]);
console.log(resolved);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const code = tgpu.resolve({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolve
([
const multiplyPipeline: TgpuComputePipeline
multiplyPipeline
]);

Resolved WGSL shader code is as follows:

@group(0) @binding(0) var<storage, read_write> dataMutable_1: array<u32, 8>;
struct computeMain_Input_2 {
@builtin(global_invocation_id) gid: vec3u,
}
@compute @workgroup_size(1) fn computeMain_0(input: computeMain_Input_2) {
var index = input.gid.x;
dataMutable_1[index] *= 2u;
}

The second tgpu.resolve overload has only one argument — an object with options, that requires two extra props: template and externals. The goal of this overload is to extend the existing WGSL code provided as template, with additional definitions from externals.

Here’s an example:

const
const timeUniform: TgpuUniform<d.U32>
timeUniform
=
const root: TgpuRoot
root
.
TgpuRoot.createUniform<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuUniform<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader. Read-only on the GPU, optimized for small data. For a general-purpose buffer, use

TgpuRoot.createBuffer

.

@paramtypeSchema The type of data that this buffer will hold.

@paraminitial The initial value of the buffer. (optional)

createUniform
(
import d
d
.
const u32: d.U32
export u32

A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)

Can also be called to cast a value to an u32 in accordance with WGSL casting rules.

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

@example const value = u32(7); // 7

@example const value = u32(3.14); // 3

@example const value = u32(-1); // 4294967295

@example const value = u32(-3.1); // 0

u32
);
const
const rangeUniform: TgpuUniform<d.F32>
rangeUniform
=
const root: TgpuRoot
root
.
TgpuRoot.createUniform<d.F32>(typeSchema: d.F32, initial?: number | undefined): TgpuUniform<d.F32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader. Read-only on the GPU, optimized for small data. For a general-purpose buffer, use

TgpuRoot.createBuffer

.

@paramtypeSchema The type of data that this buffer will hold.

@paraminitial The initial value of the buffer. (optional)

createUniform
(
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
);
const
const offsetConst: TgpuConst<d.F32>
offsetConst
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
const: <d.F32>(dataType: d.F32, value: number) => TgpuConst<d.F32>

Creates a module constant with specified value.

const
(
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
, 7);
const
const resolved: string
resolved
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolve: (options: TgpuExtendedResolveOptions) => string (+1 overload)

A shorthand for calling tgpu.resolveWithContext(...).code.

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const resolved = tgpu.resolve([Gradient]);
console.log(resolved);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const code = tgpu.resolve({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolve
({
TgpuExtendedResolveOptions.template?: string | undefined

The code template to use for the resolution. All external names will be replaced with their resolved values.

@default''

template
: /* wgsl */ `
fn calculateEffectStrength() -> f32 {
return sin(buffers.time) * buffers.range + offset;
}`,
TgpuExtendedResolveOptions.externals: Record<string, object | Wgsl>

Map of external names to their resolvable values.

externals
: {
offset: TgpuConst<d.F32>
offset
:
const offsetConst: TgpuConst<d.F32>
offsetConst
,
buffers: {
time: TgpuUniform<d.U32>;
range: TgpuUniform<d.F32>;
}
buffers
: {
time: TgpuUniform<d.U32>
time
:
const timeUniform: TgpuUniform<d.U32>
timeUniform
,
range: TgpuUniform<d.F32>
range
:
const rangeUniform: TgpuUniform<d.F32>
rangeUniform
,
},
},
});

Resolved WGSL shader code is as follows:

const offsetConst_0: f32 = 7f;
@group(0) @binding(0) var<uniform> timeUniform_1: u32;
@group(0) @binding(1) var<uniform> rangeUniform_2: f32;
fn calculateEffectStrength() -> f32 {
return sin(timeUniform_1) * rangeUniform_2 + offsetConst_0;
}

As you may note, in this case tgpu.resolve uses the structure of the externals property to detect that buffers.time, buffers.range and offset need to be replaced, and that their definitions should be included.

Here is another example. Assume, that the bind group index 0 is already taken by some existing code:

const
const LightSource: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
LightSource
=
import d
d
.
struct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>(props: {
ambientColor: d.Vec3f;
intensity: d.F32;
}): d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
export struct

Creates a struct schema that can be used to construct GPU buffers. Ensures proper alignment and padding of properties (as opposed to a d.unstruct schema). The order of members matches the passed in properties object.

@example const CircleStruct = d.struct({ radius: d.f32, pos: d.vec3f });

@paramprops Record with string keys and TgpuData values, each entry describing one struct member.

struct
({
ambientColor: d.Vec3f
ambientColor
:
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
,
intensity: d.F32
intensity
:
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
,
}).
TgpuNamable.$name(label: string): d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
$name
('Source');
// ^ giving the struct an explicit name (optional)
const
const layout: TgpuBindGroupLayout<{
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}>
layout
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
bindGroupLayout: <{
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}>(entries: {
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}) => TgpuBindGroupLayout<{
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}> (+1 overload)
bindGroupLayout
({
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
}
lightSource
: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
uniform
:
const LightSource: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
LightSource
},
sampling: {
sampler: "filtering";
}
sampling
: {
sampler: "filtering"
sampler
: 'filtering' },
bgTexture: {
externalTexture: d.WgslExternalTexture;
}
bgTexture
: {
externalTexture: d.WgslExternalTexture
externalTexture
:
import d
d
.
function textureExternal(): d.WgslExternalTexture
export textureExternal
textureExternal
() },
})
.
TgpuBindGroupLayout<{ lightSource: { uniform: WgslStruct<{ ambientColor: Vec3f; intensity: F32; }>; }; sampling: { sampler: "filtering"; }; bgTexture: { externalTexture: WgslExternalTexture; }; }>.$idx(index?: number): TgpuBindGroupLayout<{
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}>

Associates this bind group layout with an explicit numeric index. When a call to this method is omitted, a unique numeric index is assigned to it automatically.

Used when generating WGSL code: `@group(${index})

$idx
(1);
// ^ forces code-gen to assign `1` as the group index (optional)
const
const rawShader: "\n<existing code>\n\n@fragment\nfn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n var bgColor = textureSampleBaseClampToEdge(layout.$.bgTexture, layout.$.sampling, uv).rgb;\n\n var newSource: LightSource;\n newSource.ambientColor = (bgColor + layout.$.lightSource.ambientColor) * factor;\n newSource.intensity = 0.6;\n\n return vec4f(newSource.ambientColor, newSource.intensity);\n}\n"
rawShader
= /* wgsl */ `
<existing code>
@fragment
fn main(@location(0) uv: vec2f) -> @location(0) vec4f {
var bgColor = textureSampleBaseClampToEdge(layout.$.bgTexture, layout.$.sampling, uv).rgb;
var newSource: LightSource;
newSource.ambientColor = (bgColor + layout.$.lightSource.ambientColor) * factor;
newSource.intensity = 0.6;
return vec4f(newSource.ambientColor, newSource.intensity);
}
`;
const
const resolved: string
resolved
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolve: (options: TgpuExtendedResolveOptions) => string (+1 overload)

A shorthand for calling tgpu.resolveWithContext(...).code.

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const resolved = tgpu.resolve([Gradient]);
console.log(resolved);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const code = tgpu.resolve({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolve
({
TgpuExtendedResolveOptions.template?: string | undefined

The code template to use for the resolution. All external names will be replaced with their resolved values.

@default''

template
:
const rawShader: "\n<existing code>\n\n@fragment\nfn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n var bgColor = textureSampleBaseClampToEdge(layout.$.bgTexture, layout.$.sampling, uv).rgb;\n\n var newSource: LightSource;\n newSource.ambientColor = (bgColor + layout.$.lightSource.ambientColor) * factor;\n newSource.intensity = 0.6;\n\n return vec4f(newSource.ambientColor, newSource.intensity);\n}\n"
rawShader
,
TgpuExtendedResolveOptions.externals: Record<string, object | Wgsl>

Map of external names to their resolvable values.

externals
: {
type LightSource: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>
LightSource
,
factor: d.v3f
factor
:
import d
d
.
function vec3f(x: number, y: number, z: number): d.v3f (+5 overloads)
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
(0.4, 0.6, 1.0),
layout: TgpuBindGroupLayout<{
lightSource: {
uniform: d.WgslStruct<{
ambientColor: d.Vec3f;
intensity: d.F32;
}>;
};
sampling: {
sampler: "filtering";
};
bgTexture: {
externalTexture: d.WgslExternalTexture;
};
}>
layout
,
},
});

Resolved WGSL shader code is as follows:

struct Source_0 {
ambientColor: vec3f,
intensity: f32,
}
@group(1) @binding(2) var bgTexture_1: texture_external;
@group(1) @binding(1) var sampling_2: sampler;
@group(1) @binding(0) var<uniform> lightSource_3: Source_0;
<existing code>
@fragment
fn main(@location(0) uv: vec2f) -> @location(0) vec4f {
var bgColor = textureSampleBaseClampToEdge(bgTexture_1, sampling_2, uv).rgb;
var newSource: Source_0;
newSource.ambientColor = (bgColor + lightSource_3.ambientColor) * vec3f(0.4000000059604645, 0.6000000238418579, 1);
newSource.intensity = 0.6;
return vec4f(newSource.ambientColor, newSource.intensity);
}

When items are being resolved, they are given new unique names based on their name in code and the specified naming scheme (names parameter in options).

The default naming scheme is "random". It uses labels assigned to the objects via .$name("foo") method or, if they aren’t present, the keys in the externals record. In this mode labels are later transformed to match the allowed identifier pattern, as well as include some unique suffix to ensure that no identifiers conflict with each other.

Another allowed value of the parameter is "strict" which names resolved objects in the WGSL code exactly as they are labeled by the user in JS, unless there is a name conflict, in which case a suffix is added. If there is no .$name call, an object is named based on its associated key in externals. This approach makes all the generated identifiers predictable, but demands that all labels are valid identifiers and requires explicit naming (via .$name) of all objects that aren’t immediate values in the externals record.

Sometimes, it may not be clear which bind group layouts were used in a given resolution. This may occur especially when using:

  • Buffer usages/shorthands, which use a hidden, automatically created “catchall” bind group,
  • TypeGPU functions implemented in TGSL, which generate their externals automatically.

For these cases, you can use tgpu.resolveWithContext, which has the same input API as tgpu.resolve, but in addition to the resolved code, it also returns information about the layouts used. tgpu.resolveWithContext returns an object with 3 props:

  • code - the resolved code,
  • usedBindGroupLayouts - a list of used tgpu.bindGroupLayout,
  • catchall - a two-element array containing the bind group constructed for buffer usages and buffer shorthands, preceded by its index.

An example, where the “catchall” bind group is created:

const
const countMutable: TgpuMutable<d.U32>
countMutable
=
const root: TgpuRoot
root
.
TgpuRoot.createMutable<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuMutable<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader. Can be mutated in-place on the GPU. For a general-purpose buffer, use

TgpuRoot.createBuffer

.

@paramtypeSchema The type of data that this buffer will hold.

@paraminitial The initial value of the buffer. (optional)

createMutable
(
import d
d
.
const u32: d.U32
export u32

A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)

Can also be called to cast a value to an u32 in accordance with WGSL casting rules.

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

@example const value = u32(7); // 7

@example const value = u32(3.14); // 3

@example const value = u32(-1); // 4294967295

@example const value = u32(-3.1); // 0

u32
);
const {
const code: string
code
,
const usedBindGroupLayouts: TgpuBindGroupLayout<Record<string, TgpuLayoutEntry | null>>[]
usedBindGroupLayouts
,
const catchall: [number, TgpuBindGroup] | undefined
catchall
} =
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolveWithContext: (options: TgpuExtendedResolveOptions) => ResolutionResult (+1 overload)

Resolves a template with external values. Each external that is used will get resolved to a code string and replaced in the template. Any dependencies of the externals will also be resolved and included in the output.

@paramoptions - The options for the resolution.

@returns

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const { code, usedBindGroupLayouts, catchall } = tgpu.resolveWithContext({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolveWithContext
({
TgpuExtendedResolveOptions.template?: string | undefined

The code template to use for the resolution. All external names will be replaced with their resolved values.

@default''

template
: `
fn exampleFn() {
countMutable += 1;
}
`,
TgpuExtendedResolveOptions.externals: Record<string, object | Wgsl>

Map of external names to their resolvable values.

externals
: {
countMutable: TgpuMutable<d.U32>
countMutable
},
});
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const code: string
code
); // same as tgpu.resolve(...)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const usedBindGroupLayouts: TgpuBindGroupLayout<Record<string, TgpuLayoutEntry | null>>[]
usedBindGroupLayouts
); // an array containing the catchall bind group layout
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const catchall: [number, TgpuBindGroup] | undefined
catchall
?.[0]); // 0 - the group index of the catchall bind group
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const catchall: [number, TgpuBindGroup] | undefined
catchall
?.[1]); // the catchall bind group

An example, where a bind group layout is automatically included via a TGSL function:

const
const myLayout: TgpuBindGroupLayout<{
count: {
uniform: d.U32;
};
}>
myLayout
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
bindGroupLayout: <{
count: {
uniform: d.U32;
};
}>(entries: {
count: {
uniform: d.U32;
};
}) => TgpuBindGroupLayout<{
count: {
uniform: d.U32;
};
}> (+1 overload)
bindGroupLayout
({
count: {
uniform: d.U32;
}
count
: {
uniform: d.U32
uniform
:
import d
d
.
const u32: d.U32
export u32

A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)

Can also be called to cast a value to an u32 in accordance with WGSL casting rules.

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

@example const value = u32(7); // 7

@example const value = u32(3.14); // 3

@example const value = u32(-1); // 4294967295

@example const value = u32(-3.1); // 0

u32
} });
const
const exampleFn: TgpuFn<() => d.Void>
exampleFn
=
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
fn: <[]>(argTypes: [], returnType?: undefined) => TgpuFnShell<[], d.Void> (+1 overload)
fn
([])(() => {
const myLayout: TgpuBindGroupLayout<{
count: {
uniform: d.U32;
};
}>
myLayout
.
TgpuBindGroupLayout<{ count: { uniform: U32; }; }>.$: {
count: number;
}
$
.
count: number
count
+= 1;
});
const {
const code: string
code
,
const usedBindGroupLayouts: TgpuBindGroupLayout<Record<string, TgpuLayoutEntry | null>>[]
usedBindGroupLayouts
,
const catchall: [number, TgpuBindGroup] | undefined
catchall
} =
const tgpu: {
fn: {
<Args extends d.AnyData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, d.Void>;
<Args extends d.AnyData[] | [], Return extends d.AnyData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>;
};
bindGroupLayout: {
<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>;
<Entries extends Record<string, TgpuLegacyLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<MapLegacyTextureToUpToDate<...>>>;
};
... 9 more ...;
'~unstable': {
...;
};
}
tgpu
.
resolveWithContext: (options: TgpuExtendedResolveOptions) => ResolutionResult (+1 overload)

Resolves a template with external values. Each external that is used will get resolved to a code string and replaced in the template. Any dependencies of the externals will also be resolved and included in the output.

@paramoptions - The options for the resolution.

@returns

@example

const Gradient = d.struct({ from: d.vec3f, to: d.vec3f });
const { code, usedBindGroupLayouts, catchall } = tgpu.resolveWithContext({
template: `
fn getGradientAngle(gradient: Gradient) -> f32 {
return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
}
`,
externals: {
Gradient,
},
});
console.log(code);
// struct Gradient_0 {
// from: vec3f,
// to: vec3f,
// }
// fn getGradientAngle(gradient: Gradient_0) -> f32 {
// return atan(gradient.to.y - gradient.from.y, gradient.to.x - gradient.from.x);
// }

resolveWithContext
({
TgpuExtendedResolveOptions.externals: Record<string, object | Wgsl>

Map of external names to their resolvable values.

externals
: {
exampleFn: TgpuFn<() => d.Void>
exampleFn
},
});
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const code: string
code
); // same as tgpu.resolve(...)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const usedBindGroupLayouts: TgpuBindGroupLayout<Record<string, TgpuLayoutEntry | null>>[]
usedBindGroupLayouts
); // [myLayout]
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const catchall: [number, TgpuBindGroup] | undefined
catchall
); // undefined