Commit 96c4d9a
feat(shader): screen_texture / screen_uv / noise_uv builtins + {vertex, fragment} shader assets (+ Water Overworld example) (#1548)
* feat(shader): Godot-style builtins — screen_texture / screen_uv / noise_uv
Inside a ShaderEffect fragment body (design contributed by the melonJS
editor team, mirroring Godot's hint_screen_texture / SCREEN_UV):
- `uniform sampler2D name : screen_texture;` — annotation parsed and
stripped; the sampler is auto-wired to the renderer's shared
toFrameTexture capture (live GPU-resident entry) and the engine
refreshes the capture right before the effect draws: in drawImage's
customShader block (scene behind the sprite) and in endPostEffect
(camera FBO = the scene for camera chains, parent target for
renderable chains). True BackBufferCopy semantics on every path.
Optional `(repeat)` wrap honored under WebGL 2 (captures are NPOT).
- `screen_uv` — free varying, clip→0..1 screen position, computed in a
deterministically-templated vertex variant (user source never regex-
rewritten).
- `noise_uv` — free varying, frame-local 0..1 across the drawn object
(undoes atlas packing, scaled to object pixels); fed per draw through
the new @ignore ShaderEffect._setNoiseUVRect from the quad batchers'
single-texture path and both blitTextures.
Back-compat: annotation was never valid GLSL; varyings activate only
when referenced and never when the body declares them itself; a body
using no builtins compiles byte-identical to before. New renderer
helper getSharedFrameTexture() gives the shared capture slot a stable
identity from effect-construction time.
8 new tests (shadereffect-builtins.spec.js): parse/wiring/introspection,
true screen sampling + orientation via two-tone backdrop + swizzle
readback, frame-local noise_uv on an atlas sub-frame (both axes),
no-capture-without-annotation (spy), clone, self-declared back-compat.
Full suite 4810 passed | 15 skipped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* feat(examples): Water Overworld — the editor team's demo scene, ported 1:1
Side-scroller overworld (GandalfHardcore free 32x32 pack) with the
water-refraction shader from the contributed build, verbatim: two
cellular NoiseTexture2d flow maps + screenTex : screen_texture +
screen_uv mirror + noise_uv flow — the canonical showcase of the new
shader builtins. TMX level, atlas strip-sliced animated props
(campfire, portal, cooking area), drifting clouds, playable character
(A/D walk, W jump, Shift run — their controller plugin replaced by
~25 lines of plain melonJS input/body code with the same tuning).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* fix(examples): waterOverworld parity with the reference build
- water sprite uses the two regions verbatim (their settings semantics)
instead of getAnimationSettings, whose bottom-align trim mis-placed
the frame and bled the adjacent cloud5 atlas pixels (the white
artifact on the left edge); the 2dWater art carries its own
transparent sky band, matching the original placement
- clouds drift right and respawn off the left edge (ported from the
demo's update user-code: speed 1+random, wrap at x 1040)
- handle video.init() returning false (CodeRabbit finding), alongside
the existing thrown-error path
Verified side-by-side against the zip's build served statically —
scene, water surface line, reflection and drift now match; CodeRabbit
re-review clean (0 findings).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* feat(examples): waterOverworld — debug panel + arrow-key controls
- register @melonjs/debug-plugin (press "S" to toggle), like the other
examples and the original demo build
- arrow keys as movement aliases: ←/→ walk, ↑ jump (alongside A/D/W)
- controls hint updated
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* test(shader): cover both endPostEffect screen-capture paths
The camera chain (capture from the still-bound camera FBO = the scene,
orientation preserved, exactly one toFrameTexture call) and the
multi-effect renderable chain (capture = the parent target behind the
object, not the object's own rendering) were the only untested branches
of the builtins feature — the example and prior tests only exercised
the sprite/customShader path. 10 tests total now.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* feat(loader): {vertex, fragment} shader-asset pairs compile into raw GLShaders
A shader asset can now be a complete program pair — src: {vertex,
fragment} URLs (fetched in parallel) or inline via data: — compiled at
load time into a shared raw GLShader, returned by the same
loader.getShader(). This is the honest type for full programs (Mesh
custom shaders, renderer.customShader, custom batchers) and sidesteps
ShaderEffect's apply() wrapping entirely: no source rewriting, no
builtins injection — the user owns both stages. Same shared/clone/
unload lifecycle as fragment-body assets; WebGL-only (a pair loads as
null under Canvas, with a warning — no canvas analog for a raw
program; unload guards the null entry).
6 adversarial tests (shader-loader.spec.js), mutation-verified: drop
shared flag / swap vertex-fragment stages / remove the already-loaded
guard each kill exactly their matching test. Full suite 4818 | 15
skipped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* docs(changelog): note the {vertex, fragment} shader-asset pair form
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
* docs: drop third-party engine references from comments, docs, changelog
The builtins stand on their own names — comparisons to other engines'
equivalents removed from JSDoc, module comments, spec headers, the
example, and the 19.9.0 changelog entries (generic "back-buffer copy"
terminology kept where technically descriptive).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019t8kP8vp58ZrvaD2FqJU6A
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 69b578a commit 96c4d9a
19 files changed
Lines changed: 3058 additions & 31 deletions
File tree
- packages
- examples
- public/assets/waterOverworld
- image
- json
- level
- tileset
- src
- examples/waterOverworld
- melonjs
- src
- loader
- parsers
- video/webgl
- batchers
- tests
Lines changed: 165 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
0 commit comments