@codexo/exojs 0.8.4 → 0.10.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 (470) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/README.md +34 -13
  3. package/dist/esm/animation/Tween.d.ts +20 -3
  4. package/dist/esm/animation/Tween.js +16 -8
  5. package/dist/esm/animation/Tween.js.map +1 -1
  6. package/dist/esm/animation/TweenManager.d.ts +16 -1
  7. package/dist/esm/animation/TweenManager.js +27 -2
  8. package/dist/esm/animation/TweenManager.js.map +1 -1
  9. package/dist/esm/audio/AudioAnalyser.d.ts +2 -0
  10. package/dist/esm/audio/AudioAnalyser.js +24 -9
  11. package/dist/esm/audio/AudioAnalyser.js.map +1 -1
  12. package/dist/esm/audio/AudioBus.d.ts +1 -0
  13. package/dist/esm/audio/AudioBus.js +8 -4
  14. package/dist/esm/audio/AudioBus.js.map +1 -1
  15. package/dist/esm/audio/AudioListener.d.ts +1 -0
  16. package/dist/esm/audio/AudioListener.js +7 -5
  17. package/dist/esm/audio/AudioListener.js.map +1 -1
  18. package/dist/esm/audio/AudioManager.d.ts +8 -2
  19. package/dist/esm/audio/AudioManager.js +14 -1
  20. package/dist/esm/audio/AudioManager.js.map +1 -1
  21. package/dist/esm/audio/BeatDetector.d.ts +2 -0
  22. package/dist/esm/audio/BeatDetector.js +27 -661
  23. package/dist/esm/audio/BeatDetector.js.map +1 -1
  24. package/dist/esm/audio/Music.d.ts +1 -0
  25. package/dist/esm/audio/Music.js +7 -3
  26. package/dist/esm/audio/Music.js.map +1 -1
  27. package/dist/esm/audio/OscillatorSound.d.ts +1 -0
  28. package/dist/esm/audio/OscillatorSound.js +7 -3
  29. package/dist/esm/audio/OscillatorSound.js.map +1 -1
  30. package/dist/esm/audio/Sound.d.ts +1 -0
  31. package/dist/esm/audio/Sound.js +7 -3
  32. package/dist/esm/audio/Sound.js.map +1 -1
  33. package/dist/esm/audio/audio-context.d.ts +2 -2
  34. package/dist/esm/audio/audio-context.js +4 -4
  35. package/dist/esm/audio/audio-context.js.map +1 -1
  36. package/dist/esm/audio/filters/ChorusFilter.d.ts +1 -0
  37. package/dist/esm/audio/filters/ChorusFilter.js +7 -3
  38. package/dist/esm/audio/filters/ChorusFilter.js.map +1 -1
  39. package/dist/esm/audio/filters/CompressorFilter.d.ts +1 -0
  40. package/dist/esm/audio/filters/CompressorFilter.js +7 -3
  41. package/dist/esm/audio/filters/CompressorFilter.js.map +1 -1
  42. package/dist/esm/audio/filters/DelayFilter.d.ts +1 -0
  43. package/dist/esm/audio/filters/DelayFilter.js +7 -3
  44. package/dist/esm/audio/filters/DelayFilter.js.map +1 -1
  45. package/dist/esm/audio/filters/EqualizerFilter.d.ts +1 -0
  46. package/dist/esm/audio/filters/EqualizerFilter.js +7 -3
  47. package/dist/esm/audio/filters/EqualizerFilter.js.map +1 -1
  48. package/dist/esm/audio/filters/GranularFilter.js +1 -86
  49. package/dist/esm/audio/filters/GranularFilter.js.map +1 -1
  50. package/dist/esm/audio/filters/HighpassFilter.d.ts +1 -0
  51. package/dist/esm/audio/filters/HighpassFilter.js +7 -3
  52. package/dist/esm/audio/filters/HighpassFilter.js.map +1 -1
  53. package/dist/esm/audio/filters/LowpassFilter.d.ts +1 -0
  54. package/dist/esm/audio/filters/LowpassFilter.js +7 -3
  55. package/dist/esm/audio/filters/LowpassFilter.js.map +1 -1
  56. package/dist/esm/audio/filters/PitchShiftFilter.js +1 -71
  57. package/dist/esm/audio/filters/PitchShiftFilter.js.map +1 -1
  58. package/dist/esm/audio/filters/ReverbFilter.d.ts +1 -0
  59. package/dist/esm/audio/filters/ReverbFilter.js +7 -3
  60. package/dist/esm/audio/filters/ReverbFilter.js.map +1 -1
  61. package/dist/esm/audio/filters/VocoderFilter.js +1 -89
  62. package/dist/esm/audio/filters/VocoderFilter.js.map +1 -1
  63. package/dist/esm/audio/filters/WorkletFilter.d.ts +2 -0
  64. package/dist/esm/audio/filters/WorkletFilter.js +10 -5
  65. package/dist/esm/audio/filters/WorkletFilter.js.map +1 -1
  66. package/dist/esm/audio/index.d.ts +15 -10
  67. package/dist/esm/audio/worklet/registerWorklet.d.ts +1 -1
  68. package/dist/esm/audio/worklet/registerWorklet.js +2 -2
  69. package/dist/esm/audio/worklet/registerWorklet.js.map +1 -1
  70. package/dist/esm/audio/worklets/beat-detector.worklet.d.ts +1 -0
  71. package/dist/esm/audio/worklets/beat-detector.worklet.js +647 -0
  72. package/dist/esm/audio/worklets/beat-detector.worklet.js.map +1 -0
  73. package/dist/esm/audio/worklets/granular.worklet.d.ts +1 -0
  74. package/dist/esm/audio/worklets/granular.worklet.js +89 -0
  75. package/dist/esm/audio/worklets/granular.worklet.js.map +1 -0
  76. package/dist/esm/audio/worklets/pitch-shift.worklet.d.ts +1 -0
  77. package/dist/esm/audio/worklets/pitch-shift.worklet.js +74 -0
  78. package/dist/esm/audio/worklets/pitch-shift.worklet.js.map +1 -0
  79. package/dist/esm/audio/worklets/vocoder.worklet.d.ts +1 -0
  80. package/dist/esm/audio/worklets/vocoder.worklet.js +92 -0
  81. package/dist/esm/audio/worklets/vocoder.worklet.js.map +1 -0
  82. package/dist/esm/core/Application.d.ts +86 -29
  83. package/dist/esm/core/Application.js +157 -47
  84. package/dist/esm/core/Application.js.map +1 -1
  85. package/dist/esm/core/Color.d.ts +0 -8
  86. package/dist/esm/core/Color.js +0 -24
  87. package/dist/esm/core/Color.js.map +1 -1
  88. package/dist/esm/core/Perf.d.ts +23 -0
  89. package/dist/esm/core/Perf.js +49 -0
  90. package/dist/esm/core/Perf.js.map +1 -0
  91. package/dist/esm/core/Scene.d.ts +40 -80
  92. package/dist/esm/core/Scene.js +63 -43
  93. package/dist/esm/core/Scene.js.map +1 -1
  94. package/dist/esm/core/SceneManager.d.ts +11 -25
  95. package/dist/esm/core/SceneManager.js +37 -100
  96. package/dist/esm/core/SceneManager.js.map +1 -1
  97. package/dist/esm/core/SceneNode.d.ts +28 -17
  98. package/dist/esm/core/SceneNode.js +66 -42
  99. package/dist/esm/core/SceneNode.js.map +1 -1
  100. package/dist/esm/core/Signal.d.ts +24 -28
  101. package/dist/esm/core/Signal.js +64 -50
  102. package/dist/esm/core/Signal.js.map +1 -1
  103. package/dist/esm/core/Timer.d.ts +1 -0
  104. package/dist/esm/core/Timer.js +3 -0
  105. package/dist/esm/core/Timer.js.map +1 -1
  106. package/dist/esm/core/capabilities.d.ts +2 -0
  107. package/dist/esm/core/capabilities.js +15 -0
  108. package/dist/esm/core/capabilities.js.map +1 -1
  109. package/dist/esm/core/index.d.ts +1 -0
  110. package/dist/esm/core/types.d.ts +1 -1
  111. package/dist/esm/core/utils.d.ts +12 -0
  112. package/dist/esm/core/utils.js +18 -1
  113. package/dist/esm/core/utils.js.map +1 -1
  114. package/dist/esm/debug/BoundingBoxesLayer.js +1 -1
  115. package/dist/esm/debug/BoundingBoxesLayer.js.map +1 -1
  116. package/dist/esm/debug/HitTestLayer.js +1 -1
  117. package/dist/esm/debug/HitTestLayer.js.map +1 -1
  118. package/dist/esm/debug/PerformanceLayer.js +1 -2
  119. package/dist/esm/debug/PerformanceLayer.js.map +1 -1
  120. package/dist/esm/debug/PointerStackLayer.js +1 -2
  121. package/dist/esm/debug/PointerStackLayer.js.map +1 -1
  122. package/dist/esm/debug/RenderPassInspectorLayer.js +1 -2
  123. package/dist/esm/debug/RenderPassInspectorLayer.js.map +1 -1
  124. package/dist/esm/index.js +37 -10
  125. package/dist/esm/index.js.map +1 -1
  126. package/dist/esm/input/InputManager.d.ts +1 -0
  127. package/dist/esm/input/InputManager.js +30 -3
  128. package/dist/esm/input/InputManager.js.map +1 -1
  129. package/dist/esm/input/InteractionManager.d.ts +5 -2
  130. package/dist/esm/input/InteractionManager.js +29 -18
  131. package/dist/esm/input/InteractionManager.js.map +1 -1
  132. package/dist/esm/input/Pointer.js +3 -2
  133. package/dist/esm/input/Pointer.js.map +1 -1
  134. package/dist/esm/input/internal/interactionManagerRegistry.d.ts +9 -0
  135. package/dist/esm/input/internal/interactionManagerRegistry.js +10 -0
  136. package/dist/esm/input/internal/interactionManagerRegistry.js.map +1 -0
  137. package/dist/esm/math/AbstractVector.d.ts +1 -7
  138. package/dist/esm/math/AbstractVector.js +6 -20
  139. package/dist/esm/math/AbstractVector.js.map +1 -1
  140. package/dist/esm/math/Circle.js +0 -2
  141. package/dist/esm/math/Circle.js.map +1 -1
  142. package/dist/esm/math/Collision.d.ts +9 -3
  143. package/dist/esm/math/Ellipse.d.ts +2 -5
  144. package/dist/esm/math/Ellipse.js +10 -7
  145. package/dist/esm/math/Ellipse.js.map +1 -1
  146. package/dist/esm/math/ObservableVector.d.ts +1 -1
  147. package/dist/esm/math/ObservableVector.js +3 -3
  148. package/dist/esm/math/ObservableVector.js.map +1 -1
  149. package/dist/esm/math/Polygon.d.ts +0 -2
  150. package/dist/esm/math/Polygon.js +1 -9
  151. package/dist/esm/math/Polygon.js.map +1 -1
  152. package/dist/esm/math/Rectangle.js +0 -2
  153. package/dist/esm/math/Rectangle.js.map +1 -1
  154. package/dist/esm/math/collision-detection.d.ts +19 -4
  155. package/dist/esm/math/collision-detection.js +61 -4
  156. package/dist/esm/math/collision-detection.js.map +1 -1
  157. package/dist/esm/math/swept-collision.d.ts +16 -12
  158. package/dist/esm/math/swept-collision.js +109 -19
  159. package/dist/esm/math/swept-collision.js.map +1 -1
  160. package/dist/esm/particles/ParticleSystem.d.ts +8 -5
  161. package/dist/esm/particles/ParticleSystem.js +10 -6
  162. package/dist/esm/particles/ParticleSystem.js.map +1 -1
  163. package/dist/esm/particles/distributions/{Gradient.d.ts → ColorGradient.d.ts} +5 -5
  164. package/dist/esm/particles/distributions/{Gradient.js → ColorGradient.js} +5 -5
  165. package/dist/esm/particles/distributions/ColorGradient.js.map +1 -0
  166. package/dist/esm/particles/distributions/Distribution.d.ts +2 -2
  167. package/dist/esm/particles/distributions/index.d.ts +2 -2
  168. package/dist/esm/particles/gpu/ParticleGpuState.js +1 -1
  169. package/dist/esm/particles/index.d.ts +1 -0
  170. package/dist/esm/particles/modules/ColorOverLifetime.d.ts +3 -3
  171. package/dist/esm/particles/modules/ColorOverLifetime.js.map +1 -1
  172. package/dist/esm/particles/modules/ColorOverSpeed.d.ts +3 -3
  173. package/dist/esm/particles/modules/ColorOverSpeed.js.map +1 -1
  174. package/dist/esm/particles/modules/UpdateModule.d.ts +2 -2
  175. package/dist/esm/particles/modules/UpdateModule.js +1 -1
  176. package/dist/esm/particles/modules/WgslContribution.d.ts +2 -2
  177. package/dist/esm/rendering/CallbackRenderPass.d.ts +1 -0
  178. package/dist/esm/rendering/CallbackRenderPass.js +1 -0
  179. package/dist/esm/rendering/CallbackRenderPass.js.map +1 -1
  180. package/dist/esm/rendering/Camera.d.ts +33 -0
  181. package/dist/esm/rendering/Camera.js +38 -0
  182. package/dist/esm/rendering/Camera.js.map +1 -0
  183. package/dist/esm/rendering/Container.d.ts +7 -25
  184. package/dist/esm/rendering/Container.js +25 -87
  185. package/dist/esm/rendering/Container.js.map +1 -1
  186. package/dist/esm/rendering/Drawable.d.ts +8 -10
  187. package/dist/esm/rendering/Drawable.js +12 -20
  188. package/dist/esm/rendering/Drawable.js.map +1 -1
  189. package/dist/esm/rendering/RenderBackend.d.ts +19 -0
  190. package/dist/esm/rendering/RenderNode.d.ts +82 -11
  191. package/dist/esm/rendering/RenderNode.js +133 -163
  192. package/dist/esm/rendering/RenderNode.js.map +1 -1
  193. package/dist/esm/rendering/RenderPass.d.ts +1 -0
  194. package/dist/esm/rendering/RenderStats.d.ts +9 -0
  195. package/dist/esm/rendering/RenderStats.js +2 -0
  196. package/dist/esm/rendering/RenderStats.js.map +1 -1
  197. package/dist/esm/rendering/RenderTarget.d.ts +13 -0
  198. package/dist/esm/rendering/RenderTarget.js +13 -0
  199. package/dist/esm/rendering/RenderTarget.js.map +1 -1
  200. package/dist/esm/rendering/RenderTargetPass.js +17 -0
  201. package/dist/esm/rendering/RenderTargetPass.js.map +1 -1
  202. package/dist/esm/rendering/RendererRegistry.d.ts +1 -0
  203. package/dist/esm/rendering/RendererRegistry.js +1 -0
  204. package/dist/esm/rendering/RendererRegistry.js.map +1 -1
  205. package/dist/esm/rendering/RenderingContext.d.ts +87 -0
  206. package/dist/esm/rendering/RenderingContext.js +157 -0
  207. package/dist/esm/rendering/RenderingContext.js.map +1 -0
  208. package/dist/esm/rendering/TransformBuffer.d.ts +38 -0
  209. package/dist/esm/rendering/TransformBuffer.js +116 -0
  210. package/dist/esm/rendering/TransformBuffer.js.map +1 -0
  211. package/dist/esm/rendering/View.d.ts +23 -0
  212. package/dist/esm/rendering/View.js +42 -0
  213. package/dist/esm/rendering/View.js.map +1 -1
  214. package/dist/esm/rendering/filters/WebGpuShaderFilter.js +5 -12
  215. package/dist/esm/rendering/filters/WebGpuShaderFilter.js.map +1 -1
  216. package/dist/esm/rendering/geometry/Geometry.d.ts +40 -0
  217. package/dist/esm/rendering/geometry/Geometry.js +228 -0
  218. package/dist/esm/rendering/geometry/Geometry.js.map +1 -0
  219. package/dist/esm/rendering/geometry/GeometryAttribute.d.ts +32 -0
  220. package/dist/esm/rendering/geometry/QuadGeometry.d.ts +5 -0
  221. package/dist/esm/rendering/gradient/Gradient.d.ts +34 -0
  222. package/dist/esm/rendering/gradient/Gradient.js +114 -0
  223. package/dist/esm/rendering/gradient/Gradient.js.map +1 -0
  224. package/dist/esm/rendering/gradient/LinearGradient.d.ts +10 -0
  225. package/dist/esm/rendering/gradient/LinearGradient.js +26 -0
  226. package/dist/esm/rendering/gradient/LinearGradient.js.map +1 -0
  227. package/dist/esm/rendering/gradient/RadialGradient.d.ts +10 -0
  228. package/dist/esm/rendering/gradient/RadialGradient.js +25 -0
  229. package/dist/esm/rendering/gradient/RadialGradient.js.map +1 -0
  230. package/dist/esm/rendering/index.d.ts +103 -59
  231. package/dist/esm/rendering/material/Material.d.ts +114 -0
  232. package/dist/esm/rendering/material/Material.js +111 -0
  233. package/dist/esm/rendering/material/Material.js.map +1 -0
  234. package/dist/esm/rendering/material/MaterialKey.d.ts +18 -0
  235. package/dist/esm/rendering/material/MaterialKey.js +82 -0
  236. package/dist/esm/rendering/material/MaterialKey.js.map +1 -0
  237. package/dist/esm/rendering/material/MeshMaterial.d.ts +16 -0
  238. package/dist/esm/rendering/material/MeshMaterial.js +21 -0
  239. package/dist/esm/rendering/material/MeshMaterial.js.map +1 -0
  240. package/dist/esm/rendering/{mesh/MeshShader.d.ts → material/ShaderSource.d.ts} +30 -62
  241. package/dist/esm/rendering/{mesh/MeshShader.js → material/ShaderSource.js} +36 -62
  242. package/dist/esm/rendering/material/ShaderSource.js.map +1 -0
  243. package/dist/esm/rendering/material/SpriteMaterial.d.ts +15 -0
  244. package/dist/esm/rendering/material/SpriteMaterial.js +20 -0
  245. package/dist/esm/rendering/material/SpriteMaterial.js.map +1 -0
  246. package/dist/esm/rendering/mesh/Mesh.d.ts +29 -12
  247. package/dist/esm/rendering/mesh/Mesh.js +123 -4
  248. package/dist/esm/rendering/mesh/Mesh.js.map +1 -1
  249. package/dist/esm/rendering/pass/RenderPassCoordinator.d.ts +63 -0
  250. package/dist/esm/rendering/pass/RenderPassDescriptor.d.ts +48 -0
  251. package/dist/esm/rendering/pass/RenderPassDescriptor.js +16 -0
  252. package/dist/esm/rendering/pass/RenderPassDescriptor.js.map +1 -0
  253. package/dist/esm/rendering/plan/RenderCommand.d.ts +67 -0
  254. package/dist/esm/rendering/plan/RenderCommand.js +94 -0
  255. package/dist/esm/rendering/plan/RenderCommand.js.map +1 -0
  256. package/dist/esm/rendering/plan/RenderEffectExecutor.d.ts +10 -0
  257. package/dist/esm/rendering/plan/RenderEffectExecutor.js +159 -0
  258. package/dist/esm/rendering/plan/RenderEffectExecutor.js.map +1 -0
  259. package/dist/esm/rendering/plan/RenderPlan.d.ts +23 -0
  260. package/dist/esm/rendering/plan/RenderPlan.js +12 -0
  261. package/dist/esm/rendering/plan/RenderPlan.js.map +1 -0
  262. package/dist/esm/rendering/plan/RenderPlanBuilder.d.ts +31 -0
  263. package/dist/esm/rendering/plan/RenderPlanBuilder.js +242 -0
  264. package/dist/esm/rendering/plan/RenderPlanBuilder.js.map +1 -0
  265. package/dist/esm/rendering/plan/RenderPlanOptimizer.d.ts +10 -0
  266. package/dist/esm/rendering/plan/RenderPlanOptimizer.js +180 -0
  267. package/dist/esm/rendering/plan/RenderPlanOptimizer.js.map +1 -0
  268. package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts +9 -0
  269. package/dist/esm/rendering/plan/RenderPlanPlayer.js +56 -0
  270. package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -0
  271. package/dist/esm/rendering/plan/RenderScope.d.ts +70 -0
  272. package/dist/esm/rendering/plan/RenderScope.js +16 -0
  273. package/dist/esm/rendering/plan/RenderScope.js.map +1 -0
  274. package/dist/esm/rendering/plan/playRenderTree.d.ts +4 -0
  275. package/dist/esm/rendering/plan/playRenderTree.js +19 -0
  276. package/dist/esm/rendering/plan/playRenderTree.js.map +1 -0
  277. package/dist/esm/rendering/shader/Shader.d.ts +1 -0
  278. package/dist/esm/rendering/shader/Shader.js +1 -0
  279. package/dist/esm/rendering/shader/Shader.js.map +1 -1
  280. package/dist/esm/rendering/shader/ShaderUniform.d.ts +1 -0
  281. package/dist/esm/rendering/shader/ShaderUniform.js +1 -0
  282. package/dist/esm/rendering/shader/ShaderUniform.js.map +1 -1
  283. package/dist/esm/rendering/sprite/Sprite.d.ts +25 -3
  284. package/dist/esm/rendering/sprite/Sprite.js +48 -15
  285. package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
  286. package/dist/esm/rendering/sprite/spriteMaterialSources.d.ts +36 -0
  287. package/dist/esm/rendering/sprite/spriteMaterialSources.js +128 -0
  288. package/dist/esm/rendering/sprite/spriteMaterialSources.js.map +1 -0
  289. package/dist/esm/rendering/text/AbstractText.d.ts +36 -0
  290. package/dist/esm/rendering/text/AbstractText.js +49 -0
  291. package/dist/esm/rendering/text/AbstractText.js.map +1 -0
  292. package/dist/esm/rendering/text/BitmapText.d.ts +97 -0
  293. package/dist/esm/rendering/text/BitmapText.js +220 -0
  294. package/dist/esm/rendering/text/BitmapText.js.map +1 -0
  295. package/dist/esm/rendering/text/BmFont.d.ts +50 -0
  296. package/dist/esm/rendering/text/BmFont.js +24 -0
  297. package/dist/esm/rendering/text/BmFont.js.map +1 -0
  298. package/dist/esm/rendering/text/GlyphAtlas.d.ts +104 -0
  299. package/dist/esm/rendering/text/GlyphAtlas.js +347 -0
  300. package/dist/esm/rendering/text/GlyphAtlas.js.map +1 -0
  301. package/dist/esm/rendering/text/GlyphAtlasPool.d.ts +40 -0
  302. package/dist/esm/rendering/text/GlyphAtlasPool.js +67 -0
  303. package/dist/esm/rendering/text/GlyphAtlasPool.js.map +1 -0
  304. package/dist/esm/rendering/text/GlyphSdf.d.ts +92 -0
  305. package/dist/esm/rendering/text/GlyphSdf.js +220 -0
  306. package/dist/esm/rendering/text/GlyphSdf.js.map +1 -0
  307. package/dist/esm/rendering/text/HTMLText.d.ts +107 -0
  308. package/dist/esm/rendering/text/HTMLText.js +284 -0
  309. package/dist/esm/rendering/text/HTMLText.js.map +1 -0
  310. package/dist/esm/rendering/text/LayoutOptions.d.ts +30 -0
  311. package/dist/esm/rendering/text/Text.d.ts +89 -20
  312. package/dist/esm/rendering/text/Text.js +176 -101
  313. package/dist/esm/rendering/text/Text.js.map +1 -1
  314. package/dist/esm/rendering/text/TextLayout.d.ts +20 -8
  315. package/dist/esm/rendering/text/TextLayout.js +234 -25
  316. package/dist/esm/rendering/text/TextLayout.js.map +1 -1
  317. package/dist/esm/rendering/text/TextStyle.d.ts +154 -87
  318. package/dist/esm/rendering/text/TextStyle.js +257 -203
  319. package/dist/esm/rendering/text/TextStyle.js.map +1 -1
  320. package/dist/esm/rendering/text/types.d.ts +73 -13
  321. package/dist/esm/rendering/texture/DataTexture.d.ts +5 -0
  322. package/dist/esm/rendering/texture/DataTexture.js +7 -0
  323. package/dist/esm/rendering/texture/DataTexture.js.map +1 -1
  324. package/dist/esm/rendering/texture/Texture.d.ts +1 -0
  325. package/dist/esm/rendering/texture/Texture.js +1 -0
  326. package/dist/esm/rendering/texture/Texture.js.map +1 -1
  327. package/dist/esm/rendering/types.d.ts +3 -1
  328. package/dist/esm/rendering/types.js +2 -0
  329. package/dist/esm/rendering/types.js.map +1 -1
  330. package/dist/esm/rendering/video/Video.d.ts +5 -8
  331. package/dist/esm/rendering/video/Video.js +12 -13
  332. package/dist/esm/rendering/video/Video.js.map +1 -1
  333. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +40 -0
  334. package/dist/esm/rendering/webgl2/WebGl2Backend.js +344 -27
  335. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  336. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.d.ts +22 -2
  337. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +404 -112
  338. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
  339. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.d.ts +57 -0
  340. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js +79 -0
  341. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js.map +1 -0
  342. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +12 -0
  343. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +214 -58
  344. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  345. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.d.ts +34 -0
  346. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js +169 -0
  347. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js.map +1 -0
  348. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.d.ts +56 -0
  349. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +486 -0
  350. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -0
  351. package/dist/esm/rendering/webgl2/glsl/mesh.frag.js +1 -1
  352. package/dist/esm/rendering/webgl2/glsl/mesh.vert.js +1 -1
  353. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js +4 -0
  354. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js.map +1 -0
  355. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js +4 -0
  356. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js.map +1 -0
  357. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js +4 -0
  358. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js.map +1 -0
  359. package/dist/esm/rendering/webgl2/glsl/text-msdf.frag.js +4 -0
  360. package/dist/esm/rendering/webgl2/glsl/text-msdf.frag.js.map +1 -0
  361. package/dist/esm/rendering/webgl2/glsl/text-sdf.frag.js +4 -0
  362. package/dist/esm/rendering/webgl2/glsl/text-sdf.frag.js.map +1 -0
  363. package/dist/esm/rendering/webgl2/glsl/text.vert.js +4 -0
  364. package/dist/esm/rendering/webgl2/glsl/text.vert.js.map +1 -0
  365. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +50 -0
  366. package/dist/esm/rendering/webgpu/WebGpuBackend.js +151 -27
  367. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  368. package/dist/esm/rendering/webgpu/WebGpuBlendState.js +26 -0
  369. package/dist/esm/rendering/webgpu/WebGpuBlendState.js.map +1 -1
  370. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js +22 -17
  371. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js.map +1 -1
  372. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.d.ts +26 -2
  373. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +511 -89
  374. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
  375. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +13 -17
  376. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
  377. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.d.ts +141 -0
  378. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js +270 -0
  379. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js.map +1 -0
  380. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +16 -0
  381. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +344 -27
  382. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  383. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.d.ts +57 -0
  384. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js +257 -0
  385. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js.map +1 -0
  386. package/dist/esm/rendering/webgpu/WebGpuStencilState.d.ts +14 -0
  387. package/dist/esm/rendering/webgpu/WebGpuStencilState.js +36 -0
  388. package/dist/esm/rendering/webgpu/WebGpuStencilState.js.map +1 -0
  389. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.d.ts +70 -0
  390. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +775 -0
  391. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -0
  392. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +16 -0
  393. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +57 -0
  394. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -0
  395. package/dist/esm/rendering/webgpu/compute/WebGpuComputePipeline.js +96 -0
  396. package/dist/esm/rendering/webgpu/compute/WebGpuComputePipeline.js.map +1 -0
  397. package/dist/esm/rendering/webgpu/compute/WebGpuStorageBuffer.js +68 -0
  398. package/dist/esm/rendering/webgpu/compute/WebGpuStorageBuffer.js.map +1 -0
  399. package/dist/esm/resources/Asset.d.ts +23 -0
  400. package/dist/esm/resources/Asset.js +23 -0
  401. package/dist/esm/resources/Asset.js.map +1 -0
  402. package/dist/esm/resources/AssetDefinitions.d.ts +137 -0
  403. package/dist/esm/resources/Assets.d.ts +35 -0
  404. package/dist/esm/resources/Assets.js +32 -0
  405. package/dist/esm/resources/Assets.js.map +1 -0
  406. package/dist/esm/resources/IndexedDbDatabase.js +17 -1
  407. package/dist/esm/resources/IndexedDbDatabase.js.map +1 -1
  408. package/dist/esm/resources/IndexedDbStore.js +17 -1
  409. package/dist/esm/resources/IndexedDbStore.js.map +1 -1
  410. package/dist/esm/resources/JsonStore.d.ts +18 -0
  411. package/dist/esm/resources/JsonStore.js +62 -0
  412. package/dist/esm/resources/JsonStore.js.map +1 -0
  413. package/dist/esm/resources/Loader.d.ts +244 -18
  414. package/dist/esm/resources/Loader.js +456 -50
  415. package/dist/esm/resources/Loader.js.map +1 -1
  416. package/dist/esm/resources/LoadingQueue.d.ts +28 -0
  417. package/dist/esm/resources/LoadingQueue.js +59 -0
  418. package/dist/esm/resources/LoadingQueue.js.map +1 -0
  419. package/dist/esm/resources/factories/BmFontFactory.d.ts +25 -0
  420. package/dist/esm/resources/factories/BmFontFactory.js +96 -0
  421. package/dist/esm/resources/factories/BmFontFactory.js.map +1 -0
  422. package/dist/esm/resources/factories/CsvFactory.d.ts +35 -0
  423. package/dist/esm/resources/factories/CsvFactory.js +87 -0
  424. package/dist/esm/resources/factories/CsvFactory.js.map +1 -0
  425. package/dist/esm/resources/factories/ImageFactory.d.ts +14 -8
  426. package/dist/esm/resources/factories/ImageFactory.js +13 -6
  427. package/dist/esm/resources/factories/ImageFactory.js.map +1 -1
  428. package/dist/esm/resources/factories/MusicFactory.d.ts +8 -2
  429. package/dist/esm/resources/factories/MusicFactory.js +25 -14
  430. package/dist/esm/resources/factories/MusicFactory.js.map +1 -1
  431. package/dist/esm/resources/factories/SoundFactory.d.ts +2 -2
  432. package/dist/esm/resources/factories/SoundFactory.js.map +1 -1
  433. package/dist/esm/resources/factories/SubtitleFactory.d.ts +28 -0
  434. package/dist/esm/resources/factories/SubtitleFactory.js +203 -0
  435. package/dist/esm/resources/factories/SubtitleFactory.js.map +1 -0
  436. package/dist/esm/resources/factories/SvgFactory.d.ts +18 -1
  437. package/dist/esm/resources/factories/SvgFactory.js +21 -2
  438. package/dist/esm/resources/factories/SvgFactory.js.map +1 -1
  439. package/dist/esm/resources/factories/TextureFactory.d.ts +4 -4
  440. package/dist/esm/resources/factories/TextureFactory.js +8 -4
  441. package/dist/esm/resources/factories/TextureFactory.js.map +1 -1
  442. package/dist/esm/resources/factories/VideoFactory.d.ts +8 -2
  443. package/dist/esm/resources/factories/VideoFactory.js +27 -20
  444. package/dist/esm/resources/factories/VideoFactory.js.map +1 -1
  445. package/dist/esm/resources/factories/XmlFactory.d.ts +24 -0
  446. package/dist/esm/resources/factories/XmlFactory.js +37 -0
  447. package/dist/esm/resources/factories/XmlFactory.js.map +1 -0
  448. package/dist/esm/resources/index.d.ts +9 -1
  449. package/dist/esm/resources/tokens.d.ts +49 -3
  450. package/dist/esm/resources/tokens.js +50 -4
  451. package/dist/esm/resources/tokens.js.map +1 -1
  452. package/dist/exo.esm.js +15382 -8078
  453. package/dist/exo.esm.js.map +1 -1
  454. package/package.json +34 -16
  455. package/dist/esm/input/interaction-hooks.d.ts +0 -34
  456. package/dist/esm/input/interaction-hooks.js +0 -35
  457. package/dist/esm/input/interaction-hooks.js.map +0 -1
  458. package/dist/esm/particles/distributions/Gradient.js.map +0 -1
  459. package/dist/esm/rendering/mesh/MeshShader.js.map +0 -1
  460. package/dist/esm/rendering/text/DynamicGlyphAtlas.d.ts +0 -33
  461. package/dist/esm/rendering/text/DynamicGlyphAtlas.js +0 -134
  462. package/dist/esm/rendering/text/DynamicGlyphAtlas.js.map +0 -1
  463. package/dist/esm/rendering/text/atlas-singleton.d.ts +0 -7
  464. package/dist/esm/rendering/text/atlas-singleton.js +0 -17
  465. package/dist/esm/rendering/text/atlas-singleton.js.map +0 -1
  466. package/dist/esm/resources/factories/VttFactory.d.ts +0 -24
  467. package/dist/esm/resources/factories/VttFactory.js +0 -158
  468. package/dist/esm/resources/factories/VttFactory.js.map +0 -1
  469. package/dist/esm/vendor/webgl-debug.js +0 -1160
  470. package/dist/esm/vendor/webgl-debug.js.map +0 -1
@@ -1,9 +1,11 @@
1
1
  import { Color } from '../../core/Color.js';
2
2
  import { Signal } from '../../core/Signal.js';
3
+ import { Matrix } from '../../math/Matrix.js';
3
4
  import { Vector } from '../../math/Vector.js';
4
5
  import { ParticleSystem } from '../../particles/ParticleSystem.js';
6
+ import { BitmapText } from '../text/BitmapText.js';
7
+ import { Text } from '../text/Text.js';
5
8
  import { BlendModes } from '../types.js';
6
- import WebGLDebugUtils from '../../vendor/webgl-debug.js';
7
9
  import { Mesh } from '../mesh/Mesh.js';
8
10
  import { RenderBackendType } from '../RenderBackendType.js';
9
11
  import { RendererRegistry } from '../RendererRegistry.js';
@@ -12,28 +14,51 @@ import { RenderTarget } from '../RenderTarget.js';
12
14
  import { Sprite } from '../sprite/Sprite.js';
13
15
  import { DataTexture } from '../texture/DataTexture.js';
14
16
  import { RenderTexture } from '../texture/RenderTexture.js';
17
+ import { TransformBuffer } from '../TransformBuffer.js';
15
18
  import { WebGl2MaskCompositor } from './WebGl2MaskCompositor.js';
16
19
  import { WebGl2MeshRenderer } from './WebGl2MeshRenderer.js';
17
20
  import { WebGl2ParticleRenderer } from './WebGl2ParticleRenderer.js';
21
+ import { WebGl2PassCoordinator } from './WebGl2PassCoordinator.js';
18
22
  import { WebGl2SpriteRenderer } from './WebGl2SpriteRenderer.js';
23
+ import { WebGl2StencilClipper } from './WebGl2StencilClipper.js';
24
+ import { WebGl2TextRenderer } from './WebGl2TextRenderer.js';
19
25
 
20
- const throwOnGlError = (err, funcName) => {
21
- throw `${WebGLDebugUtils.glEnumToString(err)} was caused by call to: ${funcName}`;
22
- };
23
- const logGlCall = (functionName, args) => {
24
- console.log(`gl.${functionName}(${WebGLDebugUtils.glFunctionArgsToString(functionName, args)})`);
25
- };
26
- const validateNoneOfTheArgsAreUndefined = (functionName, args) => {
27
- for (const argument of args) {
28
- if (argument === undefined) {
29
- console.error(`undefined passed to gl.${functionName}(${WebGLDebugUtils.glFunctionArgsToString(functionName, args)})`);
30
- }
31
- }
32
- };
33
- const logAndValidate = (functionName, args) => {
34
- logGlCall(functionName, args);
35
- validateNoneOfTheArgsAreUndefined(functionName, args);
26
+ // Inline GL debug helpers replaces the webgl-debug vendor lib.
27
+ // Used only when renderingOptions.debug = true.
28
+ const glEnumToString = (gl, value) => {
29
+ const ctor = gl.constructor;
30
+ for (const key of Object.getOwnPropertyNames(ctor)) {
31
+ if (ctor[key] === value)
32
+ return key;
33
+ }
34
+ return `0x${value.toString(16).padStart(4, '0').toUpperCase()}`;
36
35
  };
36
+ const glArgsToString = (gl, args) => args.map(a => (typeof a === 'number' ? glEnumToString(gl, a) : String(a))).join(', ');
37
+ const makeWebGl2DebugContext = (gl) => new Proxy(gl, {
38
+ get(target, prop, receiver) {
39
+ const value = Reflect.get(target, prop, receiver);
40
+ if (typeof value !== 'function')
41
+ return value;
42
+ const name = String(prop);
43
+ return (...args) => {
44
+ console.log(`gl.${name}(${glArgsToString(target, args)})`);
45
+ for (const arg of args) {
46
+ if (arg === undefined) {
47
+ console.error(`undefined passed to gl.${name}(${glArgsToString(target, args)})`);
48
+ }
49
+ }
50
+ const result = Reflect.apply(value, target, args);
51
+ if (name !== 'getError') {
52
+ const err = target.getError();
53
+ if (err !== target.NO_ERROR) {
54
+ throw new Error(`${glEnumToString(target, err)} was caused by call to: ${name}`);
55
+ }
56
+ }
57
+ return result;
58
+ };
59
+ },
60
+ });
61
+ const renderTargetTextureSyncUnit = 15;
37
62
  /**
38
63
  * WebGL 2.0 implementation of {@link RenderBackend}. Manages the GL
39
64
  * context, texture and framebuffer caches keyed by user-side
@@ -67,6 +92,10 @@ class WebGl2Backend {
67
92
  _clipPointB = new Vector();
68
93
  _maskCompositor = new WebGl2MaskCompositor();
69
94
  _maskCompositorConnected = false;
95
+ _stencilClipper = new WebGl2StencilClipper();
96
+ _stencilStates = new Map();
97
+ _stencilClipperConnected = false;
98
+ _passCoordinatorInstance = null;
70
99
  _canvas;
71
100
  _contextLost;
72
101
  _renderTarget;
@@ -79,14 +108,28 @@ class WebGl2Backend {
79
108
  _clearColor = new Color();
80
109
  _boundFramebuffer = null;
81
110
  _stats = createRenderStats();
111
+ _transformBuffer = new TransformBuffer();
112
+ _transformTexture = null;
113
+ _transformTextureHash = 0;
114
+ _transformTextureCount = -1;
115
+ _activeDrawCommand = null;
116
+ _drawPlanDepth = 0;
82
117
  constructor(app) {
83
- const { width, height, clearColor, webglAttributes, debug, spriteRendererBatchSize, particleRendererBatchSize } = app.options;
118
+ const canvasOptions = app.options.canvas ?? {};
119
+ const renderingOptions = app.options.rendering ?? {};
120
+ const width = canvasOptions.width ?? 800;
121
+ const height = canvasOptions.height ?? 600;
122
+ const clearColor = app.options.clearColor;
123
+ const webglAttributes = renderingOptions.webglAttributes;
124
+ const debug = renderingOptions.debug ?? false;
125
+ const spriteRendererBatchSize = renderingOptions.spriteRendererBatchSize ?? 4096;
126
+ const particleRendererBatchSize = renderingOptions.particleRendererBatchSize ?? 8192;
84
127
  this._canvas = app.canvas;
85
128
  const gl = this._createContext(webglAttributes);
86
129
  if (!gl) {
87
130
  throw new Error('This browser or hardware does not support WebGL.');
88
131
  }
89
- this._context = debug ? WebGLDebugUtils.makeDebugContext(gl, throwOnGlError, logAndValidate, gl) : gl;
132
+ this._context = debug ? makeWebGl2DebugContext(gl) : gl;
90
133
  this._contextLost = this._context.isContextLost();
91
134
  if (this._contextLost) {
92
135
  this._restoreContext();
@@ -103,6 +146,8 @@ class WebGl2Backend {
103
146
  this.rendererRegistry.registerRenderer(Sprite, new WebGl2SpriteRenderer(spriteRendererBatchSize));
104
147
  this.rendererRegistry.registerRenderer(Mesh, new WebGl2MeshRenderer());
105
148
  this.rendererRegistry.registerRenderer(ParticleSystem, new WebGl2ParticleRenderer(particleRendererBatchSize));
149
+ this.rendererRegistry.registerRenderer(Text, new WebGl2TextRenderer());
150
+ this.rendererRegistry.registerRenderer(BitmapText, new WebGl2TextRenderer());
106
151
  this.rendererRegistry.connect(this);
107
152
  this._bindRenderTarget(this._renderTarget);
108
153
  this.setBlendMode(BlendModes.Normal);
@@ -123,6 +168,19 @@ class WebGl2Backend {
123
168
  get stats() {
124
169
  return this._stats;
125
170
  }
171
+ /** @internal */
172
+ get activeDrawCommand() {
173
+ return this._activeDrawCommand;
174
+ }
175
+ /**
176
+ * Internal render-pass coordinator. Owns target / view / clear orchestration
177
+ * and the scissor / stencil-clip stacks for this backend; not part of the
178
+ * public {@link RenderBackend} surface.
179
+ * @internal
180
+ */
181
+ get _passCoordinator() {
182
+ return (this._passCoordinatorInstance ??= new WebGl2PassCoordinator(this));
183
+ }
126
184
  async initialize() {
127
185
  return this;
128
186
  }
@@ -130,10 +188,55 @@ class WebGl2Backend {
130
188
  resetRenderStats(this._stats);
131
189
  return this;
132
190
  }
191
+ /** @internal */
192
+ _beginDrawPlan(nodeCount) {
193
+ this._transformBuffer.begin(nodeCount);
194
+ this._activeDrawCommand = null;
195
+ this._drawPlanDepth++;
196
+ }
197
+ /** @internal */
198
+ _prepareDrawCommand(command) {
199
+ this._activeDrawCommand = command;
200
+ const drawable = command.drawable;
201
+ this._transformBuffer.write(command.nodeIndex, drawable.getGlobalTransform(), drawable.tint);
202
+ }
203
+ /** @internal */
204
+ _endDrawPlan() {
205
+ this._activeDrawCommand = null;
206
+ if (this._drawPlanDepth > 0) {
207
+ this._drawPlanDepth--;
208
+ }
209
+ // Only assert balance at the outermost plan: cacheAsBitmap draws a cache
210
+ // sprite via a nested render(), whose inner _endDrawPlan sees the still-open
211
+ // outer clips — those are not leaks.
212
+ if (this._drawPlanDepth === 0) {
213
+ this._assertBalancedStencil();
214
+ }
215
+ }
216
+ _assertBalancedStencil() {
217
+ let unpopped = 0;
218
+ for (const state of this._stencilStates.values()) {
219
+ unpopped += state.stack.length;
220
+ }
221
+ if (unpopped === 0) {
222
+ return;
223
+ }
224
+ // Reset so a leaked clip cannot corrupt subsequent frames, then surface it.
225
+ for (const state of this._stencilStates.values()) {
226
+ state.depth = 0;
227
+ state.stack.length = 0;
228
+ }
229
+ const gl = this._context;
230
+ gl.stencilFunc(gl.ALWAYS, 0, 0xff);
231
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
232
+ gl.disable(gl.STENCIL_TEST);
233
+ throw new Error(`Unbalanced stencil clip stack at end of frame (${unpopped} unpopped clip(s)).`);
234
+ }
133
235
  draw(drawable) {
134
236
  const renderer = this.rendererRegistry.resolve(drawable);
135
237
  this._setActiveRenderer(renderer);
136
238
  renderer.render(drawable);
239
+ this._activeDrawCommand = null;
137
240
  this._stats.submittedNodes++;
138
241
  return this;
139
242
  }
@@ -145,11 +248,18 @@ class WebGl2Backend {
145
248
  }
146
249
  setRenderTarget(target) {
147
250
  const renderTarget = target || this._rootRenderTarget;
148
- if (this._renderTarget !== renderTarget) {
251
+ const changed = this._renderTarget !== renderTarget;
252
+ if (changed) {
253
+ this._flushActiveRenderer();
149
254
  this._renderTarget = renderTarget;
150
255
  this._stats.renderTargetChanges++;
151
256
  }
152
257
  this._bindRenderTarget(renderTarget);
258
+ if (changed) {
259
+ // Stencil state is per-target: restore the new target's clip depth so an
260
+ // outer clip on the previous target does not leak onto this one.
261
+ this._applyStencilState(renderTarget);
262
+ }
153
263
  return this;
154
264
  }
155
265
  pushScissorRect(bounds) {
@@ -175,6 +285,65 @@ class WebGl2Backend {
175
285
  this._applyClipState();
176
286
  return this;
177
287
  }
288
+ pushStencilClip(shape, transform) {
289
+ const target = this._renderTarget;
290
+ const state = this._getStencilState(target);
291
+ if (state.depth >= 255) {
292
+ throw new Error('Stencil clip nesting exceeds the 255-level limit.');
293
+ }
294
+ this._flushActiveRenderer();
295
+ this._setActiveRenderer(null);
296
+ if (!this._stencilClipperConnected) {
297
+ this._stencilClipper.connect(this);
298
+ this._stencilClipperConnected = true;
299
+ }
300
+ const gl = this._context;
301
+ const depth = state.depth;
302
+ if (depth === 0) {
303
+ this._ensureTargetStencil();
304
+ gl.enable(gl.STENCIL_TEST);
305
+ // Clear the whole stencil buffer to 0 regardless of any active scissor,
306
+ // then restore the scissor state for the shape/content draws.
307
+ gl.disable(gl.SCISSOR_TEST);
308
+ gl.clearStencil(0);
309
+ gl.clear(gl.STENCIL_BUFFER_BIT);
310
+ this._applyClipState();
311
+ }
312
+ // Increment the stencil where the shape covers the already-valid region
313
+ // (EQUAL depth). Color/depth writes off so only the stencil is touched.
314
+ gl.colorMask(false, false, false, false);
315
+ gl.stencilFunc(gl.EQUAL, depth, 0xff);
316
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
317
+ this._stencilClipper.draw(this, shape, transform);
318
+ gl.colorMask(true, true, true, true);
319
+ state.depth = depth + 1;
320
+ state.stack.push({ shape, transform: new Matrix().copy(transform) });
321
+ // Content now passes only where the stencil equals the new depth.
322
+ gl.stencilFunc(gl.EQUAL, state.depth, 0xff);
323
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
324
+ return this;
325
+ }
326
+ popStencilClip() {
327
+ const target = this._renderTarget;
328
+ const state = this._getStencilState(target);
329
+ const entry = state.stack.pop();
330
+ if (entry === undefined) {
331
+ return this;
332
+ }
333
+ this._flushActiveRenderer();
334
+ this._setActiveRenderer(null);
335
+ const gl = this._context;
336
+ const depth = state.depth;
337
+ // Decrement the region this clip incremented, restoring the outer level.
338
+ gl.colorMask(false, false, false, false);
339
+ gl.stencilFunc(gl.EQUAL, depth, 0xff);
340
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
341
+ this._stencilClipper.draw(this, entry.shape, entry.transform);
342
+ gl.colorMask(true, true, true, true);
343
+ state.depth = depth - 1;
344
+ this._applyStencilState(target);
345
+ return this;
346
+ }
178
347
  composeWithAlphaMask(content, mask, x, y, width, height, blendMode) {
179
348
  if (width <= 0 || height <= 0) {
180
349
  return this;
@@ -217,10 +386,14 @@ class WebGl2Backend {
217
386
  bindVertexArrayObject(vao) {
218
387
  if (this._vao !== vao) {
219
388
  if (vao) {
389
+ // Binding a VAO implicitly replaces the previous binding. Only when
390
+ // switching to "no VAO" do we explicitly unbind — unbinding the old VAO
391
+ // *after* binding the new one would leave the GL default (null) VAO
392
+ // bound and silently break the next draw (a renderer/clip VAO switch).
220
393
  vao.bind();
221
394
  }
222
- if (this._vao) {
223
- this._vao.unbind();
395
+ else {
396
+ this._vao?.unbind();
224
397
  }
225
398
  this._vao = vao;
226
399
  }
@@ -255,24 +428,64 @@ class WebGl2Backend {
255
428
  this._texture = texture;
256
429
  return this;
257
430
  }
431
+ /** @internal */
432
+ bindTransformBufferTexture(unit, minCount) {
433
+ const requiredCount = Math.max(1, minCount);
434
+ const transformTexture = this._transformTexture;
435
+ if (transformTexture?.height !== this._transformBuffer.capacity || transformTexture.buffer !== this._transformBuffer.data) {
436
+ transformTexture?.destroy();
437
+ this._transformTexture = new DataTexture({
438
+ width: 3,
439
+ height: this._transformBuffer.capacity,
440
+ format: 'rgba32f',
441
+ data: this._transformBuffer.data,
442
+ });
443
+ this._transformTextureHash = 0;
444
+ this._transformTextureCount = -1;
445
+ }
446
+ const snapshot = this._transformBuffer.commitSnapshot(requiredCount);
447
+ const nextTransformTexture = this._transformTexture;
448
+ if (nextTransformTexture === null) {
449
+ throw new Error('Transform texture must be initialized before binding.');
450
+ }
451
+ if (snapshot.changed || snapshot.count !== this._transformTextureCount || snapshot.hash !== this._transformTextureHash) {
452
+ nextTransformTexture.commitRect(0, 0, 3, snapshot.count);
453
+ this._transformTextureHash = snapshot.hash;
454
+ this._transformTextureCount = snapshot.count;
455
+ }
456
+ return this.bindTexture(nextTransformTexture, unit);
457
+ }
258
458
  setBlendMode(blendMode) {
259
459
  if (blendMode !== this._blendMode) {
260
460
  const gl = this._context;
261
461
  this._blendMode = blendMode;
262
462
  switch (blendMode) {
263
463
  case BlendModes.Additive:
464
+ gl.blendEquation(gl.FUNC_ADD);
264
465
  gl.blendFunc(gl.ONE, gl.ONE);
265
466
  break;
266
467
  case BlendModes.Subtract:
468
+ gl.blendEquation(gl.FUNC_ADD);
267
469
  gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_COLOR);
268
470
  break;
269
471
  case BlendModes.Multiply:
472
+ gl.blendEquation(gl.FUNC_ADD);
270
473
  gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA);
271
474
  break;
272
475
  case BlendModes.Screen:
476
+ gl.blendEquation(gl.FUNC_ADD);
273
477
  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
274
478
  break;
479
+ case BlendModes.Darken:
480
+ gl.blendEquation(gl.MIN);
481
+ gl.blendFunc(gl.ONE, gl.ONE);
482
+ break;
483
+ case BlendModes.Lighten:
484
+ gl.blendEquation(gl.MAX);
485
+ gl.blendFunc(gl.ONE, gl.ONE);
486
+ break;
275
487
  default:
488
+ gl.blendEquation(gl.FUNC_ADD);
276
489
  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
277
490
  break;
278
491
  }
@@ -304,8 +517,6 @@ class WebGl2Backend {
304
517
  return this;
305
518
  }
306
519
  resize(width, height) {
307
- this._canvas.width = width;
308
- this._canvas.height = height;
309
520
  this._rootRenderTarget.resize(width, height);
310
521
  this._bindRenderTarget(this._renderTarget);
311
522
  return this;
@@ -338,17 +549,33 @@ class WebGl2Backend {
338
549
  this._maskCompositor.disconnect();
339
550
  this._maskCompositorConnected = false;
340
551
  }
552
+ if (this._stencilClipperConnected) {
553
+ this._stencilClipper.disconnect();
554
+ this._stencilClipperConnected = false;
555
+ }
556
+ this._stencilStates.clear();
557
+ this._drawPlanDepth = 0;
341
558
  this._rootRenderTarget.destroy();
559
+ if (this._transformTexture !== null) {
560
+ this._transformTexture.destroy();
561
+ this._transformTexture = null;
562
+ }
342
563
  this._vao = null;
343
564
  this._renderer = null;
344
565
  this._shader = null;
345
566
  this._blendMode = null;
346
567
  this._texture = null;
347
568
  this._boundFramebuffer = null;
569
+ this._activeDrawCommand = null;
570
+ this._transformTextureCount = -1;
571
+ this._transformTextureHash = 0;
348
572
  }
349
573
  _createContext(options) {
350
574
  try {
351
- return this._canvas.getContext('webgl2', options);
575
+ // Force a stencil buffer on the default framebuffer so geometric stencil
576
+ // clipping (RenderNode.clip with a Geometry clipShape) works on the root
577
+ // target. Inert until a clip is pushed (STENCIL_TEST stays disabled).
578
+ return this._canvas.getContext('webgl2', { ...options, stencil: true });
352
579
  }
353
580
  catch (_e) {
354
581
  return null;
@@ -422,6 +649,9 @@ class WebGl2Backend {
422
649
  framebuffer: target.root ? null : this._createFramebuffer(),
423
650
  version: -1,
424
651
  attachedTexture: null,
652
+ stencilRenderbuffer: null,
653
+ stencilWidth: 0,
654
+ stencilHeight: 0,
425
655
  };
426
656
  this._renderTargetStates.set(target, state);
427
657
  }
@@ -470,8 +700,13 @@ class WebGl2Backend {
470
700
  if (state.framebuffer !== null) {
471
701
  this._context.deleteFramebuffer(state.framebuffer);
472
702
  }
703
+ if (state.stencilRenderbuffer !== null) {
704
+ this._context.deleteRenderbuffer(state.stencilRenderbuffer);
705
+ state.stencilRenderbuffer = null;
706
+ }
473
707
  this._renderTargetStates.delete(target);
474
708
  }
709
+ this._stencilStates.delete(target);
475
710
  if (this._renderTarget === target) {
476
711
  this._renderTarget = this._rootRenderTarget;
477
712
  if (rebind) {
@@ -501,7 +736,13 @@ class WebGl2Backend {
501
736
  const state = this._prepareRenderTarget(target);
502
737
  if (this._boundFramebuffer !== state.framebuffer || state.version !== target.version) {
503
738
  const gl = this._context;
504
- const { x, y, width, height } = target.getViewport();
739
+ const viewport = target.getViewport();
740
+ const scaleX = target.root && target.width > 0 ? this._canvas.width / target.width : 1;
741
+ const scaleY = target.root && target.height > 0 ? this._canvas.height / target.height : 1;
742
+ const x = Math.floor(viewport.x * scaleX);
743
+ const y = Math.floor(viewport.y * scaleY);
744
+ const width = Math.max(0, Math.round(viewport.width * scaleX));
745
+ const height = Math.max(0, Math.round(viewport.height * scaleY));
505
746
  gl.bindFramebuffer(gl.FRAMEBUFFER, state.framebuffer);
506
747
  gl.viewport(x, y, width, height);
507
748
  this._boundFramebuffer = state.framebuffer;
@@ -527,7 +768,10 @@ class WebGl2Backend {
527
768
  const state = this._getRenderTargetState(target);
528
769
  if (target instanceof RenderTexture && state.framebuffer) {
529
770
  const previousFramebuffer = this._boundFramebuffer;
771
+ const previousUnit = this._textureUnit;
772
+ this._setTextureUnit(renderTargetTextureSyncUnit);
530
773
  const textureState = this._syncTexture(target);
774
+ this._setTextureUnit(previousUnit);
531
775
  if (state.attachedTexture !== textureState.handle) {
532
776
  const gl = this._context;
533
777
  gl.bindFramebuffer(gl.FRAMEBUFFER, state.framebuffer);
@@ -535,9 +779,76 @@ class WebGl2Backend {
535
779
  gl.bindFramebuffer(gl.FRAMEBUFFER, previousFramebuffer);
536
780
  state.attachedTexture = textureState.handle;
537
781
  }
782
+ // Reset the on-demand flag for pooled RenderTexture targets, so a
783
+ // stencil renderbuffer from a previous use does not permanently
784
+ // consume GPU memory when the target is re-purposed for non-clip
785
+ // rendering.
786
+ if (!this._stencilStates.has(target)) {
787
+ target.needsStencil = false;
788
+ }
789
+ // Keep an existing stencil attachment sized to the (possibly resized)
790
+ // texture so the framebuffer stays complete during non-clip rendering.
791
+ if (target.needsStencil || state.stencilRenderbuffer !== null) {
792
+ this._syncStencilAttachment(target, state);
793
+ }
794
+ }
795
+ return state;
796
+ }
797
+ /** Attach a depth/stencil renderbuffer to the active target if it lacks one. */
798
+ _ensureTargetStencil() {
799
+ const target = this._renderTarget;
800
+ if (target.root) {
801
+ // The default framebuffer's stencil comes from the context attributes.
802
+ return;
803
+ }
804
+ target.needsStencil = true;
805
+ this._syncStencilAttachment(target, this._getRenderTargetState(target));
806
+ }
807
+ _syncStencilAttachment(target, state) {
808
+ if (state.framebuffer === null) {
809
+ return;
810
+ }
811
+ const gl = this._context;
812
+ const width = Math.max(1, target.width);
813
+ const height = Math.max(1, target.height);
814
+ if (state.stencilRenderbuffer !== null && state.stencilWidth === width && state.stencilHeight === height) {
815
+ return;
816
+ }
817
+ if (state.stencilRenderbuffer === null) {
818
+ state.stencilRenderbuffer = gl.createRenderbuffer();
819
+ }
820
+ gl.bindRenderbuffer(gl.RENDERBUFFER, state.stencilRenderbuffer);
821
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
822
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
823
+ const previousFramebuffer = this._boundFramebuffer;
824
+ gl.bindFramebuffer(gl.FRAMEBUFFER, state.framebuffer);
825
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, state.stencilRenderbuffer);
826
+ gl.bindFramebuffer(gl.FRAMEBUFFER, previousFramebuffer);
827
+ state.stencilWidth = width;
828
+ state.stencilHeight = height;
829
+ }
830
+ _getStencilState(target) {
831
+ let state = this._stencilStates.get(target);
832
+ if (state === undefined) {
833
+ state = { depth: 0, stack: [] };
834
+ this._stencilStates.set(target, state);
538
835
  }
539
836
  return state;
540
837
  }
838
+ /** Re-apply the GL stencil test to match `target`'s current clip depth. */
839
+ _applyStencilState(target) {
840
+ const gl = this._context;
841
+ const depth = this._getStencilState(target).depth;
842
+ if (depth === 0) {
843
+ gl.stencilFunc(gl.ALWAYS, 0, 0xff);
844
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
845
+ gl.disable(gl.STENCIL_TEST);
846
+ return;
847
+ }
848
+ gl.enable(gl.STENCIL_TEST);
849
+ gl.stencilFunc(gl.EQUAL, depth, 0xff);
850
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
851
+ }
541
852
  _syncTexture(texture) {
542
853
  const gl = this._context;
543
854
  const state = this._getTextureState(texture);
@@ -640,8 +951,14 @@ class WebGl2Backend {
640
951
  return;
641
952
  }
642
953
  const clip = this._clipPixelStack[this._clipPixelStack.length - 1];
954
+ const scaleX = this._renderTarget.root && this._renderTarget.width > 0 ? this._canvas.width / this._renderTarget.width : 1;
955
+ const scaleY = this._renderTarget.root && this._renderTarget.height > 0 ? this._canvas.height / this._renderTarget.height : 1;
956
+ const x = Math.floor(clip.x * scaleX);
957
+ const y = Math.floor(clip.y * scaleY);
958
+ const width = Math.max(0, Math.round(clip.width * scaleX));
959
+ const height = Math.max(0, Math.round(clip.height * scaleY));
643
960
  gl.enable(gl.SCISSOR_TEST);
644
- gl.scissor(clip.x, clip.y, clip.width, clip.height);
961
+ gl.scissor(x, y, width, height);
645
962
  }
646
963
  }
647
964
  // WebGL2RenderingContext is not defined in jsdom; resolve constants from