@driftengine/core 3.61.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 (955) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/README.md +9 -0
  4. package/dist/behavior/behaviorTree.d.ts +140 -0
  5. package/dist/behavior/behaviorTree.js +289 -0
  6. package/dist/build/shaderComments.d.ts +64 -0
  7. package/dist/build/shaderComments.js +0 -0
  8. package/dist/cinematic/player.d.ts +80 -0
  9. package/dist/cinematic/player.js +184 -0
  10. package/dist/cinematic/script.d.ts +63 -0
  11. package/dist/cinematic/script.js +141 -0
  12. package/dist/core/bootGate.d.ts +37 -0
  13. package/dist/core/bootGate.js +47 -0
  14. package/dist/core/loadTracker.d.ts +78 -0
  15. package/dist/core/loadTracker.js +106 -0
  16. package/dist/core/loop.d.ts +118 -0
  17. package/dist/core/loop.js +84 -0
  18. package/dist/core/messageQueue.d.ts +61 -0
  19. package/dist/core/messageQueue.js +104 -0
  20. package/dist/core/onceSet.d.ts +27 -0
  21. package/dist/core/onceSet.js +62 -0
  22. package/dist/core/preferences.d.ts +47 -0
  23. package/dist/core/preferences.js +140 -0
  24. package/dist/core/remoteSave.d.ts +154 -0
  25. package/dist/core/remoteSave.js +249 -0
  26. package/dist/core/rng.d.ts +64 -0
  27. package/dist/core/rng.js +72 -0
  28. package/dist/core/stepBudget.d.ts +91 -0
  29. package/dist/core/stepBudget.js +105 -0
  30. package/dist/core/storage.d.ts +52 -0
  31. package/dist/core/storage.js +85 -0
  32. package/dist/core/tickTrace.d.ts +72 -0
  33. package/dist/core/tickTrace.js +102 -0
  34. package/dist/core/timeCurve.d.ts +83 -0
  35. package/dist/core/timeCurve.js +107 -0
  36. package/dist/core/withDefaults.d.ts +21 -0
  37. package/dist/core/withDefaults.js +29 -0
  38. package/dist/dev/contactProbe.d.ts +41 -0
  39. package/dist/dev/contactProbe.js +58 -0
  40. package/dist/dev/fpsMeter.d.ts +45 -0
  41. package/dist/dev/fpsMeter.js +86 -0
  42. package/dist/environment/celestialClock.d.ts +141 -0
  43. package/dist/environment/celestialClock.js +262 -0
  44. package/dist/geometry/decal.d.ts +61 -0
  45. package/dist/geometry/decal.js +178 -0
  46. package/dist/geometry/filmPatch.d.ts +35 -0
  47. package/dist/geometry/filmPatch.js +112 -0
  48. package/dist/geometry/growable.d.ts +70 -0
  49. package/dist/geometry/growable.js +167 -0
  50. package/dist/geometry/lightVolume.d.ts +76 -0
  51. package/dist/geometry/lightVolume.js +65 -0
  52. package/dist/geometry/meshBuilder.d.ts +426 -0
  53. package/dist/geometry/meshBuilder.js +1184 -0
  54. package/dist/geometry/pixelFont.d.ts +59 -0
  55. package/dist/geometry/pixelFont.js +179 -0
  56. package/dist/geometry/ribbon.d.ts +101 -0
  57. package/dist/geometry/ribbon.js +546 -0
  58. package/dist/geometry/shellFill.d.ts +101 -0
  59. package/dist/geometry/shellFill.js +203 -0
  60. package/dist/geometry/spline.d.ts +162 -0
  61. package/dist/geometry/spline.js +527 -0
  62. package/dist/geometry/tangents.d.ts +30 -0
  63. package/dist/geometry/tangents.js +142 -0
  64. package/dist/geometry/textMesh.d.ts +51 -0
  65. package/dist/geometry/textMesh.js +57 -0
  66. package/dist/geometry/treeBuilder.d.ts +37 -0
  67. package/dist/geometry/treeBuilder.js +56 -0
  68. package/dist/host/display.d.ts +135 -0
  69. package/dist/host/display.js +114 -0
  70. package/dist/host/files.d.ts +25 -0
  71. package/dist/host/files.js +44 -0
  72. package/dist/host/lifecycle.d.ts +45 -0
  73. package/dist/host/lifecycle.js +28 -0
  74. package/dist/host/platformServices.d.ts +23 -0
  75. package/dist/host/platformServices.js +1 -0
  76. package/dist/host/screen.d.ts +49 -0
  77. package/dist/host/screen.js +90 -0
  78. package/dist/index.d.ts +289 -0
  79. package/dist/index.js +320 -0
  80. package/dist/input/actionMap.d.ts +181 -0
  81. package/dist/input/actionMap.js +314 -0
  82. package/dist/input/activeDevice.d.ts +55 -0
  83. package/dist/input/activeDevice.js +83 -0
  84. package/dist/input/gamepadIdentity.d.ts +43 -0
  85. package/dist/input/gamepadIdentity.js +108 -0
  86. package/dist/input/gamepadMapping.d.ts +56 -0
  87. package/dist/input/gamepadMapping.js +91 -0
  88. package/dist/input/input.d.ts +281 -0
  89. package/dist/input/input.js +703 -0
  90. package/dist/input/inputHarness.d.ts +42 -0
  91. package/dist/input/inputHarness.js +193 -0
  92. package/dist/input/rightGesture.d.ts +57 -0
  93. package/dist/input/rightGesture.js +49 -0
  94. package/dist/input/rumble.d.ts +71 -0
  95. package/dist/input/rumble.js +119 -0
  96. package/dist/input/touchControls.d.ts +138 -0
  97. package/dist/input/touchControls.js +352 -0
  98. package/dist/input/typingTarget.d.ts +6 -0
  99. package/dist/input/typingTarget.js +27 -0
  100. package/dist/math/bounds.d.ts +61 -0
  101. package/dist/math/bounds.js +121 -0
  102. package/dist/math/color.d.ts +8 -0
  103. package/dist/math/color.js +35 -0
  104. package/dist/math/exact.d.ts +66 -0
  105. package/dist/math/exact.js +262 -0
  106. package/dist/math/frustum.d.ts +44 -0
  107. package/dist/math/frustum.js +90 -0
  108. package/dist/math/intersect.d.ts +76 -0
  109. package/dist/math/intersect.js +185 -0
  110. package/dist/math/scalar.d.ts +51 -0
  111. package/dist/math/scalar.js +99 -0
  112. package/dist/math/spring.d.ts +59 -0
  113. package/dist/math/spring.js +88 -0
  114. package/dist/nav/navGraph.d.ts +71 -0
  115. package/dist/nav/navGraph.js +111 -0
  116. package/dist/nav/navPath.d.ts +93 -0
  117. package/dist/nav/navPath.js +162 -0
  118. package/dist/nav/navSearch.d.ts +74 -0
  119. package/dist/nav/navSearch.js +198 -0
  120. package/dist/physics/boxSurface.d.ts +48 -0
  121. package/dist/physics/boxSurface.js +73 -0
  122. package/dist/physics/colliderSurface.d.ts +46 -0
  123. package/dist/physics/colliderSurface.js +146 -0
  124. package/dist/physics/compositeSurface.d.ts +33 -0
  125. package/dist/physics/compositeSurface.js +108 -0
  126. package/dist/physics/heightSurface.d.ts +103 -0
  127. package/dist/physics/heightSurface.js +153 -0
  128. package/dist/physics/ribbonSurface.d.ts +239 -0
  129. package/dist/physics/ribbonSurface.js +522 -0
  130. package/dist/render/ambientOcclusionPass.d.ts +53 -0
  131. package/dist/render/ambientOcclusionPass.js +179 -0
  132. package/dist/render/areaLights.d.ts +116 -0
  133. package/dist/render/areaLights.js +91 -0
  134. package/dist/render/areaShadowSet.d.ts +184 -0
  135. package/dist/render/areaShadowSet.js +277 -0
  136. package/dist/render/atmosphere.d.ts +94 -0
  137. package/dist/render/atmosphere.js +91 -0
  138. package/dist/render/backend/api.d.ts +496 -0
  139. package/dist/render/backend/api.js +1 -0
  140. package/dist/render/backend/budget.d.ts +82 -0
  141. package/dist/render/backend/budget.js +99 -0
  142. package/dist/render/backend/createRenderer.d.ts +135 -0
  143. package/dist/render/backend/createRenderer.js +201 -0
  144. package/dist/render/backend/deadline.d.ts +24 -0
  145. package/dist/render/backend/deadline.js +38 -0
  146. package/dist/render/backend/probe.d.ts +30 -0
  147. package/dist/render/backend/probe.js +129 -0
  148. package/dist/render/backend/select.d.ts +70 -0
  149. package/dist/render/backend/select.js +249 -0
  150. package/dist/render/backend/timer.d.ts +50 -0
  151. package/dist/render/backend/timer.js +1 -0
  152. package/dist/render/backend/webgl2/instanced.d.ts +21 -0
  153. package/dist/render/backend/webgl2/instanced.js +42 -0
  154. package/dist/render/backend/webgl2/morphTexture.d.ts +21 -0
  155. package/dist/render/backend/webgl2/morphTexture.js +55 -0
  156. package/dist/render/backend/webgl2/renderer.d.ts +3027 -0
  157. package/dist/render/backend/webgl2/renderer.js +6041 -0
  158. package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +32 -0
  159. package/dist/render/backend/webgl2/skinPaletteTexture.js +68 -0
  160. package/dist/render/backend/webgpu/boltPass.d.ts +42 -0
  161. package/dist/render/backend/webgpu/boltPass.js +160 -0
  162. package/dist/render/backend/webgpu/buffers.d.ts +159 -0
  163. package/dist/render/backend/webgpu/buffers.js +402 -0
  164. package/dist/render/backend/webgpu/causticsPass.d.ts +36 -0
  165. package/dist/render/backend/webgpu/causticsPass.js +138 -0
  166. package/dist/render/backend/webgpu/clusterBinner.d.ts +51 -0
  167. package/dist/render/backend/webgpu/clusterBinner.js +206 -0
  168. package/dist/render/backend/webgpu/depthPass.d.ts +114 -0
  169. package/dist/render/backend/webgpu/depthPass.js +228 -0
  170. package/dist/render/backend/webgpu/device.d.ts +52 -0
  171. package/dist/render/backend/webgpu/device.js +121 -0
  172. package/dist/render/backend/webgpu/drawCommand.d.ts +43 -0
  173. package/dist/render/backend/webgpu/drawCommand.js +54 -0
  174. package/dist/render/backend/webgpu/environmentTexels.d.ts +28 -0
  175. package/dist/render/backend/webgpu/environmentTexels.js +79 -0
  176. package/dist/render/backend/webgpu/filmPass.d.ts +29 -0
  177. package/dist/render/backend/webgpu/filmPass.js +97 -0
  178. package/dist/render/backend/webgpu/flatPass.d.ts +213 -0
  179. package/dist/render/backend/webgpu/flatPass.js +482 -0
  180. package/dist/render/backend/webgpu/flockPass.d.ts +34 -0
  181. package/dist/render/backend/webgpu/flockPass.js +129 -0
  182. package/dist/render/backend/webgpu/gpuTimestamps.d.ts +94 -0
  183. package/dist/render/backend/webgpu/gpuTimestamps.js +213 -0
  184. package/dist/render/backend/webgpu/insetPass.d.ts +19 -0
  185. package/dist/render/backend/webgpu/insetPass.js +108 -0
  186. package/dist/render/backend/webgpu/instanced.d.ts +27 -0
  187. package/dist/render/backend/webgpu/instanced.js +49 -0
  188. package/dist/render/backend/webgpu/lightVolumePass.d.ts +75 -0
  189. package/dist/render/backend/webgpu/lightVolumePass.js +154 -0
  190. package/dist/render/backend/webgpu/linePass.d.ts +90 -0
  191. package/dist/render/backend/webgpu/linePass.js +220 -0
  192. package/dist/render/backend/webgpu/morphTexture.d.ts +18 -0
  193. package/dist/render/backend/webgpu/morphTexture.js +51 -0
  194. package/dist/render/backend/webgpu/panelPass.d.ts +37 -0
  195. package/dist/render/backend/webgpu/panelPass.js +114 -0
  196. package/dist/render/backend/webgpu/particlePass.d.ts +89 -0
  197. package/dist/render/backend/webgpu/particlePass.js +280 -0
  198. package/dist/render/backend/webgpu/pipelineCache.d.ts +93 -0
  199. package/dist/render/backend/webgpu/pipelineCache.js +140 -0
  200. package/dist/render/backend/webgpu/plumePass.d.ts +69 -0
  201. package/dist/render/backend/webgpu/plumePass.js +213 -0
  202. package/dist/render/backend/webgpu/pointShadowPass.d.ts +88 -0
  203. package/dist/render/backend/webgpu/pointShadowPass.js +280 -0
  204. package/dist/render/backend/webgpu/postPass.d.ts +342 -0
  205. package/dist/render/backend/webgpu/postPass.js +366 -0
  206. package/dist/render/backend/webgpu/probePass.d.ts +108 -0
  207. package/dist/render/backend/webgpu/probePass.js +188 -0
  208. package/dist/render/backend/webgpu/reflectionPass.d.ts +29 -0
  209. package/dist/render/backend/webgpu/reflectionPass.js +87 -0
  210. package/dist/render/backend/webgpu/renderer.d.ts +3082 -0
  211. package/dist/render/backend/webgpu/renderer.js +10911 -0
  212. package/dist/render/backend/webgpu/scatterPass.d.ts +95 -0
  213. package/dist/render/backend/webgpu/scatterPass.js +266 -0
  214. package/dist/render/backend/webgpu/sdfTextPass.d.ts +86 -0
  215. package/dist/render/backend/webgpu/sdfTextPass.js +190 -0
  216. package/dist/render/backend/webgpu/shaderModules.d.ts +9 -0
  217. package/dist/render/backend/webgpu/shaderModules.js +45 -0
  218. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +23 -0
  219. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.js +208 -0
  220. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +67 -0
  221. package/dist/render/backend/webgpu/skinPaletteRing.js +97 -0
  222. package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +17 -0
  223. package/dist/render/backend/webgpu/skinPaletteTexture.js +68 -0
  224. package/dist/render/backend/webgpu/skyPass.d.ts +102 -0
  225. package/dist/render/backend/webgpu/skyPass.js +70 -0
  226. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +41 -0
  227. package/dist/render/backend/webgpu/surfaceTexturePass.js +228 -0
  228. package/dist/render/backend/webgpu/textPass.d.ts +73 -0
  229. package/dist/render/backend/webgpu/textPass.js +190 -0
  230. package/dist/render/backend/webgpu/uniformRing.d.ts +133 -0
  231. package/dist/render/backend/webgpu/uniformRing.js +208 -0
  232. package/dist/render/backend/webgpu/waterPass.d.ts +73 -0
  233. package/dist/render/backend/webgpu/waterPass.js +160 -0
  234. package/dist/render/backend/webgpu/windStreakPass.d.ts +46 -0
  235. package/dist/render/backend/webgpu/windStreakPass.js +153 -0
  236. package/dist/render/billboard.d.ts +27 -0
  237. package/dist/render/billboard.js +79 -0
  238. package/dist/render/bloomChain.d.ts +66 -0
  239. package/dist/render/bloomChain.js +83 -0
  240. package/dist/render/bloomPass.d.ts +54 -0
  241. package/dist/render/bloomPass.js +219 -0
  242. package/dist/render/boltBatch.d.ts +39 -0
  243. package/dist/render/boltBatch.js +121 -0
  244. package/dist/render/boltPool.d.ts +135 -0
  245. package/dist/render/boltPool.js +259 -0
  246. package/dist/render/boom.d.ts +46 -0
  247. package/dist/render/boom.js +81 -0
  248. package/dist/render/camera.d.ts +119 -0
  249. package/dist/render/camera.js +304 -0
  250. package/dist/render/causticsRenderer.d.ts +63 -0
  251. package/dist/render/causticsRenderer.js +119 -0
  252. package/dist/render/cinematicCamera.d.ts +102 -0
  253. package/dist/render/cinematicCamera.js +227 -0
  254. package/dist/render/clusteredLights.d.ts +260 -0
  255. package/dist/render/clusteredLights.js +479 -0
  256. package/dist/render/colourGrade.d.ts +62 -0
  257. package/dist/render/colourGrade.js +91 -0
  258. package/dist/render/compute.d.ts +74 -0
  259. package/dist/render/compute.js +8 -0
  260. package/dist/render/contextLoss.d.ts +32 -0
  261. package/dist/render/contextLoss.js +46 -0
  262. package/dist/render/debugLines.d.ts +75 -0
  263. package/dist/render/debugLines.js +281 -0
  264. package/dist/render/decalPass.d.ts +34 -0
  265. package/dist/render/decalPass.js +103 -0
  266. package/dist/render/decalProjector.d.ts +140 -0
  267. package/dist/render/decalProjector.js +282 -0
  268. package/dist/render/decalQueue.d.ts +53 -0
  269. package/dist/render/decalQueue.js +87 -0
  270. package/dist/render/depthConvention.d.ts +314 -0
  271. package/dist/render/depthConvention.js +346 -0
  272. package/dist/render/drawingBuffer.d.ts +52 -0
  273. package/dist/render/drawingBuffer.js +67 -0
  274. package/dist/render/emptyTexture.d.ts +60 -0
  275. package/dist/render/emptyTexture.js +103 -0
  276. package/dist/render/envProbeArray.d.ts +85 -0
  277. package/dist/render/envProbeArray.js +164 -0
  278. package/dist/render/equirectToCube.d.ts +54 -0
  279. package/dist/render/equirectToCube.js +123 -0
  280. package/dist/render/flockGeometry.d.ts +23 -0
  281. package/dist/render/flockGeometry.js +43 -0
  282. package/dist/render/flockRenderer.d.ts +37 -0
  283. package/dist/render/flockRenderer.js +70 -0
  284. package/dist/render/frame/arena.d.ts +32 -0
  285. package/dist/render/frame/arena.js +65 -0
  286. package/dist/render/frame/index.d.ts +18 -0
  287. package/dist/render/frame/index.js +4 -0
  288. package/dist/render/frame/replay.d.ts +34 -0
  289. package/dist/render/frame/replay.js +48 -0
  290. package/dist/render/frame/resources.d.ts +25 -0
  291. package/dist/render/frame/resources.js +55 -0
  292. package/dist/render/frame/schedule.d.ts +37 -0
  293. package/dist/render/frame/schedule.js +61 -0
  294. package/dist/render/frameView.d.ts +19 -0
  295. package/dist/render/frameView.js +1 -0
  296. package/dist/render/gizmo.d.ts +236 -0
  297. package/dist/render/gizmo.js +727 -0
  298. package/dist/render/globalMedium.d.ts +124 -0
  299. package/dist/render/globalMedium.js +100 -0
  300. package/dist/render/globalMediumPass.d.ts +101 -0
  301. package/dist/render/globalMediumPass.js +250 -0
  302. package/dist/render/gpuCapability.d.ts +111 -0
  303. package/dist/render/gpuCapability.js +194 -0
  304. package/dist/render/gpuTimer.d.ts +87 -0
  305. package/dist/render/gpuTimer.js +145 -0
  306. package/dist/render/halfFloat.d.ts +4 -0
  307. package/dist/render/halfFloat.js +38 -0
  308. package/dist/render/handleRegistry.d.ts +54 -0
  309. package/dist/render/handleRegistry.js +84 -0
  310. package/dist/render/iesProfile.d.ts +64 -0
  311. package/dist/render/iesProfile.js +179 -0
  312. package/dist/render/imageTexels.d.ts +50 -0
  313. package/dist/render/imageTexels.js +91 -0
  314. package/dist/render/instancedMesh.d.ts +48 -0
  315. package/dist/render/instancedMesh.js +127 -0
  316. package/dist/render/instances.d.ts +69 -0
  317. package/dist/render/instances.js +52 -0
  318. package/dist/render/lightBudget.d.ts +397 -0
  319. package/dist/render/lightBudget.js +524 -0
  320. package/dist/render/lightMatrix.d.ts +3 -0
  321. package/dist/render/lightMatrix.js +45 -0
  322. package/dist/render/lightVolumeDraw.d.ts +132 -0
  323. package/dist/render/lightVolumeDraw.js +181 -0
  324. package/dist/render/lineBatch.d.ts +60 -0
  325. package/dist/render/lineBatch.js +160 -0
  326. package/dist/render/linePoints.d.ts +33 -0
  327. package/dist/render/linePoints.js +46 -0
  328. package/dist/render/livePointShadowSet.d.ts +72 -0
  329. package/dist/render/livePointShadowSet.js +258 -0
  330. package/dist/render/lod.d.ts +35 -0
  331. package/dist/render/lod.js +65 -0
  332. package/dist/render/mesh.d.ts +177 -0
  333. package/dist/render/mesh.js +466 -0
  334. package/dist/render/occlusion.d.ts +81 -0
  335. package/dist/render/occlusion.js +378 -0
  336. package/dist/render/oitPass.d.ts +67 -0
  337. package/dist/render/oitPass.js +213 -0
  338. package/dist/render/orderIndependent.d.ts +92 -0
  339. package/dist/render/orderIndependent.js +108 -0
  340. package/dist/render/particleBatch.d.ts +140 -0
  341. package/dist/render/particleBatch.js +186 -0
  342. package/dist/render/particleMaterial.d.ts +54 -0
  343. package/dist/render/particleMaterial.js +42 -0
  344. package/dist/render/particlePool.d.ts +124 -0
  345. package/dist/render/particlePool.js +182 -0
  346. package/dist/render/pass.d.ts +195 -0
  347. package/dist/render/pass.js +9 -0
  348. package/dist/render/passTarget.d.ts +86 -0
  349. package/dist/render/passTarget.js +121 -0
  350. package/dist/render/pickable.d.ts +31 -0
  351. package/dist/render/pickable.js +172 -0
  352. package/dist/render/planarReflection.d.ts +59 -0
  353. package/dist/render/planarReflection.js +194 -0
  354. package/dist/render/planarReflectionDraw.d.ts +31 -0
  355. package/dist/render/planarReflectionDraw.js +65 -0
  356. package/dist/render/plumeGeometry.d.ts +25 -0
  357. package/dist/render/plumeGeometry.js +61 -0
  358. package/dist/render/plumeMaterial.d.ts +31 -0
  359. package/dist/render/plumeMaterial.js +64 -0
  360. package/dist/render/plumeRenderer.d.ts +96 -0
  361. package/dist/render/plumeRenderer.js +185 -0
  362. package/dist/render/pointLightSelection.d.ts +175 -0
  363. package/dist/render/pointLightSelection.js +301 -0
  364. package/dist/render/pointShadowArray.d.ts +95 -0
  365. package/dist/render/pointShadowArray.js +219 -0
  366. package/dist/render/pointShadowBudget.d.ts +118 -0
  367. package/dist/render/pointShadowBudget.js +221 -0
  368. package/dist/render/pointShadowImage.d.ts +265 -0
  369. package/dist/render/pointShadowImage.js +339 -0
  370. package/dist/render/pointShadowMap.d.ts +93 -0
  371. package/dist/render/pointShadowMap.js +167 -0
  372. package/dist/render/pointShadowSystem.d.ts +195 -0
  373. package/dist/render/pointShadowSystem.js +336 -0
  374. package/dist/render/prefilterEnvMap.d.ts +124 -0
  375. package/dist/render/prefilterEnvMap.js +146 -0
  376. package/dist/render/prefilterPass.d.ts +44 -0
  377. package/dist/render/prefilterPass.js +98 -0
  378. package/dist/render/probeGrid.d.ts +122 -0
  379. package/dist/render/probeGrid.js +174 -0
  380. package/dist/render/rainField.d.ts +99 -0
  381. package/dist/render/rainField.js +168 -0
  382. package/dist/render/reflectionProbe.d.ts +188 -0
  383. package/dist/render/reflectionProbe.js +437 -0
  384. package/dist/render/renderQuality.d.ts +699 -0
  385. package/dist/render/renderQuality.js +293 -0
  386. package/dist/render/rendererHarness.d.ts +39 -0
  387. package/dist/render/rendererHarness.js +185 -0
  388. package/dist/render/resolutionGovernor.d.ts +107 -0
  389. package/dist/render/resolutionGovernor.js +144 -0
  390. package/dist/render/scatterDeform.d.ts +17 -0
  391. package/dist/render/scatterDeform.js +46 -0
  392. package/dist/render/sceneTarget.d.ts +288 -0
  393. package/dist/render/sceneTarget.js +856 -0
  394. package/dist/render/screenSpaceReflection.d.ts +233 -0
  395. package/dist/render/screenSpaceReflection.js +415 -0
  396. package/dist/render/sdfFont.d.ts +77 -0
  397. package/dist/render/sdfFont.js +86 -0
  398. package/dist/render/sdfTextLayout.d.ts +46 -0
  399. package/dist/render/sdfTextLayout.js +145 -0
  400. package/dist/render/sdfTextRenderer.d.ts +75 -0
  401. package/dist/render/sdfTextRenderer.js +194 -0
  402. package/dist/render/seaState.d.ts +25 -0
  403. package/dist/render/seaState.js +34 -0
  404. package/dist/render/segmentQuads.d.ts +29 -0
  405. package/dist/render/segmentQuads.js +75 -0
  406. package/dist/render/shader.d.ts +5 -0
  407. package/dist/render/shader.js +172 -0
  408. package/dist/render/shaders/ambientOcclusion.d.ts +45 -0
  409. package/dist/render/shaders/ambientOcclusion.js +352 -0
  410. package/dist/render/shaders/arcane.d.ts +19 -0
  411. package/dist/render/shaders/arcane.js +102 -0
  412. package/dist/render/shaders/bloom.d.ts +70 -0
  413. package/dist/render/shaders/bloom.js +227 -0
  414. package/dist/render/shaders/bolt.d.ts +17 -0
  415. package/dist/render/shaders/bolt.js +161 -0
  416. package/dist/render/shaders/caustics.d.ts +38 -0
  417. package/dist/render/shaders/caustics.js +167 -0
  418. package/dist/render/shaders/conditionals.d.ts +21 -0
  419. package/dist/render/shaders/conditionals.js +55 -0
  420. package/dist/render/shaders/decalProject.d.ts +25 -0
  421. package/dist/render/shaders/decalProject.js +125 -0
  422. package/dist/render/shaders/depth.d.ts +14 -0
  423. package/dist/render/shaders/depth.js +114 -0
  424. package/dist/render/shaders/depthOfField.d.ts +41 -0
  425. package/dist/render/shaders/depthOfField.js +139 -0
  426. package/dist/render/shaders/film.d.ts +15 -0
  427. package/dist/render/shaders/film.js +283 -0
  428. package/dist/render/shaders/fire.d.ts +12 -0
  429. package/dist/render/shaders/fire.js +178 -0
  430. package/dist/render/shaders/flat/directionalShadow.d.ts +1 -0
  431. package/dist/render/shaders/flat/directionalShadow.js +195 -0
  432. package/dist/render/shaders/flat/index.d.ts +135 -0
  433. package/dist/render/shaders/flat/index.js +387 -0
  434. package/dist/render/shaders/flat/lobes.d.ts +1 -0
  435. package/dist/render/shaders/flat/lobes.js +398 -0
  436. package/dist/render/shaders/flat/main.d.ts +2 -0
  437. package/dist/render/shaders/flat/main.js +1630 -0
  438. package/dist/render/shaders/flat/pointShadow.d.ts +1 -0
  439. package/dist/render/shaders/flat/pointShadow.js +322 -0
  440. package/dist/render/shaders/flat/preamble.d.ts +15 -0
  441. package/dist/render/shaders/flat/preamble.js +864 -0
  442. package/dist/render/shaders/flat/probeGrid.d.ts +21 -0
  443. package/dist/render/shaders/flat/probeGrid.js +151 -0
  444. package/dist/render/shaders/flat/surface.d.ts +2 -0
  445. package/dist/render/shaders/flat/surface.js +40 -0
  446. package/dist/render/shaders/flock.d.ts +11 -0
  447. package/dist/render/shaders/flock.js +102 -0
  448. package/dist/render/shaders/fog.d.ts +37 -0
  449. package/dist/render/shaders/fog.js +98 -0
  450. package/dist/render/shaders/fullscreen.d.ts +16 -0
  451. package/dist/render/shaders/fullscreen.js +27 -0
  452. package/dist/render/shaders/generated/ambientOcclusion.wgsl.d.ts +65 -0
  453. package/dist/render/shaders/generated/ambientOcclusion.wgsl.js +71 -0
  454. package/dist/render/shaders/generated/arcane.wgsl.d.ts +90 -0
  455. package/dist/render/shaders/generated/arcane.wgsl.js +96 -0
  456. package/dist/render/shaders/generated/bloom.wgsl.d.ts +69 -0
  457. package/dist/render/shaders/generated/bloom.wgsl.js +75 -0
  458. package/dist/render/shaders/generated/bolt.wgsl.d.ts +118 -0
  459. package/dist/render/shaders/generated/bolt.wgsl.js +124 -0
  460. package/dist/render/shaders/generated/caustics.wgsl.d.ts +118 -0
  461. package/dist/render/shaders/generated/caustics.wgsl.js +124 -0
  462. package/dist/render/shaders/generated/decalProject.wgsl.d.ts +61 -0
  463. package/dist/render/shaders/generated/decalProject.wgsl.js +67 -0
  464. package/dist/render/shaders/generated/depth.wgsl.d.ts +131 -0
  465. package/dist/render/shaders/generated/depth.wgsl.js +137 -0
  466. package/dist/render/shaders/generated/film.wgsl.d.ts +134 -0
  467. package/dist/render/shaders/generated/film.wgsl.js +140 -0
  468. package/dist/render/shaders/generated/fire.wgsl.d.ts +128 -0
  469. package/dist/render/shaders/generated/fire.wgsl.js +134 -0
  470. package/dist/render/shaders/generated/flat.wgsl.d.ts +9163 -0
  471. package/dist/render/shaders/generated/flat.wgsl.js +9192 -0
  472. package/dist/render/shaders/generated/flock.wgsl.d.ts +73 -0
  473. package/dist/render/shaders/generated/flock.wgsl.js +79 -0
  474. package/dist/render/shaders/generated/fullscreen.wgsl.d.ts +12 -0
  475. package/dist/render/shaders/generated/fullscreen.wgsl.js +18 -0
  476. package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +130 -0
  477. package/dist/render/shaders/generated/globalMedium.wgsl.js +136 -0
  478. package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +230 -0
  479. package/dist/render/shaders/generated/lightVolume.wgsl.js +239 -0
  480. package/dist/render/shaders/generated/line.wgsl.d.ts +128 -0
  481. package/dist/render/shaders/generated/line.wgsl.js +134 -0
  482. package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +51 -0
  483. package/dist/render/shaders/generated/octahedralResolve.wgsl.js +57 -0
  484. package/dist/render/shaders/generated/oitResolve.wgsl.d.ts +23 -0
  485. package/dist/render/shaders/generated/oitResolve.wgsl.js +29 -0
  486. package/dist/render/shaders/generated/panel.wgsl.d.ts +48 -0
  487. package/dist/render/shaders/generated/panel.wgsl.js +54 -0
  488. package/dist/render/shaders/generated/particle.wgsl.d.ts +332 -0
  489. package/dist/render/shaders/generated/particle.wgsl.js +338 -0
  490. package/dist/render/shaders/generated/prefilter.wgsl.d.ts +61 -0
  491. package/dist/render/shaders/generated/prefilter.wgsl.js +67 -0
  492. package/dist/render/shaders/generated/rush.wgsl.d.ts +131 -0
  493. package/dist/render/shaders/generated/rush.wgsl.js +137 -0
  494. package/dist/render/shaders/generated/scatter.wgsl.d.ts +195 -0
  495. package/dist/render/shaders/generated/scatter.wgsl.js +201 -0
  496. package/dist/render/shaders/generated/sdfText.wgsl.d.ts +69 -0
  497. package/dist/render/shaders/generated/sdfText.wgsl.js +75 -0
  498. package/dist/render/shaders/generated/sky.wgsl.d.ts +100 -0
  499. package/dist/render/shaders/generated/sky.wgsl.js +106 -0
  500. package/dist/render/shaders/generated/smoke.wgsl.d.ts +85 -0
  501. package/dist/render/shaders/generated/smoke.wgsl.js +91 -0
  502. package/dist/render/shaders/generated/ssrResolve.wgsl.d.ts +18 -0
  503. package/dist/render/shaders/generated/ssrResolve.wgsl.js +24 -0
  504. package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +86 -0
  505. package/dist/render/shaders/generated/ssrTrace.wgsl.js +92 -0
  506. package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +46 -0
  507. package/dist/render/shaders/generated/temporalResolve.wgsl.js +52 -0
  508. package/dist/render/shaders/generated/text.wgsl.d.ts +98 -0
  509. package/dist/render/shaders/generated/text.wgsl.js +104 -0
  510. package/dist/render/shaders/generated/water.wgsl.d.ts +247 -0
  511. package/dist/render/shaders/generated/water.wgsl.js +253 -0
  512. package/dist/render/shaders/generated/windStreaks.wgsl.d.ts +73 -0
  513. package/dist/render/shaders/generated/windStreaks.wgsl.js +79 -0
  514. package/dist/render/shaders/gerstner.d.ts +21 -0
  515. package/dist/render/shaders/gerstner.js +110 -0
  516. package/dist/render/shaders/globalMedium.d.ts +56 -0
  517. package/dist/render/shaders/globalMedium.js +393 -0
  518. package/dist/render/shaders/lightVolume.d.ts +61 -0
  519. package/dist/render/shaders/lightVolume.js +527 -0
  520. package/dist/render/shaders/line.d.ts +18 -0
  521. package/dist/render/shaders/line.js +122 -0
  522. package/dist/render/shaders/morph.d.ts +26 -0
  523. package/dist/render/shaders/morph.js +61 -0
  524. package/dist/render/shaders/octahedral.d.ts +76 -0
  525. package/dist/render/shaders/octahedral.js +161 -0
  526. package/dist/render/shaders/octahedralResolve.d.ts +25 -0
  527. package/dist/render/shaders/octahedralResolve.js +81 -0
  528. package/dist/render/shaders/oitResolve.d.ts +17 -0
  529. package/dist/render/shaders/oitResolve.js +42 -0
  530. package/dist/render/shaders/outputTransform.d.ts +37 -0
  531. package/dist/render/shaders/outputTransform.js +106 -0
  532. package/dist/render/shaders/panel.d.ts +17 -0
  533. package/dist/render/shaders/panel.js +50 -0
  534. package/dist/render/shaders/particle.d.ts +82 -0
  535. package/dist/render/shaders/particle.js +431 -0
  536. package/dist/render/shaders/prefilter.d.ts +37 -0
  537. package/dist/render/shaders/prefilter.js +276 -0
  538. package/dist/render/shaders/rush.d.ts +21 -0
  539. package/dist/render/shaders/rush.js +355 -0
  540. package/dist/render/shaders/scatter.d.ts +14 -0
  541. package/dist/render/shaders/scatter.js +206 -0
  542. package/dist/render/shaders/sdfText.d.ts +9 -0
  543. package/dist/render/shaders/sdfText.js +65 -0
  544. package/dist/render/shaders/skinning.d.ts +17 -0
  545. package/dist/render/shaders/skinning.js +59 -0
  546. package/dist/render/shaders/sky.d.ts +10 -0
  547. package/dist/render/shaders/sky.js +242 -0
  548. package/dist/render/shaders/smoke.d.ts +8 -0
  549. package/dist/render/shaders/smoke.js +88 -0
  550. package/dist/render/shaders/ssrResolve.d.ts +15 -0
  551. package/dist/render/shaders/ssrResolve.js +28 -0
  552. package/dist/render/shaders/ssrTrace.d.ts +22 -0
  553. package/dist/render/shaders/ssrTrace.js +230 -0
  554. package/dist/render/shaders/tangentFrame.d.ts +17 -0
  555. package/dist/render/shaders/tangentFrame.js +70 -0
  556. package/dist/render/shaders/temporalResolve.d.ts +1 -0
  557. package/dist/render/shaders/temporalResolve.js +150 -0
  558. package/dist/render/shaders/text.d.ts +17 -0
  559. package/dist/render/shaders/text.js +155 -0
  560. package/dist/render/shaders/vertexChannel.d.ts +39 -0
  561. package/dist/render/shaders/vertexChannel.js +69 -0
  562. package/dist/render/shaders/water.d.ts +18 -0
  563. package/dist/render/shaders/water.js +354 -0
  564. package/dist/render/shaders/windStreaks.d.ts +14 -0
  565. package/dist/render/shaders/windStreaks.js +129 -0
  566. package/dist/render/shadowCasters.d.ts +107 -0
  567. package/dist/render/shadowCasters.js +1 -0
  568. package/dist/render/shadowMap.d.ts +10 -0
  569. package/dist/render/shadowMap.js +80 -0
  570. package/dist/render/shotPlacement.d.ts +80 -0
  571. package/dist/render/shotPlacement.js +183 -0
  572. package/dist/render/skinPalette.d.ts +90 -0
  573. package/dist/render/skinPalette.js +136 -0
  574. package/dist/render/ssrPass.d.ts +59 -0
  575. package/dist/render/ssrPass.js +196 -0
  576. package/dist/render/surfaceSheet.d.ts +52 -0
  577. package/dist/render/surfaceSheet.js +99 -0
  578. package/dist/render/surfaceTexture.d.ts +197 -0
  579. package/dist/render/surfaceTexture.js +116 -0
  580. package/dist/render/temporalAa.d.ts +104 -0
  581. package/dist/render/temporalAa.js +194 -0
  582. package/dist/render/temporalPass.d.ts +54 -0
  583. package/dist/render/temporalPass.js +135 -0
  584. package/dist/render/textLayout.d.ts +88 -0
  585. package/dist/render/textLayout.js +201 -0
  586. package/dist/render/textRenderer.d.ts +32 -0
  587. package/dist/render/textRenderer.js +176 -0
  588. package/dist/render/thirdPersonCamera.d.ts +272 -0
  589. package/dist/render/thirdPersonCamera.js +479 -0
  590. package/dist/render/trample.d.ts +57 -0
  591. package/dist/render/trample.js +134 -0
  592. package/dist/render/translucentQueue.d.ts +76 -0
  593. package/dist/render/translucentQueue.js +90 -0
  594. package/dist/render/uniformVectorBudget.d.ts +105 -0
  595. package/dist/render/uniformVectorBudget.js +201 -0
  596. package/dist/render/uploadStep.d.ts +14 -0
  597. package/dist/render/uploadStep.js +14 -0
  598. package/dist/render/vertexDefaults.d.ts +48 -0
  599. package/dist/render/vertexDefaults.js +111 -0
  600. package/dist/render/visibility.d.ts +22 -0
  601. package/dist/render/visibility.js +47 -0
  602. package/dist/render/waterDraw.d.ts +57 -0
  603. package/dist/render/waterDraw.js +102 -0
  604. package/dist/render/waterGrid.d.ts +62 -0
  605. package/dist/render/waterGrid.js +151 -0
  606. package/dist/render/waterRenderer.d.ts +163 -0
  607. package/dist/render/waterRenderer.js +165 -0
  608. package/dist/render/wind.d.ts +45 -0
  609. package/dist/render/wind.js +32 -0
  610. package/dist/render/windField.d.ts +34 -0
  611. package/dist/render/windField.js +13 -0
  612. package/dist/render/windStreakDraw.d.ts +73 -0
  613. package/dist/render/windStreakDraw.js +86 -0
  614. package/dist/render/windStreakRenderer.d.ts +37 -0
  615. package/dist/render/windStreakRenderer.js +86 -0
  616. package/dist/scene/node.d.ts +128 -0
  617. package/dist/scene/node.js +319 -0
  618. package/dist/scene/visit.d.ts +38 -0
  619. package/dist/scene/visit.js +43 -0
  620. package/dist/ui/clipMime.d.ts +46 -0
  621. package/dist/ui/clipMime.js +88 -0
  622. package/dist/ui/exportTarget.d.ts +305 -0
  623. package/dist/ui/exportTarget.js +368 -0
  624. package/dist/ui/frameOverlay.d.ts +59 -0
  625. package/dist/ui/frameOverlay.js +76 -0
  626. package/dist/ui/framePacer.d.ts +142 -0
  627. package/dist/ui/framePacer.js +284 -0
  628. package/dist/ui/frameRecorder.d.ts +188 -0
  629. package/dist/ui/frameRecorder.js +221 -0
  630. package/dist/ui/fullscreen.d.ts +72 -0
  631. package/dist/ui/fullscreen.js +92 -0
  632. package/dist/ui/pixelCursor.d.ts +28 -0
  633. package/dist/ui/pixelCursor.js +66 -0
  634. package/dist/ui/splash.d.ts +86 -0
  635. package/dist/ui/splash.js +300 -0
  636. package/dist/ui/stillFrame.d.ts +22 -0
  637. package/dist/ui/stillFrame.js +40 -0
  638. package/package.json +60 -0
  639. package/src/behavior/behaviorTree.ts +346 -0
  640. package/src/build/shaderComments.ts +0 -0
  641. package/src/cinematic/player.ts +209 -0
  642. package/src/cinematic/script.ts +231 -0
  643. package/src/core/bootGate.ts +49 -0
  644. package/src/core/loadTracker.ts +144 -0
  645. package/src/core/loop.ts +211 -0
  646. package/src/core/messageQueue.ts +145 -0
  647. package/src/core/onceSet.ts +65 -0
  648. package/src/core/preferences.ts +177 -0
  649. package/src/core/remoteSave.ts +347 -0
  650. package/src/core/rng.ts +101 -0
  651. package/src/core/stepBudget.ts +136 -0
  652. package/src/core/storage.ts +114 -0
  653. package/src/core/tickTrace.ts +129 -0
  654. package/src/core/timeCurve.ts +175 -0
  655. package/src/core/withDefaults.ts +28 -0
  656. package/src/dev/contactProbe.ts +115 -0
  657. package/src/dev/fpsMeter.ts +101 -0
  658. package/src/environment/celestialClock.ts +385 -0
  659. package/src/geometry/decal.ts +260 -0
  660. package/src/geometry/filmPatch.ts +158 -0
  661. package/src/geometry/growable.ts +165 -0
  662. package/src/geometry/lightVolume.ts +161 -0
  663. package/src/geometry/meshBuilder.ts +1397 -0
  664. package/src/geometry/pixelFont.ts +189 -0
  665. package/src/geometry/ribbon.ts +790 -0
  666. package/src/geometry/shellFill.ts +265 -0
  667. package/src/geometry/spline.ts +659 -0
  668. package/src/geometry/tangents.ts +173 -0
  669. package/src/geometry/textMesh.ts +96 -0
  670. package/src/geometry/treeBuilder.ts +114 -0
  671. package/src/host/display.ts +180 -0
  672. package/src/host/files.ts +77 -0
  673. package/src/host/lifecycle.ts +63 -0
  674. package/src/host/platformServices.ts +23 -0
  675. package/src/host/screen.ts +134 -0
  676. package/src/index.ts +730 -0
  677. package/src/input/actionMap.ts +377 -0
  678. package/src/input/activeDevice.ts +86 -0
  679. package/src/input/gamepadIdentity.ts +131 -0
  680. package/src/input/gamepadMapping.ts +121 -0
  681. package/src/input/input.ts +872 -0
  682. package/src/input/inputHarness.ts +226 -0
  683. package/src/input/rightGesture.ts +76 -0
  684. package/src/input/rumble.ts +138 -0
  685. package/src/input/touchControls.ts +451 -0
  686. package/src/input/typingTarget.ts +26 -0
  687. package/src/math/bounds.ts +153 -0
  688. package/src/math/color.ts +37 -0
  689. package/src/math/exact.ts +274 -0
  690. package/src/math/frustum.ts +115 -0
  691. package/src/math/intersect.ts +228 -0
  692. package/src/math/scalar.ts +109 -0
  693. package/src/math/spring.ts +106 -0
  694. package/src/nav/navGraph.ts +168 -0
  695. package/src/nav/navPath.ts +217 -0
  696. package/src/nav/navSearch.ts +200 -0
  697. package/src/physics/boxSurface.ts +96 -0
  698. package/src/physics/colliderSurface.ts +213 -0
  699. package/src/physics/compositeSurface.ts +111 -0
  700. package/src/physics/heightSurface.ts +234 -0
  701. package/src/physics/ribbonSurface.ts +642 -0
  702. package/src/render/ambientOcclusionPass.ts +200 -0
  703. package/src/render/areaLights.ts +194 -0
  704. package/src/render/areaShadowSet.ts +405 -0
  705. package/src/render/atmosphere.ts +186 -0
  706. package/src/render/backend/api.ts +802 -0
  707. package/src/render/backend/budget.ts +139 -0
  708. package/src/render/backend/createRenderer.ts +343 -0
  709. package/src/render/backend/deadline.ts +37 -0
  710. package/src/render/backend/probe.ts +152 -0
  711. package/src/render/backend/select.ts +288 -0
  712. package/src/render/backend/timer.ts +59 -0
  713. package/src/render/backend/webgl2/instanced.ts +46 -0
  714. package/src/render/backend/webgl2/morphTexture.ts +58 -0
  715. package/src/render/backend/webgl2/renderer.ts +7484 -0
  716. package/src/render/backend/webgl2/skinPaletteTexture.ts +70 -0
  717. package/src/render/backend/webgpu/boltPass.ts +205 -0
  718. package/src/render/backend/webgpu/buffers.ts +553 -0
  719. package/src/render/backend/webgpu/causticsPass.ts +174 -0
  720. package/src/render/backend/webgpu/clusterBinner.ts +259 -0
  721. package/src/render/backend/webgpu/depthPass.ts +261 -0
  722. package/src/render/backend/webgpu/device.ts +148 -0
  723. package/src/render/backend/webgpu/drawCommand.ts +79 -0
  724. package/src/render/backend/webgpu/environmentTexels.ts +96 -0
  725. package/src/render/backend/webgpu/filmPass.ts +123 -0
  726. package/src/render/backend/webgpu/flatPass.ts +635 -0
  727. package/src/render/backend/webgpu/flockPass.ts +163 -0
  728. package/src/render/backend/webgpu/gpuTimestamps.ts +255 -0
  729. package/src/render/backend/webgpu/insetPass.ts +123 -0
  730. package/src/render/backend/webgpu/instanced.ts +55 -0
  731. package/src/render/backend/webgpu/lightVolumePass.ts +203 -0
  732. package/src/render/backend/webgpu/linePass.ts +270 -0
  733. package/src/render/backend/webgpu/morphTexture.ts +61 -0
  734. package/src/render/backend/webgpu/panelPass.ts +138 -0
  735. package/src/render/backend/webgpu/particlePass.ts +370 -0
  736. package/src/render/backend/webgpu/pipelineCache.ts +152 -0
  737. package/src/render/backend/webgpu/plumePass.ts +292 -0
  738. package/src/render/backend/webgpu/pointShadowPass.ts +368 -0
  739. package/src/render/backend/webgpu/postPass.ts +470 -0
  740. package/src/render/backend/webgpu/probePass.ts +218 -0
  741. package/src/render/backend/webgpu/reflectionPass.ts +137 -0
  742. package/src/render/backend/webgpu/renderer.ts +13004 -0
  743. package/src/render/backend/webgpu/scatterPass.ts +354 -0
  744. package/src/render/backend/webgpu/sdfTextPass.ts +220 -0
  745. package/src/render/backend/webgpu/shaderModules.ts +49 -0
  746. package/src/render/backend/webgpu/shaders/clusterBin.wgsl.ts +219 -0
  747. package/src/render/backend/webgpu/skinPaletteRing.ts +105 -0
  748. package/src/render/backend/webgpu/skinPaletteTexture.ts +79 -0
  749. package/src/render/backend/webgpu/skyPass.ts +85 -0
  750. package/src/render/backend/webgpu/surfaceTexturePass.ts +257 -0
  751. package/src/render/backend/webgpu/textPass.ts +224 -0
  752. package/src/render/backend/webgpu/uniformRing.ts +228 -0
  753. package/src/render/backend/webgpu/waterPass.ts +211 -0
  754. package/src/render/backend/webgpu/windStreakPass.ts +196 -0
  755. package/src/render/billboard.ts +108 -0
  756. package/src/render/bloomChain.ts +101 -0
  757. package/src/render/bloomPass.ts +256 -0
  758. package/src/render/boltBatch.ts +141 -0
  759. package/src/render/boltPool.ts +360 -0
  760. package/src/render/boom.ts +123 -0
  761. package/src/render/camera.ts +348 -0
  762. package/src/render/causticsRenderer.ts +171 -0
  763. package/src/render/cinematicCamera.ts +278 -0
  764. package/src/render/clusteredLights.ts +598 -0
  765. package/src/render/colourGrade.ts +109 -0
  766. package/src/render/compute.ts +83 -0
  767. package/src/render/contextLoss.ts +50 -0
  768. package/src/render/debugLines.ts +411 -0
  769. package/src/render/decalPass.ts +124 -0
  770. package/src/render/decalProjector.ts +390 -0
  771. package/src/render/decalQueue.ts +110 -0
  772. package/src/render/depthConvention.ts +383 -0
  773. package/src/render/drawingBuffer.ts +89 -0
  774. package/src/render/emptyTexture.ts +130 -0
  775. package/src/render/envProbeArray.ts +201 -0
  776. package/src/render/equirectToCube.ts +160 -0
  777. package/src/render/flockGeometry.ts +53 -0
  778. package/src/render/flockRenderer.ts +111 -0
  779. package/src/render/frame/arena.ts +93 -0
  780. package/src/render/frame/index.ts +29 -0
  781. package/src/render/frame/replay.ts +50 -0
  782. package/src/render/frame/resources.ts +61 -0
  783. package/src/render/frame/schedule.ts +85 -0
  784. package/src/render/frameView.ts +20 -0
  785. package/src/render/gizmo.ts +923 -0
  786. package/src/render/globalMedium.ts +154 -0
  787. package/src/render/globalMediumPass.ts +323 -0
  788. package/src/render/gpuCapability.ts +244 -0
  789. package/src/render/gpuTimer.ts +182 -0
  790. package/src/render/halfFloat.ts +39 -0
  791. package/src/render/handleRegistry.ts +96 -0
  792. package/src/render/iesProfile.ts +215 -0
  793. package/src/render/imageTexels.ts +109 -0
  794. package/src/render/instancedMesh.ts +187 -0
  795. package/src/render/instances.ts +92 -0
  796. package/src/render/lightBudget.ts +655 -0
  797. package/src/render/lightMatrix.ts +69 -0
  798. package/src/render/lightVolumeDraw.ts +216 -0
  799. package/src/render/lineBatch.ts +180 -0
  800. package/src/render/linePoints.ts +61 -0
  801. package/src/render/livePointShadowSet.ts +285 -0
  802. package/src/render/lod.ts +86 -0
  803. package/src/render/mesh.ts +536 -0
  804. package/src/render/occlusion.ts +406 -0
  805. package/src/render/oitPass.ts +230 -0
  806. package/src/render/orderIndependent.ts +136 -0
  807. package/src/render/particleBatch.ts +299 -0
  808. package/src/render/particleMaterial.ts +84 -0
  809. package/src/render/particlePool.ts +291 -0
  810. package/src/render/pass.ts +203 -0
  811. package/src/render/passTarget.ts +225 -0
  812. package/src/render/pickable.ts +222 -0
  813. package/src/render/planarReflection.ts +233 -0
  814. package/src/render/planarReflectionDraw.ts +87 -0
  815. package/src/render/plumeGeometry.ts +75 -0
  816. package/src/render/plumeMaterial.ts +99 -0
  817. package/src/render/plumeRenderer.ts +272 -0
  818. package/src/render/pointLightSelection.ts +447 -0
  819. package/src/render/pointShadowArray.ts +276 -0
  820. package/src/render/pointShadowBudget.ts +305 -0
  821. package/src/render/pointShadowImage.ts +470 -0
  822. package/src/render/pointShadowMap.ts +228 -0
  823. package/src/render/pointShadowSystem.ts +408 -0
  824. package/src/render/prefilterEnvMap.ts +162 -0
  825. package/src/render/prefilterPass.ts +115 -0
  826. package/src/render/probeGrid.ts +248 -0
  827. package/src/render/rainField.ts +240 -0
  828. package/src/render/reflectionProbe.ts +530 -0
  829. package/src/render/renderQuality.ts +1054 -0
  830. package/src/render/rendererHarness.ts +214 -0
  831. package/src/render/resolutionGovernor.ts +189 -0
  832. package/src/render/scatterDeform.ts +72 -0
  833. package/src/render/sceneTarget.ts +1032 -0
  834. package/src/render/screenSpaceReflection.ts +524 -0
  835. package/src/render/sdfFont.ts +157 -0
  836. package/src/render/sdfTextLayout.ts +206 -0
  837. package/src/render/sdfTextRenderer.ts +233 -0
  838. package/src/render/seaState.ts +55 -0
  839. package/src/render/segmentQuads.ts +92 -0
  840. package/src/render/shader.ts +190 -0
  841. package/src/render/shaders/ambientOcclusion.ts +354 -0
  842. package/src/render/shaders/arcane.ts +103 -0
  843. package/src/render/shaders/bloom.ts +232 -0
  844. package/src/render/shaders/bolt.ts +164 -0
  845. package/src/render/shaders/caustics.ts +169 -0
  846. package/src/render/shaders/conditionals.ts +58 -0
  847. package/src/render/shaders/decalProject.ts +127 -0
  848. package/src/render/shaders/depth.ts +131 -0
  849. package/src/render/shaders/depthOfField.ts +141 -0
  850. package/src/render/shaders/film.ts +285 -0
  851. package/src/render/shaders/fire.ts +180 -0
  852. package/src/render/shaders/flat/directionalShadow.ts +196 -0
  853. package/src/render/shaders/flat/index.ts +502 -0
  854. package/src/render/shaders/flat/lobes.ts +399 -0
  855. package/src/render/shaders/flat/main.ts +1631 -0
  856. package/src/render/shaders/flat/pointShadow.ts +323 -0
  857. package/src/render/shaders/flat/preamble.ts +875 -0
  858. package/src/render/shaders/flat/probeGrid.ts +152 -0
  859. package/src/render/shaders/flat/surface.ts +41 -0
  860. package/src/render/shaders/flock.ts +103 -0
  861. package/src/render/shaders/fog.ts +99 -0
  862. package/src/render/shaders/fullscreen.ts +28 -0
  863. package/src/render/shaders/generated/ambientOcclusion.wgsl.ts +74 -0
  864. package/src/render/shaders/generated/arcane.wgsl.ts +98 -0
  865. package/src/render/shaders/generated/bloom.wgsl.ts +79 -0
  866. package/src/render/shaders/generated/bolt.wgsl.ts +127 -0
  867. package/src/render/shaders/generated/caustics.wgsl.ts +127 -0
  868. package/src/render/shaders/generated/decalProject.wgsl.ts +69 -0
  869. package/src/render/shaders/generated/depth.wgsl.ts +142 -0
  870. package/src/render/shaders/generated/film.wgsl.ts +143 -0
  871. package/src/render/shaders/generated/fire.wgsl.ts +137 -0
  872. package/src/render/shaders/generated/flat.wgsl.ts +9195 -0
  873. package/src/render/shaders/generated/flock.wgsl.ts +82 -0
  874. package/src/render/shaders/generated/fullscreen.wgsl.ts +20 -0
  875. package/src/render/shaders/generated/globalMedium.wgsl.ts +139 -0
  876. package/src/render/shaders/generated/lightVolume.wgsl.ts +242 -0
  877. package/src/render/shaders/generated/line.wgsl.ts +137 -0
  878. package/src/render/shaders/generated/octahedralResolve.wgsl.ts +60 -0
  879. package/src/render/shaders/generated/oitResolve.wgsl.ts +31 -0
  880. package/src/render/shaders/generated/panel.wgsl.ts +57 -0
  881. package/src/render/shaders/generated/particle.wgsl.ts +343 -0
  882. package/src/render/shaders/generated/prefilter.wgsl.ts +69 -0
  883. package/src/render/shaders/generated/rush.wgsl.ts +139 -0
  884. package/src/render/shaders/generated/scatter.wgsl.ts +205 -0
  885. package/src/render/shaders/generated/sdfText.wgsl.ts +78 -0
  886. package/src/render/shaders/generated/sky.wgsl.ts +109 -0
  887. package/src/render/shaders/generated/smoke.wgsl.ts +93 -0
  888. package/src/render/shaders/generated/ssrResolve.wgsl.ts +26 -0
  889. package/src/render/shaders/generated/ssrTrace.wgsl.ts +94 -0
  890. package/src/render/shaders/generated/temporalResolve.wgsl.ts +54 -0
  891. package/src/render/shaders/generated/text.wgsl.ts +107 -0
  892. package/src/render/shaders/generated/water.wgsl.ts +256 -0
  893. package/src/render/shaders/generated/windStreaks.wgsl.ts +82 -0
  894. package/src/render/shaders/gerstner.ts +110 -0
  895. package/src/render/shaders/globalMedium.ts +396 -0
  896. package/src/render/shaders/lightVolume.ts +546 -0
  897. package/src/render/shaders/line.ts +125 -0
  898. package/src/render/shaders/morph.ts +62 -0
  899. package/src/render/shaders/octahedral.ts +170 -0
  900. package/src/render/shaders/octahedralResolve.ts +83 -0
  901. package/src/render/shaders/oitResolve.ts +42 -0
  902. package/src/render/shaders/outputTransform.ts +107 -0
  903. package/src/render/shaders/panel.ts +51 -0
  904. package/src/render/shaders/particle.ts +438 -0
  905. package/src/render/shaders/prefilter.ts +278 -0
  906. package/src/render/shaders/rush.ts +357 -0
  907. package/src/render/shaders/scatter.ts +211 -0
  908. package/src/render/shaders/sdfText.ts +68 -0
  909. package/src/render/shaders/skinning.ts +59 -0
  910. package/src/render/shaders/sky.ts +243 -0
  911. package/src/render/shaders/smoke.ts +89 -0
  912. package/src/render/shaders/ssrResolve.ts +28 -0
  913. package/src/render/shaders/ssrTrace.ts +233 -0
  914. package/src/render/shaders/tangentFrame.ts +70 -0
  915. package/src/render/shaders/temporalResolve.ts +151 -0
  916. package/src/render/shaders/text.ts +156 -0
  917. package/src/render/shaders/vertexChannel.ts +71 -0
  918. package/src/render/shaders/water.ts +356 -0
  919. package/src/render/shaders/windStreaks.ts +130 -0
  920. package/src/render/shadowCasters.ts +124 -0
  921. package/src/render/shadowMap.ts +89 -0
  922. package/src/render/shotPlacement.ts +266 -0
  923. package/src/render/skinPalette.ts +157 -0
  924. package/src/render/ssrPass.ts +241 -0
  925. package/src/render/surfaceSheet.ts +158 -0
  926. package/src/render/surfaceTexture.ts +310 -0
  927. package/src/render/temporalAa.ts +221 -0
  928. package/src/render/temporalPass.ts +153 -0
  929. package/src/render/textLayout.ts +239 -0
  930. package/src/render/textRenderer.ts +201 -0
  931. package/src/render/thirdPersonCamera.ts +578 -0
  932. package/src/render/trample.ts +140 -0
  933. package/src/render/translucentQueue.ts +161 -0
  934. package/src/render/uniformVectorBudget.ts +246 -0
  935. package/src/render/uploadStep.ts +14 -0
  936. package/src/render/vertexDefaults.ts +115 -0
  937. package/src/render/visibility.ts +56 -0
  938. package/src/render/waterDraw.ts +167 -0
  939. package/src/render/waterGrid.ts +180 -0
  940. package/src/render/waterRenderer.ts +352 -0
  941. package/src/render/wind.ts +79 -0
  942. package/src/render/windField.ts +50 -0
  943. package/src/render/windStreakDraw.ts +131 -0
  944. package/src/render/windStreakRenderer.ts +130 -0
  945. package/src/scene/node.ts +336 -0
  946. package/src/scene/visit.ts +82 -0
  947. package/src/ui/clipMime.ts +109 -0
  948. package/src/ui/exportTarget.ts +491 -0
  949. package/src/ui/frameOverlay.ts +159 -0
  950. package/src/ui/framePacer.ts +351 -0
  951. package/src/ui/frameRecorder.ts +333 -0
  952. package/src/ui/fullscreen.ts +113 -0
  953. package/src/ui/pixelCursor.ts +99 -0
  954. package/src/ui/splash.ts +347 -0
  955. package/src/ui/stillFrame.ts +44 -0
@@ -0,0 +1,491 @@
1
+ import { FramePacer } from './framePacer.ts';
2
+ import type { FramePacingReport } from './framePacer.ts';
3
+ import { bakeOverlay } from './frameOverlay.ts';
4
+ import type { FrameOverlay } from './frameOverlay.ts';
5
+
6
+ /**
7
+ * The surface a clip is recorded from: a fixed-size frame, composited and paced.
8
+ *
9
+ * Three things it fixes, all of which were visible in the first export:
10
+ *
11
+ * **Aspect is rendered, not cropped.** The scene is drawn at the export's own
12
+ * pixel size, so a vertical clip is *framed* vertically. Cropping a 16:9 view to
13
+ * 9:16 throws away 44% of the width, and the subject is exactly what falls
14
+ * outside — the shot was composed for the other rectangle.
15
+ *
16
+ * **The frame is composited.** The scene canvas is copied into a target of
17
+ * exactly the requested size and the mark is stamped on top, so branding is
18
+ * inside the video rather than in DOM that the capture never sees.
19
+ *
20
+ * **Frames are paced.** `captureStream(0)` records nothing until asked, so every
21
+ * frame in the file is one the renderer actually finished. Capturing at a rate
22
+ * the renderer cannot hold samples some frames twice and misses the next, which
23
+ * is what uneven duplication looks like: judder.
24
+ *
25
+ * **The honest limit.** `MediaRecorder` timestamps by wall clock, so an export
26
+ * runs in real time and no amount of pacing changes that. There is no in-browser
27
+ * way to render slower than real time and still have the audio line up, short of
28
+ * shipping a muxer — which is a dependency, and the standing rule says no. What
29
+ * pacing *can* do is make every frame in the file the same distance from the last,
30
+ * by counting animation frames rather than milliseconds — see `FramePacer`. A
31
+ * device that cannot hold the requested rate then records a slower clip rather than
32
+ * a juddering one, and the measurement in `pacing` says which it was.
33
+ */
34
+ export interface LockableSurface {
35
+ /** Pin the drawing buffer to an exact pixel size, ignoring CSS and DPR. */
36
+ lockDrawingBuffer(width: number, height: number): void;
37
+ unlockDrawingBuffer(): void;
38
+ }
39
+
40
+ export interface ExportTargetOptions {
41
+ /** The canvas the scene is drawn into. */
42
+ readonly source: HTMLCanvasElement;
43
+ /** Whoever owns that canvas's drawing-buffer size. */
44
+ readonly surface: LockableSurface;
45
+ readonly width: number;
46
+ readonly height: number;
47
+ readonly fps: number;
48
+ /**
49
+ * Stamped into every frame, and baked once.
50
+ *
51
+ * Accepts a function of the final frame size, because the size is not always
52
+ * the one asked for — a device that cannot hold the rate records smaller. A
53
+ * mark laid out for the larger frame and drawn into the smaller one lands on
54
+ * fractional pixels, which is the difference between a wordmark and a smudge.
55
+ */
56
+ readonly overlay?: FrameOverlay | ((width: number, height: number) => FrameOverlay);
57
+ /**
58
+ * Drawn into every frame, live.
59
+ *
60
+ * The counterpart to `overlay`, which is baked once because a wordmark and a
61
+ * share code do not change. Anything that *does* change per frame — a
62
+ * speedometer, a clock, a lap counter — cannot go through that path at all, and
63
+ * re-baking an overlay each frame would allocate a canvas per frame to say so.
64
+ * So this is handed the composite's own context instead and draws straight into
65
+ * it, after the scene and after the baked mark.
66
+ *
67
+ * Called once per composed frame, including the still-image path, so a still
68
+ * carries whatever a clip would. Receives the *final* frame size for the same
69
+ * reason `overlay` does: a device that cannot hold the rate records smaller, and
70
+ * an instrument laid out for the larger frame lands on fractional pixels.
71
+ *
72
+ * The context is owned by the target: a hook that leaves transforms, clips or
73
+ * composite state behind will corrupt later frames, so it must restore what it
74
+ * changes. Save/restore is wrapped here so the common case needs no discipline.
75
+ */
76
+ readonly drawFrame?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
77
+ /**
78
+ * The renderer's own presented-frame count, e.g. `() => renderer.presentedFrames`.
79
+ *
80
+ * Optional, and reached for no reason but this: `compose()` composites once per encoded
81
+ * frame regardless of whether the renderer presented anything new since the call before —
82
+ * it has no way to ask, only to draw whatever is on `source` right now — so a scene that
83
+ * presents nothing between two frames of an export is composited twice, byte-identical, at
84
+ * two different timestamps. Passing this closes the loop: `duplicateFrame` after `compose()`
85
+ * says whether that just happened, read out of the renderer rather than guessed at from
86
+ * outside it. Omit it and `compose()` behaves exactly as before — nothing here forces or
87
+ * skips a draw, it only reports what already happened.
88
+ */
89
+ readonly presentedFrames?: () => number;
90
+ }
91
+
92
+ /**
93
+ * How much smaller the fallback frame is, per side.
94
+ *
95
+ * Two thirds, which takes 1080x1920 to exactly 720x1280 and costs 56% of the
96
+ * pixels — enough to buy back a frame rate, little enough that the clip is still
97
+ * sharp on a phone. The choice between them is made from a *measurement* of what
98
+ * the renderer is actually managing, never from a device string: the same model
99
+ * of phone runs at two different rates depending on how warm it is.
100
+ */
101
+ export const EXPORT_FALLBACK_SCALE = 2 / 3;
102
+ /**
103
+ * The share of the target rate the renderer has to be holding to earn the full
104
+ * frame. Below it, the export is already dropping frames before the extra
105
+ * composite work is added.
106
+ */
107
+ const FULL_SIZE_FPS_MARGIN = 1.15;
108
+
109
+ export interface ExportSize {
110
+ readonly width: number;
111
+ readonly height: number;
112
+ /** True when the measurement forced the smaller frame. */
113
+ readonly reduced: boolean;
114
+ }
115
+
116
+ /**
117
+ * The size asked for, evened — for an encode whose schedule is *ours*.
118
+ *
119
+ * The counterpart to `exportSizeFor`, and the distinction is the whole point.
120
+ * `exportSizeFor` trades pixels for frame rate, which is the right trade for a
121
+ * real-time recorder: `MediaRecorder` stamps by wall clock, so a device that
122
+ * cannot draw an export-size frame in 16 ms produces a *worse file*, and a
123
+ * smaller frame it can hold is the better clip.
124
+ *
125
+ * An offline encode makes no such trade, because it has no clock to lose to.
126
+ * Every frame is stamped with where it belongs (see `frameTimestampUs`), so a
127
+ * device that needs 40 ms a frame produces the same file as one that needs 4 —
128
+ * it just waits longer for it. Reducing there buys nothing but a shorter wait,
129
+ * and it is paid for in the one thing the clip is for.
130
+ *
131
+ * That mattered most on exactly the devices least able to argue: the reduction
132
+ * gate is `measuredFps × windowPixels / exportPixels ≥ targetFps × 1.15`, which
133
+ * at a vsync-capped 60 fps needs a drawing buffer of 2.38 Mpx to clear. A phone
134
+ * has about 1.5 Mpx (a ~412×915 viewport at a DPR capped to 2), so *no* 60 Hz
135
+ * phone could ever earn the full frame: every mobile clip came out 720×1280 at
136
+ * 6.1 Mbit/s where a desktop's was 1080×1920 at 13.7. Same shot, same 60 fps,
137
+ * a quarter of the detail — which gets reported as a difference in "graphics
138
+ * detail" rather than in frame rate. It was neither; it was pixels.
139
+ *
140
+ * Both dimensions stay even, for the same reason as below.
141
+ */
142
+ export function exportSizeExact(width: number, height: number): ExportSize {
143
+ return { width: even(width), height: even(height), reduced: false };
144
+ }
145
+
146
+ /**
147
+ * The frame size to record at, given what the renderer is currently managing.
148
+ *
149
+ * Both dimensions stay even: every H.264 encoder in the share path wants an even
150
+ * width and height, and an odd one is either rejected or silently padded.
151
+ */
152
+ export function exportSizeFor(
153
+ width: number,
154
+ height: number,
155
+ measuredFps: number,
156
+ targetFps: number,
157
+ /**
158
+ * Pixels the measurement was taken at — the window's own drawing buffer.
159
+ *
160
+ * Without it the comparison is between a rate measured on a 1200x700 window and
161
+ * a demand made of a 1080x1920 frame, which is three times the pixels: a
162
+ * machine holding a comfortable 100 fps in the window is credited with being
163
+ * able to hold it at the export size, and it cannot. That optimism is why an
164
+ * export dropped frames on hardware whose preview was flawless. Omit for the
165
+ * old behaviour, which is to trust the raw number.
166
+ */
167
+ measuredAtPixels = 0,
168
+ ): ExportSize {
169
+ /*
170
+ * Fill rate is the binding cost here — shadow maps, water, the film pass are
171
+ * all per-pixel — so the estimate is linear in pixel count. Crude, and far
172
+ * closer than assuming the frame is free.
173
+ */
174
+ const estimate =
175
+ measuredAtPixels > 0
176
+ ? (measuredFps * measuredAtPixels) / Math.max(width * height, 1)
177
+ : measuredFps;
178
+ if (measuredFps <= 0 || estimate >= targetFps * FULL_SIZE_FPS_MARGIN) {
179
+ return exportSizeExact(width, height);
180
+ }
181
+ return {
182
+ width: even(width * EXPORT_FALLBACK_SCALE),
183
+ height: even(height * EXPORT_FALLBACK_SCALE),
184
+ reduced: true,
185
+ };
186
+ }
187
+
188
+ /**
189
+ * Frame rates a clip may be recorded at, best first.
190
+ *
191
+ * A ladder rather than a constant: a clip records at 120 if it can, else 60, else 30,
192
+ * falling one rung at a time rather than straight to the floor.
193
+ * Each rung is half the one above it so a display's refresh divides cleanly by the
194
+ * stride the pacer ends up using, which is what keeps the cadence even.
195
+ */
196
+ export const CLIP_FPS_LADDER: readonly number[] = [240, 165, 144, 120, 90, 60, 30];
197
+
198
+ /**
199
+ * The highest rate on the ladder this device can actually deliver, at this size.
200
+ *
201
+ * **The default is the device's own maximum** rather than a fixed rate. The ladder
202
+ * therefore starts above any
203
+ * panel this is likely to meet and walks down, so a 165 Hz monitor records 165 rather
204
+ * than being rounded to the nearest tidy number. The rungs are the rates real displays
205
+ * actually run at; anything between them is served by the next one down, which the
206
+ * pacer can hit with a whole stride.
207
+ *
208
+ * Two ceilings, and both are hard. **A clip cannot be captured faster than the game
209
+ * is drawn**, because `FramePacer` takes every n-th animation frame, so a 60 Hz panel
210
+ * cannot produce a 120 fps file however fast the machine is; asking anyway would
211
+ * write a file claiming 120 while holding 60, which is precisely the lie the frame
212
+ * schedule exists to prevent. And **the export size is not the window size**, so the
213
+ * measured rate is scaled by pixel count exactly as `exportSizeFor` scales it, or a
214
+ * machine comfortable in a small window is credited with a 1080x1920 frame it cannot
215
+ * push.
216
+ *
217
+ * Returns the lowest rung when nothing clears, rather than nothing: at that point the
218
+ * device is slow enough that `exportSizeFor` is about to reduce the frame, and the
219
+ * lower rate is what makes that reduction sufficient.
220
+ */
221
+ export function clipFpsFor(
222
+ width: number,
223
+ height: number,
224
+ measuredFps: number,
225
+ /** Pixels the measurement was taken at. Zero trusts the raw number, as above. */
226
+ measuredAtPixels = 0,
227
+ ladder: readonly number[] = CLIP_FPS_LADDER,
228
+ ): number {
229
+ const lowest = ladder[ladder.length - 1] ?? 30;
230
+ if (!Number.isFinite(measuredFps) || measuredFps <= 0) return lowest;
231
+
232
+ const estimate =
233
+ measuredAtPixels > 0
234
+ ? (measuredFps * measuredAtPixels) / Math.max(width * height, 1)
235
+ : measuredFps;
236
+
237
+ for (const rate of ladder) {
238
+ // Never above what the display itself produces, and never above what the frame
239
+ // costs allow at export size.
240
+ if (rate > measuredFps) continue;
241
+ if (estimate >= rate * FULL_SIZE_FPS_MARGIN) return rate;
242
+ }
243
+ return lowest;
244
+ }
245
+
246
+ /** The aspect ratio a camera must be given to frame for this export. */
247
+ export function exportAspect(width: number, height: number): number {
248
+ return width / Math.max(height, 1);
249
+ }
250
+
251
+ /**
252
+ * Bits per second for a frame size and rate.
253
+ *
254
+ * Scaled to the pixel count rather than fixed. A constant 8 Mbit/s is generous
255
+ * at 720p and thin at 1080x1920, and thin bitrate on high-motion footage reads
256
+ * to the eye as stutter rather than as softness — a fast-cut gameplay edit is
257
+ * nothing but high motion, so this is not a subtle effect. Bounded at both ends: below the
258
+ * floor the picture falls apart, above the ceiling the upload is the slow part
259
+ * of sharing.
260
+ */
261
+ export function clipBitrate(width: number, height: number, fps: number): number {
262
+ const bitsPerPixel = 0.11;
263
+ const raw = width * height * fps * bitsPerPixel;
264
+ return Math.round(Math.min(Math.max(raw, 2_500_000), 24_000_000));
265
+ }
266
+
267
+ function even(value: number): number {
268
+ return Math.max(2, Math.round(value / 2) * 2);
269
+ }
270
+
271
+ /**
272
+ * Whether a frame read at `presentedCount` repeats the one composed at `lastPresentedCount`.
273
+ *
274
+ * `null` says nothing has been composed yet, so a first frame is never a duplicate of a frame
275
+ * that never happened — a literal `0` there would misread the renderer's own starting count as
276
+ * a repeat of it. Pulled out of `compose()` on purpose: it is the one piece of that method's
277
+ * job that touches no canvas, so it is the one piece a test can hold to account without a DOM —
278
+ * this repository's tests run in `node`, per `vitest.config.ts`, and `ExportTarget` itself
279
+ * creates a real `<canvas>` at construction.
280
+ */
281
+ export function isDuplicateFrame(
282
+ lastPresentedCount: number | null,
283
+ presentedCount: number,
284
+ ): boolean {
285
+ return lastPresentedCount !== null && presentedCount === lastPresentedCount;
286
+ }
287
+
288
+ export class ExportTarget {
289
+ private readonly composite: HTMLCanvasElement;
290
+ private readonly ctx: CanvasRenderingContext2D;
291
+ private readonly pacer: FramePacer;
292
+ private mark: HTMLCanvasElement | null = null;
293
+ private stream: MediaStream | null = null;
294
+ private videoTrack: MediaStreamTrack | null = null;
295
+ private acquired = false;
296
+ /** The instant this animation frame was decided on — see `captureDue`. */
297
+ private frameAtMs = 0;
298
+ /**
299
+ * The renderer's `presentedFrames` as of the last `compose()`, or null before the first one.
300
+ *
301
+ * Null rather than 0, deliberately: a renderer's own count starts at 0 too, and a first
302
+ * frame compared against that literal would read as a duplicate of a frame that never
303
+ * happened. Null can only mean "nothing composed yet".
304
+ */
305
+ private lastPresentedFrames: number | null = null;
306
+ /** What the last `compose()` found. See `duplicateFrame`. */
307
+ private wasDuplicate = false;
308
+
309
+ constructor(private readonly options: ExportTargetOptions) {
310
+ const canvas = document.createElement('canvas');
311
+ canvas.width = options.width;
312
+ canvas.height = options.height;
313
+ const ctx = canvas.getContext('2d', { alpha: false });
314
+ if (ctx === null) throw new Error('This browser cannot composite an export frame.');
315
+ this.composite = canvas;
316
+ this.ctx = ctx;
317
+ this.pacer = new FramePacer(options.fps);
318
+ }
319
+
320
+ get width(): number {
321
+ return this.options.width;
322
+ }
323
+
324
+ get height(): number {
325
+ return this.options.height;
326
+ }
327
+
328
+ get aspect(): number {
329
+ return exportAspect(this.options.width, this.options.height);
330
+ }
331
+
332
+ /**
333
+ * Take over the render surface and hand back the stream to record.
334
+ *
335
+ * `captureStream(0)` rather than a frame rate: the recorder then takes a frame
336
+ * only when `frameRendered` says one is ready, so it can never sample the same
337
+ * rendered frame twice.
338
+ */
339
+ /**
340
+ * Take over the render surface and bake the mark, without a stream.
341
+ *
342
+ * For an offline render, which composites and encodes frames itself and has nothing to
343
+ * stream to. `acquire` is this plus a stream; keeping them separate means the offline
344
+ * path never creates a `MediaStream` it would only have to stop.
345
+ */
346
+ lock(): void {
347
+ if (this.acquired) return;
348
+ this.options.surface.lockDrawingBuffer(this.options.width, this.options.height);
349
+ this.acquired = true;
350
+ const { overlay, width, height } = this.options;
351
+ const resolved = typeof overlay === 'function' ? overlay(width, height) : overlay;
352
+ this.mark = resolved === undefined ? null : bakeOverlay(resolved, width, height);
353
+ }
354
+
355
+ /** Whether the source canvas has actually taken the locked size yet. */
356
+ get ready(): boolean {
357
+ const { source, width, height } = this.options;
358
+ return source.width === width && source.height === height;
359
+ }
360
+
361
+ acquire(): MediaStream {
362
+ if (this.stream !== null) return this.stream;
363
+ this.lock();
364
+ const stream = this.composite.captureStream(0);
365
+ this.stream = stream;
366
+ this.videoTrack = stream.getVideoTracks()[0] ?? null;
367
+ return stream;
368
+ }
369
+
370
+ /**
371
+ * Whether the next frame drawn will be kept.
372
+ *
373
+ * Asked *before* rendering, so the render loop can skip a frame the recorder
374
+ * would only throw away — see `FramePacer.due` for why that is a correctness
375
+ * matter and not merely a saving.
376
+ *
377
+ * **Call this once per animation frame, drawing or not.** The instant is kept and
378
+ * reused when the frame is handed over, so the schedule is queried and advanced
379
+ * on one clock. It used to take a second reading at the end of the render pass,
380
+ * which put the pacer's grid a whole render ahead of the frames arriving and cost
381
+ * most of the rate: target 60 fps on a 60 Hz display captured 59.5 when a frame
382
+ * cost 4 ms, 40 at 6 ms and 30 at 12 ms, and an export-size frame always costs
383
+ * more than 6 ms.
384
+ */
385
+ captureDue(nowMs: number): boolean {
386
+ this.frameAtMs = nowMs;
387
+ if (this.stream === null) return true;
388
+ return this.pacer.due(nowMs);
389
+ }
390
+
391
+ /**
392
+ * One rendered frame. Composites and offers it to the recorder if it is due.
393
+ *
394
+ * Must be called at the end of the render pass, in the same task: a WebGL
395
+ * drawing buffer is only guaranteed readable until the browser composites the
396
+ * page, so copying it from a timer produces black frames on some drivers.
397
+ *
398
+ * Takes no instant on purpose — it uses the one `captureDue` was given for this
399
+ * frame. There is no second clock to get wrong.
400
+ *
401
+ * Returns true when the frame was captured, so a caller can count.
402
+ */
403
+ frameRendered(): boolean {
404
+ if (this.stream === null) return false;
405
+ /*
406
+ * Until the lock has actually taken effect the scene canvas is still the
407
+ * window's size, and copying it would stretch the first frames to the export
408
+ * aspect — the exact distortion this class exists to avoid. Skipping them
409
+ * costs a fraction of a second of clip and guarantees every recorded frame
410
+ * is genuinely the requested shape.
411
+ */
412
+ const { source } = this.options;
413
+ if (source.width !== this.options.width || source.height !== this.options.height) return false;
414
+ if (!this.pacer.offer(this.frameAtMs)) return false;
415
+ this.compose();
416
+ const track = this.videoTrack;
417
+ if (track !== null && 'requestFrame' in track) {
418
+ (track as MediaStreamTrack & { requestFrame(): void }).requestFrame();
419
+ }
420
+ return true;
421
+ }
422
+
423
+ /**
424
+ * Draw the current scene plus the mark into the composite.
425
+ *
426
+ * Also the still-image path: a downloadable frame is the cheapest shareable
427
+ * artefact there is, and it must carry the same mark as the clip.
428
+ *
429
+ * **Draws unconditionally, even when `duplicateFrame` is about to say the source has not
430
+ * changed.** Deciding what to do with a repeated frame — drop it, hold the last one longer,
431
+ * encode it anyway — is a policy choice about the file being produced, and this class
432
+ * produces composites rather than files; see `presentedFrames` on `ExportTargetOptions` for
433
+ * where that decision gets the information it needs to make it.
434
+ */
435
+ compose(): HTMLCanvasElement {
436
+ const { source, width, height, drawFrame, presentedFrames } = this.options;
437
+ if (presentedFrames !== undefined) {
438
+ const count = presentedFrames();
439
+ this.wasDuplicate = isDuplicateFrame(this.lastPresentedFrames, count);
440
+ this.lastPresentedFrames = count;
441
+ }
442
+ this.ctx.drawImage(source, 0, 0, width, height);
443
+ if (this.mark !== null) this.ctx.drawImage(this.mark, 0, 0);
444
+ if (drawFrame !== undefined) {
445
+ // Wrapped, so a hook cannot leak transform or composite state into the next
446
+ // frame — see `drawFrame`. Cheap: save/restore on a 2D context is a stack push.
447
+ this.ctx.save();
448
+ drawFrame(this.ctx, width, height);
449
+ this.ctx.restore();
450
+ }
451
+ return this.composite;
452
+ }
453
+
454
+ /**
455
+ * Whether the frame `compose()` just drew is byte-identical to the one before it, because
456
+ * the renderer's own count of presented frames did not move between the two calls.
457
+ *
458
+ * False when `presentedFrames` was never supplied, and false for the very first `compose()`
459
+ * regardless — a frame nothing has been compared against yet is not a repeat of anything.
460
+ */
461
+ get duplicateFrame(): boolean {
462
+ return this.wasDuplicate;
463
+ }
464
+
465
+ get pacing(): FramePacingReport {
466
+ return this.pacer.report;
467
+ }
468
+
469
+ /** Start the measurement over, keeping the schedule. See `FramePacer`. */
470
+ resetPacing(): void {
471
+ this.pacer.resetMeasurement();
472
+ }
473
+
474
+ /** Give the surface back. Safe to call more than once. */
475
+ release(): void {
476
+ if (this.acquired) {
477
+ this.options.surface.unlockDrawingBuffer();
478
+ this.acquired = false;
479
+ }
480
+ // Only the track this class created. The audio the caller mixed in belongs
481
+ // to the audio graph and must survive to be recorded again.
482
+ this.videoTrack?.stop();
483
+ this.videoTrack = null;
484
+ this.stream = null;
485
+ this.mark = null;
486
+ /* So a caller that locks the same instance again starts with nothing to compare against,
487
+ rather than measuring its next frame against a session that already ended. */
488
+ this.lastPresentedFrames = null;
489
+ this.wasDuplicate = false;
490
+ }
491
+ }
@@ -0,0 +1,159 @@
1
+ import {
2
+ GLYPH_HEIGHT,
3
+ GLYPH_SPACING,
4
+ GLYPH_WIDTH,
5
+ forEachCell,
6
+ measureText,
7
+ } from '../geometry/pixelFont.ts';
8
+
9
+ /**
10
+ * Baking a mark into a still image sized to a video frame.
11
+ *
12
+ * Everything is placed and sized in **fractions of the frame**, never pixels.
13
+ * That is the whole point of the module: the same overlay has to read correctly
14
+ * at 1080x1920 and at 720x1280, and a mark laid out in pixels is either
15
+ * illegible at the smaller size or covers a quarter of the smaller frame. Text
16
+ * scales against the frame's *shorter* side so a portrait and a landscape
17
+ * export get a mark of the same apparent size rather than one that grows with
18
+ * whichever dimension happens to be long.
19
+ *
20
+ * Baked once, drawn once per captured frame. Painting a few hundred glyph cells
21
+ * per frame would be thirty times the work for an image that never changes.
22
+ *
23
+ * Nothing here knows what the mark says. Text, colour and position are the
24
+ * caller's; the font is the engine's 5x7 grid, so a mark needs no asset and
25
+ * cannot fail to load.
26
+ */
27
+ export interface OverlayText {
28
+ readonly text: string;
29
+ /** Left edge, as a fraction of frame width. */
30
+ readonly x: number;
31
+ /** Top edge, as a fraction of frame height. */
32
+ readonly y: number;
33
+ /** One glyph cell, as a fraction of the frame's shorter side. */
34
+ readonly cell: number;
35
+ readonly color: string;
36
+ readonly alpha?: number;
37
+ }
38
+
39
+ /** Anything a 2D context can draw and report a natural size for. */
40
+ export type OverlayImageSource = HTMLImageElement | HTMLCanvasElement | ImageBitmap;
41
+
42
+ export interface OverlayImage {
43
+ readonly image: OverlayImageSource;
44
+ readonly x: number;
45
+ readonly y: number;
46
+ /** Drawn height, as a fraction of the frame's shorter side. */
47
+ readonly height: number;
48
+ readonly alpha?: number;
49
+ }
50
+
51
+ export interface FrameOverlay {
52
+ readonly texts?: readonly OverlayText[];
53
+ readonly images?: readonly OverlayImage[];
54
+ }
55
+
56
+ /**
57
+ * How far the shadow sits behind the mark, in cells.
58
+ *
59
+ * A watermark has to survive both a night sky and a noon one. Light type alone
60
+ * disappears against a bright horizon — which in this game is most of the frame
61
+ * — so every glyph is stamped once in near-black first. One cell of offset,
62
+ * because a blur would fight the hard-edged look everything else has.
63
+ */
64
+ const SHADOW_CELLS = 1;
65
+ const SHADOW_COLOR = 'rgba(2, 5, 10, 0.55)';
66
+
67
+ /** Lit cells of a string, at a cell size in device pixels. */
68
+ export function drawPixelText(
69
+ ctx: CanvasRenderingContext2D,
70
+ text: string,
71
+ left: number,
72
+ top: number,
73
+ cell: number,
74
+ color: string,
75
+ ): void {
76
+ const height = GLYPH_HEIGHT * cell;
77
+ const paint = (dx: number, dy: number, fill: string): void => {
78
+ ctx.fillStyle = fill;
79
+ forEachCell(text, (cx, cy) => {
80
+ // Cell y counts up from the baseline; a canvas counts down from the top.
81
+ ctx.fillRect(
82
+ left + dx + cx * cell,
83
+ top + dy + height - (cy + 1) * cell,
84
+ // A hair of overlap, or antialiasing draws a seam between adjacent
85
+ // cells and the letters look woven rather than solid.
86
+ cell + 0.5,
87
+ cell + 0.5,
88
+ );
89
+ });
90
+ };
91
+
92
+ paint(SHADOW_CELLS * cell, SHADOW_CELLS * cell, SHADOW_COLOR);
93
+ paint(0, 0, color);
94
+ }
95
+
96
+ /** Pixel width and height of a string at a given cell size. */
97
+ export function pixelTextSize(text: string, cell: number): { width: number; height: number } {
98
+ return { width: measureText(text) * cell, height: GLYPH_HEIGHT * cell };
99
+ }
100
+
101
+ /** Cells a string occupies horizontally, including inter-glyph gaps. */
102
+ export function pixelTextCells(text: string): number {
103
+ return text.length === 0 ? 0 : text.length * (GLYPH_WIDTH + GLYPH_SPACING) - GLYPH_SPACING;
104
+ }
105
+
106
+ /**
107
+ * Paint an overlay into a transparent canvas of exactly the frame's size.
108
+ *
109
+ * Returns null when there is nothing to draw, so a caller can skip the
110
+ * composite entirely rather than blending a blank layer over every frame.
111
+ */
112
+ export function bakeOverlay(
113
+ overlay: FrameOverlay,
114
+ width: number,
115
+ height: number,
116
+ ): HTMLCanvasElement | null {
117
+ const texts = overlay.texts ?? [];
118
+ const images = overlay.images ?? [];
119
+ if (texts.length === 0 && images.length === 0) return null;
120
+
121
+ const canvas = document.createElement('canvas');
122
+ canvas.width = width;
123
+ canvas.height = height;
124
+ const ctx = canvas.getContext('2d');
125
+ if (ctx === null) return null;
126
+
127
+ const short = Math.min(width, height);
128
+ for (const image of images) {
129
+ const drawHeight = image.height * short;
130
+ const natural = imageAspect(image.image);
131
+ ctx.globalAlpha = image.alpha ?? 1;
132
+ ctx.drawImage(image.image, image.x * width, image.y * height, drawHeight * natural, drawHeight);
133
+ }
134
+ for (const text of texts) {
135
+ ctx.globalAlpha = text.alpha ?? 1;
136
+ /*
137
+ * Snapped to whole pixels. A 5x7 grid drawn on a half-pixel boundary is
138
+ * antialiased on every cell edge, which turns a hard-edged mark into a grey
139
+ * smudge — the one thing a watermark cannot be, since it is small by design.
140
+ */
141
+ drawPixelText(
142
+ ctx,
143
+ text.text,
144
+ Math.round(text.x * width),
145
+ Math.round(text.y * height),
146
+ text.cell * short,
147
+ text.color,
148
+ );
149
+ }
150
+ ctx.globalAlpha = 1;
151
+ return canvas;
152
+ }
153
+
154
+ function imageAspect(image: OverlayImageSource): number {
155
+ const width = image instanceof HTMLImageElement ? image.naturalWidth || image.width : image.width;
156
+ const height =
157
+ image instanceof HTMLImageElement ? image.naturalHeight || image.height : image.height;
158
+ return height > 0 ? width / height : 1;
159
+ }