@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,351 @@
1
+ /**
2
+ * Deciding which of a render loop's frames go into a recording, and measuring
3
+ * what came out.
4
+ *
5
+ * The measuring half is not diagnostics bolted on afterwards — it is half the
6
+ * reason this module exists. A clip that "judders" has at least three possible
7
+ * causes (the renderer missing its rate, the encoder starved of bitrate, the
8
+ * content itself stepping unevenly) and they are indistinguishable by eye. What
9
+ * separates them is a number: how many frames the loop produced, how many were
10
+ * handed to the recorder, and how far apart in wall-clock time those were.
11
+ *
12
+ * **The schedule counts animation frames, not milliseconds, and that is the
13
+ * whole design.** A recorder stamps each frame with the instant it arrived, and
14
+ * the only instants a render loop can offer are its display's own — so a
15
+ * schedule expressed in wall-clock slots asks for moments that do not exist. It
16
+ * then takes the nearest frame either side, alternately early and late, and the
17
+ * file holds frames of uneven duration: 13.9 ms, 20.8 ms, 13.9 ms on a 144 Hz
18
+ * panel asked for 60 a second. Capturing every *n*-th frame instead makes every
19
+ * gap identical by construction, which is what makes the clip play evenly.
20
+ *
21
+ * The rate that comes out is therefore the display's rate divided by a whole
22
+ * number — 60 from 60 Hz, 72 from 144, 60 from 240 — rather than exactly what
23
+ * was asked for. That is the right trade: a clip at 72 fps whose frames are
24
+ * evenly spaced is smooth, and one at exactly 60 whose frames are not is the
25
+ * defect this replaced.
26
+ *
27
+ * Two rules the schedule follows, both learned from what a stutter looks like:
28
+ *
29
+ * - **Never two captures for one animation frame.** A duplicated frame is a
30
+ * frozen instant followed by a double-length step, which reads as a hitch
31
+ * even though nothing was dropped. Counting frames makes this true by
32
+ * construction.
33
+ * - **After falling behind, resume — do not catch up.** Firing twice in quick
34
+ * succession to make up a missed slot converts one gap into a lurch forward.
35
+ * A gap is a frame nobody notices; a lurch is the artefact everybody calls
36
+ * lag.
37
+ */
38
+ export interface FramePacingReport {
39
+ readonly targetFps: number;
40
+ /** Animation frames the loop produced while the pacer was running. */
41
+ readonly rendered: number;
42
+ /** Frames handed to the recorder. */
43
+ readonly captured: number;
44
+ /** Frames per second actually captured, over the whole run. */
45
+ readonly capturedFps: number;
46
+ /** Mean wall-clock gap between captured frames, ms. */
47
+ readonly meanGapMs: number;
48
+ /** The worst single gap, ms — the one the eye actually notices. */
49
+ readonly worstGapMs: number;
50
+ /**
51
+ * Captures that arrived well outside the cadence the rest of the clip holds.
52
+ *
53
+ * Measured against the clip's *own* spacing rather than against the requested
54
+ * rate, because the two are allowed to differ: a display that divides to 72 fps
55
+ * or a loop that can only manage 40 both produce a clip whose every frame is
56
+ * evenly spaced, and neither is a fault. What is a fault is one frame taking
57
+ * half again as long as its neighbours, and that is what this counts.
58
+ */
59
+ readonly slipped: number;
60
+ /** Animation frames per capture — the schedule the clip actually ran on. */
61
+ readonly stride: number;
62
+ readonly elapsedMs: number;
63
+ }
64
+
65
+ /**
66
+ * How far outside the established cadence a gap has to fall to count as slipped.
67
+ * A little over one gap, so ordinary display jitter is not reported as a fault.
68
+ */
69
+ const SLIP_FACTOR = 1.4;
70
+ /** Weight of the newest gap in the cadence estimate. */
71
+ const CADENCE_EMA = 0.15;
72
+ /**
73
+ * Animation frames the interval estimate is taken over.
74
+ *
75
+ * Sixteen: a quarter of a second at 60 Hz, which is long enough to absorb one bad
76
+ * sample and short enough that the schedule is settled before anything is recorded.
77
+ * The estimate is re-taken every time the window fills, so a loop that gets heavier
78
+ * mid-clip is followed rather than held to a schedule it can no longer keep.
79
+ */
80
+ const SAMPLE_WINDOW = 16;
81
+ /**
82
+ * Slack in the stride calculation, as a share of the ratio being floored.
83
+ *
84
+ * Half a percent, and it is small because the estimator earns it. A 60 Hz display
85
+ * asked for 30 fps wants a stride of exactly 2, and a measured interval of 16.6668 ms
86
+ * gives a ratio of 1.99998 — so a bare `floor` answers 1 and doubles the rate. That
87
+ * is the entire job: cover a measurement that lands a hair long, and floating point.
88
+ *
89
+ * It was five percent while the estimate came from a median, which sits *above* the
90
+ * display's period and needed the room. A trimmed minimum sits at or just below it,
91
+ * so the ratio errs high already and slack on top only pushes it over the next
92
+ * boundary the wrong way: measured at five percent, a 100 Hz panel asked for 60
93
+ * sometimes recorded 50 instead of 100, because a jittery window read the period as
94
+ * 8.6 ms and 1.94 became 2.03.
95
+ */
96
+ const STRIDE_SLACK = 0.005;
97
+ /**
98
+ * How far past its boundary the measurement has to move before the stride changes,
99
+ * in whole strides.
100
+ *
101
+ * A fifth, and this is the part slack alone could not do. The stride is a *discrete*
102
+ * choice, so a ratio sitting near a boundary flips it on the noise in the estimate —
103
+ * and a flip between 1 and 2 doubles the clip's frame rate. Measured on a loop with
104
+ * 24% frame-time jitter and a true ratio of exactly 2.0: the median of a
105
+ * sixteen-frame window wanders between 16.7 ms and 18.3 ms, which is a ratio between
106
+ * 2.0 and 1.82, and the stride flipped five times in a ten-second clip.
107
+ *
108
+ * A display's period does not change, so the right default is to keep the schedule
109
+ * already chosen and demand real evidence to leave it. A fifth of a stride is well
110
+ * past what a median of sixteen frames is wrong by and well short of a genuine step.
111
+ */
112
+ const STRIDE_HYSTERESIS = 0.2;
113
+
114
+ /**
115
+ * Animation frames per capture, given the target interval, what one animation frame
116
+ * actually costs, and the schedule already running.
117
+ *
118
+ * Rounded down, so the rate that comes out is never *below* the one asked for while
119
+ * the loop can hold it: a 100 Hz display asked for 60 records 100 rather than 50,
120
+ * which is more frames than needed and smooth, where the other way round is fewer
121
+ * frames than promised.
122
+ *
123
+ * `current` is held on to unless the measurement has moved clearly past its
124
+ * boundary — see `STRIDE_HYSTERESIS`. Pass 0 to choose freely.
125
+ */
126
+ function strideFor(targetIntervalMs: number, frameIntervalMs: number, current = 0): number {
127
+ if (!(frameIntervalMs > 0)) return Math.max(1, current);
128
+ const scaled = (targetIntervalMs / frameIntervalMs) * (1 + STRIDE_SLACK);
129
+ if (
130
+ current > 0 &&
131
+ scaled >= current - STRIDE_HYSTERESIS &&
132
+ scaled < current + 1 + STRIDE_HYSTERESIS
133
+ ) {
134
+ return current;
135
+ }
136
+ return Math.max(1, Math.floor(scaled));
137
+ }
138
+
139
+ /**
140
+ * Second-smallest of `values`, sorted into `scratch`.
141
+ *
142
+ * **A trimmed minimum, and the choice of statistic is the whole point.** What is
143
+ * being estimated is the display's period, and that is a *floor* on how long an
144
+ * animation frame can take — a frame cannot come back sooner than the next vsync, it
145
+ * can only take longer and land on a later one. So the low end of the distribution is
146
+ * where the answer lives, and the mean and the median are both biased above it by
147
+ * however hard the loop is working.
148
+ *
149
+ * Which matters because the estimate feeds a `floor`: a stride of 2 asks whether the
150
+ * ratio is above or below 2, and an estimator that wanders either side of the answer
151
+ * flips the clip's frame rate. Measured with a median of sixteen: on a loop with 24%
152
+ * frame-time jitter and a true ratio of exactly 2, the median wandered between
153
+ * 16.7 ms and 18.3 ms and the stride flipped, taking a 30 fps request to 36.
154
+ *
155
+ * Second-smallest rather than smallest because the minimum has no defence at all
156
+ * against a bad sample — two callbacks in one frame, a clock that jumped, a tab
157
+ * waking up — and one of those in a window would set a stride far too long. One
158
+ * anomaly per sixteen frames is absorbed; two in the same window is not, which is a
159
+ * trade rather than an oversight.
160
+ *
161
+ * Insertion sort into a caller-owned buffer, because this runs inside a render loop
162
+ * and must not allocate. Sixteen elements nearly in order is a handful of
163
+ * comparisons; the general case is still trivial at this size.
164
+ */
165
+ function trimmedMinimum(values: Float64Array, scratch: Float64Array): number {
166
+ const n = values.length;
167
+ for (let i = 0; i < n; i++) {
168
+ const value = values[i] ?? 0;
169
+ let j = i - 1;
170
+ while (j >= 0 && (scratch[j] ?? 0) > value) {
171
+ scratch[j + 1] = scratch[j] ?? 0;
172
+ j--;
173
+ }
174
+ scratch[j + 1] = value;
175
+ }
176
+ return scratch[Math.min(1, n - 1)] ?? 0;
177
+ }
178
+
179
+ export class FramePacer {
180
+ private readonly intervalMs: number;
181
+ /** Animation frames per capture. One until the loop's own rate is known. */
182
+ private strideFrames = 1;
183
+ private framesSinceCapture = 0;
184
+ private startMs = 0;
185
+ private lastCaptureMs = 0;
186
+ /**
187
+ * What one animation frame costs, ms — a trimmed minimum over a recent window.
188
+ *
189
+ * See `trimmedMinimum` for why the low end and not the middle. Three estimators
190
+ * were tried before it and each failed in a way worth recording: a running minimum
191
+ * over all time ratcheted down on anomalies until a clean 120 Hz loop recorded
192
+ * **24 fps**; a mean was dragged up by every overrunning frame, doubling the rate
193
+ * for the thirty frames an average takes to decay after one hitch; a median sat too
194
+ * far above the floor and wandered across the stride boundary.
195
+ */
196
+ private frameIntervalMs = 0;
197
+ /** Recent animation-frame intervals, and a scratch buffer to sort them in. */
198
+ private readonly samples = new Float64Array(SAMPLE_WINDOW);
199
+ private readonly sorted = new Float64Array(SAMPLE_WINDOW);
200
+ private sampleCount = 0;
201
+ /** The instant last seen, so a frame is only ever counted once. */
202
+ private lastSeenMs = 0;
203
+ private seen = false;
204
+ /** Rolling estimate of the gap the clip is actually holding, for `slipped`. */
205
+ private cadenceMs = 0;
206
+ private renderedFrames = 0;
207
+ private capturedFrames = 0;
208
+ private gapSumMs = 0;
209
+ private worstGapMs = 0;
210
+ private slippedFrames = 0;
211
+ private started = false;
212
+
213
+ constructor(readonly targetFps: number) {
214
+ this.intervalMs = 1000 / Math.max(targetFps, 1);
215
+ }
216
+
217
+ /**
218
+ * Whether this animation frame is one the recording wants, without committing.
219
+ *
220
+ * The query half of `offer`, and it exists so a caller can decide *before
221
+ * rendering* whether the frame it is about to draw will be kept. A renderer that
222
+ * draws every animation frame and then discards most of them spends its whole
223
+ * budget competing with the frame it means to keep.
224
+ *
225
+ * Called once per animation frame, before drawing. That is also where the loop's
226
+ * own interval is measured, since it is the only call that sees every frame:
227
+ * `offer` only sees the ones that were drawn.
228
+ *
229
+ * Allocation-free: this is called from inside a render loop.
230
+ */
231
+ due(nowMs: number): boolean {
232
+ this.observe(nowMs);
233
+ if (!this.started) return true;
234
+ return this.framesSinceCapture >= this.strideFrames;
235
+ }
236
+
237
+ /**
238
+ * Commit to the frame `due` was asked about.
239
+ *
240
+ * **`nowMs` must be the instant `due` was given, not the instant the frame
241
+ * finished drawing.** Both halves have to agree about when the frame is, or a
242
+ * frame is counted twice — once on the way in and once on the way out — and the
243
+ * loop's measured interval comes out at half its true value.
244
+ *
245
+ * A caller with nothing to gate may pass whatever clock it has, as long as it is
246
+ * the same one every frame.
247
+ */
248
+ offer(nowMs: number): boolean {
249
+ this.observe(nowMs);
250
+ if (!this.started) {
251
+ this.started = true;
252
+ this.startMs = nowMs;
253
+ this.lastCaptureMs = nowMs;
254
+ this.framesSinceCapture = 0;
255
+ this.capturedFrames = 1;
256
+ return true;
257
+ }
258
+
259
+ if (this.framesSinceCapture < this.strideFrames) return false;
260
+
261
+ const gap = nowMs - this.lastCaptureMs;
262
+ this.gapSumMs += gap;
263
+ if (gap > this.worstGapMs) this.worstGapMs = gap;
264
+ // Against the cadence so far, and only once there is one to compare with.
265
+ if (this.cadenceMs > 0 && gap > this.cadenceMs * SLIP_FACTOR) this.slippedFrames++;
266
+ this.cadenceMs =
267
+ this.cadenceMs === 0 ? gap : this.cadenceMs + (gap - this.cadenceMs) * CADENCE_EMA;
268
+ this.lastCaptureMs = nowMs;
269
+ this.framesSinceCapture = 0;
270
+ this.capturedFrames++;
271
+ return true;
272
+ }
273
+
274
+ /** One animation frame seen, for the interval estimate and the frame count. */
275
+ private observe(nowMs: number): void {
276
+ if (this.seen && nowMs === this.lastSeenMs) return;
277
+ const since = this.seen ? nowMs - this.lastSeenMs : 0;
278
+ this.lastSeenMs = nowMs;
279
+ this.seen = true;
280
+ this.renderedFrames++;
281
+ if (this.started) this.framesSinceCapture++;
282
+ if (since <= 0) return;
283
+
284
+ this.samples[this.sampleCount % SAMPLE_WINDOW] = since;
285
+ this.sampleCount++;
286
+ /*
287
+ * Until there is a window to take a median of, the estimate is the *shortest*
288
+ * frame seen so far. A schedule is needed before sixteen frames have passed — a
289
+ * recording that waited would capture all sixteen of them, a burst at the head of
290
+ * every clip — and of the estimators available before then the minimum is the one
291
+ * that errs the safe way: it reads the loop as faster than it is, which makes the
292
+ * stride longer and captures *fewer* frames than intended rather than more.
293
+ *
294
+ * The minimum's own failing, that one anomalous frame owns it for good, cannot
295
+ * bite here: sixteen frames later the median takes over and never gives it back.
296
+ */
297
+ if (this.sampleCount < SAMPLE_WINDOW) {
298
+ if (this.frameIntervalMs === 0 || since < this.frameIntervalMs) {
299
+ this.frameIntervalMs = since;
300
+ this.strideFrames = strideFor(this.intervalMs, since);
301
+ }
302
+ return;
303
+ }
304
+ /*
305
+ * Re-taken when the window fills rather than on every frame: sorting sixteen
306
+ * numbers is cheap but this is a render loop, and a display's period does not
307
+ * change between one frame and the next.
308
+ */
309
+ if (this.sampleCount % SAMPLE_WINDOW !== 0) return;
310
+ this.frameIntervalMs = trimmedMinimum(this.samples, this.sorted);
311
+ this.strideFrames = strideFor(this.intervalMs, this.frameIntervalMs, this.strideFrames);
312
+ }
313
+
314
+ /**
315
+ * Forget what has been measured, keep the schedule.
316
+ *
317
+ * For a recording with a warm-up in front of it: the frames a device spends
318
+ * getting an encoder and a driver going are genuinely awful — measured at 411 ms
319
+ * and 503 ms for a 1080x1920 clip — and they are not what the clip is like. Left in
320
+ * the report they become the worst gap and a couple of slipped frames, which is the
321
+ * evidence an export decides whether to warn the player on.
322
+ *
323
+ * The schedule survives on purpose: it was chosen from those same frames and it is
324
+ * still right.
325
+ */
326
+ resetMeasurement(): void {
327
+ this.startMs = this.lastCaptureMs;
328
+ this.capturedFrames = 1;
329
+ this.renderedFrames = 0;
330
+ this.gapSumMs = 0;
331
+ this.worstGapMs = 0;
332
+ this.slippedFrames = 0;
333
+ this.cadenceMs = 0;
334
+ }
335
+
336
+ get report(): FramePacingReport {
337
+ const elapsedMs = this.started ? Math.max(this.lastCaptureMs - this.startMs, 0) : 0;
338
+ const gaps = Math.max(this.capturedFrames - 1, 0);
339
+ return {
340
+ targetFps: this.targetFps,
341
+ rendered: this.renderedFrames,
342
+ captured: this.capturedFrames,
343
+ capturedFps: elapsedMs > 0 ? (gaps * 1000) / elapsedMs : 0,
344
+ meanGapMs: gaps > 0 ? this.gapSumMs / gaps : 0,
345
+ worstGapMs: this.worstGapMs,
346
+ slipped: this.slippedFrames,
347
+ stride: this.strideFrames,
348
+ elapsedMs,
349
+ };
350
+ }
351
+ }
@@ -0,0 +1,333 @@
1
+ import { supportedClipMimeType } from './clipMime.ts';
2
+ import { ExportTarget, clipBitrate, exportSizeFor } from './exportTarget.ts';
3
+ import type { LockableSurface } from './exportTarget.ts';
4
+ import type { FrameOverlay } from './frameOverlay.ts';
5
+ import type { FramePacingReport } from './framePacer.ts';
6
+
7
+ export const DEFAULT_CLIP_FPS = 30;
8
+
9
+ /**
10
+ * Recording what is on a canvas — or on a prepared export target — to a file.
11
+ *
12
+ * A convenience on top of the replay, not the feature. The replay itself is
13
+ * what makes a run worth posting; this saves the trouble of reaching for a
14
+ * screen recorder — and where the browser cannot do it, saying so plainly beats
15
+ * producing a file that will not play.
16
+ *
17
+ * Deliberately not a server-side render. That is the "proper" answer and it is
18
+ * a backend, a queue, a storage bill and a moderation problem, for something
19
+ * the browser already does.
20
+ *
21
+ * **The honest limit, and it belongs here rather than in a commit message:**
22
+ * `MediaRecorder` timestamps every frame by wall clock, and that is measured
23
+ * rather than assumed — a probe recording requested frames at gaps of 8.6 / 24.5 /
24
+ * 8.1 / 28.6 ms and `ffprobe` read the MP4's own timestamps back as 8.8 / 24.2 /
25
+ * 8.1 / 28.5 ms, `avg_frame_rate=7110000/120161`. Two things follow.
26
+ *
27
+ * An export has to run in real time: there is no in-browser way to render a clip
28
+ * slower than real time and have the audio line up, short of shipping our own
29
+ * muxer, which is a dependency and the standing rule says no. So the export can be
30
+ * *paced* (see `ExportTarget`) and *measured*, but it cannot be given more time.
31
+ *
32
+ * And a constant-rate file is not on offer either. What is on offer is a file whose
33
+ * frames are evenly spaced *and* hold moments the same distance apart, which is
34
+ * what a viewer reads as smooth — so the schedule captures every n-th animation
35
+ * frame and the content follows the wall clock. A device that cannot hold the
36
+ * target rate then produces a slower clip rather than a juddering one, and the
37
+ * measurement in `pacing` says which it was.
38
+ */
39
+ export interface FrameRecorderOptions {
40
+ /**
41
+ * Record the canvas directly, at `fps`. Simple and appropriate for a debug
42
+ * capture; for a clip anybody else will see, prefer `stream` from an
43
+ * `ExportTarget`, which fixes the aspect, stamps the mark and paces the
44
+ * frames.
45
+ */
46
+ readonly canvas?: HTMLCanvasElement;
47
+ /** A prepared video stream, e.g. `ExportTarget.acquire()`. Wins over `canvas`. */
48
+ readonly stream?: MediaStream;
49
+ /** Mixed into the clip. Omit for a silent recording. */
50
+ readonly audio?: MediaStream | null;
51
+ /**
52
+ * Frames per second wanted — a floor, not a promise.
53
+ *
54
+ * The schedule counts animation frames (see `FramePacer`), so what comes out is
55
+ * the loop's own rate divided by a whole number. Asking for 60 on a 144 Hz panel
56
+ * records 72; asking for it on a loop that can only deliver 40 records 40.
57
+ */
58
+ readonly fps?: number;
59
+ /**
60
+ * Bits per second for video. Defaults to a figure scaled from the frame's
61
+ * pixel count and rate — a constant is generous at one size and starved at
62
+ * another, and a starved encoder on high-motion footage looks like stutter.
63
+ */
64
+ readonly videoBitsPerSecond?: number;
65
+ /**
66
+ * Record at a fixed frame size rather than at whatever the canvas happens to
67
+ * be, compositing the scene and an optional mark into it.
68
+ *
69
+ * This is what makes an export a *product* rather than a screen capture: the
70
+ * frame is the requested shape whatever the window is, the mark is inside the
71
+ * video where a DOM overlay could never be, and frames are handed over one at a
72
+ * time so none is ever recorded twice.
73
+ */
74
+ readonly target?: {
75
+ /** The canvas the scene is drawn into. */
76
+ readonly source: HTMLCanvasElement;
77
+ /** Whoever owns that canvas's drawing-buffer size — normally the renderer. */
78
+ readonly surface: LockableSurface;
79
+ readonly width: number;
80
+ readonly height: number;
81
+ readonly overlay?: FrameOverlay | ((width: number, height: number) => FrameOverlay);
82
+ /**
83
+ * Drawn live into every composed frame, after the scene and the baked mark.
84
+ *
85
+ * For anything that changes frame to frame — a speedometer, a clock — which the
86
+ * baked `overlay` cannot express at all. See `ExportTargetOptions.drawFrame`.
87
+ */
88
+ readonly drawFrame?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
89
+ /**
90
+ * What the renderer is currently managing, frames per second. A device below
91
+ * the target rate records at a smaller frame instead: a slightly softer clip
92
+ * that holds its rate beats a full-size one that judders. Omit for no
93
+ * measurement, which is treated as no evidence rather than as bad news.
94
+ */
95
+ readonly measuredFps?: number;
96
+ /** Forwarded to `ExportTargetOptions.presentedFrames`; see `duplicateFrame` below. */
97
+ readonly presentedFrames?: () => number;
98
+ };
99
+ }
100
+
101
+ export class FrameRecorder {
102
+ private recorder: MediaRecorder | null = null;
103
+ private chunks: Blob[] = [];
104
+ private readonly mime: string;
105
+ private target: ExportTarget | null = null;
106
+ private targetStream: MediaStream | null = null;
107
+
108
+ constructor(private readonly options: FrameRecorderOptions) {
109
+ const mime = supportedClipMimeType();
110
+ if (mime === null) throw new Error('This browser cannot record video.');
111
+ if (
112
+ options.canvas === undefined &&
113
+ options.stream === undefined &&
114
+ options.target === undefined
115
+ ) {
116
+ throw new Error('A recording needs a canvas, a stream or a target.');
117
+ }
118
+ this.mime = mime;
119
+ }
120
+
121
+ get mimeType(): string {
122
+ return this.mime;
123
+ }
124
+
125
+ /**
126
+ * Take over the render surface before recording starts.
127
+ *
128
+ * Separate from `start` because the aspect has to be in force *before* the
129
+ * first frame anybody records: the camera composes for `renderer.aspect`, so
130
+ * locking and recording in the same breath would put a screen-shaped shot in
131
+ * the first frames of a vertical clip. Returns the frame size that will be
132
+ * recorded, which is not always the one requested — see `measuredFps`.
133
+ */
134
+ prepare(): { width: number; height: number; reduced: boolean } | null {
135
+ const options = this.options.target;
136
+ if (options === undefined) return null;
137
+ if (this.target !== null) {
138
+ return { width: this.target.width, height: this.target.height, reduced: false };
139
+ }
140
+ const fps = this.options.fps ?? DEFAULT_CLIP_FPS;
141
+ // The measurement was taken while rendering the *window*, so it is handed in
142
+ // with the pixel count it was taken at — see `exportSizeFor`.
143
+ const size = exportSizeFor(
144
+ options.width,
145
+ options.height,
146
+ options.measuredFps ?? 0,
147
+ fps,
148
+ options.source.width * options.source.height,
149
+ );
150
+ this.target = new ExportTarget({
151
+ source: options.source,
152
+ surface: options.surface,
153
+ width: size.width,
154
+ height: size.height,
155
+ fps,
156
+ ...(options.overlay === undefined ? {} : { overlay: options.overlay }),
157
+ ...(options.drawFrame === undefined ? {} : { drawFrame: options.drawFrame }),
158
+ ...(options.presentedFrames === undefined
159
+ ? {}
160
+ : { presentedFrames: options.presentedFrames }),
161
+ });
162
+ this.targetStream = this.target.acquire();
163
+ return size;
164
+ }
165
+
166
+ /**
167
+ * Whether the frame about to be drawn will be kept. True when there is no
168
+ * fixed target, so a caller can gate its render pass unconditionally.
169
+ *
170
+ * Call once per animation frame, drawing or not: the instant is kept and reused
171
+ * when the frame is handed over, so one clock decides and commits.
172
+ */
173
+ captureDue(nowMs: number): boolean {
174
+ return this.target?.captureDue(nowMs) ?? true;
175
+ }
176
+
177
+ /**
178
+ * One rendered frame, offered to the recording.
179
+ *
180
+ * Call at the very end of the render pass. Cheap and false when there is no
181
+ * fixed target, so a caller can hand every frame over unconditionally. Takes no
182
+ * instant — it uses the one `captureDue` was given for this frame.
183
+ */
184
+ frameRendered(): boolean {
185
+ return this.target?.frameRendered() ?? false;
186
+ }
187
+
188
+ /**
189
+ * What the pacing actually was, or null when recording the canvas directly.
190
+ *
191
+ * The measurement is the point rather than a diagnostic afterthought: an export
192
+ * that ran below its target rate produced a juddering file, and the only honest
193
+ * options are to say so or to have not measured.
194
+ */
195
+ get pacing(): FramePacingReport | null {
196
+ return this.target === null ? null : this.target.pacing;
197
+ }
198
+
199
+ /**
200
+ * Whether the frame `frameRendered` just composited repeats the one before it.
201
+ *
202
+ * False without a target, and false when `presentedFrames` was never supplied — the same
203
+ * two "no evidence yet" cases `pacing` already has to account for. See
204
+ * `ExportTarget.duplicateFrame`, which this only forwards.
205
+ */
206
+ get duplicateFrame(): boolean {
207
+ return this.target?.duplicateFrame ?? false;
208
+ }
209
+
210
+ /**
211
+ * Start the measurement over, keeping the schedule.
212
+ *
213
+ * For a caller that records a warm-up in front of the clip proper: what a device
214
+ * costs while an encoder gets going is not what the clip is like, and the report is
215
+ * what the export decides whether to warn the player on.
216
+ */
217
+ resetPacing(): void {
218
+ this.target?.resetPacing();
219
+ }
220
+
221
+ start(): void {
222
+ if (this.recorder !== null) return;
223
+ const { canvas, audio, fps = DEFAULT_CLIP_FPS } = this.options;
224
+
225
+ if (this.options.target !== undefined) this.prepare();
226
+ const source = this.targetStream ?? this.options.stream ?? canvas?.captureStream(fps) ?? null;
227
+ if (source === null) throw new Error('A recording needs a canvas, a stream or a target.');
228
+
229
+ /*
230
+ * A fresh stream rather than the source one. Adding the audio tracks to a
231
+ * stream the caller owns means stopping the recording would stop the audio
232
+ * graph's capture track too, and a second export would then come out silent.
233
+ */
234
+ const stream = new MediaStream();
235
+ for (const track of source.getVideoTracks()) stream.addTrack(track);
236
+ if (audio != null) {
237
+ for (const track of audio.getAudioTracks()) stream.addTrack(track);
238
+ }
239
+
240
+ this.chunks = [];
241
+ this.recorder = new MediaRecorder(stream, {
242
+ mimeType: this.mime,
243
+ videoBitsPerSecond: this.options.videoBitsPerSecond ?? this.defaultBitrate(stream, fps),
244
+ });
245
+ this.recorder.ondataavailable = (event): void => {
246
+ if (event.data.size > 0) this.chunks.push(event.data);
247
+ };
248
+ this.recorder.start();
249
+ }
250
+
251
+ /**
252
+ * Resolves with the finished clip, or null if nothing was recorded.
253
+ *
254
+ * The surface goes back before the promise resolves either way. A cancelled
255
+ * export that left the drawing buffer pinned to 1080x1920 would leave the game
256
+ * rendering into the wrong shape for the rest of the session.
257
+ */
258
+ async stop(): Promise<Blob | null> {
259
+ const recorder = this.recorder;
260
+ if (recorder === null) {
261
+ this.release();
262
+ return null;
263
+ }
264
+ this.recorder = null;
265
+
266
+ await new Promise<void>((resolve) => {
267
+ recorder.onstop = (): void => resolve();
268
+ try {
269
+ recorder.stop();
270
+ } catch {
271
+ resolve();
272
+ }
273
+ });
274
+ this.release();
275
+
276
+ if (this.chunks.length === 0) return null;
277
+ return new Blob(this.chunks, { type: this.mime });
278
+ }
279
+
280
+ /** Give the render surface back. Safe at any point, and idempotent. */
281
+ release(): void {
282
+ this.target?.release();
283
+ this.target = null;
284
+ this.targetStream = null;
285
+ }
286
+
287
+ /**
288
+ * Bitrate from whatever the frame's real size turns out to be.
289
+ *
290
+ * Read from the track where possible, because that is the authority: a stream
291
+ * from a composited target has nothing to do with the canvas that was passed
292
+ * in, and guessing from the wrong one is how a 1080x1920 clip ends up encoded
293
+ * at a bitrate chosen for a 400-pixel window.
294
+ */
295
+ private defaultBitrate(stream: MediaStream, fps: number): number {
296
+ const track = stream.getVideoTracks()[0];
297
+ const settings = track?.getSettings();
298
+ const width = settings?.width ?? this.options.canvas?.width ?? 1280;
299
+ const height = settings?.height ?? this.options.canvas?.height ?? 720;
300
+ return clipBitrate(width, height, fps);
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Hand a file to the player.
306
+ *
307
+ * `navigator.share` where it exists, because on a phone that is one tap into
308
+ * the app they were going to post to anyway; a download otherwise. A file in
309
+ * the Downloads folder that nobody can find is most of the way to no export at
310
+ * all.
311
+ */
312
+ export async function offerClip(blob: Blob, filename: string): Promise<void> {
313
+ const file = new File([blob], filename, { type: blob.type });
314
+
315
+ if (typeof navigator.canShare === 'function' && navigator.canShare({ files: [file] })) {
316
+ try {
317
+ await navigator.share({ files: [file] });
318
+ return;
319
+ } catch {
320
+ // Cancelled, or refused. Fall through to a download rather than leaving
321
+ // the player with nothing.
322
+ }
323
+ }
324
+
325
+ const url = URL.createObjectURL(blob);
326
+ const link = document.createElement('a');
327
+ link.href = url;
328
+ link.download = filename;
329
+ link.click();
330
+ // Revoked on the next turn: doing it synchronously races the download in
331
+ // some browsers and produces an empty file.
332
+ setTimeout(() => URL.revokeObjectURL(url), 10_000);
333
+ }