Skip to content

Buffers

Memory on the GPU can be allocated and managed through buffers. That way, WGSL shaders can be provided with an additional context, or retrieve the results of parallel computation back to JS. When creating a buffer, a schema for the contained values has to be provided, which allows for:

  • Calculating the required size of the buffer,
  • Automatic conversion to-and-from a binary representation,
  • Type-safe APIs for writing and reading.

As an example, let’s create a buffer for storing particles.

import
const tgpu: {
bindGroupLayout: <Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries) => TgpuBindGroupLayout<Prettify<Entries>>;
... 4 more ...;
'~unstable': {
...;
};
}
tgpu
from 'typegpu';
import * as
import d
d
from 'typegpu/data';
// Defining a struct type
const
const Particle: d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>
Particle
=
import d
d
.
struct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>(props: {
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}): d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: 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
({
position: d.Vec3f
position
:
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
,
velocity: d.Vec3f
velocity
:
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
,
health: d.F32
health
:
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(true); // 1

f32
,
});
// Utility for creating a random particle
function
function createParticle(): d.Infer<typeof Particle>
createParticle
():
import d
d
.
type Infer<T> = T extends {
readonly '~repr': infer TRepr;
} ? TRepr : T
export Infer

Extracts the inferred representation of a resource.

@example type A = Infer // => number type B = Infer<WgslArray> // => number[]

Infer
<typeof
const Particle: d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>
Particle
> {
return {
position: d.v3f
position
:
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
(
var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.
Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
(), 2,
var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.
Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
()),
velocity: d.v3f
velocity
:
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, 9.8, 0),
health: number
health
: 100,
};
}
const
const root: TgpuRoot
root
= await
const tgpu: {
bindGroupLayout: <Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries) => TgpuBindGroupLayout<Prettify<Entries>>;
... 4 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
();
// Creating and initializing a buffer.
const
const buffer: TgpuBuffer<d.WgslArray<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>> & StorageFlag
buffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslArray<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>>(typeSchema: d.WgslArray<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>, initial?: {
...;
}[] | undefined): TgpuBuffer<...> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
import d
d
.
arrayOf<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>(elementType: d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>, elementCount: number): d.WgslArray<...>
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);

@paramelementType The type of elements in the array.

@paramelementCount The number of elements in the array.

arrayOf
(
const Particle: d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>
Particle
, 100), // <- holds 100 particles
var Array: ArrayConstructor
Array
.
ArrayConstructor.from<unknown>(iterable: Iterable<unknown> | ArrayLike<unknown>): unknown[] (+3 overloads)

Creates an array from an iterable object.

@paramiterable An iterable object to convert to an array.

from
({
ArrayLike<T>.length: number
length
: 100 }).
Array<unknown>.map<{
position: d.v3f;
velocity: d.v3f;
health: number;
}>(callbackfn: (value: unknown, index: number, array: unknown[]) => {
position: d.v3f;
velocity: d.v3f;
health: number;
}, thisArg?: any): {
position: d.v3f;
velocity: d.v3f;
health: number;
}[]

Calls a defined callback function on each element of an array, and returns an array that contains the results.

@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.

@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

map
(
function createParticle(): d.Infer<typeof Particle>
createParticle
), // <- initial value
)
.
TgpuBuffer<WgslArray<WgslStruct<{ position: Vec3f; velocity: Vec3f; health: F32; }>>>.$usage<["storage"]>(usages_0: "storage"): TgpuBuffer<d.WgslArray<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>> & StorageFlag
$usage
('storage'); // <- can be used as a "storage buffer"
// -
// --
// --- Shader omitted for brevity...
// --
// -
// Reading back from the buffer
const value = await
const buffer: TgpuBuffer<d.WgslArray<d.WgslStruct<{
position: d.Vec3f;
velocity: d.Vec3f;
health: d.F32;
}>>> & StorageFlag
buffer
.
TgpuBuffer<WgslArray<WgslStruct<{ position: Vec3f; velocity: Vec3f; health: F32; }>>>.read(): Promise<{
position: d.v3f;
velocity: d.v3f;
health: number;
}[]>
read
();
const value: {
position: d.v3f;
velocity: d.v3f;
health: number;
}[]

This buffer can then be used and/or updated by a WGSL shader.

Creating a buffer

To create a buffer, you will need to define its schema by composing data types imported from typegpu/data. Every WGSL data-type can be represented as JS schemas, including structs and arrays. They will be explored in more detail in a following chapter.

const countBuffer =
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuBuffer<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
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(3.14); // 3

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

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

u32
);
const countBuffer: TgpuBuffer<d.U32>
const listBuffer =
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslArray<d.F32>>(typeSchema: d.WgslArray<d.F32>, initial?: number[] | undefined): TgpuBuffer<d.WgslArray<d.F32>> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
import d
d
.
arrayOf<d.F32>(elementType: d.F32, elementCount: number): d.WgslArray<d.F32>
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);

@paramelementType The type of elements in the array.

@paramelementCount The number of elements in the array.

arrayOf
(
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(true); // 1

f32
, 10));
const listBuffer: TgpuBuffer<d.WgslArray<d.F32>>
const uniformsBuffer =
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslStruct<{
a: d.F32;
b: d.F32;
}>>(typeSchema: d.WgslStruct<{
a: d.F32;
b: d.F32;
}>, initial?: {
a: number;
b: number;
} | undefined): TgpuBuffer<d.WgslStruct<{
a: d.F32;
b: d.F32;
}>> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
import d
d
.
struct<{
a: d.F32;
b: d.F32;
}>(props: {
a: d.F32;
b: d.F32;
}): d.WgslStruct<{
a: d.F32;
b: 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
({
a: d.F32
a
:
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(true); // 1

f32
,
b: d.F32
b
:
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(true); // 1

f32
}));
const uniformsBuffer: TgpuBuffer<d.WgslStruct<{
a: d.F32;
b: d.F32;
}>>

Usage flags

To be able to use these buffers in WGSL shaders, we have to declare their usage upfront with .$usage(...).

const
const buffer: TgpuBuffer<d.U32> & UniformFlag & StorageFlag & VertexFlag
buffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuBuffer<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
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(3.14); // 3

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

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

u32
)
.
TgpuBuffer<U32>.$usage<["uniform"]>(usages_0: "uniform"): TgpuBuffer<d.U32> & UniformFlag
$usage
('uniform')
.
TgpuBuffer<U32>.$usage<("uniform" | "storage" | "vertex")[]>(...usages: ("uniform" | "storage" | "vertex")[]): TgpuBuffer<d.U32> & UniformFlag & StorageFlag & VertexFlag
$usage
(' ')
uniform
storage
vertex

You can also add all flags in a single $usage().

const
const buffer: TgpuBuffer<d.U32> & UniformFlag & StorageFlag & VertexFlag
buffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuBuffer<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
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(3.14); // 3

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

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

u32
)
.
TgpuBuffer<U32>.$usage<("uniform" | "storage" | "vertex")[]>(...usages: ("uniform" | "storage" | "vertex")[]): TgpuBuffer<d.U32> & UniformFlag & StorageFlag & VertexFlag
$usage
('uniform', 'storage', ' ');
uniform
storage
vertex

Additional flags

It is also possible to add any of the GPUBufferUsage flags to a typed buffer object, using the .$addFlags method. Though it shouldn’t be necessary in most scenarios as majority of the flags are handled automatically by the library or indirectly through the .$usage method.

const buffer: TgpuBuffer<d.F32>
buffer
.
TgpuBuffer<F32>.$addFlags(flags: GPUBufferUsageFlags): TgpuBuffer<d.F32>
$addFlags
(
var GPUBufferUsage: {
readonly MAP_READ: GPUFlagsConstant;
readonly MAP_WRITE: GPUFlagsConstant;
readonly COPY_SRC: GPUFlagsConstant;
readonly COPY_DST: GPUFlagsConstant;
readonly INDEX: GPUFlagsConstant;
... 4 more ...;
readonly QUERY_RESOLVE: GPUFlagsConstant;
}
GPUBufferUsage
.
type QUERY_RESOLVE: number
QUERY_RESOLVE
);

Flags can only be added this way if the typed buffer was not created with an existing GPU buffer. If it was, then all flags need to be provided to the existing buffer when constructing it.

Initial value

You can also pass an initial value to the root.createBuffer function. When the buffer is created, it will be mapped at creation, and the initial value will be written to the buffer.

// Will be initialized to `100`
const
const buffer1: TgpuBuffer<d.U32>
buffer1
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.U32>(typeSchema: d.U32, initial?: number | undefined): TgpuBuffer<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
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(3.14); // 3

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

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

u32
, 100);
// Will be initialized to an array of two vec3fs with the specified values.
const
const buffer2: TgpuBuffer<d.WgslArray<d.Vec3f>>
buffer2
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslArray<d.Vec3f>>(typeSchema: d.WgslArray<d.Vec3f>, initial?: d.v3f[] | undefined): TgpuBuffer<d.WgslArray<d.Vec3f>> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
import d
d
.
arrayOf<d.Vec3f>(elementType: d.Vec3f, elementCount: number): d.WgslArray<d.Vec3f>
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);

@paramelementType The type of elements in the array.

@paramelementCount The number of elements in the array.

arrayOf
(
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
, 2), [
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, 1, 2),
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
(3, 4, 5),
]);

Using an existing buffer

You can also create a buffer using an existing WebGPU buffer. This is useful when you have existing logic but want to introduce type-safe data operations.

// A raw WebGPU buffer
const
const existingBuffer: GPUBuffer
existingBuffer
=
const root: TgpuRoot
root
.
TgpuRoot.device: GPUDevice

The GPU device associated with this root.

device
.
GPUDevice.createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer

Creates a

GPUBuffer

.

@paramdescriptor - Description of the GPUBuffer to create.

createBuffer
({
GPUBufferDescriptor.size: number

The size of the buffer in bytes.

size
: 4,
GPUBufferDescriptor.usage: number

The allowed usages for the buffer.

usage
:
var GPUBufferUsage: {
readonly MAP_READ: GPUFlagsConstant;
readonly MAP_WRITE: GPUFlagsConstant;
readonly COPY_SRC: GPUFlagsConstant;
readonly COPY_DST: GPUFlagsConstant;
readonly INDEX: GPUFlagsConstant;
... 4 more ...;
readonly QUERY_RESOLVE: GPUFlagsConstant;
}
GPUBufferUsage
.
type STORAGE: number
STORAGE
|
var GPUBufferUsage: {
readonly MAP_READ: GPUFlagsConstant;
readonly MAP_WRITE: GPUFlagsConstant;
readonly COPY_SRC: GPUFlagsConstant;
readonly COPY_DST: GPUFlagsConstant;
readonly INDEX: GPUFlagsConstant;
... 4 more ...;
readonly QUERY_RESOLVE: GPUFlagsConstant;
}
GPUBufferUsage
.
type COPY_DST: number
COPY_DST
,
});
const
const buffer: TgpuBuffer<d.U32>
buffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.U32>(typeSchema: d.U32, gpuBuffer: GPUBuffer): TgpuBuffer<d.U32> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

@paramgpuBuffer A vanilla WebGPU buffer.

createBuffer
(
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(3.14); // 3

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

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

u32
,
const existingBuffer: GPUBuffer
existingBuffer
);
const buffer: TgpuBuffer<d.U32>
buffer
.
TgpuBuffer<U32>.write(data: number): void
write
(12); // Writing to `existingBuffer` through a type-safe API

Writing to a buffer

To write data to a buffer, you can use the .write(value) method. The typed schema enables auto-complete as well as static validation of this method’s arguments.

const
const Particle: d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>
Particle
=
import d
d
.
struct<{
position: d.Vec2f;
health: d.U32;
}>(props: {
position: d.Vec2f;
health: d.U32;
}): d.WgslStruct<{
position: d.Vec2f;
health: 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
({
position: d.Vec2f
position
:
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
,
health: d.U32
health
:
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(3.14); // 3

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

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

u32
,
});
const
const particleBuffer: TgpuBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>
particleBuffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>(typeSchema: d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>, initial?: {
position: d.v2f;
health: number;
} | undefined): TgpuBuffer<...> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
const Particle: d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>
Particle
);
const particleBuffer: TgpuBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>
particleBuffer
.
TgpuBuffer<WgslStruct<{ position: Vec2f; health: U32; }>>.write(data: {
position: d.v2f;
health: number;
}): void
write
({
position: d.v2f
position
:
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
(1.0, 2.0),
heal
heal: any
health
});

Partial writes

When you want to update only a subset of a buffer’s fields, you can use the .writePartial(data) method. This method updates only the fields provided in the data object and leaves the rest unchanged.

The format of the data value depends on your schema type:

  • For d.struct schemas: Provide an object with keys corresponding to the subset of the schema’s fields you wish to update.

  • For d.array schemas: Provide an array of objects. Each object should specify:

    • idx: the index of the element to update.
    • value: the new value for that element.
const
const Planet: d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>
Planet
=
import d
d
.
struct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>(props: {
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}): d.WgslStruct<...>
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
({
radius: d.F32
radius
:
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(true); // 1

f32
,
mass: d.F32
mass
:
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(true); // 1

f32
,
position: d.Vec3f
position
:
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
,
colors: d.WgslArray<d.Vec3f>
colors
:
import d
d
.
arrayOf<d.Vec3f>(elementType: d.Vec3f, elementCount: number): d.WgslArray<d.Vec3f>
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);

@paramelementType The type of elements in the array.

@paramelementCount The number of elements in the array.

arrayOf
(
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
, 5),
});
const
const planetBuffer: TgpuBuffer<d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>>
planetBuffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>>(typeSchema: d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>, initial?: {
...;
} | undefined): TgpuBuffer<...> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
const Planet: d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>
Planet
);
const planetBuffer: TgpuBuffer<d.WgslStruct<{
radius: d.F32;
mass: d.F32;
position: d.Vec3f;
colors: d.WgslArray<d.Vec3f>;
}>>
planetBuffer
.
TgpuBuffer<WgslStruct<{ radius: F32; mass: F32; position: Vec3f; colors: WgslArray<Vec3f>; }>>.writePartial(data: {
radius?: number | undefined;
mass?: number | undefined;
position?: d.v3f | undefined;
colors?: {
idx: number;
value: d.v3f | undefined;
}[];
}): void
writePartial
({
mass?: number | undefined
mass
: 123.1,
colors?: {
idx: number;
value: d.v3f | undefined;
}[]
colors
: [
{
idx: number
idx
: 2,
value: d.v3f | undefined
value
:
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
(1, 0, 0) },
{
idx: number
idx
: 4,
value: d.v3f | undefined
value
:
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, 0, 1) },
],
});

Copying

There’s also an option to copy value from another typed buffer using the .copyFrom(buffer) method, as long as both buffers have a matching data schema.

const
const backupParticleBuffer: TgpuBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>
backupParticleBuffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>(typeSchema: d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>, initial?: {
position: d.v2f;
health: number;
} | undefined): TgpuBuffer<...> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
const Particle: d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>
Particle
);
const backupParticleBuffer: TgpuBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>
backupParticleBuffer
.
TgpuBuffer<WgslStruct<{ position: Vec2f; health: U32; }>>.copyFrom(srcBuffer: TgpuBuffer<d.WgslStruct<MemIdentityRecord<{
position: d.Vec2f;
health: d.U32;
}>>>): void
copyFrom
(
const particleBuffer: TgpuBuffer<d.WgslStruct<{
position: d.Vec2f;
health: d.U32;
}>>
particleBuffer
);

Reading from a buffer

To read data from a buffer, you can use the .read() method. It returns a promise that resolves to the data read from the buffer.

const
const buffer: TgpuBuffer<d.WgslArray<d.U32>>
buffer
=
const root: TgpuRoot
root
.
TgpuRoot.createBuffer<d.WgslArray<d.U32>>(typeSchema: d.WgslArray<d.U32>, initial?: number[] | undefined): TgpuBuffer<d.WgslArray<d.U32>> (+1 overload)

Allocates memory on the GPU, allows passing data between host and shader.

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

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

createBuffer
(
import d
d
.
arrayOf<d.U32>(elementType: d.U32, elementCount: number): d.WgslArray<d.U32>
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);

@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(3.14); // 3

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

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

u32
, 10));
const data = await
const buffer: TgpuBuffer<d.WgslArray<d.U32>>
buffer
.
TgpuBuffer<WgslArray<U32>>.read(): Promise<number[]>
read
();
const data: number[]