melonjs 20.7.0 → 20.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/README.md +6 -3
  2. package/build/application/defaultApplicationSettings.d.ts +5 -0
  3. package/build/application/defaultApplicationSettings.d.ts.map +1 -1
  4. package/build/application/header.d.ts.map +1 -1
  5. package/build/application/settings.d.ts +88 -0
  6. package/build/application/settings.d.ts.map +1 -1
  7. package/build/audio/backend/engine.d.ts +0 -1
  8. package/build/audio/backend/sound.d.ts +0 -1
  9. package/build/camera/camera2d.d.ts.map +1 -1
  10. package/build/camera/camera3d.d.ts +95 -8
  11. package/build/camera/camera3d.d.ts.map +1 -1
  12. package/build/geometries/box3d.d.ts +24 -6
  13. package/build/geometries/box3d.d.ts.map +1 -1
  14. package/build/geometries/ellipse.d.ts +14 -0
  15. package/build/geometries/ellipse.d.ts.map +1 -1
  16. package/build/geometries/polygon.d.ts +14 -0
  17. package/build/geometries/polygon.d.ts.map +1 -1
  18. package/build/geometries/sphere.d.ts +35 -6
  19. package/build/geometries/sphere.d.ts.map +1 -1
  20. package/build/index.d.ts +9 -2
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +2770 -538
  23. package/build/index.js.map +4 -4
  24. package/build/input/pointerevent.d.ts +8 -0
  25. package/build/input/pointerevent.d.ts.map +1 -1
  26. package/build/level/gltf/GLTFModel.d.ts +17 -31
  27. package/build/level/gltf/GLTFModel.d.ts.map +1 -1
  28. package/build/level/gltf/GLTFScene.d.ts +40 -1
  29. package/build/level/gltf/GLTFScene.d.ts.map +1 -1
  30. package/build/level/level.d.ts +35 -0
  31. package/build/level/level.d.ts.map +1 -1
  32. package/build/level/tiled/TMXLayer.d.ts +5 -2
  33. package/build/level/tiled/TMXLayer.d.ts.map +1 -1
  34. package/build/level/tiled/TMXObject.d.ts +0 -1
  35. package/build/level/tiled/TMXTile.d.ts +2 -1
  36. package/build/level/tiled/TMXTile.d.ts.map +1 -1
  37. package/build/level/tiled/TMXTileMap.d.ts +7 -4
  38. package/build/level/tiled/TMXTileMap.d.ts.map +1 -1
  39. package/build/level/tiled/TMXTileset.d.ts +1 -1
  40. package/build/level/tiled/TMXTileset.d.ts.map +1 -1
  41. package/build/level/tiled/TMXTilesetGroup.d.ts +5 -0
  42. package/build/level/tiled/TMXTilesetGroup.d.ts.map +1 -1
  43. package/build/level/tiled/factories/shape.d.ts +0 -1
  44. package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts +6 -5
  45. package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts.map +1 -1
  46. package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts +5 -0
  47. package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts.map +1 -1
  48. package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts +8 -7
  49. package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts.map +1 -1
  50. package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts +5 -0
  51. package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts.map +1 -1
  52. package/build/level/tiled/renderer/TMXRenderer.d.ts +19 -4
  53. package/build/level/tiled/renderer/TMXRenderer.d.ts.map +1 -1
  54. package/build/level/tiled/renderer/autodetect.d.ts +0 -4
  55. package/build/level/tiled/renderer/autodetect.d.ts.map +1 -1
  56. package/build/loader/loader.d.ts +9 -0
  57. package/build/loader/loader.d.ts.map +1 -1
  58. package/build/loader/loadingscreen.d.ts +1 -2
  59. package/build/loader/loadingscreen.d.ts.map +1 -1
  60. package/build/loader/parsers/shader.d.ts +0 -2
  61. package/build/math/color.d.ts +27 -4
  62. package/build/math/color.d.ts.map +1 -1
  63. package/build/particles/emitter.d.ts.map +1 -1
  64. package/build/particles/particle.d.ts +22 -1
  65. package/build/particles/particle.d.ts.map +1 -1
  66. package/build/particles/settings.d.ts +69 -0
  67. package/build/particles/settings.d.ts.map +1 -1
  68. package/build/physics/adapter.d.ts +9 -1
  69. package/build/physics/adapter.d.ts.map +1 -1
  70. package/build/physics/builtin/body.d.ts +3 -2
  71. package/build/physics/builtin/body.d.ts.map +1 -1
  72. package/build/physics/builtin/builtin-adapter.d.ts.map +1 -1
  73. package/build/physics/builtin/detector.d.ts +0 -1
  74. package/build/physics/builtin/detector.d.ts.map +1 -1
  75. package/build/physics/builtin/sat.d.ts +0 -7
  76. package/build/physics/builtin/sat3d.d.ts +46 -0
  77. package/build/physics/builtin/sat3d.d.ts.map +1 -1
  78. package/build/physics/response.d.ts +45 -62
  79. package/build/physics/response.d.ts.map +1 -1
  80. package/build/renderable/collectable.d.ts +6 -1
  81. package/build/renderable/collectable.d.ts.map +1 -1
  82. package/build/renderable/colorlayer.d.ts +4 -4
  83. package/build/renderable/colorlayer.d.ts.map +1 -1
  84. package/build/renderable/container.d.ts +23 -17
  85. package/build/renderable/container.d.ts.map +1 -1
  86. package/build/renderable/entity/entity.d.ts +12 -16
  87. package/build/renderable/entity/entity.d.ts.map +1 -1
  88. package/build/renderable/frameAnimation.d.ts +1 -1
  89. package/build/renderable/groundshadow.d.ts +1 -0
  90. package/build/renderable/groundshadow.d.ts.map +1 -1
  91. package/build/renderable/imagelayer.d.ts +12 -5
  92. package/build/renderable/imagelayer.d.ts.map +1 -1
  93. package/build/renderable/instanced_mesh.d.ts +2 -9
  94. package/build/renderable/instanced_mesh.d.ts.map +1 -1
  95. package/build/renderable/mesh.d.ts +283 -4
  96. package/build/renderable/mesh.d.ts.map +1 -1
  97. package/build/renderable/nineslicesprite.d.ts +3 -13
  98. package/build/renderable/nineslicesprite.d.ts.map +1 -1
  99. package/build/renderable/renderable.d.ts +90 -27
  100. package/build/renderable/renderable.d.ts.map +1 -1
  101. package/build/renderable/sprite.d.ts +5 -19
  102. package/build/renderable/sprite.d.ts.map +1 -1
  103. package/build/renderable/sprite3d.d.ts +27 -16
  104. package/build/renderable/sprite3d.d.ts.map +1 -1
  105. package/build/renderable/text/bitmaptext.d.ts +13 -3
  106. package/build/renderable/text/bitmaptext.d.ts.map +1 -1
  107. package/build/renderable/text/bitmaptextdata.d.ts +0 -4
  108. package/build/renderable/text/bitmaptextdata.d.ts.map +1 -1
  109. package/build/renderable/text/text.d.ts +5 -3
  110. package/build/renderable/text/text.d.ts.map +1 -1
  111. package/build/renderable/text/textmetrics.d.ts +2 -0
  112. package/build/renderable/text/textmetrics.d.ts.map +1 -1
  113. package/build/renderable/trail.d.ts +0 -1
  114. package/build/renderable/trail.d.ts.map +1 -1
  115. package/build/renderable/trigger.d.ts +27 -5
  116. package/build/renderable/trigger.d.ts.map +1 -1
  117. package/build/renderable/ui/progressbar.d.ts +194 -0
  118. package/build/renderable/ui/progressbar.d.ts.map +1 -0
  119. package/build/renderable/ui/uibaseelement.d.ts +48 -3
  120. package/build/renderable/ui/uibaseelement.d.ts.map +1 -1
  121. package/build/renderable/ui/uispriteelement.d.ts +19 -3
  122. package/build/renderable/ui/uispriteelement.d.ts.map +1 -1
  123. package/build/system/legacy_pool.d.ts +2 -2
  124. package/build/system/legacy_pool.d.ts.map +1 -1
  125. package/build/system/pool.d.ts +10 -0
  126. package/build/system/pool.d.ts.map +1 -1
  127. package/build/tweens/tween.d.ts +49 -2
  128. package/build/tweens/tween.d.ts.map +1 -1
  129. package/build/video/canvas/canvas_renderer.d.ts +34 -23
  130. package/build/video/canvas/canvas_renderer.d.ts.map +1 -1
  131. package/build/video/effects/blendEffect.d.ts +0 -1
  132. package/build/video/effects/bloom.d.ts +72 -0
  133. package/build/video/effects/bloom.d.ts.map +1 -0
  134. package/build/video/effects/blur.d.ts +3 -2
  135. package/build/video/effects/blur.d.ts.map +1 -1
  136. package/build/video/effects/chromaticAberration.d.ts +3 -2
  137. package/build/video/effects/chromaticAberration.d.ts.map +1 -1
  138. package/build/video/effects/colorMatrix.d.ts +3 -2
  139. package/build/video/effects/colorMatrix.d.ts.map +1 -1
  140. package/build/video/effects/desaturate.d.ts +10 -2
  141. package/build/video/effects/desaturate.d.ts.map +1 -1
  142. package/build/video/effects/dissolve.d.ts +3 -2
  143. package/build/video/effects/dissolve.d.ts.map +1 -1
  144. package/build/video/effects/dropShadow.d.ts +3 -2
  145. package/build/video/effects/dropShadow.d.ts.map +1 -1
  146. package/build/video/effects/flash.d.ts +3 -2
  147. package/build/video/effects/flash.d.ts.map +1 -1
  148. package/build/video/effects/glow.d.ts +3 -2
  149. package/build/video/effects/glow.d.ts.map +1 -1
  150. package/build/video/effects/hologram.d.ts +3 -2
  151. package/build/video/effects/hologram.d.ts.map +1 -1
  152. package/build/video/effects/invert.d.ts +10 -2
  153. package/build/video/effects/invert.d.ts.map +1 -1
  154. package/build/video/effects/outline.d.ts +3 -2
  155. package/build/video/effects/outline.d.ts.map +1 -1
  156. package/build/video/effects/pixelate.d.ts +3 -2
  157. package/build/video/effects/pixelate.d.ts.map +1 -1
  158. package/build/video/effects/radialGradient.d.ts +8 -3
  159. package/build/video/effects/radialGradient.d.ts.map +1 -1
  160. package/build/video/effects/scanline.d.ts +3 -2
  161. package/build/video/effects/scanline.d.ts.map +1 -1
  162. package/build/video/effects/sepia.d.ts +10 -2
  163. package/build/video/effects/sepia.d.ts.map +1 -1
  164. package/build/video/effects/shadereffect.d.ts +10 -4
  165. package/build/video/effects/shadereffect.d.ts.map +1 -1
  166. package/build/video/effects/shine.d.ts +3 -2
  167. package/build/video/effects/shine.d.ts.map +1 -1
  168. package/build/video/effects/tintPulse.d.ts +3 -2
  169. package/build/video/effects/tintPulse.d.ts.map +1 -1
  170. package/build/video/effects/tonemap.d.ts +121 -0
  171. package/build/video/effects/tonemap.d.ts.map +1 -0
  172. package/build/video/effects/vignette.d.ts +3 -2
  173. package/build/video/effects/vignette.d.ts.map +1 -1
  174. package/build/video/effects/wave.d.ts +3 -2
  175. package/build/video/effects/wave.d.ts.map +1 -1
  176. package/build/video/gpu/vertexformat.d.ts +26 -0
  177. package/build/video/gpu/vertexformat.d.ts.map +1 -1
  178. package/build/video/gradient.d.ts +0 -1
  179. package/build/video/gradient.d.ts.map +1 -1
  180. package/build/video/renderer.d.ts +111 -7
  181. package/build/video/renderer.d.ts.map +1 -1
  182. package/build/video/renderstate.d.ts +2 -0
  183. package/build/video/renderstate.d.ts.map +1 -1
  184. package/build/video/rendertarget/canvasrendertarget.d.ts +3 -4
  185. package/build/video/rendertarget/canvasrendertarget.d.ts.map +1 -1
  186. package/build/video/rendertarget/render_target_pool.d.ts +0 -1
  187. package/build/video/rendertarget/webglrendertarget.d.ts +0 -1
  188. package/build/video/rendertarget/webglrendertarget.d.ts.map +1 -1
  189. package/build/video/rendertarget/webgpurendertarget.d.ts +18 -2
  190. package/build/video/rendertarget/webgpurendertarget.d.ts.map +1 -1
  191. package/build/video/texture/atlas.d.ts +1 -0
  192. package/build/video/texture/atlas.d.ts.map +1 -1
  193. package/build/video/texture/cache.d.ts +1 -3
  194. package/build/video/texture/frametexture.d.ts +0 -1
  195. package/build/video/texture/frametexture.d.ts.map +1 -1
  196. package/build/video/texture/noise_texture2d.d.ts +1 -0
  197. package/build/video/texture/noise_texture2d.d.ts.map +1 -1
  198. package/build/video/utils/autodetect.d.ts +0 -2
  199. package/build/video/webgl/batchers/batcher.d.ts +0 -9
  200. package/build/video/webgl/batchers/batcher.d.ts.map +1 -1
  201. package/build/video/webgl/batchers/lit_quad_batcher.d.ts +11 -0
  202. package/build/video/webgl/batchers/lit_quad_batcher.d.ts.map +1 -1
  203. package/build/video/webgl/batchers/material_batcher.d.ts +4 -2
  204. package/build/video/webgl/batchers/material_batcher.d.ts.map +1 -1
  205. package/build/video/webgl/batchers/mesh_batcher.d.ts +0 -3
  206. package/build/video/webgl/batchers/mesh_batcher.d.ts.map +1 -1
  207. package/build/video/webgl/batchers/quad_batcher.d.ts +4 -0
  208. package/build/video/webgl/batchers/quad_batcher.d.ts.map +1 -1
  209. package/build/video/webgl/buffer/index.d.ts +0 -1
  210. package/build/video/webgl/buffer/retained_geometry.d.ts +0 -1
  211. package/build/video/webgl/glshader.d.ts +5 -3
  212. package/build/video/webgl/glshader.d.ts.map +1 -1
  213. package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts +0 -4
  214. package/build/video/webgl/texture/store.d.ts +0 -1
  215. package/build/video/webgl/webgl_renderer.d.ts +63 -24
  216. package/build/video/webgl/webgl_renderer.d.ts.map +1 -1
  217. package/build/video/webgpu/batchers/mesh_batcher.d.ts +0 -3
  218. package/build/video/webgpu/batchers/mesh_batcher.d.ts.map +1 -1
  219. package/build/video/webgpu/batchers/quad_batcher.d.ts +0 -2
  220. package/build/video/webgpu/batchers/quad_batcher.d.ts.map +1 -1
  221. package/build/video/webgpu/batchers/webgpu_batcher.d.ts +0 -2
  222. package/build/video/webgpu/batchers/webgpu_batcher.d.ts.map +1 -1
  223. package/build/video/webgpu/pipeline/cache.d.ts.map +1 -1
  224. package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts +0 -2
  225. package/build/video/webgpu/texture/frametexture.d.ts +0 -2
  226. package/build/video/webgpu/texture/frametexture.d.ts.map +1 -1
  227. package/build/video/webgpu/texture/store.d.ts +0 -1
  228. package/build/video/webgpu/webgpu_renderer.d.ts +7 -75
  229. package/build/video/webgpu/webgpu_renderer.d.ts.map +1 -1
  230. package/package.json +1 -1
  231. package/skills/melonjs-3d/SKILL.md +277 -19
  232. package/skills/melonjs-3d-assets/SKILL.md +76 -9
  233. package/skills/melonjs-camera-and-drawing/SKILL.md +57 -1
  234. package/skills/melonjs-effects-and-shaders/SKILL.md +341 -29
  235. package/skills/melonjs-input/SKILL.md +48 -4
  236. package/skills/melonjs-particles-and-trails/SKILL.md +106 -4
  237. package/skills/melonjs-performance/SKILL.md +79 -2
  238. package/skills/melonjs-physics/SKILL.md +101 -27
  239. package/skills/melonjs-renderables/SKILL.md +2 -1
  240. package/skills/melonjs-scenes-and-state/SKILL.md +121 -1
  241. package/skills/melonjs-ui-and-text/SKILL.md +165 -4
  242. package/build/level/gltf/srgb.d.ts +0 -20
  243. package/build/level/gltf/srgb.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu_renderer.d.ts","sourceRoot":"","sources":["../../../src/video/webgpu/webgpu_renderer.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webgpu_renderer.d.ts","sourceRoot":"","sources":["../../../src/video/webgpu/webgpu_renderer.js"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "melonjs",
3
- "version": "20.7.0",
3
+ "version": "20.8.0",
4
4
  "description": "melonJS Game Engine",
5
5
  "homepage": "http://www.melonjs.org/",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: melonjs-3d
3
- description: "Use this skill for anything 3D or 2.5D in melonJS — Camera3d, Mesh, InstancedMesh, Sprite3d billboards, Light3d, ground shadows, glTF/GLB scenes, and depth sorting. Covers the Y-down/+Z-forward convention that is the inverse of OpenGL, the cameraClass opt-in, clip planes, and what does not work on the Canvas fallback. Triggers on: Camera3d, Mesh, InstancedMesh, Sprite3d, Light3d, billboard, glTF, glb, 3D, 2.5D, depth, cameraClass, fov, setClipPlanes, setFog, fog, distance fog, height fog, heightFalloff, transparent, transparency, alpha, blendMode, fade, castGroundShadow, lit."
3
+ description: "Use this skill for anything 3D or 2.5D in melonJS — Camera3d, Mesh, InstancedMesh, Sprite3d billboards, Light3d, ground shadows, glTF/GLB scenes, and depth sorting. Covers the Y-down/+Z-forward convention that is the inverse of OpenGL, the cameraClass opt-in, clip planes, and what does not work on the Canvas fallback. Triggers on: Camera3d, Mesh, InstancedMesh, Sprite3d, Light3d, billboard, glTF, glb, 3D, 2.5D, depth, cameraClass, fov, setClipPlanes, setFog, fog, distance fog, height fog, heightFalloff, transparent, transparency, alpha, blendMode, fade, castGroundShadow, lit, setBasis, getBasis, lookAt, up vector, gimbal."
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -20,11 +20,15 @@ This is the single most important thing on this page.
20
20
  | vertical | **Y-down** — higher `y` is *lower* on screen | Y-up |
21
21
  | depth | **+Z forward** — higher `z` is *farther* away | −Z forward |
22
22
 
23
- Rotations are extrinsic XYZ, and `Camera3d` exposes all three: `camera.pitch`
23
+ `Camera3d` exposes three rotation angles: `camera.pitch`
24
24
  (X, look up/down), `camera.yaw` (Y, look left/right) and `camera.roll` (Z, bank
25
25
  the horizon). The view is `R(yaw) ∘ R(pitch) ∘ R(roll)` inverted, and the frustum
26
26
  planes come off that same matrix — so culling follows a banked view.
27
27
 
28
+ The basis those angles produce is **readable and writable**: `getBasis(right,
29
+ up, forward)` reads it, `setBasis(right, up, forward)` poses the camera from
30
+ one.
31
+
28
32
  `camera.rotate()` is NOT the way to bank a 3D camera. It writes the inherited
29
33
  `currentTransform`, which a 3D view never reads, so the call is silently inert.
30
34
  Set `roll`. (On a `Camera2d` it is the other way round: roll IS that transform's
@@ -89,11 +93,72 @@ class GameStage extends Stage {
89
93
  `camera.setClipPlanes(near, far)`.
90
94
  - **`camera.pos.set(x, y)` is 2-argument and zeroes z.** Use `camera.depth` —
91
95
  the documented z accessor — or assign `pos.x`/`pos.y` individually.
96
+ - **`lookAt(target)` solves pitch and yaw only**, so on its own it cannot
97
+ express "up is this direction" and it leaves `roll` alone. Pass an up to
98
+ bank the horizon too: `camera.lookAt(target, up)`, where `up` is what should
99
+ appear UP ON SCREEN. This engine renders Y-down, so a level horizon is
100
+ `(0, -1, 0)`. There is deliberately no default, because giving one would
101
+ silently level every camera that had banked its own horizon.
102
+ - **When the game already has all three axes, hand them over**:
103
+ `camera.setBasis(right, up, forward)`, the writable counterpart of
104
+ `getBasis`. The case that needs it is a view over a curved surface, where up
105
+ is the surface normal and differs at every point, so no pitch and yaw pair
106
+ expresses it and integrating towards one drifts and gimbals at the poles.
107
+ `setBasis` absorbs a triple that has drifted off orthonormal rather than
108
+ leaving the camera holding something that is not a rotation, and it does not
109
+ care what the axes are scaled to: a direction is a direction, so anything
110
+ from a denormal to 1e300 resolves the same way. Note its `up` is the camera's
111
+ local +Y column, which under Y-down points DOWN the screen: the opposite
112
+ sense to `lookAt`'s, and one negation apart.
92
113
  - **`worldToLocal` does not project.** It is a 2D camera's offset subtraction.
93
114
  To pin a label or marker to a point in the scene use
94
115
  `camera.worldToScreen(x, y, z)`, which applies the projection and returns
95
116
  `null` behind the camera. See `melonjs-camera-and-drawing`.
96
117
 
118
+ ## Where an up vector earns its keep
119
+
120
+ Three cases. In the first two, `lookAt(target)` on its own is already right and
121
+ an up would be noise. The third is the one it exists for.
122
+
123
+ ```js
124
+ // 1. ordinary third-person: world up never changes, so say nothing
125
+ camera.setPosition(x, y, z).lookAt(player);
126
+
127
+ // 2. a deliberate dutch angle: this is a ROLL, not an up vector
128
+ camera.lookAt(player);
129
+ camera.roll = Math.PI / 32;
130
+
131
+ // 3. a view over a curved surface: up is the surface normal, and it is
132
+ // different at every point on the globe. No pitch and yaw pair expresses
133
+ // it, and integrating towards it drifts and gimbals over the poles.
134
+ const up = player.pos.clone().sub(planetCentre).normalize(); // surface normal
135
+ camera.setPosition(eye.x, eye.y, eye.z).lookAt(player, up.negate());
136
+ ```
137
+
138
+ Note the `negate()` in case 3. The surface normal points away from the planet,
139
+ which is the direction the player's head points, and `up` wants what should
140
+ appear UP ON SCREEN. This engine renders Y-down, so `(0, -1, 0)` is a level
141
+ horizon and a world-space "up" direction has to be handed over in that sense.
142
+ Get it backwards and the view is upside down, which is the single most likely
143
+ mistake with this argument.
144
+
145
+ If the game already computes all three axes, skip the solve entirely:
146
+
147
+ ```js
148
+ // a surface frame the game is already maintaining
149
+ camera.setBasis(right, up, forward);
150
+ ```
151
+
152
+ `setBasis` takes the camera's OWN columns, where `up` is local +Y and so points
153
+ down the screen: the opposite sense to `lookAt`'s, one negation apart. It also
154
+ absorbs a frame that has drifted off orthonormal, which one integrated over
155
+ thousands of steps will have.
156
+
157
+ **A camera posed this way and a world rotated into a fixed camera's frame are
158
+ the same picture.** If a game already transforms its world into view space by
159
+ hand, there is nothing to gain by switching; the value of `setBasis` is not
160
+ having to write that transform in the first place.
161
+
97
162
  ## Depth sorting
98
163
 
99
164
  Under `Camera3d` the world sorts on `"depth"` **every frame** (recursively), so
@@ -153,6 +218,40 @@ geometry with an opaque one would drag the opaque half into the transparent pass
153
218
 
154
219
  **`transparent: false`** pins a mesh to the opaque pass however it is faded.
155
220
 
221
+ ### `depthTest: false` for something with no surface to be occluded on
222
+
223
+ `transparent` decides the PASS, and the transparent pass turns depth *writing*
224
+ off on its own so overlapping blended draws blend instead of fighting. Whether
225
+ geometry in front of a mesh **hides** it is a separate question, and
226
+ `depthTest` is where you answer it. The default, `true`, is what you want for
227
+ anything genuinely in the scene — a muzzle flash behind a wall should still be
228
+ behind the wall, and this is not a synonym for "additive".
229
+
230
+ Set it `false` for a mesh standing in for a screen-space effect: an additive
231
+ glow carrying a world position only so it can sort and move with the thing it
232
+ belongs to. A world-space caption billboarded over a prop wants it for the
233
+ same reason, since it has no surface for the prop's own foliage to be in front
234
+ of. Left depth tested, a flat billboard is sliced along a hard straight
235
+ line the moment any geometry is nearer at some pixel. That shows up worst
236
+ around something round — a glow on a rock near a planet's limb gets cut,
237
+ and no offset escapes it, because the near surface bulges further toward the
238
+ camera than any offset you would dare apply.
239
+
240
+ ```js
241
+ const halo = new Sprite3d(0, 0, {
242
+ image: glowTexture,
243
+ width: rock.radius * 3, height: rock.radius * 3,
244
+ billboard: "spherical",
245
+ blendMode: "additive",
246
+ transparent: true, // the blended pass
247
+ alphaCutoff: 0, // do not cut the soft falloff
248
+ depthTest: false, // and do not let the world slice it
249
+ });
250
+ ```
251
+
252
+ Honoured in the transparent pass on both GPU backends; the Canvas renderer has
253
+ no depth buffer and ignores it.
254
+
156
255
  Blending uses the renderable's existing `blendMode`, so a glow is one property.
157
256
  The advanced modes (`"overlay"`, `"difference"`, and the rest that need a
158
257
  compositing pass) fall back to `"normal"` here, on both backends:
@@ -233,10 +332,14 @@ mesh shaders, so a screen-space overlay stays clean with no work.
233
332
  **A custom mesh shader is not fogged unless it asks to be.** Fog is compiled
234
333
  into the engine's own mesh programs — `#define FOG` on WebGL, an `enable_fog`
235
334
  overridable constant on WebGPU — and a shader you supply is yours: the engine
236
- binds it as written and never substitutes a fogged variant. So a mesh carrying a
237
- `ShaderEffect` keeps full contrast while the scene around it recedes. It is safe
238
- — nothing throws, and the camera's fog is simply not applied — but it is usually
239
- surprising.
335
+ binds it as written and never substitutes a fogged variant. So a mesh given its
336
+ own `GLShader` keeps full contrast while the scene around it recedes. It is
337
+ safe — nothing throws, and the camera's fog is simply not applied — but it is
338
+ usually surprising.
339
+
340
+ A hosted `ShaderEffect` is the other case and needs nothing: its body is
341
+ spliced into the engine's own mesh program as a colour hook, and fog is applied
342
+ to the hook's result, so such a mesh fogs like any other.
240
343
 
241
344
  To opt in, declare the same uniforms and the engine will feed them, because the
242
345
  fog values are pushed to any mesh program that declares them rather than only to
@@ -475,6 +578,22 @@ Billboarding needs a `Camera3d` drawing the frame; under a 2D camera the quad
475
578
  renders fixed-orientation. **Any other string falls through to the spherical
476
579
  branch**, so a guessed value like `"upright"` silently gives you spherical.
477
580
 
581
+ A billboard takes its **orientation** from the camera, so `rotate()` has no
582
+ effect on one: a card already turned to face the camera has no free rotation
583
+ left to give. Everything that is not an orientation still applies, `scale()`
584
+ and `meshScale` included, so animating the size of a shockwave or a pickup is
585
+ the ordinary call and the cull bounds grow with it:
586
+
587
+ ```js
588
+ const wave = new Sprite3d(x, y, { image: "ring", width: 64, height: 64,
589
+ billboard: "spherical", transparent: true });
590
+ wave.scale(1 + 3 * t); // grows; `scale` accumulates, so drive it
591
+ // from the authored size, not per frame
592
+ ```
593
+
594
+ For an in-plane rotation, a bolt streak or an exhaust, use `billboard: false`
595
+ and orient the quad yourself.
596
+
478
597
  ## Lighting
479
598
 
480
599
  `Light3d` takes **one argument — the options object** (it has no `x, y, z`
@@ -543,23 +662,131 @@ the model needs no tangent attribute, and an unmapped mesh is unaffected. This
543
662
  is the 3D counterpart of the `Sprite` normal maps in the lighting skill; they
544
663
  are separate systems and a `Mesh` uses this one.
545
664
 
665
+ ### What the ground-shadow tier can and cannot do
666
+
667
+ Check this table before claiming a setting is unsupported. Every one of these
668
+ is read **every draw**, so all of them can be animated.
669
+
670
+ | setting | `Mesh` / `Sprite3d` / `GLTFModel` part | `InstancedMesh` |
671
+ |---|---|---|
672
+ | `castGroundShadow` | yes | yes |
673
+ | `shadowGroundY` | yes, the caster's own floor | yes, **one plane** through the SET's origin |
674
+ | `shadowGroundNormal` | yes | yes, one plane for the set |
675
+ | `shadowOpacity` | yes | yes |
676
+ | `shadowScale` | yes | yes |
677
+ | `shadowOffset` | yes | yes, one throw for the set |
678
+ | `shadowStretch` | yes | yes, one stretch for the set |
679
+ | `shadowDirectionX` / `Z` | yes | yes |
680
+ | `shadowLight` | yes | yes |
681
+ | height fade as the caster rises | yes | **no** |
682
+ | a different value per instance | n/a | **no**, and there is no plan for one |
683
+
684
+ The two "no"s are the same limitation seen twice: a set gets ONE shadow plane
685
+ and ONE shared quad, so the instance's own height is dropped and nothing can
686
+ vary between instances. Everything else is one value for the whole set, which
687
+ is what a set means. A scatter over curved ground is therefore one set per flat
688
+ facet, and a flying scatter wanting a height fade has to be per-object meshes.
689
+
690
+ Nothing here is per-object-only. If a claim that a setting "does not work on an
691
+ `InstancedMesh`" is in your head, it is out of date: `shadowOffset` and
692
+ `shadowStretch` both reached the instanced tier in 20.8.
693
+
546
694
  Ground shadows are **on by default** (the `castGroundShadow` application
547
695
  setting), and need a GPU backend and a `Camera3d`. As a blanket default they
548
696
  skip geometry with no vertical extent — a ground plane. Per object,
549
697
  `castGroundShadow: true`/`false` overrides the app setting and is obeyed as
550
- given, safeguard included; `shadowGroundY` names the floor the blob lands on.
698
+ given, safeguard included; `shadowGroundY` names the floor the blob lands on,
699
+ `shadowOpacity` how dark it is and `shadowScale` how big it is.
551
700
 
552
701
  The blob is an ellipse sized to the caster's own footprint and placed at the
553
- caster's x/z — it is **never offset by light direction**. So a tall or narrow
554
- object (a character, a tree, a pickup) shows its shadow clearly, while a wide,
555
- flat-bottomed one resting on the floor covers its own completely from a camera
556
- looking down at it. That is the shadow behaving correctly, not a bug.
702
+ caster's x/z. So a tall or narrow object (a character, a tree, a pickup) shows
703
+ its shadow clearly, while a wide, flat-bottomed one resting on the floor covers
704
+ its own completely from a camera looking down at it. That is the shadow
705
+ behaving correctly, not a bug.
557
706
 
558
707
  **Do not chase it by raising `shadowGroundY`.** Lifting the plane does not slide
559
708
  the blob out from under the object, it floats the blob *up* — and past a few
560
- units it projects over the top of the caster as a dark halo ringing it. If an
561
- object needs a visible shadow, give it a smaller footprint relative to its
562
- height, or accept that a boulder bedded in the ground has none.
709
+ units it projects over the top of the caster as a dark halo ringing it.
710
+
711
+ The simplest fix is a bigger blob, so its edge shows past the object:
712
+
713
+ ```js
714
+ mesh.shadowScale = 1.5; // 1 is the default; 0 hides the shadow
715
+ ```
716
+
717
+ `shadowScale` works everywhere, `InstancedMesh` included. Changing it on a
718
+ set rewrites the shared quad's four corners in place rather than rebuilding
719
+ it, as does a `shadowLight` that moves, so an animated sun costs no
720
+ allocation.
721
+
722
+ Or, for the look of a sun that is not overhead, use the shape controls:
723
+
724
+ ```js
725
+ mesh.shadowOffset = 1.5; // slide it out, in blob radii
726
+ mesh.shadowDirectionX = 1; // the ground direction it is cast along
727
+ mesh.shadowDirectionZ = 0;
728
+ mesh.shadowStretch = 2; // and lengthen it along the same line
729
+ ```
730
+
731
+ `shadowOffset` is measured in multiples of the blob's **own radius**, not in
732
+ world units, so one value serves a boulder and a pebble and every part of a
733
+ glTF model. About `stretch - 1` is what keeps the shadow attached to its
734
+ caster. It is honoured **only when `shadowGroundY` is set**, because the
735
+ blob is a flat quad on one named plane: sliding it across a plane the game has
736
+ not named puts it where there may be no floor. `shadowStretch` is clamped to 3
737
+ and the blob fades as it pulls, so an extreme value degrades to nothing rather
738
+ than to a smear.
739
+
740
+ An `InstancedMesh` honours both, as **one** offset and **one** stretch for the
741
+ whole set, which is all a shared set can carry. Both ride the quad the blobs
742
+ share rather than the matrix that also places them: a stretch in the matrix
743
+ would scale the instance positions too and smear the scatter instead of
744
+ lengthening its blobs. So a scatter can sit next to loose props under the same
745
+ sun without looking lit from somewhere else.
746
+
747
+ `shadowLight` takes the direction from a `Light3d` you name, re-read every
748
+ draw, so a moving sun carries the shadows with it. Nothing is inferred: the
749
+ engine never picks a dominant light, because a scene with several has no
750
+ non-arbitrary answer and one with none has no answer at all.
751
+
752
+ ### A floor that is not level
753
+
754
+ `shadowGroundY` says where the floor is; `shadowGroundNormal` says which way
755
+ it faces:
756
+
757
+ ```js
758
+ prop.shadowGroundY = floorY;
759
+ prop.shadowGroundNormal = [Math.sin(0.35), -Math.cos(0.35), 0]; // a 20 deg slope
760
+ ```
761
+
762
+ World up is `(0, -1, 0)`, because render space is Y-down, and that is the
763
+ default. The blob is **rotated** onto the plane rather than projected, so it
764
+ keeps its size; it still sits directly under the caster, since the normal
765
+ turns it rather than moving it. The tilt is clamped at 75 degrees, past which
766
+ an edge-on blob has nothing left to show. It needs `shadowGroundY`, for the
767
+ same reason the offset does: tilting the bounds fallback has no anchor to turn
768
+ about.
769
+
770
+ On an `InstancedMesh` one plane serves the **whole set**: it passes through
771
+ the set's origin at `shadowGroundY`, faces the normal, and every blob is
772
+ projected onto it whatever height its own instance sits at, exactly as the
773
+ level case puts every blob at one height. A scatter over curved ground is
774
+ therefore one set per flat facet, each with the facet's own plane, not one
775
+ set with an averaged normal.
776
+
777
+ All three compose on a set: the stretch turns the shared quad, the offset
778
+ slides the whole set along the light, and both are carried onto the tilted
779
+ plane rather than applied flat, so a bank's planting lies along its slope
780
+ instead of hovering across it.
781
+
782
+ Give blobs to the plants that stand apart. Dense low ground cover is better
783
+ left without: a thousand blobs each as wide as its own fern sum to a darkened
784
+ hillside, not to a thousand shadows, and ground cover is the ground.
785
+
786
+ These are **art direction, not a projection**. A stretched ellipse is not a
787
+ silhouette and has no contact with terrain, so on ground that is not the plane
788
+ you named it will not lie on it. Direction-correct shadows want a shadow map,
789
+ which this tier does not do.
563
790
 
564
791
  ### Get the sign right: the floor is a GREATER y
565
792
 
@@ -587,10 +814,28 @@ caster's own y and check which one is larger.
587
814
 
588
815
  ## Collision in 3D
589
816
 
590
- Use `Box3d` bodies, not a hand-rolled distance check. `Box3d`-vs-`Box3d` is
591
- the engine's 3D narrowphase and the only contact that pushes back along Z; the
592
- response carries `overlapNZ` / `overlapZ` for the depth axis. See the physics
593
- skill for the contract and the mixed-pair caveat.
817
+ Use a body with a depth shape, not a hand-rolled distance check. Two shapes
818
+ carry depth — `Box3d` and `Sphere` — and any pair of them is resolved in three
819
+ dimensions; the response carries `overlapNZ` / `overlapZ` for the depth axis.
820
+
821
+ Pick by whether the thing turns. `Box3d` is world-axis-aligned and cannot be
822
+ oriented, so it fits walls, floors and crates and misfits anything that
823
+ tumbles. `Sphere` has no orientation at all, which makes it the shape for
824
+ spinning debris, projectiles, and anything spread over a curved surface: on a
825
+ globe each object's own "up" points a different way, so one axis-aligned box
826
+ cannot fit any of them.
827
+
828
+ A hand-rolled check is the usual mistake here and it costs twice — it throws
829
+ away the penetration vector the response already carries, and it is invisible
830
+ to the debug plugin's hitbox overlay, which draws from `body.shapes`. If the
831
+ red boxes never appear, the reason is usually that there is no body to draw.
832
+
833
+ Against a planar shape, either 3D shape degrades to its XY footprint with the
834
+ planar side read as unbounded along Z, so a sphere or box body still collides
835
+ with an ordinary collision layer, just without a depth result. And mind the
836
+ normal: a box pair separates along one world axis, a sphere along the line
837
+ between two centres, so a sphere contact fills the 2D and depth halves of the
838
+ response at the same time. See the physics skill for the full contract.
594
839
 
595
840
  ## glTF / GLB scenes
596
841
 
@@ -599,6 +844,13 @@ Loaded through the same level director as everything else:
599
844
  ```js
600
845
  await loader.preload([{ name: "diorama", type: "glb", src: "data/diorama.glb" }]);
601
846
  level.load("diorama", { scale, castGroundShadow, shadowGroundY, onLoaded });
847
+
848
+ // every ground-shadow setting travels, not just those two: a loaded scene can
849
+ // be told where its sun is, and `shadowLight` is re-read every draw
850
+ level.load("diorama", {
851
+ scale, castGroundShadow: true, shadowGroundY: 0,
852
+ shadowLight: sun, shadowOffset: 0.6, shadowStretch: 1.8, async: true,
853
+ });
602
854
  ```
603
855
 
604
856
  `.obj` / `.mtl` are also supported loader types.
@@ -658,6 +910,7 @@ To branch rather than fail, read `app.renderer.supportsDepthBuffer` after
658
910
  | a `lit` mesh renders fullbright | it had no normals — supply them, or let the engine generate them |
659
911
  | a gradient across one mesh is impossible | `tint` is per object — use `vertexColors` / `setVertexColor` |
660
912
  | a mesh stays solid as you fade it out | meshes render opaque; only `alpha` 0 (hidden) and 1 differ |
913
+ | a glow is cut along a hard straight line, worst near a round object's limb | a flat billboard being depth tested against the geometry behind it — `depthTest: false` |
661
914
  | vertex colour applies under a 2D camera but not `Camera3d` | wrote the array directly without setting `needsUpdate` |
662
915
  | `Mesh: vertexColors has N entries, expected M` | one colour per *vertex*, not per triangle or per index |
663
916
  | nothing renders, or a backdrop covers everything | wrong depth sign — "far" is *larger* z when looking along +Z |
@@ -676,11 +929,16 @@ To branch rather than fail, read `app.renderer.supportsDepthBuffer` after
676
929
  | fog does not match the sky after a background fade | an explicit `color` was passed; omit it to track `renderer.backgroundColor` |
677
930
  | geometry clips before it has finished fading | fog `far` beyond the clip far — omit the distances and they default to the clip planes |
678
931
  | one marker must stay readable in fog | `fog: false` on that mesh |
679
- | an object casts no visible shadow | wide and flat-bottomed — its own blob is underneath it; raising `shadowGroundY` haloes it instead of revealing it |
932
+ | an object casts no visible shadow | wide and flat-bottomed — its own blob is underneath it; raise `shadowScale` (or slide it out with `shadowOffset`), not `shadowGroundY`, which haloes it instead of revealing it |
680
933
  | a dark ring around the top of an object | `shadowGroundY` lifted too far, floating the blob up into the caster |
681
934
  | a mesh sits at the wrong depth after being added | `autoDepth` overwrote `pos.z` with the child index — pass `addChild(mesh, z)` |
682
935
  | a mesh sits half its size off | `anchorPoint` — only on the 2D-camera path; a `Camera3d` mesh pivots on its model origin |
683
936
  | a billboard tips over when the camera looks down | `"spherical"`, or a mistyped mode string falling through to it — use `true` / `"cylindrical"` |
937
+ | `rotate()` does nothing on a billboard | the camera owns its orientation; `billboard: false` and orient the quad yourself |
938
+ | the camera will not tilt its horizon to an arbitrary up | `lookAt(target)` solves pitch and yaw only; pass the up as the next argument, or hand all three axes to `setBasis` |
939
+ | the view is upside down after `lookAt(target, up)` | `up` is the direction that should appear UP ON SCREEN, and this is Y-down, so a level horizon is `(0, -1, 0)` |
940
+ | `setBasis` throws "forward must have a non-zero length" | `forward` is all zeros, the one case that names no direction; a short one is fine, so a surface frame that shrank as it drifted still works |
941
+ | roll is ignored when the target is straight up or down | no rotation about the view axis is determined there, so `lookAt` keeps the roll it had and `setBasis` falls back to the `right` axis |
684
942
  | an object jumps to the camera plane | `Vector3d.set(x, y)` / `camera.pos.set(x, y)` zeroed its z |
685
943
  | lighting looks wrong under a 3D camera | `Light2d` used instead of `Light3d` |
686
944
 
@@ -40,6 +40,13 @@ or it renders flat. See `melonjs-3d` for the camera.
40
40
  | `lightIntensityScale` | — | keep authored intensity ratios instead of normalising every light to 1 |
41
41
  | `castGroundShadow` | inherits the app setting (**on**) | blob shadows for this scene's meshes |
42
42
  | `shadowGroundY` | each object's own base | world Y of the floor the blobs land on |
43
+ | `shadowOpacity` | `0.45` | how dark the blobs are |
44
+ | `shadowScale` | `1` | blob footprint multiplier; `0` or less hides them |
45
+ | `shadowOffset` | `0` | slide them along the light, in blob radii; needs `shadowGroundY` |
46
+ | `shadowStretch` | `1` | lengthen them along it, clamped to 3 |
47
+ | `shadowDirectionX` / `shadowDirectionZ` | `0` | the ground direction they are cast along |
48
+ | `shadowGroundNormal` | world up | up normal of the floor, for a scene that is not level |
49
+ | `shadowLight` | — | a `Light3d` to take the direction from, re-read every draw |
43
50
 
44
51
  `onLoaded` receives the level id — it is a "done" signal, not a handle on the
45
52
  scene. You need it, or `async`: with the game loop running, `level.load` stops
@@ -79,10 +86,11 @@ world.addChild(new Trigger(x, y, {
79
86
  }));
80
87
  ```
81
88
 
82
- `scale`, `rightHanded`, `lights`, `lightIntensityScale`, `castGroundShadow` and
83
- `shadowGroundY` all travel, and so do `container`, `onLoaded`, `flatten` and
84
- `setViewportBounds`. That list is **hardcoded** in `Trigger` — a `level.load`
85
- option outside it is dropped without a warning.
89
+ Every `level.load` option above travels, including the whole ground-shadow set,
90
+ and so do `container`, `onLoaded`, `flatten` and `setViewportBounds`. The list is
91
+ **derived** from `level.loadOptions` rather than restated, so an option added to
92
+ a level format arrives here for free. It used to be hand-written and had fallen
93
+ three releases behind the glTF path (#1649).
86
94
 
87
95
  **`async` is deliberately excluded.** A trigger with a `color` + `duration`
88
96
  sets it itself, because it needs the promise to sequence its fade and reveal; a
@@ -129,6 +137,54 @@ asset fails to load. Export uncompressed.
129
137
  `"auto"`) drives sampling; glTF materials that declare their own sampler carry
130
138
  it through. Pixel-art models want `"nearest"`.
131
139
 
140
+ ### `baseColorFactor` is LINEAR; a `tint` is sRGB
141
+
142
+ The loader handles this for you. It only bites when you build meshes yourself
143
+ from `loader.getGLTF(name).nodes` — which is what you do for per-node control,
144
+ since there is no public per-node `Mesh` factory — and reach for the obvious
145
+ `* 255`:
146
+
147
+ ```js
148
+ // WRONG — every untextured material renders far too dark
149
+ mesh.tint.setColor(f[0] * 255, f[1] * 255, f[2] * 255, 1);
150
+ ```
151
+
152
+ glTF defines `pbrMetallicRoughness.baseColorFactor` in **linear** space (spec
153
+ 3.9.2), while a melonJS `tint` is 8-bit **sRGB** — the same space as a CSS
154
+ colour or a texel out of a PNG. They are not the same number, and the gap is
155
+ widest exactly where art tends to live:
156
+
157
+ | linear | `* 255` | correct |
158
+ |---|---|---|
159
+ | 0.05 | 13 | 63 |
160
+ | 0.20 | 51 | 124 |
161
+ | 0.42 | 107 | 173 |
162
+ | 0.72 | 184 | 221 |
163
+ | 1.00 | 255 | 255 |
164
+
165
+ `Color.setLinear` does the encoding for you — it is the linear-space sibling of
166
+ `setFloat`, which takes the same `0..1` range but treats it as already-sRGB:
167
+
168
+ ```js
169
+ mesh.tint.setLinear(...node.baseColorFactor); // encodes; what you want
170
+ mesh.tint.setFloat(...node.baseColorFactor); // does NOT encode; too dark
171
+ ```
172
+
173
+ It clamps, so the slightly out-of-range factors some exporters emit cannot turn
174
+ into `NaN`, and it keeps the encoded value as a float rather than rounding
175
+ through 8 bits.
176
+
177
+ Measured on a scene whose every material went through `* 255`: mean frame luma
178
+ 85.5 against 147.8 once encoded, with each channel sitting 60 to 73 counts low.
179
+
180
+ **Fix it early.** It is nearly invisible as a bug, because the scene still
181
+ looks coherent — just moody — so lighting and bloom thresholds get tuned
182
+ against the wrong values. Correcting the encoding afterwards blows the frame
183
+ out and forces a lighting retune, which is a much bigger job than the encode.
184
+
185
+ This applies only to factors coming out of glTF. Colours **you** author for the
186
+ screen, a HUD tint or a glow, are already sRGB: `* 255` is right for those.
187
+
132
188
  ## Lights
133
189
 
134
190
  Authored `KHR_lights_punctual` lights — sun, point, spot — become `Light3d`
@@ -223,11 +279,21 @@ Omit `shadowGroundY` and each blob sits at its own object's base at full
223
279
  strength, which is right for props already resting on the ground. Set it when
224
280
  things jump or fly, so the shadow stays on the floor and shrinks with height.
225
281
 
226
- A blob is centred on its caster's x/z and is never offset by light direction, so
227
- a wide flat-bottomed prop hides its own shadow under itself. Raising
228
- `shadowGroundY` to force one into view floats the blob up over the object as a
229
- dark ring rather than sliding it clear — the setting is for things that leave
230
- the ground, not a visibility knob.
282
+ A blob sits on its caster's x/z by default, so a wide flat-bottomed prop hides
283
+ its own shadow under itself. The knob for that is `shadowScale`, which widens
284
+ the blob until its edge shows past the prop, or `shadowOffset` plus a direction,
285
+ which slides it clear. **Not** `shadowGroundY`: raising that floats the blob up
286
+ over the object as a dark ring instead of sliding it out, because it is for
287
+ things that leave the ground, not a visibility control.
288
+
289
+ For a light that is not overhead, name one: `shadowLight` takes the direction
290
+ from a `Light3d` and is re-read every draw, so a day or night cycle carries
291
+ every shadow in the scene with it. Nothing is inferred — a scene with no named
292
+ light and no `shadowDirectionX`/`Z` gets no direction, because a scene with
293
+ several lights has no non-arbitrary answer. `shadowStretch` lengthens the blob
294
+ along that direction and fades it as it pulls; `shadowGroundNormal` lays it on
295
+ a floor that is not level. All of these apply to an `InstancedMesh` too, as one
296
+ value for the whole set.
231
297
 
232
298
  ## OBJ/MTL
233
299
 
@@ -423,6 +489,7 @@ need a prefix.
423
489
  | one part of a rig renders rigid while its curves exist | it was re-parented mid-pose, baking the inverse into `matrix_parent_inverse` |
424
490
  | a merged mesh lights wrong along one axis | it inherited the active object's non-uniform scale on join — apply transforms |
425
491
  | an authored palette comes out uniformly dark, but white is correct | linear values written to a strip that is saved verbatim |
492
+ | every untextured glTF material renders too dark, white unaffected | `baseColorFactor` is linear and a `tint` is sRGB — `tint.setLinear(...)`, not `* 255` or `setFloat` |
426
493
  | `getGLTF(name).nodes[0]` geometry lands in the wrong place | `nodes` is per primitive, each with its own `world`; merge to one primitive and export at the origin |
427
494
  | a prop casts no visible shadow | wide and flat-bottomed — the blob is under it; `shadowGroundY` haloes it rather than revealing it |
428
495
  | shadows only show on casters near the camera | `shadowGroundY` is on the wrong side — Y-down means the floor is a **greater** y, so a `pos.y - lift` puts the blob inside the caster and the depth test leaves only a hairline ring |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: melonjs-camera-and-drawing
3
- description: "Use this skill for camera control and immediate-mode drawing in melonJS — following a target, viewport bounds, shake and fade, secondary cameras, and drawing shapes, lines and gradients inside a custom draw(). Covers world versus screen coordinate conversion, clipping and masking, and baking with CanvasRenderTarget. Triggers on: Camera2d, viewport, follow, setBounds, shake, fadeIn, fadeOut, worldToLocal, localToWorld, colorMatrix, renderer.fill, renderer.stroke, Rect, Ellipse, Polygon, Line, Gradient, clipRect, mask, CanvasRenderTarget, NoiseTexture2d."
3
+ description: "Use this skill for camera control and immediate-mode drawing in melonJS — following a target, viewport bounds, shake and fade, secondary cameras, and drawing shapes, lines and gradients inside a custom draw(). Covers world versus screen coordinate conversion, clipping and masking, and baking with CanvasRenderTarget. Triggers on: Camera2d, viewport, follow, setBounds, shake, fadeIn, fadeOut, worldToLocal, localToWorld, colorMatrix, renderer.fill, renderer.stroke, Rect, Ellipse, Polygon, Line, Gradient, clipRect, mask, CanvasRenderTarget, NoiseTexture2d, lookAt, setBasis."
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -24,6 +24,25 @@ frame-rate independent since 19.7. `AXIS.HORIZONTAL` / `AXIS.VERTICAL` /
24
24
 
25
25
  Call it from the followed entity's `onActivateEvent`, using `this.parentApp`.
26
26
 
27
+ **For anything that is NOT the camera, the same smoothing is `math.damp`.**
28
+ `follow()` is frame-rate independent for you; a value you smooth yourself is
29
+ not, and `lerp(current, target, alpha)` once per frame moves further on a slow
30
+ frame than on a fast one, so the feel changes with the frame rate:
31
+
32
+ ```js
33
+ import { math } from "melonjs";
34
+
35
+ // dt is milliseconds, damp wants seconds
36
+ this.speed = math.damp(this.speed, targetSpeed, 5, dt / 1000);
37
+ this.turret.angle = math.damp(this.turret.angle, wanted, 8, dt / 1000);
38
+ ```
39
+
40
+ `damp(current, target, lambda, dt)`. Higher `lambda` converges faster; it is
41
+ the rate, not a per-frame fraction. Use it for camera pans you drive yourself,
42
+ turret tracking, zoom, input smoothing and any value that should chase another
43
+ one — it is the tool that is easy to miss and easy to hand-write slightly
44
+ wrong.
45
+
27
46
  ## Bounds are the thing people forget
28
47
 
29
48
  The camera's bounds default to the **renderer size**, so it cannot scroll until
@@ -102,6 +121,24 @@ coordinate that puts your label on the wrong side of the screen. Skip it.
102
121
  Do not hand-roll this with `Matrix3d` — the perspective divide and the behind-
103
122
  camera case are exactly what gets it wrong.
104
123
 
124
+ ## Pointing a 3D camera
125
+
126
+ A 2D camera's only rotation is `roll`. A 3D one can be pointed at a target, and
127
+ optionally banked at the same time:
128
+
129
+ ```js
130
+ camera.lookAt(target); // pitch and yaw; roll untouched
131
+ camera.lookAt(target, up); // and bank, where `up` is what should
132
+ // appear UP ON SCREEN
133
+ camera.setBasis(right, up, forward); // or pose it from a basis outright
134
+ ```
135
+
136
+ `up` has no default, so the one-argument form behaves exactly as it always
137
+ did. Because this engine renders Y-down, a level horizon is `(0, -1, 0)`.
138
+ `setBasis` is the writable counterpart of `getBasis` and takes the camera's
139
+ own columns, whose `up` points down the screen: the opposite sense, one
140
+ negation apart. See `melonjs-3d` for the full account.
141
+
105
142
  ## Secondary cameras
106
143
 
107
144
  Cameras are first-class — a minimap is a second camera with `autoResize = false`
@@ -195,6 +232,24 @@ hand `.canvas` on for exactly that reason.
195
232
 
196
233
  This is the sanctioned performance idiom before reaching for a custom shader.
197
234
 
235
+ **For a solid fill you do not need a canvas at all.** `Renderer.getWhitePixel()`
236
+ is a shared, lazily-created 1x1 white canvas, and stretching it is how you get
237
+ a coloured rectangle, a bar, a flat screen overlay, or a blank carrier for an
238
+ effect that paints from scratch:
239
+
240
+ ```js
241
+ const bar = new Sprite(0, 0, { image: Renderer.getWhitePixel() });
242
+ bar.anchorPoint.set(0, 0);
243
+ bar.tint.parseCSS("#39d0ff");
244
+ bar.scale(width, height); // a 1x1 texture, so scale IS the size in pixels
245
+ ```
246
+
247
+ It is also the right texture under a `ShaderEffect` whose body ignores the
248
+ incoming colour, and it keeps the quad batched with everything else using it.
249
+ When you DO need a real canvas, `Renderer.createCanvas(width, height)` is the
250
+ engine's allocator: it hands back an `OffscreenCanvas` where that is safe and
251
+ throws on a zero dimension, instead of `document.createElement("canvas")`.
252
+
198
253
  `renderer.toFrameTexture()` is the related tool for capturing the *current frame*
199
254
  into a texture for a shader to sample.
200
255
 
@@ -213,6 +268,7 @@ into a texture for a shader to sample.
213
268
  | `container.clipping = true` does nothing | container has no explicit size, so `width`/`height` are `Infinity` |
214
269
  | baked target draws nothing / throws | passed the `CanvasRenderTarget`, not its `.canvas` |
215
270
  | frame rate drops with many static draws | bake into a `CanvasRenderTarget` instead |
271
+ | a 3D camera cannot be given an arbitrary up | `Camera3d#lookAt(target, up)` or `setBasis(right, up, forward)`; see `melonjs-3d` |
216
272
 
217
273
  ## Related skills
218
274