WebGPU 3D tier + full backend parity, spine on WebGPU — 20.0.0 (#1184, #1536) - #1564
Merged
Conversation
The WebGPU renderer completes the engine contract and becomes the AUTO default (WebGPU → WebGL 2 → Canvas, negotiated inside app.init()): - 3D tier: drawMesh through unlit/lit WGSL pipelines — retained model-space geometry under Camera3d (upload once, placement/tint/ cutoff/emissive per-draw uniforms) and the CPU-projected 2D path; per-mesh cull/winding as pipeline state; depth as pass load/store ops (one clear per target per frame, pure-2D passes byte-identical) - point + spot Light3d on both backends (#1536): 12-float std140 light entries (posRange/dirCone/colorInner), quadratic-over-range falloff, runtime-mutable fields; glTF loader instantiates all three punctual types (scene-scaled), carries authored light names, and gains a lightIntensityScale load option - custom mesh shaders on both backends: GLShader is now dual-language — object sources form {vertex, fragment, wgsl} with isWebGL/isWebGPU flags; mesh.shader hosts it (warn-and-degrade on mismatch); shader assets grow the matching complete-program shape - antiAlias => 4x MSAA on WebGPU canvas passes; mesh textures gain generated mip chains + trilinear + 4x anisotropy on both backends (authored compressed chains included; "nearest" opts out); 8-slot multi-texture quad batching - renderer parity batch: setBlendMode("none") on WebGL; enableScissor/ setBlendEnabled/clearRenderTarget, settings.batcher, settings.blendMode, GPUVendor, failIfMajorPerformanceCaveat on WebGPU; frameless-video guard on WebGL; instance-scoped compressed-format memo - shine adopts the uUVYDir seam (vertical sweeps ran backwards on the GL pooled path); GLTFScene flags meshes lit for lamp-only scenes - shared neutral hoists: gpu/meshvertex.ts, gpu/quadcorners.ts, gpu/primitives.ts (~250 duplicated lines deleted) - d.ts hygiene: @internal + a strip-internal build pass keep renderer internals out of the published typings - examples swept to video.AUTO; 3D examples guard on supportsDepthBuffer - documentation refresh across JSDoc and README (retained-mesh story, capability flags, dual-language shaders, glTF light options) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
On the WebGPU backend, skeletons now render through the new
WebGPUSpineBatcher instead of the canvas-renderer fallback: spine-core's
backend-neutral SkeletonRendererCore geometry pass (world vertices,
clipping, draw-order batching, packed light+dark colors) feeds a WGSL
port of the official two-colored-textured shader, one indexed draw per
texture/blend batch — the same rendering model as the WebGL path.
- dark-tint (two-color) rendering now works on WebGPU; mesh-heavy
skeletons go from one drawImage per triangle to batched indexed draws
- atlas pages stay image-backed and upload through the engine texture
store honoring each page's pma flag
- backend dispatch keys on renderer.type ("WebGL2"/"WebGPU"/canvas
fallback) instead of the deprecated WebGLVersion sniff
- SpineBatcher renamed WebGLSpineBatcher for symmetry (internal class)
- bundled spine runtimes bumped ^4.3.7 -> ^4.3.13 (SkeletonRendererCore
clipping fixes); debug rendering remains WebGL-only for now
All 18 example skeletons verified headed on WebGPU, WebGL and Canvas.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
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.
Completes the WebGPU renderer (#1184): the full 3D tier, the remaining backend-parity surface, point/spot 3D lights (#1536), custom mesh shaders on both GPU backends, and a WebGPU spine batcher with full two-color tinting. With this,
video.AUTOdefaults to WebGPU → WebGL 2 → Canvas and every engine feature renders identically on both GPU backends (all 44 examples verified side-by-side, headed).Engine (
packages/melonjs)3D tier on WebGPU
drawMeshthrough unlit/lit WGSL mesh pipelines: retained model-space geometry underCamera3d(upload once; placement/tint/alpha-cutoff/emissive ride one per-draw uniform snapshot) plus the CPU-projected 2D-camera path; per-mesh cull/winding as pipeline state;supportsDepthBuffer/supportsRetainedMeshnowtrueSprite3dbillboards and split-screenCamera3dviewports run unchanged on topLighting (#1536)
Light3dgains"point"and"spot"on both backends: 12-float std140 light entries, quadratic-over-rangefalloff (theLight2dmodel — deliberately not physical inverse-square), smooth-edged cones, runtime-mutable fieldsLight3d(getChildByName("Sun")), and gains alightIntensityScaleload option; lamp-only scenes now correctly flag their mesheslitCustom mesh shaders
GLShaderis now dual-language:new GLShader(renderer.gl, { vertex, fragment, wgsl })withisWebGL/isWebGPUflags;mesh.shaderhosts it on either backend, warn-and-degrade on mismatch (WGSL validation is async and contained — a bad module can never poison frame submission){ type: "shader", src: { vertex, fragment, wgsl } }Completion + parity batch
antiAlias: true→ 4× MSAA on WebGPU canvas passes; mesh textures gain generated mip chains + trilinear + 4× anisotropy on both backends (authored compressed chains included;"nearest"opts out); 8-slot multi-texture quad batchingsetBlendMode("none")and the frameless-video upload guard; WebGPU gainsenableScissor/setBlendEnabled/clearRenderTarget,settings.batcher, startupsettings.blendMode,GPUVendor,failIfMajorPerformanceCaveat(rejects software adapters)ShineEffectadopts theuUVYDirseam (vertical sweeps ran backwards on the GL pooled path — same family as the DropShadow fix)gpu/meshvertex.ts,gpu/quadcorners.ts,gpu/primitives.ts) delete ~250 duplicated lines across backends@internal-tagged and stripped from the emitted.d.tsby a new build passDocs
Spine plugin (
packages/spine-plugin, 4.0.0)WebGPUSpineBatcher: spine-core's backend-neutral geometry pass feeds a WGSL port of the official two-colored shader — dark-tint now works on WebGPU, and mesh-heavy skeletons batch instead of drawing per-trianglerenderer.type;SpineBatcher→WebGLSpineBatcher(internal rename); spine runtimes^4.3.7→^4.3.13Examples
video.AUTO; the 3D examples guard onsupportsDepthBuffer; reworked Hello WebGPUVerification
🤖 Generated with Claude Code
https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi