vgpu/coreAdvanced8 symbolsView source ↗

Symbols in this topic

StructuredUniform

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.

Import

TypeScript
1
2
import { StructuredUniform } from "vgpu/core";
import type { StructuredUniformOptions, UniformValues, ScalarUniformType, VectorUniformInput, UniformLayoutInfo, UniformField, WgslUniformType } from "vgpu/core";

Signature

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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

ParamTypeRequiredDefaultNotes
deviceDeviceCore device.
optsStructuredUniformOptions<S>Schema and optional labels/visibility.
opts.schemaS extends Record<string, WgslUniformType>Insertion order is WGSL member order. Empty schema and unsupported type strings are invalid.
opts.labelstringundefinedBuffer label; lazy layout/bind group labels become ${label}.bgl and ${label}.bg.
opts.visibilityBindVisibility["vertex", "fragment"]Used only by lazy bindGroupLayout; ignored until that getter is read.
write.valuesPartial<UniformValues<S>>Field patch. Scalars require number; vectors/matrices require exact-length array or typed array.
wgsl.structNamestring"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

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
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.