@typegpu/gl
@typegpu/gl lets TypeGPU generate GLSL and provides an experimental WebGL 2 backend for a subset of TypeGPU’s render API.
It is useful when an application needs to run a render effect in browsers without WebGPU, or when TypeGPU shader functions need to be integrated into an existing WebGL renderer.
Refer to TypeGPU’s installation guide for setting up TypeGPU if you haven’t already.
After that, install @typegpu/gl using the package manager of your choice.
npm install @typegpu/glpnpm add @typegpu/glyarn add @typegpu/glYour first fallback
Section titled “Your first fallback”Use initWithGLFallback in place of tgpu.init to try WebGPU first and fall back to WebGL 2 if WebGPU is unavailable or initialization fails.
import { function initWithGLFallback(): Promise<TgpuRoot>
initWithGLFallback } from '@typegpu/gl';
const const root: TgpuRoot
root = await function initWithGLFallback(): Promise<TgpuRoot>
initWithGLFallback();The returned root exposes the common TypeGPU API, so a supported render pipeline does not need separate WebGPU and WebGL implementations. Let’s create a triangle whose color varies with its UV coordinates.
const const positions: TgpuConst<d.WgslArray<d.Vec2f>>
positions = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.const: <d.WgslArray<d.Vec2f>>(dataType: d.WgslArray<d.Vec2f>, value: d.v2f[]) => TgpuConst<d.WgslArray<d.Vec2f>> (+1 overload)
Creates a module constant with specified value.
const(import d
d.arrayOf<d.Vec2f>(elementType: d.Vec2f, elementCount: number): d.WgslArray<d.Vec2f> (+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.
arrayOf(import d
d.const vec2f: d.Vec2fexport vec2f
Schema representing vec2f - a vector with 2 elements of type f32.
Also a constructor function for this vector value.
vec2f, 3), [ 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.
vec2f(0, 0.5), 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.
vec2f(-0.5, -0.5), 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.
vec2f(0.5, -0.5),]);
const const uvs: TgpuConst<d.WgslArray<d.Vec2f>>
uvs = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.const: <d.WgslArray<d.Vec2f>>(dataType: d.WgslArray<d.Vec2f>, value: d.v2f[]) => TgpuConst<d.WgslArray<d.Vec2f>> (+1 overload)
Creates a module constant with specified value.
const(import d
d.arrayOf<d.Vec2f>(elementType: d.Vec2f, elementCount: number): d.WgslArray<d.Vec2f> (+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.
arrayOf(import d
d.const vec2f: d.Vec2fexport vec2f
Schema representing vec2f - a vector with 2 elements of type f32.
Also a constructor function for this vector value.
vec2f, 3), [ 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.
vec2f(0.5, 1), 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.
vec2f(0, 0), 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.
vec2f(1, 0),]);
const const pipeline: TgpuRenderPipeline<d.Vec4f>
pipeline = const root: TgpuRoot
root.WithBinding.createRenderPipeline<Record<string, any>, { [x: string]: any;}, { $position: d.v4f; uv: d.v2f;}, d.v4f>(descriptor: TgpuRenderPipeline<in Targets = never>.DescriptorBase & { attribs?: { [x: string]: any; } | undefined; vertex: TgpuVertexFn<Record<string, any>, TgpuVertexFn<in VertexIn extends TgpuVertexFn.In = Record<string, never>, out VertexOut extends TgpuVertexFn.Out = TgpuVertexFn.Out>.Out> | ((input: AutoVertexIn<InferGPURecord<AttribRecordToDefaultDataTypes<{ [x: string]: any; }>>>) => AutoVertexOut<...>); fragment: TgpuFragmentFn<...> | ((input: AutoFragmentIn<...>) => d.v4f); targets?: TgpuColorTargetState;}): TgpuRenderPipeline<...> (+2 overloads)
createRenderPipeline({ vertex: TgpuVertexFn<Record<string, any>, TgpuVertexFn.Out> | ((input: AutoVertexIn<InferGPURecord<AttribRecordToDefaultDataTypes<{ [x: string]: any;}>>>) => AutoVertexOut<{ $position: d.v4f; uv: d.v2f;}>)
vertex: ({ $vertexIndex: number
$vertexIndex: index: number
index }) => { 'use gpu'; return { $position?: d.v4f | undefined
$position: import d
d.function vec4f(v0: AnyNumericVec2Instance, 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.
vec4f(const positions: TgpuConst<d.WgslArray<d.Vec2f>>
positions.TgpuConst<WgslArray<Vec2f>>.$: readonly d.v2f[]
$[index: number
index], 0, 1), uv: d.v2f
uv: const uvs: TgpuConst<d.WgslArray<d.Vec2f>>
uvs.TgpuConst<WgslArray<Vec2f>>.$: readonly d.v2f[]
$[index: number
index], }; }, fragment: TgpuFragmentFn<{ uv: d.Vec2f;} & Record<string, AnyFragmentInputBuiltin>, TgpuFragmentFn.Out> | ((input: AutoFragmentIn<InferGPURecord<{ uv: d.Vec2f;}>>) => d.v4f)
fragment: ({ uv: d.v2f
uv }) => { 'use gpu'; return import d
d.function vec4f(v0: AnyNumericVec2Instance, 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.
vec4f(uv: d.v2f
uv, 0.5, 1); },});The vertex data is stored in TypeGPU constants rather than vertex buffers because the fallback backend does not currently support buffers.
Next, configure a canvas and draw the three vertices:
const canvas = document.querySelector('canvas') as HTMLCanvasElement;const context = root.configureContext({ canvas, alphaMode: 'premultiplied',});
pipeline.withColorAttachment({ view: context }).draw(3);The fallback renders on an internal OffscreenCanvas, then transfers the result to the configured canvas. This requires support for OffscreenCanvas, WebGL 2, and the bitmaprenderer canvas context.
Dynamic values
Section titled “Dynamic values”Uniforms are the supported way to pass values that change without recompiling the shaders. Create them with root.createUniform, reference them through .$ in GPU code, and update them with .write().
const time = root.createUniform(d.f32);
const pipeline = root.createRenderPipeline({ vertex: ({ $vertexIndex: index }) => { 'use gpu'; return { $position: d.vec4f(positions.$[index], 0, 1), uv: uvs.$[index], }; }, fragment: ({ uv }) => { 'use gpu'; return d.vec4f(uv, 0.5, 1); return d.vec4f((uv + time.$) % 1, 0.5, 1); },});Then write the time before each draw:
function draw(timestamp: number) { time.write(timestamp * 0.001); pipeline.withColorAttachment({ view: context }).draw(3); requestAnimationFrame(draw);}
requestAnimationFrame(draw);Complete example
Section titled “Complete example”import { const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu, import d
d } from 'typegpu';import { function initWithGLFallback(): Promise<TgpuRoot>
initWithGLFallback } from '@typegpu/gl';
const const root: TgpuRoot
root = await function initWithGLFallback(): Promise<TgpuRoot>
initWithGLFallback();const const time: TgpuUniform<d.F32>
time = const root: TgpuRoot
root.TgpuRoot.createUniform<d.F32>(typeSchema: d.F32, initial?: number | ((buffer: TgpuBuffer<NoInfer<d.F32>>) => void) | 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
.
createUniform(import d
d.const f32: d.F32export 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.
f32);
const const positions: TgpuConst<d.WgslArray<d.Vec2f>>
positions = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.const: <d.WgslArray<d.Vec2f>>(dataType: d.WgslArray<d.Vec2f>, value: d.v2f[]) => TgpuConst<d.WgslArray<d.Vec2f>> (+1 overload)
Creates a module constant with specified value.
const(import d
d.arrayOf<d.Vec2f>(elementType: d.Vec2f, elementCount: number): d.WgslArray<d.Vec2f> (+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.
arrayOf(import d
d.const vec2f: d.Vec2fexport vec2f
Schema representing vec2f - a vector with 2 elements of type f32.
Also a constructor function for this vector value.
vec2f, 3), [ 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.
vec2f(0, 0.5), 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.
vec2f(-0.5, -0.5), 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.
vec2f(0.5, -0.5),]);
const const uvs: TgpuConst<d.WgslArray<d.Vec2f>>
uvs = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.const: <d.WgslArray<d.Vec2f>>(dataType: d.WgslArray<d.Vec2f>, value: d.v2f[]) => TgpuConst<d.WgslArray<d.Vec2f>> (+1 overload)
Creates a module constant with specified value.
const(import d
d.arrayOf<d.Vec2f>(elementType: d.Vec2f, elementCount: number): d.WgslArray<d.Vec2f> (+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.
arrayOf(import d
d.const vec2f: d.Vec2fexport vec2f
Schema representing vec2f - a vector with 2 elements of type f32.
Also a constructor function for this vector value.
vec2f, 3), [ 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.
vec2f(0.5, 1), 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.
vec2f(0, 0), 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.
vec2f(1, 0),]);
const const pipeline: TgpuRenderPipeline<d.Vec4f>
pipeline = const root: TgpuRoot
root.WithBinding.createRenderPipeline<Record<string, any>, { [x: string]: any;}, { $position: d.v4f; uv: d.v2f;}, d.v4f>(descriptor: TgpuRenderPipeline<in Targets = never>.DescriptorBase & { attribs?: { [x: string]: any; } | undefined; vertex: TgpuVertexFn<Record<string, any>, TgpuVertexFn<in VertexIn extends TgpuVertexFn.In = Record<string, never>, out VertexOut extends TgpuVertexFn.Out = TgpuVertexFn.Out>.Out> | ((input: AutoVertexIn<InferGPURecord<AttribRecordToDefaultDataTypes<{ [x: string]: any; }>>>) => AutoVertexOut<...>); fragment: TgpuFragmentFn<...> | ((input: AutoFragmentIn<...>) => d.v4f); targets?: TgpuColorTargetState;}): TgpuRenderPipeline<...> (+2 overloads)
createRenderPipeline({ vertex: TgpuVertexFn<Record<string, any>, TgpuVertexFn.Out> | ((input: AutoVertexIn<InferGPURecord<AttribRecordToDefaultDataTypes<{ [x: string]: any;}>>>) => AutoVertexOut<{ $position: d.v4f; uv: d.v2f;}>)
vertex: ({ $vertexIndex: number
$vertexIndex: index: number
index }) => { 'use gpu'; return { $position?: d.v4f | undefined
$position: import d
d.function vec4f(v0: AnyNumericVec2Instance, 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.
vec4f(const positions: TgpuConst<d.WgslArray<d.Vec2f>>
positions.TgpuConst<WgslArray<Vec2f>>.$: readonly d.v2f[]
$[index: number
index], 0, 1), uv: d.v2f
uv: const uvs: TgpuConst<d.WgslArray<d.Vec2f>>
uvs.TgpuConst<WgslArray<Vec2f>>.$: readonly d.v2f[]
$[index: number
index], }; }, fragment: TgpuFragmentFn<{ uv: d.Vec2f;} & Record<string, AnyFragmentInputBuiltin>, TgpuFragmentFn.Out> | ((input: AutoFragmentIn<InferGPURecord<{ uv: d.Vec2f;}>>) => d.v4f)
fragment: ({ uv: d.v2f
uv }) => { 'use gpu'; return import d
d.function vec4f(v0: AnyNumericVec2Instance, 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.
vec4f((uv: d.v2f
uv + const time: TgpuUniform<d.F32>
time.TgpuUniform<F32>.$: number
$) % 1, 0.5, 1); },});
const const canvas: HTMLCanvasElement
canvas = var document: Document
window.document returns a reference to the document contained in the window.
document.ParentNode.querySelector<"canvas">(selectors: "canvas"): HTMLCanvasElement | null (+4 overloads)
Returns the first element that is a descendant of node that matches selectors.
querySelector('canvas') as interface HTMLCanvasElement
The HTMLCanvasElement interface provides properties and methods for manipulating the layout and presentation of elements. The HTMLCanvasElement interface also inherits the properties and methods of the HTMLElement interface.
HTMLCanvasElement;const const context: GPUCanvasContext
context = const root: TgpuRoot
root.TgpuRoot.configureContext(options: ConfigureContextOptions): GPUCanvasContext
Creates and configures context for the provided canvas.
Automatically sets the format to navigator.gpu.getPreferredCanvasFormat() if not provided.
configureContext({ canvas: HTMLCanvasElement | OffscreenCanvas
The canvas for which a context will be created and configured.
canvas, alphaMode?: GPUCanvasAlphaMode | undefined
Determines the effect that alpha values will have on the content of textures returned by
GPUCanvasContext#getCurrentTexture
when read, displayed, or used as an image source.
alphaMode: 'premultiplied',});
let let animationFrame: number
animationFrame = 0;
function function draw(timestamp: number): void
draw(timestamp: number
timestamp: number) { const time: TgpuUniform<d.F32>
time.TgpuBufferBindingBase<F32>.write(data: number, options?: BufferWriteOptions): void
write(timestamp: number
timestamp * 0.001); const pipeline: TgpuRenderPipeline<d.Vec4f>
pipeline.TgpuRenderPipeline<Vec4f>.withColorAttachment(attachment: ColorAttachment): TgpuRenderPipeline<d.Vec4f>
Attaches texture views to the pipeline's targets (outputs).
withColorAttachment({ ColorAttachment.view: GPUCanvasContext | (ColorTextureConstraint & RenderFlag) | GPUTextureView | TgpuTextureView<d.WgslTexture<WgslTextureProps>> | TgpuTextureRenderView
A
GPUTextureView
describing the texture subresource that will be output to for this
color attachment.
view: const context: GPUCanvasContext
context }).TgpuRenderPipeline<Vec4f>.draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void
draw(3); let animationFrame: number
animationFrame = function requestAnimationFrame(callback: FrameRequestCallback): number
requestAnimationFrame(function draw(timestamp: number): void
draw);}
let animationFrame: number
animationFrame = function requestAnimationFrame(callback: FrameRequestCallback): number
requestAnimationFrame(function draw(timestamp: number): void
draw);
function function cleanup(): void
cleanup() { function cancelAnimationFrame(handle: number): void
cancelAnimationFrame(let animationFrame: number
animationFrame); const root: TgpuRoot
root.TgpuRoot.destroy(): void
Destroys all underlying resources (i.e. buffers...) created through this root object.
If the object is created via tgpu.init instead of tgpu.initFromDevice,
then the inner GPU device is destroyed as well.
destroy();}Supported API
Section titled “Supported API”The fallback root is designed for shader-driven effects that can keep their geometry in constants and their changing state in uniforms.
| Feature | WebGL 2 fallback |
|---|---|
| Vertex and fragment functions | Supported |
| TypeGPU constants and helper functions | Supported |
| Uniforms | Supported for scalar, floating-point vector, and floating-point matrix schemas |
| Non-indexed triangle draws | Supported |
| Vertex and index buffers | Not supported |
| Textures and samplers | Not supported |
| Bind groups, readonly buffers, and mutable buffers | Not supported |
| Compute pipelines | Not supported |
| Command and render bundle encoders | Not supported |
Unsupported root operations throw an error explaining that the operation is unavailable in the WebGL fallback. When you need different resource strategies for WebGPU and WebGL, use isGLRoot after initialization.
Generating GLSL
Section titled “Generating GLSL”The GLSL generator can also be used independently of the fallback root. Pass glOptions() to tgpu.resolve to resolve a TypeGPU function as GLSL instead of WGSL.
import { const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu, import d
d } from 'typegpu';import { function glOptions(): { unstable_shaderGenerator: GlslGenerator;}
glOptions } from '@typegpu/gl';
const const getColor: TgpuFn<(uv: d.Vec2f) => d.Vec4f>
getColor = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.fn: <[d.Vec2f], d.Vec4f>(argTypes: [d.Vec2f], returnType: d.Vec4f) => TgpuFnShell<[d.Vec2f], d.Vec4f> (+2 overloads)
fn( [import d
d.const vec2f: d.Vec2fexport vec2f
Schema representing vec2f - a vector with 2 elements of type f32.
Also a constructor function for this vector value.
vec2f], import d
d.const vec4f: d.Vec4fexport vec4f
Schema representing vec4f - a vector with 4 elements of type f32.
Also a constructor function for this vector value.
vec4f,)((uv: d.v2f
uv) => { 'use gpu'; return import d
d.function vec4f(v0: AnyNumericVec2Instance, 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.
vec4f(uv: d.v2f
uv, 0.5, 1);});
const const glsl: string
glsl = const tgpu: { const: typeof import("node_modules/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("node_modules/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("node_modules/typegpu/src/core/function/comptime").comptime; resolve: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("node_modules/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("node_modules/typegpu/src/core/root/init").init; initFromDevice: typeof import("node_modules/typegpu/src/core/root/init").initFromDevice; slot: typeof import("node_modules/typegpu/src/core/slot/slot").slot; lazy: typeof import("node_modules/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("node_modules/typegpu/src/tgpuUnstable");}
tgpu.resolve: (items: ResolvableObject[], options?: TgpuResolveOptions) => string (+1 overload)
A shorthand for calling tgpu.resolveWithContext(...).code.
resolve([const getColor: TgpuFn<(uv: d.Vec2f) => d.Vec4f>
getColor], function glOptions(): { unstable_shaderGenerator: GlslGenerator;}
glOptions());For a vertex and fragment pair, use dualGlOptions(). Both stages share naming state, which keeps uniforms and inter-stage values consistent.
import { dualGlOptions } from '@typegpu/gl';
const options = dualGlOptions();const vertexGlsl = tgpu.resolve([vertexFn, fragmentFn], options.vertex);const fragmentGlsl = tgpu.resolve([vertexFn, fragmentFn], options.fragment);API Reference
Section titled “API Reference”initWithGLFallback
Section titled “initWithGLFallback”const root = await initWithGLFallback();Attempts to initialize the standard WebGPU root first. If WebGPU is unavailable or initialization fails, it creates a WebGL 2 root using an internal OffscreenCanvas.
Use this function when WebGPU is preferred and the effect only relies on the supported fallback API.
initWithGL
Section titled “initWithGL”const root = initWithGL();Creates a WebGL 2 root without attempting WebGPU. This is useful for testing the fallback path or deliberately targeting WebGL 2.
You can provide an existing WebGL 2 context, but it must belong to an OffscreenCanvas:
const offscreen = new OffscreenCanvas(1, 1);const gl = offscreen.getContext('webgl2');
if (!gl) { throw new Error('WebGL 2 is unavailable');}
const root = initWithGL({ gl });Calling initWithGL() without an argument creates the offscreen canvas and context for you.
isGLRoot
Section titled “isGLRoot”if (isGLRoot(root)) { // Use a fallback-compatible resource strategy.} else { // The root uses WebGPU.}Returns whether a root was created by the WebGL 2 backend. This is primarily useful after initWithGLFallback() when an application can use an optimized WebGPU path but still needs a fallback-compatible alternative.
glOptions
Section titled “glOptions”const glsl = tgpu.resolve([resolvable], glOptions());Returns resolution options that make TypeGPU generate GLSL for a single shader or helper-function graph.
dualGlOptions
Section titled “dualGlOptions”const options = dualGlOptions();
const vertexGlsl = tgpu.resolve([vertexFn], options.vertex);const fragmentGlsl = tgpu.resolve([fragmentFn], options.fragment);Returns separate vertex and fragment resolution options backed by shared cross-stage state. Create one options object per shader pair and use each side for its corresponding stage.