Repository navigation
Draw the Matrix ourselves: WebGPU and WebGL 2, and no three.js - #6
Merged
Merged
Conversation
src/gpu/ is a renderer written for these games: a scene graph, three shaders (lit, unlit, backdrop), and two backends. WebGPU is tried first, WebGL 2 is the fallback, and ?renderer=webgl|webgpu forces one. The shaders live in src/gpu/shaders/ as .glsl and .wgsl and are the same programs twice. frame.js culls, sorts and packs every uniform once a frame into vec4/mat4-only blocks that std140 and WGSL lay out identically, so the backends only issue draws and cannot disagree. The wireframe is native one-pixel lines, additive, fogged into the black before they are added; the deck fill keeps its polygon offset and its place at the front of the see-through queue; the rain is a full-frame backdrop at 0.32. Marc's shell keeps three r185's physical lighting term for term — GGX with multiscatter compensation off the same DFG table, Charlie sheen, clearcoat, the studio's hemisphere and two keys — and the studio environment is prefiltered on the CPU in a worker, same cube-UV layout and GGX VNDF sampling as before. Checked by rendering the old and new builds headlessly from the same seeded run: WebGL agrees within 1/255 on every frame; WebGPU differs only by a pixel here and there along the lines and the egg's edge. test/gpu.test.js checks the GLSL and WGSL blocks against frame.js, shape winding, the prefilter on a uniform world, draw order and per-material animation; the rig test projects through the new camera. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAsxgyQ3z7SBtRq9X4N3R7
A phone reclaiming memory from a backgrounded tab, or a driver reset, takes the WebGL context or the WebGPU device with it. The renderer now stops drawing when that happens and builds a fresh backend on the same canvas when it can: on webglcontextrestored for WebGL, straight away for a lost (not destroyed) WebGPU device. Everything it draws is re-uploaded from the scene and the canvases on the next frame. Checked with WEBGL_lose_context: lose, keep calling render, restore — no errors, and the frame after comes back the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAsxgyQ3z7SBtRq9X4N3R7
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WebGPU multisamples at 4x and no more. Chrome gives a WebGL canvas 8x on a desktop GPU, and that is what the three.js build was drawn with — so on a desktop the WebGPU backend came out with jaggier edges and small bright things (the pickups) a little less glowing than before. The renderer now asks a throwaway WebGL context how many samples it could take: more than 4 and WebGL draws, otherwise (most phones) WebGPU does. Either falls back to the other if it will not start, and ?renderer=webgl|webgpu still forces one. The WebGL backend makes the same calls as three did on the same API, so on a desktop the picture is the one it always was. Checked headlessly by faking an 8-sample GPU: WebGL is chosen; at 4 samples WebGPU is; ?renderer=webgpu overrides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAsxgyQ3z7SBtRq9X4N3R7
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
three.js is gone.
src/gpu/is a small renderer written for these games, with two backends: WebGPU (shaders in WGSL) and WebGL 2 (shaders in GLSL). The shaders are separate files insrc/gpu/shaders/(*.glsl,*.wgsl). The engine is the same file set in all three eggs.?renderer=webglor?renderer=webgpuin the URL forces one.src/core/is untouched, and so are the camera rig, pools and timings.How it works
frame.jsmakes the decisions, once per frame. It culls, sorts and packs every uniform intovec4/mat4blocks that std140 and WGSL lay out identically, so the two backends can't disagree.One quirk is preserved on purpose: three takes a hemisphere light's "up" from the light's world position. The studio travels with the egg, so its "up" tilts toward +z as you run. That's part of how the game looks today, so the new renderer copies it.
Testing
npm test: 110 pass. The newtest/gpu.test.jschecks the GLSL blocks and WGSL structs againstframe.js, shape winding, the prefilter, draw order and per-material animation. The rig test now projects through the new camera.npm run lintis clean, andnpm run buildsucceeds.?renderer=webgpuoverrides.🤖 Generated with Claude Code
https://claude.ai/code/session_01DAsxgyQ3z7SBtRq9X4N3R7