@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,856 @@
1
+ import { glSceneDepthFormat } from './depthConvention.js';
2
+ import { AmbientOcclusionPass } from './ambientOcclusionPass.js';
3
+ import { BloomPass } from './bloomPass.js';
4
+ import { GRADE_PLACEHOLDER_SIZE, identityGradeLut, validateGradeLut, } from './colourGrade.js';
5
+ import { compileProgram, uniformLocations } from './shader.js';
6
+ import { TemporalPass } from './temporalPass.js';
7
+ import { FULLSCREEN_VERT } from './shaders/fullscreen.js';
8
+ import { RUSH_FRAG } from './shaders/rush.js';
9
+ /** No veil, so a caller that omits the argument gets exactly the frame it always got. */
10
+ const NO_VEIL = [0, 0, 0];
11
+ /**
12
+ * An off-screen colour target for the frame, and the pass that resolves it to the canvas.
13
+ *
14
+ * The renderer drew straight to the canvas, which is the right default and is why this is
15
+ * opt-in: with nothing to sample a finished frame from, no screen-space effect can exist at
16
+ * all. A speed blur faked with a compositor filter over the canvas gets the boundary
17
+ * wrong in both directions: it is too strong, and it cannot leave the HUD alone. The
18
+ * effect belongs to the 3D scene, so the scene needs somewhere to land before it is shown.
19
+ *
20
+ * **It resolves to the canvas, always.** Two consumers depend on that and neither is
21
+ * optional: a frame recorder reads the canvas to build a clip, and a still is a canvas
22
+ * copy. Leaving the scene in a framebuffer would produce a black export while the screen
23
+ * looked correct, which is the worst shape a bug can have.
24
+ *
25
+ * Sized from the drawing buffer and rebuilt when that changes, so a resize, a DPR change
26
+ * and an export lock all land on an exactly-sized target rather than a stretched one. The
27
+ * depth buffer lives here too: a scene drawn into a colour attachment with the canvas's
28
+ * depth buffer would have no depth at all.
29
+ */
30
+ export class SceneTarget {
31
+ gl;
32
+ discardResolved;
33
+ framebuffer = null;
34
+ texture = null;
35
+ /**
36
+ * Depth as a *texture* rather than a renderbuffer, so the composite pass can read it.
37
+ *
38
+ * A renderbuffer is write-only from a shader's point of view, and every screen-space
39
+ * effect worth having needs the depth back: motion blur reconstructs a world position
40
+ * from it to reproject through the previous view, and ambient occlusion is nothing but
41
+ * depth compared against its neighbours. Costing the same memory and being sampleable,
42
+ * there is no reason for it to be anything else.
43
+ */
44
+ depth = null;
45
+ /**
46
+ * A copy of the frame's depth taken mid-pass, for anything that must read it while drawing.
47
+ *
48
+ * **Not `depth` itself, and the distinction is the whole reason this exists.** `depth` is the
49
+ * attachment the frame is testing against, and sampling a texture that is attached to the
50
+ * bound framebuffer is undefined in WebGL2 — it draws something plausible on this driver and
51
+ * something else on the next. So a volume of light, which has to know where the opaque scene
52
+ * is in order to stop marching at it, reads this instead.
53
+ *
54
+ * Filled by `snapshotDepth`, on demand, and only in frames that ask.
55
+ */
56
+ depthCopy = null;
57
+ depthCopyFramebuffer = null;
58
+ /** Whether this frame has filled it. One snapshot serves every volume in a frame. */
59
+ depthCopyFilled = false;
60
+ /**
61
+ * The colour the frame had already drawn when something first asked for it.
62
+ *
63
+ * **A copy and never the attachment**, which is the difference `colorAttachment` documents from
64
+ * the other side: that one returns null while multisampling, because the frame lives in a
65
+ * renderbuffer until `resolve` blits into it. A blit from a multisampled source to a
66
+ * single-sampled destination *is* a resolve, so this answers in exactly the configuration where
67
+ * reading the attachment cannot.
68
+ *
69
+ * Filled by `snapshotColor`, on demand, and only in frames that ask.
70
+ */
71
+ colorCopy = null;
72
+ colorCopyFramebuffer = null;
73
+ /** Whether this frame has filled it. One snapshot serves every refracting draw in a frame. */
74
+ colorCopyFilled = false;
75
+ /**
76
+ * The colour grade, as a 3D texture on unit 4, and the table it was built from.
77
+ *
78
+ * **The source is kept to compare identities, not to read.** A grade is set every frame by a
79
+ * consumer that has one, and re-uploading a 32-lattice table is 131 kilobytes of `texImage3D`
80
+ * sixty times a second for bytes that did not change. Comparing the object is what makes
81
+ * `setColourGrade` free to call from a frame loop — and a consumer crossfading between two
82
+ * grades holds two objects, which compare unequal and upload once each on the swap.
83
+ */
84
+ gradeTexture = null;
85
+ gradeSource = null;
86
+ gradeSize = GRADE_PLACEHOLDER_SIZE;
87
+ gradeStrength = 0;
88
+ width = 0;
89
+ height = 0;
90
+ /**
91
+ * The multisampled pair, present only when a caller asked for samples.
92
+ *
93
+ * Two framebuffers rather than one, because a multisampled attachment cannot be sampled
94
+ * by a shader: the scene is drawn into `msaaFramebuffer`, blitted down into the ordinary
95
+ * texture, and the post chain reads that exactly as it always has. Everything downstream
96
+ * of the blit is unchanged, which is what keeps this a quality option rather than a
97
+ * second rendering path.
98
+ */
99
+ msaaFramebuffer = null;
100
+ msaaColor = null;
101
+ msaaDepth = null;
102
+ /** What was actually allocated, after clamping to what the driver reports. */
103
+ samples = 1;
104
+ /** Whether anything actually reads the resolved depth. Nothing is copied if not. */
105
+ depthWanted = false;
106
+ /** Set once if the driver refuses the depth copy, so it is attempted once and not per frame. */
107
+ depthBlitRefused = false;
108
+ program;
109
+ uniforms;
110
+ vao;
111
+ /**
112
+ * Built the first time a caller asks for occlusion, and never for one that does not.
113
+ *
114
+ * Two programs and two full-frame targets is not a thing to allocate on the chance somebody
115
+ * turns the option on later: the option is construction-time, so a renderer that was not
116
+ * asked for it will never be.
117
+ */
118
+ ao = null;
119
+ /** Built the first time a caller asks for bloom, on the same terms as the occlusion pass. */
120
+ bloom = null;
121
+ /** Built on the first frame that asks for it, like `bloom` beside it. */
122
+ temporal = null;
123
+ /** Whether the colour attachments hold half floats. See the constructor. */
124
+ floatColor = false;
125
+ constructor(gl, requestedSamples = 1, wantsRange = false,
126
+ /**
127
+ * Whether the multisampled buffers may be thrown away once blitted down.
128
+ *
129
+ * True is correct and saves a full attachment write per frame on a tiler. It is a switch
130
+ * because, like WebGPU's `storeOp: 'discard'`, it is invisible on an immediate-mode desktop
131
+ * part and therefore cannot be verified by a screenshot: see
132
+ * `RenderQuality.discardResolvedAttachments`.
133
+ */
134
+ discardResolved = true) {
135
+ this.gl = gl;
136
+ this.discardResolved = discardResolved;
137
+ /*
138
+ * Clamped to MAX_SAMPLES rather than trusted. Asking for more than the part supports
139
+ * produces a framebuffer that never completes, and an incomplete framebuffer is a black
140
+ * frame with no GL error attached to explain it.
141
+ */
142
+ const maximum = gl.getParameter(gl.MAX_SAMPLES);
143
+ this.samples = Math.max(1, Math.min(Math.round(requestedSamples), Number.isFinite(maximum) ? maximum : 1));
144
+ /*
145
+ * A float colour target where the part will render to one, and eight bits where it will not.
146
+ *
147
+ * **The reason it matters is what a composite can still tell apart.** With an eight-bit
148
+ * target the scene has already been squashed into 0 to 1 by the time anything downstream
149
+ * looks at it, so a star at five times white and a sheet of white paper arrive identical and
150
+ * nothing can treat them differently. Half floats keep the difference, which is what makes a
151
+ * bloom threshold mean brightness rather than mean whiteness, and it is why the tone curve
152
+ * moved from the mesh pass to the resolve: a curve applied before the buffer throws away the
153
+ * range the buffer exists to keep.
154
+ *
155
+ * `EXT_color_buffer_float` is required for this in WebGL2 and is absent on some parts, so it
156
+ * is asked for rather than assumed. Without it the target stays eight-bit and everything
157
+ * still draws: values clip where they always clipped.
158
+ */
159
+ this.floatColor = wantsRange && gl.getExtension('EXT_color_buffer_float') !== null;
160
+ this.program = compileProgram(gl, FULLSCREEN_VERT, RUSH_FRAG, 'rush');
161
+ this.uniforms = uniformLocations(gl, this.program, 'sceneTarget');
162
+ /*
163
+ * A VAO with no attributes: the fullscreen triangle is built from `gl_VertexID`, so
164
+ * there is nothing to bind. WebGL2 still requires *a* vertex array to be bound for a
165
+ * draw, and binding one with no state is cheaper than leaving whatever the previous
166
+ * pass left attached.
167
+ */
168
+ const vao = gl.createVertexArray();
169
+ if (vao === null)
170
+ throw new Error('SceneTarget: createVertexArray failed');
171
+ this.vao = vao;
172
+ }
173
+ /** Match the target to the drawing buffer. Cheap when unchanged. */
174
+ ensureSize(width, height) {
175
+ if (this.width === width && this.height === height && this.framebuffer !== null)
176
+ return;
177
+ const { gl } = this;
178
+ this.width = width;
179
+ this.height = height;
180
+ if (this.texture === null)
181
+ this.texture = gl.createTexture();
182
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
183
+ if (this.floatColor) {
184
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, width, height, 0, gl.RGBA, gl.HALF_FLOAT, null);
185
+ }
186
+ else {
187
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
188
+ }
189
+ // Linear, because the blur samples between texels; clamped, because a tap that
190
+ // wrapped would pull the opposite edge of the screen into the corner.
191
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
192
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
193
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
194
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
195
+ const sceneDepth = glSceneDepthFormat(gl);
196
+ if (this.depth === null)
197
+ this.depth = gl.createTexture();
198
+ gl.bindTexture(gl.TEXTURE_2D, this.depth);
199
+ gl.texImage2D(gl.TEXTURE_2D, 0, sceneDepth.internalFormat, width, height, 0, gl.DEPTH_COMPONENT, sceneDepth.type, null);
200
+ /* NEAREST, and not a preference: a depth texture with no compare mode cannot be
201
+ linearly filtered, and asking for it makes the sample come back undefined. */
202
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
203
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
204
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
205
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
206
+ /* The mid-pass copy, same format as the depth it is blitted from — `blitFramebuffer`
207
+ refuses a depth copy between formats that do not match exactly. See `depthCopy`. */
208
+ if (this.depthCopy === null)
209
+ this.depthCopy = gl.createTexture();
210
+ gl.bindTexture(gl.TEXTURE_2D, this.depthCopy);
211
+ gl.texImage2D(gl.TEXTURE_2D, 0, sceneDepth.internalFormat, width, height, 0, gl.DEPTH_COMPONENT, sceneDepth.type, null);
212
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
213
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
214
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
215
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
216
+ /*
217
+ * The colour copy, and its format follows the scene texture exactly.
218
+ *
219
+ * **`blitFramebuffer` refuses a copy between formats that do not match**, which is the same
220
+ * constraint the depth copy above is built under — so an HDR profile copies `RGBA16F` and an
221
+ * LDR one `RGBA8`, chosen by the flag the scene texture itself reads.
222
+ *
223
+ * `LINEAR` filtering, because a refracting draw samples at an offset that lands between
224
+ * texels; `CLAMP_TO_EDGE`, because a sample that wrapped would pull the opposite edge of the
225
+ * screen into a pane at the frame's border, which reads as a tear.
226
+ */
227
+ if (this.colorCopy === null)
228
+ this.colorCopy = gl.createTexture();
229
+ gl.bindTexture(gl.TEXTURE_2D, this.colorCopy);
230
+ if (this.floatColor) {
231
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, width, height, 0, gl.RGBA, gl.HALF_FLOAT, null);
232
+ }
233
+ else {
234
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
235
+ }
236
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
237
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
238
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
239
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
240
+ /*
241
+ * Colour only, and no depth attachment at all — the mirror image of the depth copy below,
242
+ * which attaches depth and switches the colour buffers off by name. **They are kept apart
243
+ * deliberately**: this file records a combined colour-and-depth blit losing the colour
244
+ * because the driver disliked the depth, and the depth-only path losing the depth for a
245
+ * missing colour target. One blit, one buffer bit, each time.
246
+ */
247
+ if (this.colorCopyFramebuffer === null)
248
+ this.colorCopyFramebuffer = gl.createFramebuffer();
249
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.colorCopyFramebuffer);
250
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.colorCopy, 0);
251
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
252
+ /* Loud, once, at allocation. A refracting draw then shades as an ordinary translucent one
253
+ and says why, rather than quietly disagreeing with the other backend. */
254
+ console.warn('SceneTarget: this driver will not give a colour-only framebuffer, so a refracting ' +
255
+ 'surface cannot read the scene behind it and will draw as ordinary glass.');
256
+ gl.deleteFramebuffer(this.colorCopyFramebuffer);
257
+ this.colorCopyFramebuffer = null;
258
+ }
259
+ if (this.depthCopyFramebuffer === null)
260
+ this.depthCopyFramebuffer = gl.createFramebuffer();
261
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.depthCopyFramebuffer);
262
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this.depthCopy, 0);
263
+ /*
264
+ * **Depth only, and the colour buffers have to be switched off by name.**
265
+ *
266
+ * A framebuffer with a depth attachment and no colour one still advertises
267
+ * `COLOR_ATTACHMENT0` as its draw and read buffer, and a `blitFramebuffer` into it is
268
+ * refused for the missing colour target — taking the depth half of the copy with it, since
269
+ * the call fails whole. `resolve` documents the same trap from the other direction, where a
270
+ * combined colour+depth blit lost the colour because the driver disliked the depth.
271
+ *
272
+ * Without these two lines the copy silently never happened: `snapshotDepth` returned null,
273
+ * `uSceneDepthEnabled` stayed 0, and WebGL2 kept marching through the floor while WebGPU
274
+ * clamped. Two backends doing different things with nothing said about it, which is the
275
+ * 2026-08-13 rule exactly — and it was found from a capture pair whose only disagreement
276
+ * was the band of floor the clamp acts on.
277
+ */
278
+ gl.drawBuffers([gl.NONE]);
279
+ gl.readBuffer(gl.NONE);
280
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
281
+ /* Loud, once, at allocation. A volume then draws unclamped on this driver and says why,
282
+ rather than quietly disagreeing with the other backend. */
283
+ console.warn('SceneTarget: this driver will not give a depth-only framebuffer, so light volumes ' +
284
+ 'cannot clamp to the scene and will march through it. The frame is unaffected.');
285
+ gl.deleteFramebuffer(this.depthCopyFramebuffer);
286
+ this.depthCopyFramebuffer = null;
287
+ }
288
+ if (this.framebuffer === null)
289
+ this.framebuffer = gl.createFramebuffer();
290
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
291
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
292
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this.depth, 0);
293
+ if (this.samples > 1) {
294
+ if (this.msaaColor === null)
295
+ this.msaaColor = gl.createRenderbuffer();
296
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.msaaColor);
297
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this.samples, this.floatColor ? gl.RGBA16F : gl.RGBA8, width, height);
298
+ if (this.msaaDepth === null)
299
+ this.msaaDepth = gl.createRenderbuffer();
300
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.msaaDepth);
301
+ /*
302
+ * **Must match the resolve target's format exactly**, or `blitFramebuffer` refuses the depth
303
+ * half of the copy — so it follows the same convention the depth texture does rather than
304
+ * naming a format of its own. It said 24-bit here for as long as the texture was 24-bit;
305
+ * making the texture float and leaving this behind produced
306
+ * `GL_INVALID_OPERATION: glBlitFramebuffer: Depth/stencil buffer format combination not
307
+ * allowed for blit` on every scene with MSAA, which is what the pixel gate reported first.
308
+ */
309
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this.samples, glSceneDepthFormat(gl).internalFormat, width, height);
310
+ if (this.msaaFramebuffer === null)
311
+ this.msaaFramebuffer = gl.createFramebuffer();
312
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.msaaFramebuffer);
313
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.msaaColor);
314
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.msaaDepth);
315
+ /*
316
+ * Checked here rather than discovered as a black frame. A multisampled attachment can
317
+ * be refused for a combination the driver does not support even after the sample count
318
+ * was clamped, and the honest response is to fall back to no multisampling and carry
319
+ * on drawing, rather than to render nothing.
320
+ */
321
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
322
+ this.releaseMultisample();
323
+ this.samples = 1;
324
+ }
325
+ }
326
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
327
+ gl.bindTexture(gl.TEXTURE_2D, null);
328
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
329
+ }
330
+ releaseMultisample() {
331
+ const { gl } = this;
332
+ if (this.msaaFramebuffer !== null)
333
+ gl.deleteFramebuffer(this.msaaFramebuffer);
334
+ if (this.msaaColor !== null)
335
+ gl.deleteRenderbuffer(this.msaaColor);
336
+ if (this.msaaDepth !== null)
337
+ gl.deleteRenderbuffer(this.msaaDepth);
338
+ this.msaaFramebuffer = null;
339
+ this.msaaColor = null;
340
+ this.msaaDepth = null;
341
+ }
342
+ /** Bind the off-screen target for a frame. The caller clears as it normally would. */
343
+ begin(width, height) {
344
+ this.ensureSize(width, height);
345
+ /* Last frame's snapshot is last frame's scene. See `snapshotDepth`. */
346
+ this.depthCopyFilled = false;
347
+ this.colorCopyFilled = false;
348
+ this.bind();
349
+ }
350
+ /**
351
+ * Point drawing back at this target, at its own size.
352
+ *
353
+ * Needed because every borrowing pass — the shadow maps, the planar reflection — hands
354
+ * the framebuffer back by binding `null`, which is the *canvas*, not the frame's target.
355
+ * Without somewhere to come back to, everything drawn after a reflection would land on
356
+ * the canvas and then be overwritten by the resolve of a half-empty target: a black
357
+ * frame from a renderer that looked correct in isolation.
358
+ */
359
+ bind() {
360
+ const { gl } = this;
361
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.msaaFramebuffer ?? this.framebuffer);
362
+ gl.viewport(0, 0, this.width, this.height);
363
+ }
364
+ /**
365
+ * Whether this target keeps values above 1, which decides where the tone curve belongs.
366
+ *
367
+ * False on a part without `EXT_color_buffer_float`, where the scene is squashed into 0 to 1 on
368
+ * the way in exactly as it always was.
369
+ */
370
+ get keepsRange() {
371
+ return this.floatColor;
372
+ }
373
+ /** How many samples the scene is actually being drawn with. 1 means no multisampling. */
374
+ get sampleCount() {
375
+ return this.samples;
376
+ }
377
+ /** The frame's depth, resolved and sampleable, for screen-space effects that need it. */
378
+ get depthTexture() {
379
+ return this.depth;
380
+ }
381
+ /**
382
+ * Copy the depth drawn so far, so something still drawing can read it. Returns what to bind.
383
+ *
384
+ * **Once per frame however many callers ask**, because they all want the same thing: where
385
+ * the opaque scene is. `begin` clears the latch.
386
+ *
387
+ * The blit is from whichever framebuffer the frame is actually rendering into — the
388
+ * multisampled one where there is one — and it restores that binding afterwards, because the
389
+ * caller is in the middle of a pass and expects to carry on drawing into it. Forgetting that
390
+ * is a frame that finishes into the wrong target and comes out empty.
391
+ *
392
+ * Null where the copy could not be made, and the caller must read that as "no clamp" rather
393
+ * than as a texture full of zeros — a depth of zero is the near plane, which would clamp every
394
+ * march to nothing and delete every beam in the scene.
395
+ */
396
+ /**
397
+ * The depth the frame is testing against, for a pass that must test against it too.
398
+ *
399
+ * **Not `snapshotDepth`, and the difference matters.** That returns a *copy*, for a pass that
400
+ * samples depth while the attachment is bound; this is the attachment itself, for a pass that
401
+ * attaches it and depth-tests against it without writing. Order-independent transparency needs
402
+ * the second: its two passes reject a pane behind a wall exactly where the wall is, and both
403
+ * must reject it in the same place or the accumulation and the revealage cover different
404
+ * fragments.
405
+ */
406
+ depthAttachment() {
407
+ return this.depth;
408
+ }
409
+ /**
410
+ * The colour the frame has drawn so far, for a pass that reads the picture rather than the depth.
411
+ *
412
+ * **Null while multisampling, and that is the honest answer rather than a missing feature.** With
413
+ * samples above one the frame is drawn into a renderbuffer and this texture holds nothing until
414
+ * `resolve` blits into it — so a pass running mid-frame would read the frame before last. A
415
+ * caller that needs the finished picture in the middle of the frame is asking for something a
416
+ * multisampled attachment cannot give without a resolve of its own.
417
+ */
418
+ colorAttachment() {
419
+ return this.msaaFramebuffer === null ? this.texture : null;
420
+ }
421
+ /**
422
+ * The colour the frame has drawn so far, copied so a draw can sample it while still drawing.
423
+ *
424
+ * **A copy and never the attachment.** Sampling a texture attached to the bound framebuffer is
425
+ * undefined in WebGL2 — it draws something plausible on this driver and something else on the
426
+ * next — and `colorAttachment` returns null under multisampling anyway. A blit answers both:
427
+ * it detaches the read, and from a multisampled source it resolves.
428
+ *
429
+ * **Latched, and the latch is the same trap `snapshotDepth` documents.** One copy serves every
430
+ * refracting draw in a frame, so glass does not refract other glass — which is correct, a pane
431
+ * behind a pane should show the room. What it also means is that opaque geometry drawn *after*
432
+ * the first refracting draw is missing from what a pane shows. Draw the world, then the glass;
433
+ * a caller that must have the later geometry asks `afresh` and pays another blit.
434
+ *
435
+ * Null where the copy could not be made, and a caller must read that as "do not refract" rather
436
+ * than as a black texture — refracting against black paints every pane the colour of a hole.
437
+ */
438
+ snapshotColor(afresh = false) {
439
+ if (this.colorCopy === null || this.colorCopyFramebuffer === null)
440
+ return null;
441
+ if (this.colorCopyFilled && !afresh)
442
+ return this.colorCopy;
443
+ const { gl } = this;
444
+ const source = this.msaaFramebuffer ?? this.framebuffer;
445
+ if (source === null)
446
+ return null;
447
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, source);
448
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.colorCopyFramebuffer);
449
+ /* Drained first, for the reason `resolve` gives at length: `getError` reports whatever is
450
+ pending from anywhere, so a check that does not start clean blames this call for somebody
451
+ else's mistake — and did, once, permanently disabling an effect. */
452
+ while (gl.getError() !== gl.NO_ERROR) {
453
+ /* discard whatever was already pending */
454
+ }
455
+ /* `NEAREST` because the rectangles are the same size, so there is nothing to filter and the
456
+ choice only decides which refusals are possible. */
457
+ gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
458
+ const refused = gl.getError() !== gl.NO_ERROR;
459
+ /* Back to what the caller was drawing into, whichever that was. */
460
+ gl.bindFramebuffer(gl.FRAMEBUFFER, source);
461
+ if (refused)
462
+ return null;
463
+ this.colorCopyFilled = true;
464
+ return this.colorCopy;
465
+ }
466
+ snapshotDepth(
467
+ /**
468
+ * Take the copy again even though one has already been taken this frame.
469
+ *
470
+ * **The latch that makes this cheap is also the trap in it.** A beam asks for the depth in
471
+ * the middle of the frame, so the copy holds the world *as it stood then* — and a pass that
472
+ * runs once every draw is in and reuses that copy marks a scene missing everything drawn
473
+ * after the beam. The symptom is a decal landing on a wall that is no longer the nearest
474
+ * thing, which reads as a depth-test bug rather than as a stale texture.
475
+ *
476
+ * So a caller at the end of the frame asks for it afresh, and pays one more blit on the
477
+ * frames where something had already asked. `begin` clears the latch either way.
478
+ */
479
+ afresh = false) {
480
+ if (this.depthCopy === null || this.depthCopyFramebuffer === null)
481
+ return null;
482
+ if (this.depthCopyFilled && !afresh)
483
+ return this.depthCopy;
484
+ const { gl } = this;
485
+ const source = this.msaaFramebuffer ?? this.framebuffer;
486
+ if (source === null)
487
+ return null;
488
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, source);
489
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.depthCopyFramebuffer);
490
+ /* Drained first, for the reason `resolve` gives at length: `getError` reports whatever is
491
+ pending from anywhere, so a check that does not start clean blames this call for
492
+ somebody else's mistake — and did, once, permanently disabling an effect. */
493
+ while (gl.getError() !== gl.NO_ERROR) {
494
+ /* discard whatever was already pending */
495
+ }
496
+ gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
497
+ const refused = gl.getError() !== gl.NO_ERROR;
498
+ /* Back to what the caller was drawing into, whichever that was. */
499
+ gl.bindFramebuffer(gl.FRAMEBUFFER, source);
500
+ if (refused)
501
+ return null;
502
+ this.depthCopyFilled = true;
503
+ return this.depthCopy;
504
+ }
505
+ /**
506
+ * Resolve the scene to the canvas, blurred by `strength`.
507
+ *
508
+ * Depth and blending are explicitly off for the pass: it is one opaque triangle over the
509
+ * whole viewport, and inheriting a depth test from the last scene draw would let it fail
510
+ * against nothing.
511
+ */
512
+ /**
513
+ * The colour grade this and every later frame applies, until it is set again.
514
+ *
515
+ * **Held rather than passed to `resolve`**, because a lookup table is a *texture* and every
516
+ * other texture this pass reads is owned here. The alternative is a ninth parameter on a call
517
+ * that already takes eight, carrying an object the caller would then have to keep stable
518
+ * anyway.
519
+ *
520
+ * `null`, or a strength at or below zero, is exactly the frame that existed before the effect
521
+ * did: the shader's branch is on a uniform, so no fetch happens at all.
522
+ */
523
+ setColourGrade(lut, strength) {
524
+ this.gradeStrength = lut === null ? 0 : Math.max(0, Math.min(1, strength));
525
+ if (lut === null || lut === this.gradeSource)
526
+ return;
527
+ validateGradeLut(lut);
528
+ this.uploadGrade(lut);
529
+ this.gradeSource = lut;
530
+ }
531
+ /**
532
+ * Put a table on the device, replacing whatever was there.
533
+ *
534
+ * `RGBA8` with `LINEAR` in every direction and `CLAMP_TO_EDGE` on all three axes. The filtering
535
+ * is the whole point — an unfiltered 32-lattice table bands, which is the one artefact a grade
536
+ * must never introduce — and the clamp is what makes the texel-centre coordinate safe at the
537
+ * ends of the range rather than wrapping black round to white.
538
+ */
539
+ uploadGrade(lut) {
540
+ const { gl } = this;
541
+ this.gradeTexture ??= gl.createTexture();
542
+ gl.activeTexture(gl.TEXTURE4);
543
+ gl.bindTexture(gl.TEXTURE_3D, this.gradeTexture);
544
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, lut.size, lut.size, lut.size, 0, gl.RGBA, gl.UNSIGNED_BYTE, lut.data);
545
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
546
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
547
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
548
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
549
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
550
+ gl.activeTexture(gl.TEXTURE0);
551
+ this.gradeSize = lut.size;
552
+ }
553
+ resolve(strength, reachUv,
554
+ /* The grade, applied here because this is the last pass. See RUSH_FRAG's own note. */
555
+ grade = {
556
+ transform: 0,
557
+ exposure: 1,
558
+ }, motion, ao, bloom,
559
+ /*
560
+ * Depth of field, between the camera smear and the occlusion in the shader's own order. Like
561
+ * `motion` and `ao` it needs the depth, and like them it is absent rather than zeroed when the
562
+ * frame has not asked — so a renderer nobody asked for it never resolves a depth buffer to
563
+ * feed it.
564
+ */
565
+ dof,
566
+ /*
567
+ * The frame veil, composited last of everything this pass does. See
568
+ * `Renderer.setFrameVeil` for why it sits here rather than upstream or downstream of the
569
+ * grade. Defaulted rather than optional: the shader always reads both uniforms, so a
570
+ * caller that never veils anything uploads the same two numbers it always would have.
571
+ */
572
+ veilColor = NO_VEIL, veilAlpha = 0,
573
+ /*
574
+ * The temporal resolve, appended rather than placed beside the other effects because
575
+ * `veilColor` and `veilAlpha` are positional defaults and every existing caller passes them
576
+ * by position.
577
+ */
578
+ temporal) {
579
+ const { gl } = this;
580
+ this.depthWanted =
581
+ motion !== undefined || ao !== undefined || dof !== undefined || temporal !== undefined;
582
+ /*
583
+ * Down from the multisampled buffer into the texture first, because a shader cannot
584
+ * sample a multisampled attachment. NEAREST is the only filter `blitFramebuffer` accepts
585
+ * for a same-size resolve, and the two are the same size by construction.
586
+ */
587
+ if (this.msaaFramebuffer !== null) {
588
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.msaaFramebuffer);
589
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.framebuffer);
590
+ /*
591
+ * **Colour on its own, always, and depth as a separate call that is allowed to fail.**
592
+ *
593
+ * These were one blit with both bits set, and that shipped a black game. A driver may
594
+ * refuse a depth copy for a format combination it does not like, and `blitFramebuffer`
595
+ * refuses the *whole* call when it does — so a disagreement about depth took the
596
+ * colour with it and the frame resolved to nothing. The symptom is total and the cause
597
+ * is a flag in a bitmask.
598
+ *
599
+ * Split, the worst case is losing the effect that wanted depth. The frame is never at
600
+ * risk, which is the only acceptable ordering: this method's contract is that the scene
601
+ * reaches the canvas.
602
+ */
603
+ gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
604
+ if (this.depthWanted && !this.depthBlitRefused) {
605
+ /*
606
+ * Drained first, and this is not defensive tidiness. `getError` returns whatever
607
+ * error is *pending*, from anywhere, and clears it — so a check that does not start
608
+ * from a clean queue attributes somebody else's mistake to this call. That happened
609
+ * here immediately: an unrelated error elsewhere in the frame was read as the driver
610
+ * refusing depth, which switched motion blur off permanently and silently.
611
+ */
612
+ while (gl.getError() !== gl.NO_ERROR) {
613
+ /* discard whatever was already pending */
614
+ }
615
+ gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
616
+ /*
617
+ * Asked once rather than every frame: `getError` is a synchronisation point, and a
618
+ * format combination that was refused on the first frame will be refused on every
619
+ * one. After that the effect that wanted depth simply does not run.
620
+ */
621
+ if (gl.getError() !== gl.NO_ERROR) {
622
+ this.depthBlitRefused = true;
623
+ console.warn('SceneTarget: this driver will not resolve multisampled depth, so effects that ' +
624
+ 'read it are off. The frame itself is unaffected.');
625
+ }
626
+ }
627
+ /*
628
+ * **Thrown away the moment they have been blitted down, which is WebGL2's half of the
629
+ * same statement `storeOp: 'discard'` makes on the other backend.**
630
+ *
631
+ * The blit above is the resolve, and on its own it is only half of one: the multisampled
632
+ * renderbuffers still hold contents the driver has no reason to believe are finished
633
+ * with, so a tile-based GPU dutifully writes all four samples out to memory at the end of
634
+ * the pass. Nothing can ever read them — a multisampled renderbuffer cannot be sampled by
635
+ * a shader at all, which is the entire reason this blit exists — so the write buys
636
+ * nothing and costs a full attachment.
637
+ *
638
+ * Measured on the WebGPU side of the same frame at 824x1830 with four samples: 23 MB per
639
+ * attachment, and the game keeps two of them. On a desktop part it is invisible, which is
640
+ * why it survived; on a phone it is a share of the memory bandwidth the frame has.
641
+ *
642
+ * **Before the unbind, deliberately.** `invalidateFramebuffer` acts on whatever is bound
643
+ * to the target it is given, so moving these two lines below the ones that follow would
644
+ * discard the default framebuffer instead — which is the frame.
645
+ */
646
+ if (this.discardResolved) {
647
+ gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, [gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT]);
648
+ }
649
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
650
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
651
+ }
652
+ /*
653
+ * Occlusion before the composite, because the composite consumes it, and after the
654
+ * resolve above, because it reads the depth that resolve produced. It leaves the
655
+ * framebuffer unbound and the viewport its own, both of which the composite sets again
656
+ * below.
657
+ */
658
+ let aoTexture = null;
659
+ if (ao !== undefined && !this.depthBlitRefused && this.depth !== null) {
660
+ this.ao ??= new AmbientOcclusionPass(gl);
661
+ aoTexture = this.ao.run(this.depth, this.width, this.height, ao.radius, ao.projScale, ao.invProjection);
662
+ }
663
+ /*
664
+ * Bloom beside occlusion rather than after the composite, because the composite is what
665
+ * consumes it. It reads the resolved colour rather than the depth, so it is independent of
666
+ * the blit above having produced anything, and it leaves the framebuffer unbound and the
667
+ * viewport its own — both of which the composite sets again below.
668
+ */
669
+ /*
670
+ * **The temporal resolve happens before all of it**, and what it returns is what everything
671
+ * below must treat as the scene. Bloom, occlusion and the grade each read the scene texture,
672
+ * and reading the unresolved one would put the crawl the resolve just removed back on screen
673
+ * through the bloom — a stable picture lit by an unstable one.
674
+ */
675
+ let scene = this.texture;
676
+ if (temporal !== undefined && this.texture !== null && this.depth !== null) {
677
+ this.temporal ??= new TemporalPass(gl, this.floatColor);
678
+ scene = this.temporal.temporalResolve(this.texture, this.depth, temporal.reprojection, this.width, this.height, temporal.blend);
679
+ }
680
+ let bloomTexture = null;
681
+ if (bloom !== undefined && scene !== null) {
682
+ this.bloom ??= new BloomPass(gl);
683
+ bloomTexture = this.bloom.run(scene, this.width, this.height, bloom.threshold);
684
+ }
685
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
686
+ gl.viewport(0, 0, this.width, this.height);
687
+ gl.disable(gl.DEPTH_TEST);
688
+ gl.disable(gl.BLEND);
689
+ gl.disable(gl.CULL_FACE);
690
+ gl.depthMask(false);
691
+ gl.useProgram(this.program);
692
+ gl.activeTexture(gl.TEXTURE0);
693
+ gl.bindTexture(gl.TEXTURE_2D, scene);
694
+ gl.uniform1i(this.uniforms['uScene'] ?? null, 0);
695
+ gl.uniform1f(this.uniforms['uStrength'] ?? null, strength);
696
+ gl.uniform1f(this.uniforms['uReach'] ?? null, reachUv);
697
+ gl.uniform1i(this.uniforms['uOutputTransform'] ?? null, grade.transform);
698
+ gl.uniform1f(this.uniforms['uOutputExposure'] ?? null, grade.exposure);
699
+ /*
700
+ * Depth on its own unit, and the reprojection with it. Bound every frame rather than
701
+ * once, because a texture unit is context state and any pass between two frames is free
702
+ * to have left something else there.
703
+ */
704
+ gl.activeTexture(gl.TEXTURE1);
705
+ gl.bindTexture(gl.TEXTURE_2D, this.depth);
706
+ gl.uniform1i(this.uniforms['uDepth'] ?? null, 1);
707
+ /* Off if the driver would not give the depth back, so the shader never samples a
708
+ texture that holds whatever was in it before. */
709
+ const motionUsable = motion !== undefined && !this.depthBlitRefused;
710
+ gl.uniform1f(this.uniforms['uMotionStrength'] ?? null, motionUsable ? motion.strength : 0);
711
+ gl.uniform1f(this.uniforms['uMotionMax'] ?? null, motion?.max ?? 0);
712
+ if (motionUsable) {
713
+ gl.uniformMatrix4fv(this.uniforms['uReprojection'] ?? null, false, motion.reprojection);
714
+ }
715
+ /*
716
+ * Depth of field, on the depth unit bound just above and gated on the same refusal: a driver
717
+ * that would not give the depth back leaves that texture holding a previous frame, and a
718
+ * circle of confusion computed from it defocuses the wrong half of the picture.
719
+ */
720
+ const dofUsable = dof !== undefined && !this.depthBlitRefused;
721
+ gl.uniform1f(this.uniforms['uDofStrength'] ?? null, dofUsable ? dof.strength : 0);
722
+ if (dofUsable) {
723
+ gl.uniform1f(this.uniforms['uFocusDistance'] ?? null, dof.distance);
724
+ gl.uniform1f(this.uniforms['uFocusRange'] ?? null, dof.range);
725
+ /* Height over width, so a radius in fractions of the height is a circle on screen. */
726
+ gl.uniform2f(this.uniforms['uDofAspect'] ?? null, this.height / this.width, 1);
727
+ gl.uniform4fv(this.uniforms['uDepthToView'] ?? null, dof.depthToView);
728
+ }
729
+ /*
730
+ * Ambient occlusion on its own unit, gated on the same fact as the blur and for the same
731
+ * reason: a refused depth resolve leaves that texture holding whatever a previous frame
732
+ * put there, and occlusion measured from it is not a degraded picture but a pattern of
733
+ * dirt with no relationship to the scene. The pass may also decline for itself, which
734
+ * arrives here as a null texture. Either way the strength goes to zero, which is exactly
735
+ * the frame that existed before the effect did.
736
+ *
737
+ * The placeholder rather than an unbound unit when it is off: an incomplete texture is
738
+ * something a driver may fetch the descriptor for before it evaluates the branch that
739
+ * would have skipped the read.
740
+ */
741
+ gl.activeTexture(gl.TEXTURE2);
742
+ gl.bindTexture(gl.TEXTURE_2D, aoTexture ?? scene);
743
+ gl.uniform1i(this.uniforms['uAo'] ?? null, 2);
744
+ gl.uniform1f(this.uniforms['uAoStrength'] ?? null, aoTexture === null ? 0 : (ao?.strength ?? 0));
745
+ /* Bloom on its own unit, and the placeholder for the same reason as the one above: a
746
+ driver may fetch a texture's descriptor before it evaluates the branch that skips the
747
+ read, and an incomplete texture is not a thing to hand it. */
748
+ gl.activeTexture(gl.TEXTURE3);
749
+ gl.bindTexture(gl.TEXTURE_2D, bloomTexture ?? scene);
750
+ gl.uniform1i(this.uniforms['uBloom'] ?? null, 3);
751
+ gl.uniform1f(this.uniforms['uBloomStrength'] ?? null, bloomTexture === null ? 0 : (bloom?.strength ?? 0));
752
+ /*
753
+ * The grade on unit 4, and the placeholder built here rather than at construction: a frame
754
+ * that never grades anything should not carry a texture, and a sampler declared in the
755
+ * program must still have a complete one bound whether or not the branch reads it — the
756
+ * argument the occlusion and bloom placeholders above make, one dimension up.
757
+ *
758
+ * The placeholder is an **identity** table at two lattice points, which is exact: identity
759
+ * is linear and a trilinear fetch through corners holding their own coordinates reproduces a
760
+ * linear function precisely. So it is the right answer if anything ever samples it rather
761
+ * than an inert stand-in that happens not to be read.
762
+ */
763
+ if (this.gradeTexture === null)
764
+ this.uploadGrade(identityGradeLut(GRADE_PLACEHOLDER_SIZE));
765
+ gl.activeTexture(gl.TEXTURE4);
766
+ gl.bindTexture(gl.TEXTURE_3D, this.gradeTexture);
767
+ gl.uniform1i(this.uniforms['uGradeLut'] ?? null, 4);
768
+ gl.uniform1f(this.uniforms['uGradeStrength'] ?? null, this.gradeStrength);
769
+ gl.uniform1f(this.uniforms['uGradeSize'] ?? null, this.gradeSize);
770
+ gl.activeTexture(gl.TEXTURE0);
771
+ /* No unit and no texture: a flat colour, not a sample. Uploaded unconditionally — two
772
+ floats and a triplet cost nothing next to the triangle this pass already draws — and it
773
+ is `withVeil` in the shader, not a branch here, that keeps a veil-less frame free of the
774
+ mix it does not need. */
775
+ gl.uniform3fv(this.uniforms['uVeilColor'] ?? null, veilColor);
776
+ gl.uniform1f(this.uniforms['uVeilAlpha'] ?? null, veilAlpha);
777
+ gl.bindVertexArray(this.vao);
778
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
779
+ gl.bindVertexArray(null);
780
+ /*
781
+ * **The units this pass used are released, and that is not tidiness.**
782
+ *
783
+ * Unit 1 holds `depth` — an attachment of this very target — and a binding survives the frame
784
+ * it was made in. Anything that later *attaches* that texture while it is still bound to a
785
+ * sampler the active program declares forms a feedback loop, which WebGL2 reports as
786
+ * `GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture` and then
787
+ * draws something undefined. Order-independent transparency attaches exactly this depth to its
788
+ * own framebuffers on the next frame, and that is how this was found: 120 pixels of a frame
789
+ * that should have been identical, and a warning per draw explaining why.
790
+ */
791
+ for (let unit = 0; unit <= 4; unit++) {
792
+ gl.activeTexture(gl.TEXTURE0 + unit);
793
+ gl.bindTexture(gl.TEXTURE_2D, null);
794
+ }
795
+ gl.activeTexture(gl.TEXTURE0);
796
+ // Handed back the way the rest of the renderer expects to find it.
797
+ gl.depthMask(true);
798
+ gl.enable(gl.DEPTH_TEST);
799
+ /*
800
+ * **And culling, which this pass switched off and the next frame's world is drawn with.**
801
+ *
802
+ * It was the one borrowed state never returned. `resolve` runs at `endFrame`, so from the
803
+ * second frame onwards every `drawMesh` in every scene ran with `CULL_FACE` disabled — the
804
+ * world drawn double-sided on the backend this engine is most often looked at, against a
805
+ * renderer that enables culling once at setup and documents it as "on for the life of the
806
+ * renderer because the world is solid".
807
+ *
808
+ * Invisible wherever geometry is wound correctly, which is every scene here, so nothing
809
+ * caught it. What caught it was a scene whose geometry was wound *backwards*: it looked
810
+ * perfect on WebGL2 and lost its entire ground on WebGPU, where culling is pipeline state
811
+ * that no pass can leak. The defect read as a WebGPU bug for a fortnight and was this line.
812
+ */
813
+ gl.enable(gl.CULL_FACE);
814
+ }
815
+ dispose() {
816
+ const { gl } = this;
817
+ this.ao?.dispose();
818
+ this.ao = null;
819
+ this.bloom?.dispose();
820
+ this.bloom = null;
821
+ if (this.framebuffer !== null)
822
+ gl.deleteFramebuffer(this.framebuffer);
823
+ if (this.texture !== null)
824
+ gl.deleteTexture(this.texture);
825
+ if (this.depth !== null)
826
+ gl.deleteTexture(this.depth);
827
+ /*
828
+ * The two snapshots and their framebuffers, which this method did not release before the
829
+ * colour one was added. **The depth pair is the same leak and is freed here for the same
830
+ * reason**: they are allocated in `ensureSize` beside everything above, so releasing some of
831
+ * what that allocates and not the rest is a distinction nothing here intends.
832
+ */
833
+ if (this.colorCopy !== null)
834
+ gl.deleteTexture(this.colorCopy);
835
+ if (this.colorCopyFramebuffer !== null)
836
+ gl.deleteFramebuffer(this.colorCopyFramebuffer);
837
+ if (this.depthCopy !== null)
838
+ gl.deleteTexture(this.depthCopy);
839
+ if (this.depthCopyFramebuffer !== null)
840
+ gl.deleteFramebuffer(this.depthCopyFramebuffer);
841
+ if (this.gradeTexture !== null)
842
+ gl.deleteTexture(this.gradeTexture);
843
+ this.gradeTexture = null;
844
+ this.gradeSource = null;
845
+ this.releaseMultisample();
846
+ gl.deleteProgram(this.program);
847
+ gl.deleteVertexArray(this.vao);
848
+ this.framebuffer = null;
849
+ this.texture = null;
850
+ this.depth = null;
851
+ this.colorCopy = null;
852
+ this.colorCopyFramebuffer = null;
853
+ this.depthCopy = null;
854
+ this.depthCopyFramebuffer = null;
855
+ }
856
+ }