@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.
| Symbol | Signature | Description |
|---|---|---|
initGPU | (canvas, maxDpr?) => Promise<GPUContext> | Request an adapter + device, configure the canvas, and return the context. Throws WebGPUUnsupportedError if WebGPU is unavailable. |
GPUContext | interface | { canvas, device, context, format, caps, adapterInfo, depthTexture, depthView, width, height, renderScale, resize() }. |
GPUCaps | interface | { indirectFirstInstance, maxStorageBuffersPerStage, textureCompressionBC, timestampQuery } - the flags the renderer branches on. |
WebGPUUnsupportedError | class extends Error | Thrown 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 | () => boolean | Module-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
| Method | Signature | Description |
|---|---|---|
render | (world, view, proj) => void | Draw 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 | () => void | Mark the draw cache stale (call when transforms/meshes/visibility change). |
syncTransforms | (world, worldMats, entities) => void | Push moved entities' matrices into the persistent instance buffer without a full rebuild. |
moveObject | (e, mat) => boolean | Fast-path single-object matrix update (returns false if a rebuild is needed). |
getStats | () => RenderStats | Per-frame stats: draw calls, vertices, batches, shadow draws, CPU rebuild/cull ms, and real GPU pass timings (when timestampQuery is supported). |
Assets
| Method | Signature | Description |
|---|---|---|
uploadMesh | (id, data: MeshData) => void | Upload/replace a mesh's interleaved geometry (frees old buffers on re-upload). |
updateSkinnedMesh | (id, positions) => void | In-place vertex rewrite for a CPU-skinned mesh (same topology; no reallocation, no full re-merge). |
uploadTexture | (id, source, roleOverride?) => void | Upload an albedo/normal/mask texture; block-compresses to BC for the local GPU when supported. |
hasTexture | (id) => boolean | Whether a texture id has been uploaded. |
meshCenter | (id) => Vec3 | null | Local-space AABB centre of an uploaded mesh. |
gpuTextureBytes | (id) => number | Real VRAM (post-compression) for one texture. |
setMaterials | (list: Material[]) => void | Register authored materials into the renderer's registry. |
Configuration & overlays
| Method / Field | Type | Description |
|---|---|---|
setRenderSettings | (s: RenderSettings) => void | Apply the full settings bag: shadows, batching, GPU cull, MSAA, render scale, and the effect stack. |
setSelection | (entities: Entity[]) => void | Which entities draw the selection outline. |
setGizmo / setOverlay | (lines: Float32Array | null) => void | Editor gizmo triangles / wireframe line overlays (e.g. a camera frustum). |
setPreview | (p | null) => void | Render a camera-preview inset into a swapchain sub-rect this frame. |
showGrid | boolean | Toggle the infinite editor ground grid (hide in Game/Play). |
outlineColor / outlineThickness | [r,g,b] / number | Selection-outline appearance. |
compressTextures | boolean | Compress RGBA textures to BC at upload when the GPU supports it. |
useGpuCull | boolean | Opt-in GPU-driven frustum culling (needs indirect-first-instance). |
staticEnabled, staticMergeMaxUses, drawDistanceScale, shadowCache | various | Batching / 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.
| Symbol | Signature / Shape | Description |
|---|---|---|
RenderSettings | interface | shadowStrength, cascadeCount, shadowDistance, shadowCache, staticBatching, staticMergeMaxUses, staticMergeBudgetM, useGpuCull, drawDistanceScale, msaaSamples, renderScale, groundPlane, and effects. |
defaultRenderSettings | () => RenderSettings | Defaults: shadow strength 0.85, 3 cascades, 120 m shadow distance, batching on, MSAA 4, render scale 1, ground plane on, sky + ambient effects present. |
RenderEffects | interface | The optional effect stack (all fields optional): tonemap, sky, ambient, fog, colorGrade, liftGammaGain, shadowMidHigh, bloom, vignette, ssao. |
EFFECT_KEYS | readonly tuple | The ordered add-menu keys: ["sky","ambient","fog","colorGrade","liftGammaGain","shadowMidHigh","bloom","vignette","ssao"]. |
EFFECT_LABELS | Record<EffectKey,string> | Display labels ("Color Adjustments", "Ambient Occlusion (SSAO)", …). |
defaultEffect | (key) => Effect | The neutral value for a freshly-added effect (does nothing until tuned). |
defaultEffects | () => RenderEffects | A blank scene starts with just sky + ambient. |
effectsFromFlat | (FlatRender) => RenderEffects | Convert 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, SsaoEffect | interfaces | Per-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
| Symbol | Signature | Description |
|---|---|---|
Camera | ComponentType + 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 | null | The 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) => Mat4 | Perspective projection, WebGPU clip space. |
orthographicZO | (out, left, right, bottom, top, near, far) => Mat4 | Orthographic projection, WebGPU clip space (same -Z view space + depth direction as perspectiveZO). |
lookAt | (out, eye, target, up) => Mat4 | Right-handed view matrix. |
cameraPositionFromView | (view) => Vec3 | World camera position from a view matrix. |
transformPoint | (m, p) => Vec3 | Apply a matrix to a point (perspective divide). |
OrbitCamera | class | The editor's orbit/pan/zoom viewport camera. |
light & shadow
| Symbol | Signature | Description |
|---|---|---|
Light | ComponentType + 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) => Mat4 | A 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.
| Symbol | Signature | Description |
|---|---|---|
MeshData | interface | { positions, normals, uvs, indices, colors? } - the renderer's canonical mesh shape. |
cubeMesh | (size?) => MeshData | Unit cube, per-face normals. |
sphereMesh | (radius?, seg?) => MeshData | UV sphere. |
planeMesh | (size?, seg?) => MeshData | XZ plane facing +Y (seg subdivides it for vertex-stage material hooks). |
quadMesh | (size?) => MeshData | Unit quad in the XY plane facing +Z - the sprite/2D primitive (quad builtin id). |
cylinderMesh | (radius?, height?, seg?) => MeshData | Capped cylinder along Y. |
capsuleMesh | (radius?, height?, seg?, capRings?) => MeshData | Capsule (cylinder + hemisphere caps). |
gridLines | (halfExtent, step) => Float32Array | Endpoint 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.
| Symbol | Signature / Shape | Description |
|---|---|---|
Material | interface | { 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. |
ParamType | union | "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) => string | Compose final WGSL from a template + hooks + generated param/globals structs. Pure string splice - it does not compile and cannot fail. |
composeShaderMapped | (baseTemplate, m) => ComposedShader | The 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_WGSL | string | The 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) => void | Pack 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) => number | Float lanes a schema consumes (author budget check). |
MATERIAL_PARAM_FLOATS | 16 | Per-object slot size in floats (64 bytes). |
MaterialCache<P> | class | Dedups 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:
| Symbol | Description |
|---|---|
MeshRenderer | ComponentType + 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. |
MeshMaterial | ComponentType + 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_GPU | Format selection by role/content/device + the GPU-format table. |
See also
- Rendering Pipeline Overview - how a frame is drawn end to end.
- PBR & Lighting, Shadows, Post-processing - the feature pages.
- Render Settings - the UI over
RenderSettings+ effects. - Component Reference -
MeshRenderer,MeshMaterial,Light,Camerafields. - @awaken/core - the
Worldand math the renderer consumes.