Skip to content

@awaken/render

The WebGPU rendering package: the Renderer, the render-settings + post-effect stack, cameras, lights, cascaded shadows, primitive meshes, the material system, and GPU device setup. It depends only on @awaken/core.

This page is the API surface; for how the pipeline actually draws a frame - PBR lighting, cascaded shadows, post-processing - see the Rendering section.

ts
import { Renderer, initGPU, defaultRenderSettings, cubeMesh } from "@awaken/render";

The package's pieces feed one Renderer.render call - you set the device up once, upload assets and settings as they change, then hand a World + camera matrices per frame:

Everything after Renderer is internal - the API you drive is the left column. See Rendering Pipeline Overview for what each pass does.

device

WebGPU setup and capability probing. Awaken3D asks for optional features opportunistically (indirect-first-instance, texture-compression-bc, timestamp-query) and degrades gracefully when they are absent.

SymbolSignatureDescription
initGPU(canvas, maxDpr?) => Promise<GPUContext>Request an adapter + device, configure the canvas, and return the context. Throws WebGPUUnsupportedError if WebGPU is unavailable.
GPUContextinterface{ canvas, device, context, format, caps, adapterInfo, depthTexture, depthView, width, height, renderScale, resize() }.
GPUCapsinterface{ indirectFirstInstance, maxStorageBuffersPerStage, textureCompressionBC, timestampQuery } - the flags the renderer branches on.
WebGPUUnsupportedErrorclass extends ErrorThrown when there is no GPU adapter or no navigator.gpu.
probeAdapters() => Promise<AdapterOption[]>Detect a discrete + integrated GPU choice (empty when there is only one).
savedGpuPref / setGpuPref() => GPUPowerPreference / (pref)Read/write the persisted GPU power preference.
textureCompressionBCSupported() => booleanModule-level mirror of BC support (so the import dialog can gate compression without a context).

renderScale (0.25–1) sets the internal render resolution; the browser upscales to the canvas. See Performance.

Renderer

The single WebGPU renderer. You upload meshes and textures, hand it a World + camera matrices, and it draws - building a cached draw list that it only rebuilds when the scene's topology changes (World.structureRev). Construct it with a GPUContext.

Frame & scene

MethodSignatureDescription
render(world, view, proj) => voidDraw one frame from the given camera matrices.
pick(world, view, proj, px, py) => Promise<Entity | null>GPU id-buffer pick at a pixel (async readback).
invalidate() => voidMark the draw cache stale (call when transforms/meshes/visibility change).
syncTransforms(world, worldMats, entities) => voidPush moved entities' matrices into the persistent instance buffer without a full rebuild.
moveObject(e, mat) => booleanFast-path single-object matrix update (returns false if a rebuild is needed).
getStats() => RenderStatsPer-frame stats: draw calls, vertices, batches, shadow draws, CPU rebuild/cull ms, and real GPU pass timings (when timestampQuery is supported).

Assets

MethodSignatureDescription
uploadMesh(id, data: MeshData) => voidUpload/replace a mesh's interleaved geometry (frees old buffers on re-upload).
updateSkinnedMesh(id, positions) => voidIn-place vertex rewrite for a CPU-skinned mesh (same topology; no reallocation, no full re-merge).
uploadTexture(id, source, roleOverride?) => voidUpload an albedo/normal/mask texture; block-compresses to BC for the local GPU when supported.
hasTexture(id) => booleanWhether a texture id has been uploaded.
meshCenter(id) => Vec3 | nullLocal-space AABB centre of an uploaded mesh.
gpuTextureBytes(id) => numberReal VRAM (post-compression) for one texture.
setMaterials(list: Material[]) => voidRegister authored materials into the renderer's registry.

Configuration & overlays

Method / FieldTypeDescription
setRenderSettings(s: RenderSettings) => voidApply the full settings bag: shadows, batching, GPU cull, MSAA, render scale, and the effect stack.
setSelection(entities: Entity[]) => voidWhich entities draw the selection outline.
setGizmo / setOverlay(lines: Float32Array | null) => voidEditor gizmo triangles / wireframe line overlays (e.g. a camera frustum).
setPreview(p | null) => voidRender a camera-preview inset into a swapchain sub-rect this frame.
showGridbooleanToggle the infinite editor ground grid (hide in Game/Play).
outlineColor / outlineThickness[r,g,b] / numberSelection-outline appearance.
compressTexturesbooleanCompress RGBA textures to BC at upload when the GPU supports it.
useGpuCullbooleanOpt-in GPU-driven frustum culling (needs indirect-first-instance).
staticEnabled, staticMergeMaxUses, drawDistanceScale, shadowCachevariousBatching / cull / shadow tuning (usually driven via setRenderSettings).

render (settings & effects)

Render settings are split into always-present engine config and an add/remove effect stack modelled on Unity's post-process Volume - an absent effect is simply not applied, so no default fog or bloom leaks into an ungraded import.

SymbolSignature / ShapeDescription
RenderSettingsinterfaceshadowStrength, cascadeCount, shadowDistance, shadowCache, staticBatching, staticMergeMaxUses, staticMergeBudgetM, useGpuCull, drawDistanceScale, msaaSamples, renderScale, groundPlane, and effects.
defaultRenderSettings() => RenderSettingsDefaults: shadow strength 0.85, 3 cascades, 120 m shadow distance, batching on, MSAA 4, render scale 1, ground plane on, sky + ambient effects present.
RenderEffectsinterfaceThe optional effect stack (all fields optional): tonemap, sky, ambient, fog, colorGrade, liftGammaGain, shadowMidHigh, bloom, vignette, ssao.
EFFECT_KEYSreadonly tupleThe ordered add-menu keys: ["sky","ambient","fog","colorGrade","liftGammaGain","shadowMidHigh","bloom","vignette","ssao"].
EFFECT_LABELSRecord<EffectKey,string>Display labels ("Color Adjustments", "Ambient Occlusion (SSAO)", …).
defaultEffect(key) => EffectThe neutral value for a freshly-added effect (does nothing until tuned).
defaultEffects() => RenderEffectsA blank scene starts with just sky + ambient.
effectsFromFlat(FlatRender) => RenderEffectsConvert the flat render bag the Godot/Unreal loaders produce into effects (only the fields the source actually set).
SkyEffect, AmbientEffect, FogEffect, ColorGradeEffect, LiftGammaGainEffect, ShadowMidHighEffect, BloomEffect, VignetteEffect, SsaoEffectinterfacesPer-effect parameter shapes.

tonemap is "linear" (stylized hard clamp, Godot/default) or "aces" (filmic rolloff, Unity/Unreal). See Post-processing and Render Settings.

camera & orbit

SymbolSignatureDescription
CameraComponentType + interface{ projection, fov, orthoSize, near, far } - the scene camera component (default projection: "perspective", fov 60, orthoSize 5, near 0.1, far 1000). projection: "orthographic" uses orthoSize (half-height in world units, Unity convention) and ignores fov.
activeCamera(world) => Entity | nullThe first active, enabled camera entity.
cameraMatrices(world, entity, mats, aspect) => { view, proj }View + projection for a Camera entity (perspective or orthographic per projection).
perspectiveZO(out, fovyRad, aspect, near, far) => Mat4Perspective projection, WebGPU clip space.
orthographicZO(out, left, right, bottom, top, near, far) => Mat4Orthographic projection, WebGPU clip space (same -Z view space + depth direction as perspectiveZO).
lookAt(out, eye, target, up) => Mat4Right-handed view matrix.
cameraPositionFromView(view) => Vec3World camera position from a view matrix.
transformPoint(m, p) => Vec3Apply a matrix to a point (perspective divide).
OrbitCameraclassThe editor's orbit/pan/zoom viewport camera.

light & shadow

SymbolSignatureDescription
LightComponentType + interface{ kind: "directional" | "point", color, intensity, range }.
gatherLights(world, mats) => PackedLight[]Collect active lights into GPU-packed records (direction for directional, position for point).
computeCascadeMatrices(view, proj, sunDir, count, …) => { mats, splits }Cascaded-shadow-map light matrices + split distances.
directionalLightMatrix(dir, center, radius) => Mat4A single directional light's ortho view-proj.

Shadows are cascaded (up to 4), with cached static-caster maps - see Shadows.

primitives

Procedural MeshData generators (positions/normals/uvs/indices), used for built-in shapes and collider previews.

SymbolSignatureDescription
MeshDatainterface{ positions, normals, uvs, indices, colors? } - the renderer's canonical mesh shape.
cubeMesh(size?) => MeshDataUnit cube, per-face normals.
sphereMesh(radius?, seg?) => MeshDataUV sphere.
planeMesh(size?, seg?) => MeshDataXZ plane facing +Y (seg subdivides it for vertex-stage material hooks).
quadMesh(size?) => MeshDataUnit quad in the XY plane facing +Z - the sprite/2D primitive (quad builtin id).
cylinderMesh(radius?, height?, seg?) => MeshDataCapped cylinder along Y.
capsuleMesh(radius?, height?, seg?, capRings?) => MeshDataCapsule (cylinder + hemisphere caps).
gridLines(halfExtent, step) => Float32ArrayEndpoint positions for an XZ grid.

See Mesh format for the on-GPU vertex layout.

material

Hook-based materials: a material is authored WGSL snippets (vertexPosition, discard, surfaceNormal, surfaceColor hooks - listed in execution order) plus a typed parameter schema, composed into the base mesh shader at pipeline-build time. A broken shader falls back to the default pipeline rather than erroring a frame.

SymbolSignature / ShapeDescription
Materialinterface{ version, id, name, hooks: MaterialHooks, params: MaterialParam[], metadata? }.
MaterialParam{ name, type: ParamType, default, perObject }One material parameter. perObject params can be overridden per entity via MeshMaterial.overrides.
ParamTypeunion"float" | "vec2" | "vec3" | "vec4" | "color" | "bool" | "texture".
MaterialHooks{ vertexPosition?, discard?, surfaceNormal?, surfaceColor? }WGSL hook bodies. vertexPosition mutates world (world-space vec4), surfaceNormal mutates N, surfaceColor mutates albedo + outAlpha; discard is an early exit that runs before the albedo sample.
composeShader(baseTemplate, m) => stringCompose final WGSL from a template + hooks + generated param/globals structs. Pure string splice - it does not compile and cannot fail.
composeShaderMapped(baseTemplate, m) => ComposedShaderThe same splice, plus spans: HookSpan[] recording which composed lines each hook body occupies - so a compiler diagnostic in composed-line coordinates can be routed back to the owning hook.
ComposedShader / HookSpan{ code, spans } / { hook, startLine, lineCount }1-based composed line numbers, matching GPUCompilationMessage.lineNum. Hooks with no body produce no span.
MESH_MATERIAL_WGSLstringThe material-enabled mesh template (toMaterial(MESH_WGSL)) both material caches compose against. Not compilable on its own - composeShader prepends the generated Globals + MaterialParams structs.
packMaterialParams(params, overrides, out, offset) => voidPack a material's params into a 64-byte per-object slot - the override when a perObject param has one, else the param's default.
materialParamFloats(params) => numberFloat lanes a schema consumes (author budget check).
MATERIAL_PARAM_FLOATS16Per-object slot size in floats (64 bytes).
MaterialCache<P>classDedups compiled pipelines by composed-shader hash; async compile with a fallback.

There is no built-in material registry - the engine ships no materials, and BUILTIN_MATERIALS no longer exists. Every material comes from the project's materialAssets (authored in the editor or imported from a .awakenmat), and is registered with Renderer.setMaterials. The stylized water material is importable starter content at starter-content/materials/Water.awakenmat (id water).

See the Shader Editor and Materials.

Shared types

Two component types authored here (not in core) travel with meshes and materials:

SymbolDescription
MeshRendererComponentType + interface: { mesh, color, metallic, roughness, texture, opacity?, transparent?, castShadow? }. The primary "make this entity visible" component. castShadow: false draws the object without writing it to the shadow map - required for a vertex-displacing material, whose displacement the shadow pass does not apply.
MeshMaterialComponentType + interface: { material: string, overrides? }. Attaches an authored Material by id. overrides is a declared, serialized field (materialParams): a sparse map holding this object's values for the material's perObject params - a key exists only where the object diverges from the asset default.
TextureRole"albedo" | "normal" | "mask" - drives the compression format + colour space.
TextureFormat"rgba8" | "bc1" | "bc3" | "bc4" | "bc5" - storage format.
pickTextureFormat, FORMAT_GPUFormat selection by role/content/device + the GPU-format table.

See also

Awaken — browser-native WebGPU game engine.