---
title: StructuredUniform
description: Low-level structured uniform buffer that computes WGSL-compatible offsets from a schema and writes typed values into one stable uniform buffer. Prefer main API (`vgpu`) `set({ params: ... })` unless you need a reusable resource and generated WGSL struct text.
---

# StructuredUniform



## Import

```ts
import { StructuredUniform } from "vgpu/core";
import type { StructuredUniformOptions, UniformValues, ScalarUniformType, VectorUniformInput, UniformLayoutInfo, UniformField, WgslUniformType } from "vgpu/core";
```

## Signature

```ts
import type { BindVisibility, Device } from "vgpu/core";

type ScalarUniformType = "f32" | "u32" | "i32";
type VectorUniformInput = readonly number[] | Float32Array | Uint32Array | Int32Array;
type WgslUniformType =
  | "f32" | "u32" | "i32"
  | "vec2f" | "vec3f" | "vec4f"
  | "vec2u" | "vec3u" | "vec4u"
  | "vec2i" | "vec3i" | "vec4i"
  | "mat3x3f" | "mat4x4f";

type UniformValues<S extends Record<string, WgslUniformType>> = {
  [K in keyof S]: S[K] extends ScalarUniformType ? number : VectorUniformInput;
};

interface UniformField {
  readonly name: string;
  readonly type: WgslUniformType;
  readonly offset: number;
  readonly size: number;
  readonly align: number;
}

interface UniformLayoutInfo {
  readonly fields: readonly UniformField[];
  readonly offsets: Readonly<Record<string, number>>;
  readonly byteSize: number;
}

interface StructuredUniformOptions<S extends Record<string, WgslUniformType>> {
  readonly schema: S;
  readonly label?: string;
  readonly visibility?: BindVisibility;
}

declare class StructuredUniform<S extends Record<string, WgslUniformType>> {
  readonly device: Device;
  readonly schema: S;
  readonly layout: UniformLayoutInfo;
  readonly byteSize: number;
  readonly offsets: Readonly<Record<keyof S, number>>;
  readonly buffer: import("vgpu/core").Buffer;
  constructor(device: Device, opts: StructuredUniformOptions<S>);
  get gpu(): GPUBuffer;
  get bindGroupLayout(): GPUBindGroupLayout;
  get bindGroup(): GPUBindGroup;
  write(values: Partial<UniformValues<S>>): void;
  wgsl(structName?: string): string;
  destroy(): void;
  dispose(): void;
}
```

## Parameters

| Param           | Type                                        | Required | Default                  | Notes                                                                                              |
| --------------- | ------------------------------------------- | -------: | ------------------------ | -------------------------------------------------------------------------------------------------- |
| device          | `Device`                                    |        ✔ | —                        | Core device.                                                                                       |
| opts            | `StructuredUniformOptions<S>`               |        ✔ | —                        | Schema and optional labels/visibility.                                                             |
| opts.schema     | `S extends Record<string, WgslUniformType>` |        ✔ | —                        | Insertion order is WGSL member order. Empty schema and unsupported type strings are invalid.       |
| opts.label      | `string`                                    |        ✖ | `undefined`              | Buffer label; lazy layout/bind group labels become `${label}.bgl` and `${label}.bg`.               |
| opts.visibility | `BindVisibility`                            |        ✖ | `["vertex", "fragment"]` | Used only by lazy `bindGroupLayout`; ignored until that getter is read.                            |
| write.values    | `Partial<UniformValues<S>>`                 |        ✔ | —                        | Field patch. Scalars require `number`; vectors/matrices require exact-length array or typed array. |
| wgsl.structName | `string`                                    |        ✖ | `"Uniforms"`             | Name for generated WGSL struct text.                                                               |

**Returns:** Constructor returns `StructuredUniform`; `bindGroupLayout` and `bindGroup` lazily create native objects; `write()` returns `void`; `wgsl()` returns WGSL struct source; `destroy()` / `dispose()` return `void`.

**Throws:** `VGPU-CORE-INVALID-USAGE` when schema is empty, contains unsupported types, writing an unknown field, writing a scalar with a non-number, writing vector/matrix data with a non-array, wrong exact length, or using the object after destroy.

## Examples

```ts
import { init } from "vgpu/mock";
import { StructuredUniform } from "vgpu/core";

const gpu = await init();
const params = new StructuredUniform(gpu.device, {
  label: "params",
  schema: { time: "f32", tint: "vec3f", viewProjection: "mat4x4f" },
});
params.write({
  time: 1,
  tint: [1, 0.5, 0.25],
  viewProjection: new Float32Array(16),
});
const wgsl = params.wgsl("Params");
void wgsl;
```

```ts
import { init, draw } from "vgpu/mock";
import { StructuredUniform } from "vgpu/core";

const gpu = await init();
const params = new StructuredUniform(gpu.device, { schema: { value: "f32" } });
const drawable = draw(gpu, { shader: `
  struct Params { value: f32 }
  @group(0) @binding(0) var<uniform> params: Params;
  @vertex fn vs_main() -> @builtin(position) vec4f { return vec4f(0, 0, 0, 1); }
  @fragment fn fs_main() -> @location(0) vec4f { return vec4f(params.value); }
` });
params.write({ value: 1 });
drawable.set({ params });
```

## Notes

* `vec3*` fields align to 16 bytes; inspect `offsets` / `layout` instead of assuming tight packing.
* `mat3x3f` stores columns at 16-byte stride and needs exactly 9 values in `write()`.
* `wgsl()` only emits the struct; you still declare the `@group/@binding var<uniform>` line in your shader.
* **See also:** `Uniform`, `SharedUniforms`, `UniformPool`, `Draw.set`.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)