Skip to content

feat: share the WebGPU core across Three and Babylon - #91

Open
bpodwinski wants to merge 2 commits into
pmndrs:mainfrom
bpodwinski:feat/webgpu-core-babylon-pr
Open

bpodwinski wants to merge 2 commits into
pmndrs:mainfrom
bpodwinski:feat/webgpu-core-babylon-pr

Conversation

@bpodwinski

Copy link
Copy Markdown

Three currently owns the upscaler orchestration, preventing another WebGPU engine
from reusing it directly. This change extracts a shared GPUDevice-based core and
makes the existing Three API an adapter, then adds a Babylon 9.29 Frame Graph
adapter with native texture ownership and history rotation.

  • Add /core, /three and /babylon; preserve root Three exports and signatures.
    Engine peers are optional and isolated packed consumers verify declarations and runtime imports.
  • Keep host encoder/submission ownership, separate early/late uniforms, split-frame
    ordering checks, asynchronous preparation cancellation and explicit history reset.
  • Add opt-in positive linear R32F depth, supplied exposure, independent conditioning/
    host pre-exposure correction and age-conditioned temporal RCAS. Neutral defaults
    preserve existing Three shader behavior; spatial sharpening is unchanged.
  • Add raw WebGPU, analytic Babylon and twelve mesh examples with effects, alpha,
    reactive coverage and split guides. Group the gallery by engine and document contracts.

The package name/version, repository metadata and release/Pages workflows stay
upstream. No npm publication or application migration is included.

Validation

  • Prepared contribution: 603 CPU tests across 39 files, lint, typecheck, library/
    gallery builds, packed Three guides build and isolated packed entrypoint consumers pass.
  • Final CPU repetition used two workers with unchanged assertions and timeouts.
    An earlier run under contention had three release-fixture timeouts and a Vitest
    RPC timeout; the full repeat and targeted affected cases passed. Both logs are retained.
  • Actual RX 580, AMD/gcn-4: packed raw/Babylon core checks and packaged Three
    guides pass. All twelve built mesh pages passed again on both RX 580 and RTX 5080,
    including odd resize, NativeAA, aliasing, reset and disabled/reenabled history.
  • Both adapters passed controlled GPUDevice.destroy loss, invalidation and restored
    output. Core/Babylon each exercised 24 dynamic configurations and two host effects
    between guides/upscale; per-frame GPU readback checks both exposure domains.
    Babylon restoration awaits actual WebGPU initialization before graph/task recreation.
    Three rejects old-instance preparation and renders again after caller recreation.
  • Prior RTX 5080 baseline Q0 captures at ratio 1.5, frames 8/32 matched upstream
    pixel for pixel. New cross-build throughput probes ran on both devices.
  • October 10, eight-block/1200-sample repeats found no delta above observed drift:
    RX ratios 1/1.5/2/3, RTX ratios 1/1.5. Older runs and all new samples are retained.
    RTX drift remains 9.87–11.46%, limiting sensitivity to small regressions.
  • Q0 RGB convergence and transparent-canvas alpha metrics/traces matched upstream
    exactly in the measured windows. Scene captures were inspected.
  • Camera-motion validation measures spatial regions to avoid transparent-background
    dilution and requires a tenfold signal over stationary jitter. The alpha meter
    verifies browser ownership and closes it through CDP; its busy-port regression passes.
  • Core/Babylon GPU verifiers also reject occupied debugging ports and verify the
    launched profile before creating a page; occupied-port fixtures stay open.
  • Release-workflow fixtures disable commit/tag signing in each temporary clone;
    cloning does not inherit seed-local Git configuration. Personal Git configuration is unchanged.
  • Read-only independent review found no remaining critical/important issue. The
    parity tool now rejects missing/extra captures; packaged guide example links are portable.

Limits

Final low-variance performance acceptance and exhaustive human visual review remain
open. Device loss was triggered through WebGPU, not an OS/driver crash. Babylon internals are centralized and
guarded, with peer support limited to 9.29.x. Dependency WebGPU declaration collisions
may require skipLibCheck for Babylon/Three consumers; core declarations are checked
without it. Full contracts and evidence: docs/webgpu-core.md,
docs/babylon-framegraph.md and docs/webgpu-validation.md.

@DennisSmolek

Copy link
Copy Markdown
Member

I'm for sure interested in the concept but can we talk about your methods a bit?
DId you plan this or throw an agent at it?

@bpodwinski

Copy link
Copy Markdown
Author

Thanks for the feedback. I've been using your upscaler for months in my Babylon.js WebGPU project (Exokosm). Babylon has no temporal equivalent, so I extracted the WebGPU core and wrote an adapter for the Babylon Frame Graph.

Methods: yes, I used an AI agent (Claude Code) heavily, directed and reviewed by me. Guardrails:

  • Three API unchanged by default, WGSL passes untouched
  • Q0 captures from your own bench pixel-identical to main
  • 603 CPU tests, tarball tested in isolated projects
  • perf measured on RTX 5080 and RX 580

Not done yet: final low-variance perf acceptance, exhaustive visual review, real driver-crash recovery, remote CI. Details in docs/fork-validation.md.

Where to look:

  • docs/webgpu-core.md (core)
  • docs/babylon-framegraph.md (adapter)
  • examples/18-babylon-framegraph/main.ts (minimal example)

The diff is big: happy to split it (core / Babylon / examples+docs) if you prefer.

Resolve import conflicts in UpscalerNode.ts and resolution.test.ts: keep the
branch's .js import specifiers and add upstream's getPassRenderResolution (pmndrs#89).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@DennisSmolek

Copy link
Copy Markdown
Member

The diff is big and I'll review it. I dont mind an agent working as long as theres humans behind the thinking.

I want to think about how we do a "core" and how then the packages are built for the different vendors. If you look at the work here: https://github.com/pmndrs/denoiser

I've already kind of started it.

im thinking I convert to a mono-repo with sub-packages for vendors that consume the core. I will take a stab at this today and use this PR for the babylon base work

@DennisSmolek

Copy link
Copy Markdown
Member

Hey @bpodwinski, thanks for this, and for the patience. The monorepo split is up as #94, and #91 was the reference for its Babylon side.

How it's structured (same shape as pmndrs/denoiser):

  • There's one published @pmndrs/upscaler with subpaths: the root and /three (unchanged for three users), plus /core, /babylon and /pixi. The engine code lives in private workspace packages, and the build bundles them with one shared chunk. Every engine is an optional peer.
  • packages/core has UpscalerCore: a GPUDevice, GPUTexture inputs and plain FrameCamera data. Published textures go through a TextureAllocator hook. You can bring your own encoder with encode(), or call dispatch() to submit. docs/engine-contract.md is the contract any adapter writes against.

Babylon (packages/babylon, experimental, docs/babylon.md): I wrote it fresh against that contract, using your bridge findings as the map. A few choices differ from #91:

  • Jitter goes through TAAMaterialManager, so the camera and Babylon's velocity stay jitter-free.
  • Inputs stay in Babylon's Y-flipped render-target layout. That makes the jitter clip offset (-2x/w, -2y/h) and motionScale [-1, -1]. Both signs were checked on GPU against native.
  • The core keeps history and ping-pong ownership, so the host doesn't manage rotation.
  • There's a FrameGraphUpscaleTask; examples/babylon/hello is the reference.
  • The peer is @babylonjs/core >=9.31 <10. Is Exokosm still on 9.29?

The opt-in features from #91 are now tracked as their own issues, so each one can be judged on its own evidence:

Each issue says what exists today, what has to stay byte-identical, and what GPU evidence would land it. You've already done most of that work in #91, so if you'd like to take any of them on top of the new layout, PRs are very welcome. If you have a repro of the split-frame problem behind #96, please drop it there.

Could you try #94 in Exokosm and tell me what breaks or what's missing for your Frame Graph setup? Once you're happy with the Babylon adapter there, I think we can close #91 in favour of these. The work here shaped the whole split, so thank you.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants