Skip to content

Releases: oframe/ogpu

0.2.0 — core hardening + PerDrawBuffer restructure

Choose a tag to compare

@DougLilliequist DougLilliequist released this 18 Jul 20:33

Port of the dgpu core audit outcome (parity-reviewed against dgpu as reference).

Breaking

  • Per-mesh uniform buffers replaced by one renderer-owned PerDrawBuffer
    (dynamic offsets).
    Every Mesh.draw allocates an aligned slice of a shared
    uniform buffer and binds group(0) with a dynamic offset — a mesh can now repeat
    across passes inside one chained-encoder submit (shadow + main in one command
    buffer) without uniforms stomping each other. Mesh no longer owns
    uniformBuffer; it exposes uniformResource ({buffer, offset, size}), and
    the bindGroups factory receives that descriptor instead of a GPUBuffer:
    bind it verbatim — { binding: 0, resource: uniformResource }. All examples
    and GLTFLoader are migrated. The buffer's pointer resets each frame; size
    via the new Renderer option perDrawSize (default 1 MiB), overflow logs
    loudly. group(0)/binding(0) is marked hasDynamicOffset on every
    RenderPipeline — non-Mesh direct draws must pass pass.setBindGroup(0, bg, [0]); shaders that declare but never read uniforms are handled via
    RenderPipeline.hasDynamicUniform.
  • Renderer stencil constructor option removed — it was stored and never
    read.
  • Geometry without data now throws with a clear message instead of
    warning and then crashing inside webgpu-utils.

Fixed

  • Canvas transparency never worked — the context was configured with a
    misspelled alphamode key (silently ignored). Now alphaMode: 'premultiplied'|'opaque'.
  • ComputeShader crashed on devices without timestamp-query — timestamp
    query-set creation throws per spec; all timestamp resources are now
    feature-gated and timing: true degrades to a no-op (also skipped for
    external passes, which never receive timestamp writes).
  • RenderTarget silently flattened 3D/array/cube targets — the
    constructor's own onResize wiped depth/dimension; both are now
    preserved through every resize.
  • Geometry.destroy() leaked index buffers (webgpu-utils returns
    indexBuffer separately from buffers).
  • Orthographic cameras swallowed 0 extents (left: 0 became -1 via
    ||); presence-based type detection and ?? defaults.
  • Wrong-sized swapchain depth texture was never recreated — the resize
    mismatch branch was dead code.
  • Tab-switch delta spike — resuming after the page was hidden delivered the
    entire hidden duration as one deltaTime; pause() now actually stops the
    clock and callbacks, and resume starts with a zero-delta frame.
  • RenderPipeline mutated caller-owned targets descriptors when applying
    blend state (shared arrays leaked blending into opaque pipelines); partial
    blending without alpha now gets the engine default instead of failing
    pipeline creation.
  • Skin replaced bone position/quaternion/scale instances, orphaning
    the Transform rotation-sync hooks; bind poses are applied in place.
  • 2D-array texture mip uploads shrank the layer count per mip (only 3D
    depth shrinks); upper mips of higher layers were never written.
  • cameraQuaternion uniform was the camera's local rotation — now
    world-space via the new Camera.worldQuaternion.
  • resolution uniform was always canvas-sized — draws into a
    RenderTarget now receive the target's dimensions.
  • Camera.getFrustumSize returned half extents (missing ×2).
  • A superseded device's late lost event could re-init over a healthy
    replacement
    ; device-loss recovery failures now log an honest
    recovery-specific error instead of the boot-time message.
  • Instanced attribute shader locations could collide when vertex data spans
    multiple buffer layouts — locations now derive from all layouts.

Changed

  • Mesh.draw always calls setPipeline — the redundant-bind skip cache
    desynced when external code set a pipeline on a shared pass.
  • gui.uniform(target, key) requires only .uniforms + .gpu;
    .uniformBuffer is optional (passes with private buffers keep immediate
    writes; meshes upload on next draw).
  • Texture and depth views are cached per texture generation instead of being
    recreated every frame (invalidated through destroy/resize/device-restore).

v0.1.3

Choose a tag to compare

@DougLilliequist DougLilliequist released this 30 Jun 08:13

webgpu-spec-lookup: cached local W3C spec + grep

W3C spec lookups now run against a preprocessed local copy refreshed at most once per day, instead of a WebFetch of the 4.5 MB spec page per question.

  • New update_spec.py downloads https://www.w3.org/TR/webgpu/ only when the cached copy's date differs from today, strips it to ~628 KB of greppable text, and prefixes every heading with its [#anchor] so a grep hit traces back to a spec section.
  • Benefit: spec answers go from slow, lossy whole-page fetches to near-instant local grep — exact identifiers and limit values (GPUFeatureName, GPUSupportedLimits, defaults) come back verbatim, and repeat lookups reuse the same-day cache.
  • Chrome "What's New" lookups still use WebFetch. The downloaded cache is gitignored.

v0.1.2 — skinning + glTF PBR

Choose a tag to compare

@DougLilliequist DougLilliequist released this 28 Jun 08:38

Focused on the skinning and glTF paths.

Highlights

Skinning + glTF

  • GLTFLoader.getSkinnedMesh({ code, ibl }) — new turnkey getter that returns a fully-wired skinned, PBR-lit mesh: it builds the Skin (compute buffers) and its Animation, decodes the glTF material maps (with factor-only fallbacks for the maps a file lacks), and binds everything — skin buffers, IBL, material factors — against the skinned-PBR shader layout. Returns { mesh, skin, animation }; drive animation.elapsed + skin.update() per frame.
  • Skinning examples split into JSON + glTF (PBR) — the hand-built JSON rig and the glTF/Mixamo path are now separate examples. The new skinninggltf example deliberately keeps the manual wiring (geometry, material maps, IBL bindings) to show how to unfold a glTF mesh yourself; PBR shading was folded in via the pbr-shading skill. getSkinnedMesh is the one-liner alternative.
  • Real-time shadow mapping in skinninggltf — the glTF example now renders a depth-pass shadow map: a vertex-only caster pulls skinned positions from the Skin compute buffer (so the cast shadow tracks the animation) into an orthographic light's depth target, and the character + a floor sample it back with 3×3 PCF for a soft contact shadow and self-shadowing.
  • glTF inverse-bind matrices are read straight from the file (authoritative bind-inverse), with FK-from-bind-pose only as the fallback for hand-built rigs.
  • Skeleton-ancestor nodes (Blender armature / Mixamo Neo_Reference) are rebuilt as animatable transforms so baked root motion plays back correctly.

PBR / IBL

  • createBrdfLUT util — the split-sum BRDF LUT is now a shared helper, deduped across the PBR/skinning examples instead of being rebuilt per example.
  • glTF textures go through the engine Texture class instead of raw WebGPU calls (sRGB-correct, mipmapped).

Skills (agent tooling)

  • shadow-mapping skill — folds real-time shadow mapping (depth-pass caster + comparison-sampled PCF receiver) into any existing RenderPipeline/shader, covering the static, skinned/compute-positioned, and IBL-only cases. Companion to the pbr-shading skill; it's the skill the skinninggltf shadow pass above was built with.

Performance

  • Skinning animation sampling sped up; added a high-mesh-count example to exercise it.
  • glTF primitives share RenderPipelines keyed by cull/blend state (typically 1–2 pipelines per file).
  • Meshes skip redundant setPipeline via per-pass bookkeeping.

Full diff: v0.1.1...v0.1.2

v0.1.1 — repomap tooling normalization

Choose a tag to compare

@DougLilliequist DougLilliequist released this 27 Jun 09:14

Tooling

  • Repomap path separators normalized to POSIX. build-module-graph.mjs and build-api-digest.mjs emitted OS-native separators, so a repomap regenerated on Windows differed from one on mac/Linux on every path — churning the drift gate and blocking cross-platform commits. Both generators now route every repo-relative id through a rel() helper that forces /. Output is unchanged on mac/Linux; the fix is preventive for Windows contributors. (eda299e)

Full changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@DougLilliequist DougLilliequist released this 27 Jun 07:57

First tagged release.

Highlights:

  • New High Mesh Count performance example (one pipeline + shared box geometry, N meshes each with own bind group; mesh count live-tunable via GUI).
  • New Performance gallery section.
  • Faster skinning example animation.
  • glTF (fix): previously created one pipeline per node — now shared across nodes by cull/blend state, cutting redundant pipeline objects per model. Pull to pick up.
  • Shadowmapping refactor; shared vertex-buffer layout when a pipeline draws multiple geometries.