@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,21 @@
1
+ /**
2
+ * `#if NAME` / `#else` / `#endif` resolved here rather than left to GLSL.
3
+ *
4
+ * The driver's own preprocessor would reach the same compiled program, so this is not
5
+ * about the result — it is about what the driver is handed at all. A `#define` still ships
6
+ * every declaration in the source text and asks the compiler to discard them, which leaves
7
+ * the thing being avoided inside the component being blamed. Cutting the lines out in
8
+ * JavaScript means a shadowless profile never sends a sampler anywhere, and it turns the
9
+ * absence into something a test can assert on a string rather than something only a GPU
10
+ * could confirm.
11
+ *
12
+ * Deliberately not a preprocessor: one directive, names only, no expressions. Anything
13
+ * more belongs in GLSL, which already has one.
14
+ *
15
+ * It lived inside `flat.ts` until a second program needed permuting. Nothing about it was
16
+ * ever specific to that shader, and the reason it moved is the reason it is worth stating:
17
+ * the cost that justified it, a shadowless profile still compiling every sampler it could
18
+ * never reach, is paid by whichever program declares them, not by the one that happens to
19
+ * have found it first.
20
+ */
21
+ export declare function resolveConditionals(source: string, defines: Readonly<Record<string, boolean>>, shaderName: string): string;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `#if NAME` / `#else` / `#endif` resolved here rather than left to GLSL.
3
+ *
4
+ * The driver's own preprocessor would reach the same compiled program, so this is not
5
+ * about the result — it is about what the driver is handed at all. A `#define` still ships
6
+ * every declaration in the source text and asks the compiler to discard them, which leaves
7
+ * the thing being avoided inside the component being blamed. Cutting the lines out in
8
+ * JavaScript means a shadowless profile never sends a sampler anywhere, and it turns the
9
+ * absence into something a test can assert on a string rather than something only a GPU
10
+ * could confirm.
11
+ *
12
+ * Deliberately not a preprocessor: one directive, names only, no expressions. Anything
13
+ * more belongs in GLSL, which already has one.
14
+ *
15
+ * It lived inside `flat.ts` until a second program needed permuting. Nothing about it was
16
+ * ever specific to that shader, and the reason it moved is the reason it is worth stating:
17
+ * the cost that justified it, a shadowless profile still compiling every sampler it could
18
+ * never reach, is paid by whichever program declares them, not by the one that happens to
19
+ * have found it first.
20
+ */
21
+ export function resolveConditionals(source, defines, shaderName) {
22
+ const kept = [];
23
+ /** One frame per open `#if`, holding whether its own branch is the live one. */
24
+ const stack = [];
25
+ const keeping = () => stack.every((frame) => frame.keep);
26
+ for (const line of source.split('\n')) {
27
+ const directive = line.trim();
28
+ if (directive.startsWith('#if ')) {
29
+ const name = directive.slice(4).trim();
30
+ if (!(name in defines)) {
31
+ throw new Error(`${shaderName} shader: unknown condition ${name}`);
32
+ }
33
+ stack.push({ keep: defines[name] === true });
34
+ continue;
35
+ }
36
+ if (directive === '#else') {
37
+ const frame = stack[stack.length - 1];
38
+ if (frame === undefined)
39
+ throw new Error(`${shaderName} shader: #else outside #if`);
40
+ frame.keep = !frame.keep;
41
+ continue;
42
+ }
43
+ if (directive === '#endif') {
44
+ if (stack.pop() === undefined) {
45
+ throw new Error(`${shaderName} shader: #endif outside #if`);
46
+ }
47
+ continue;
48
+ }
49
+ if (keeping())
50
+ kept.push(line);
51
+ }
52
+ if (stack.length > 0)
53
+ throw new Error(`${shaderName} shader: unterminated #if`);
54
+ return kept.join('\n');
55
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A decal projected onto whatever the depth buffer holds.
3
+ *
4
+ * **The pass is the inverse of the camera and nothing else.** Each pixel inside the projector's
5
+ * scissor rectangle is turned back into the world point its depth stands for, that point is put
6
+ * into the box's own space, and a mark lands where all three coordinates come back within one. No
7
+ * geometry is clipped and no mesh is built, so the receiving surface may deform, stream in, or be
8
+ * drawn by something with no CPU-side geometry at all — which is exactly what `projectDecal`
9
+ * cannot do and the whole reason this exists beside it.
10
+ *
11
+ * **It multiplies rather than covers, and that is a design decision rather than a shortcut.** A
12
+ * forward renderer has no G-buffer, so by the time this runs the receiving pixel is already lit
13
+ * and there is nowhere to write an albedo. Painting a flat colour over it would light the mark by
14
+ * nothing at all: a scorch mark in an unlit corner would glow. Multiplying takes the receiver's
15
+ * lighting exactly — for a diffuse surface it is identical to having marked the albedo before the
16
+ * light was applied — at the cost that a mark can darken and tint and can never brighten. Scorch,
17
+ * oil, blood, wet patches and blob shadows are what that covers; a glowing rune is not.
18
+ *
19
+ * **Nothing here branches and nothing discards.** White is the identity of a multiply, so a pixel
20
+ * the projector misses writes white and changes nothing, which means the whole shader is one
21
+ * straight line. That is not tidiness: the surface normal comes from the derivatives of the
22
+ * reconstructed position, and a derivative taken inside non-uniform control flow is undefined —
23
+ * the rule `AGENTS.md` states for `texture()` in a branch, arriving through the other door.
24
+ */
25
+ export declare const DECAL_PROJECT_FRAG: string;
@@ -0,0 +1,125 @@
1
+ /**
2
+ * A decal projected onto whatever the depth buffer holds.
3
+ *
4
+ * **The pass is the inverse of the camera and nothing else.** Each pixel inside the projector's
5
+ * scissor rectangle is turned back into the world point its depth stands for, that point is put
6
+ * into the box's own space, and a mark lands where all three coordinates come back within one. No
7
+ * geometry is clipped and no mesh is built, so the receiving surface may deform, stream in, or be
8
+ * drawn by something with no CPU-side geometry at all — which is exactly what `projectDecal`
9
+ * cannot do and the whole reason this exists beside it.
10
+ *
11
+ * **It multiplies rather than covers, and that is a design decision rather than a shortcut.** A
12
+ * forward renderer has no G-buffer, so by the time this runs the receiving pixel is already lit
13
+ * and there is nowhere to write an albedo. Painting a flat colour over it would light the mark by
14
+ * nothing at all: a scorch mark in an unlit corner would glow. Multiplying takes the receiver's
15
+ * lighting exactly — for a diffuse surface it is identical to having marked the albedo before the
16
+ * light was applied — at the cost that a mark can darken and tint and can never brighten. Scorch,
17
+ * oil, blood, wet patches and blob shadows are what that covers; a glowing rune is not.
18
+ *
19
+ * **Nothing here branches and nothing discards.** White is the identity of a multiply, so a pixel
20
+ * the projector misses writes white and changes nothing, which means the whole shader is one
21
+ * straight line. That is not tidiness: the surface normal comes from the derivatives of the
22
+ * reconstructed position, and a derivative taken inside non-uniform control flow is undefined —
23
+ * the rule `AGENTS.md` states for `texture()` in a branch, arriving through the other door.
24
+ */
25
+ import { glslIsFarDepth } from '../depthConvention.js';
26
+ export const DECAL_PROJECT_FRAG = `#version 300 es
27
+ precision highp float;
28
+
29
+ in vec2 vUv;
30
+
31
+ /**
32
+ * The depth the frame has drawn, as a copy.
33
+ *
34
+ * **A copy and never the attachment.** Sampling a texture that is attached to the bound
35
+ * framebuffer is undefined in WebGL2, and undefined here means a plausible picture on this driver
36
+ * and a different one on the next: \`SceneTarget.snapshotDepth\` exists for exactly this, and the
37
+ * WebGPU backend reads its resolved depth for the same reason.
38
+ *
39
+ * \`highp\` because it is a 32-bit depth and the reconstruction below is a division by it.
40
+ */
41
+ uniform highp sampler2D uDecalDepth;
42
+ /**
43
+ * Screen position and stored depth back to the world, which is
44
+ * \`inverse(viewProjection) * DEPTH_01_TO_CLIP\`.
45
+ *
46
+ * The Y-flipped variant of that constant is what the other backend passes, and \`lightVolumeDraw.ts\`
47
+ * carries the derivation and what one missing negation costs.
48
+ */
49
+ uniform mat4 uDecalDepthToWorld;
50
+ /** World space into the projector's unit box. See \`worldToDecalMatrix\`. */
51
+ uniform mat4 uWorldToDecal;
52
+ /** Where the eye is, which is what gives the reconstructed normal a defined sign. */
53
+ uniform vec3 uDecalEye;
54
+ /** The projection axis, normalised. A surface is marked when it faces back along this. */
55
+ uniform vec3 uDecalAxis;
56
+ /** What the mark multiplies the surface by. */
57
+ uniform vec3 uDecalColor;
58
+ /** How much of that colour lands. */
59
+ uniform float uDecalOpacity;
60
+ /** How far a surface may be turned from facing the projector, as a cosine. */
61
+ uniform float uDecalFacingCos;
62
+ /** How much of the mark's radius is edge. */
63
+ uniform float uDecalSoftness;
64
+
65
+ out vec4 fragColor;
66
+
67
+ void main() {
68
+ float stored = textureLod(uDecalDepth, vUv, 0.0).r;
69
+
70
+ /*
71
+ * The pixel's world position. \`vUv * 2 - 1\` is the screen half of it and \`stored\` the depth
72
+ * half, and the matrix carries the remap from the buffer's sense to the clip space the camera
73
+ * was built in — including, on one backend, the Y flip that the generated WGSL applies to every
74
+ * vertex stage.
75
+ */
76
+ vec4 world = uDecalDepthToWorld * vec4(vUv * 2.0 - 1.0, stored, 1.0);
77
+ vec3 point = world.xyz / world.w;
78
+
79
+ /*
80
+ * **The surface normal from the reconstruction's own derivatives**, because there is no normal
81
+ * buffer to read one from and adding one means a second colour attachment on every draw path in
82
+ * the engine. Two neighbouring pixels of the same surface span it, so their cross product is its
83
+ * plane — noisy along a silhouette, where one of the two neighbours is a different surface
84
+ * altogether, and exact everywhere else.
85
+ *
86
+ * **Turned to face the eye rather than trusted.** Which way \`cross\` points depends on which way
87
+ * the framebuffer's rows run, and the two backends disagree about that — so a sign taken from
88
+ * the cross product alone marks the tops of things on one and the undersides on the other, with
89
+ * nothing raising. A visible surface faces the eye by definition, so that is what fixes it.
90
+ */
91
+ vec3 plane = cross(dFdx(point), dFdy(point));
92
+ float span = length(plane);
93
+ vec3 normal = span > 0.0 ? plane / span : uDecalAxis;
94
+ normal *= sign(dot(uDecalEye - point, normal));
95
+
96
+ vec3 box = (uWorldToDecal * vec4(point, 1.0)).xyz;
97
+
98
+ /* Inside the box on every axis, as a product of three steps rather than three branches. */
99
+ vec3 inside = step(abs(box), vec3(1.0));
100
+ float mark = inside.x * inside.y * inside.z;
101
+
102
+ /*
103
+ * An ellipse across the face with a soft edge, rather than the box's own rectangle. A mark with
104
+ * no texture has nothing else to shape it, and a hard rectangle reads as a decal cut out with
105
+ * scissors.
106
+ */
107
+ float radius = length(box.xy);
108
+ mark *= 1.0 - smoothstep(1.0 - uDecalSoftness, 1.0, radius);
109
+
110
+ /*
111
+ * Faded rather than cut where the surface turns away from the projector. A wall standing edge-on
112
+ * to the projector occupies one pixel of depth per metre of wall, so an unfaded mark aimed at
113
+ * the floor smears the whole depth of the box up it — the classic failure of a projected decal,
114
+ * and what \`facingCos\` is for on the static half of this too.
115
+ */
116
+ float facing = dot(normal, -uDecalAxis);
117
+ mark *= smoothstep(uDecalFacingCos, min(1.0, uDecalFacingCos + 0.25), facing);
118
+
119
+ /* Nothing was drawn here at all, so there is no surface to mark — only the sky. */
120
+ mark *= ${glslIsFarDepth('stored')} ? 0.0 : 1.0;
121
+
122
+ /* White is the identity of a multiply, so a pixel the projector missed changes nothing. */
123
+ fragColor = vec4(mix(vec3(1.0), uDecalColor, mark * uDecalOpacity), 1.0);
124
+ }
125
+ `;
@@ -0,0 +1,14 @@
1
+ /** The rigid variant: the world, a prop, a mesh with no rig behind it. */
2
+ export declare const DEPTH_VERT: string;
3
+ /** The skinned variant, which reads a joint palette and moves the vertex by it. */
4
+ export declare const DEPTH_SKINNED_VERT: string;
5
+ /**
6
+ * The variant an instanced draw casts its shadow through.
7
+ *
8
+ * **It exists because a shadow is not optional.** An instanced mesh whose depth pass still read
9
+ * uModel would cast every instance's shadow from the last matrix uploaded — one shadow in the
10
+ * right place and the rest stacked underneath it, which reads as a lighting fault rather than as
11
+ * a missing variant, and is the shape the per-draw ring exists to prevent one level up.
12
+ */
13
+ export declare const DEPTH_INSTANCED_VERT: string;
14
+ export declare const DEPTH_FRAG = "#version 300 es\nprecision highp float;\nin vec4 vLightPosition;\n\nuniform highp sampler2D uPreviousShadowMap;\nuniform int uPeelShadowLayer;\n\nvoid main() {\n if (uPeelShadowLayer != 0) {\n vec3 p = vLightPosition.xyz / vLightPosition.w;\n vec2 uv = p.xy * 0.5 + 0.5;\n float previousDepth = texture(uPreviousShadowMap, uv).r;\n // Discard the already-recorded surface and everything in front of it. The\n // ordinary depth test then stores the next independently fading occluder.\n if (gl_FragCoord.z <= previousDepth + 0.00001) discard;\n }\n}\n";
@@ -0,0 +1,114 @@
1
+ import { resolveConditionals } from './conditionals.js';
2
+ import { SKINNING_GLSL } from './skinning.js';
3
+ import { CHANNEL_ATTRIBUTE, CHANNEL_BEND } from './vertexChannel.js';
4
+ /**
5
+ * Depth-only shadow pass. Its optional peel mode rejects the first recorded
6
+ * surface so the next independently fading occluder can be retained.
7
+ *
8
+ * **Two vertex variants, skinned and not**, for the reason `ShadowCasterSink.scatter` already
9
+ * states about the wind: handing the depth pass a different deformation from the colour pass is
10
+ * how a shadow comes loose from its caster. A skinned character cast rigidly does not drift
11
+ * slightly — it casts its bind pose, so a running figure throws the shadow of a statue.
12
+ *
13
+ * The permutation rather than a uniform gate is the same decision `skinning.ts` measured for the
14
+ * flat shader, and it is cheaper here: this vertex shader is a fifth the size of that one, so the
15
+ * second copy dedupes almost entirely inside deflate's window.
16
+ */
17
+ const DEPTH_VERT_SOURCE = `#version 300 es
18
+ layout(location = 0) in vec3 aPosition;
19
+ #if SKINNED
20
+ ${SKINNING_GLSL}
21
+ #endif
22
+
23
+ uniform mat4 uLightViewProj;
24
+ /*
25
+ * Placement last, and in the instanced variant not at all — see the flat shader, where the same
26
+ * arrangement is load-bearing. Here it costs nothing to keep: uModel is already the last field,
27
+ * so the instanced block is this one without its tail and uLightViewProj does not move.
28
+ */
29
+ #if INSTANCED
30
+ /**
31
+ * One instance's placement, four vec4 columns, at the same locations the flat stage uses.
32
+ *
33
+ * No tint: this stage writes depth and nothing samples its colour.
34
+ *
35
+ * The same exclusions apply and for the same reasons — skinning owns locations 11 and 12, and a
36
+ * shadow must be deformed exactly as its caster is or it comes loose from the body casting it.
37
+ */
38
+ layout(location = 11) in vec4 aInstanceModel0;
39
+ layout(location = 12) in vec4 aInstanceModel1;
40
+ layout(location = 13) in vec4 aInstanceModel2;
41
+ layout(location = 14) in vec4 aInstanceModel3;
42
+ #else
43
+ uniform mat4 uModel;
44
+
45
+ /*
46
+ * **The same channel and the same bend the colour pass runs, and it is not optional here.**
47
+ * scatter.ts records why it shares one expression between its two programs: a canopy that bends
48
+ * in the picture and stands still in the shadow map slides its whole shade off the ground it
49
+ * belongs to, and the offset follows the gust, so it never reads as a fixed error anybody could
50
+ * find by looking at one frame.
51
+ *
52
+ * Only .x is read. The sky and alpha lanes are shading, and this stage writes depth.
53
+ */
54
+ ${CHANNEL_ATTRIBUTE}
55
+ ${CHANNEL_BEND}
56
+ #endif
57
+
58
+ out vec4 vLightPosition;
59
+
60
+ void main() {
61
+ #if SKINNED
62
+ /* In model space, before uModel, because a palette entry already carries the bind pose —
63
+ the same order the flat shader applies it in, and the two must agree or a shadow parts
64
+ from the body casting it. */
65
+ vec4 local = skinMatrix() * vec4(aPosition, 1.0);
66
+ #else
67
+ vec4 local = vec4(aPosition, 1.0);
68
+ #endif
69
+ #if INSTANCED
70
+ mat4 model = mat4(aInstanceModel0, aInstanceModel1, aInstanceModel2, aInstanceModel3);
71
+ #else
72
+ mat4 model = uModel;
73
+ #endif
74
+ vec4 world = model * local;
75
+ #if INSTANCED
76
+ vec3 bent = world.xyz;
77
+ #else
78
+ vec3 bent = channelBend(world.xyz, aChannel.x);
79
+ #endif
80
+ vLightPosition = uLightViewProj * vec4(bent, world.w);
81
+ gl_Position = vLightPosition;
82
+ }
83
+ `;
84
+ /** The rigid variant: the world, a prop, a mesh with no rig behind it. */
85
+ export const DEPTH_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: false }, 'depth');
86
+ /** The skinned variant, which reads a joint palette and moves the vertex by it. */
87
+ export const DEPTH_SKINNED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: true, INSTANCED: false }, 'depth-skinned');
88
+ /**
89
+ * The variant an instanced draw casts its shadow through.
90
+ *
91
+ * **It exists because a shadow is not optional.** An instanced mesh whose depth pass still read
92
+ * uModel would cast every instance's shadow from the last matrix uploaded — one shadow in the
93
+ * right place and the rest stacked underneath it, which reads as a lighting fault rather than as
94
+ * a missing variant, and is the shape the per-draw ring exists to prevent one level up.
95
+ */
96
+ export const DEPTH_INSTANCED_VERT = resolveConditionals(DEPTH_VERT_SOURCE, { SKINNED: false, INSTANCED: true }, 'depth-instanced');
97
+ export const DEPTH_FRAG = `#version 300 es
98
+ precision highp float;
99
+ in vec4 vLightPosition;
100
+
101
+ uniform highp sampler2D uPreviousShadowMap;
102
+ uniform int uPeelShadowLayer;
103
+
104
+ void main() {
105
+ if (uPeelShadowLayer != 0) {
106
+ vec3 p = vLightPosition.xyz / vLightPosition.w;
107
+ vec2 uv = p.xy * 0.5 + 0.5;
108
+ float previousDepth = texture(uPreviousShadowMap, uv).r;
109
+ // Discard the already-recorded surface and everything in front of it. The
110
+ // ordinary depth test then stores the next independently fading occluder.
111
+ if (gl_FragCoord.z <= previousDepth + 0.00001) discard;
112
+ }
113
+ }
114
+ `;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Depth of field: a circle of confusion from the depth buffer, and a disc blur that follows it.
3
+ *
4
+ * **A snippet spliced into the composite rather than a pass of its own**, because the composite
5
+ * already holds everything this needs — the resolved scene, its depth, and a place in the chain
6
+ * where the picture is finished but not yet graded. A second fullscreen pass would mean a second
7
+ * read and a second write of the whole frame to add eight taps to the pixels that are out of
8
+ * focus, which is the shape `ambientOcclusion.ts` takes only because it must blur its own noisy
9
+ * estimate first. Nothing here is noisy.
10
+ *
11
+ * **Off costs one comparison.** `uDofStrength` at zero is a branch on a uniform — provably uniform
12
+ * control flow, so it is not the 2026-08-07 case — and the frame is the frame that existed before
13
+ * the effect did, bit for bit.
14
+ *
15
+ * **The model, and why it is stated in metres.** A lens has a plane it is focused on and a depth
16
+ * either side of it that is acceptably sharp; past that, a point becomes a disc whose diameter
17
+ * grows with how far out of focus it is. So the two numbers a caller gives are a *distance* and a
18
+ * *range*, both in metres of the world, and the shader turns them into a radius in pixels. A
19
+ * formulation in depth-buffer units would be cheaper and would mean nothing to anyone: a camera
20
+ * focuses on a thing at a distance, not on a value of `gl_FragCoord.z`.
21
+ *
22
+ * **What the ramp is, exactly.** Zero inside `range` metres of the plane, reaching full blur one
23
+ * more `range` beyond it, clamped there. Linear rather than physical: a real circle of confusion
24
+ * grows without bound behind the plane and toward the lens in front of it, and reproducing that
25
+ * needs an aperture, a focal length and a sensor size — three numbers a game camera does not have
26
+ * and would have to invent. *What that gives up* is that a caller cannot reproduce a particular
27
+ * lens. *What would reverse it* is a consumer matching real optics, and the answer then is those
28
+ * three numbers rather than a different curve on these two.
29
+ *
30
+ * **The bleed, and the one line that handles it.** The classic artefact of a gather blur is a
31
+ * sharp foreground subject collecting colour from the blurred background behind it, so it wears a
32
+ * halo of whatever it is standing in front of. A tap here is weighted by whether it is *behind*
33
+ * the pixel it is blurring into — which it may always contribute to — or in front of it, where it
34
+ * contributes only as far as it is itself defocused. That is one compare per tap and it removes
35
+ * the halo. *What it does not do* is spread a blurred foreground *over* a sharp background, which
36
+ * a gather cannot do at all: no tap on the background ever reaches out to find it. A scatter pass
37
+ * or a separate near field is the answer, and neither is here.
38
+ */
39
+ /** How many taps the disc takes. Eight, fixed, so the cost of the effect is a constant. */
40
+ export declare const DOF_TAPS = 8;
41
+ export declare const DEPTH_OF_FIELD_GLSL: string;
@@ -0,0 +1,139 @@
1
+ import { glslSceneDepthToNdc } from '../depthConvention.js';
2
+ /**
3
+ * Depth of field: a circle of confusion from the depth buffer, and a disc blur that follows it.
4
+ *
5
+ * **A snippet spliced into the composite rather than a pass of its own**, because the composite
6
+ * already holds everything this needs — the resolved scene, its depth, and a place in the chain
7
+ * where the picture is finished but not yet graded. A second fullscreen pass would mean a second
8
+ * read and a second write of the whole frame to add eight taps to the pixels that are out of
9
+ * focus, which is the shape `ambientOcclusion.ts` takes only because it must blur its own noisy
10
+ * estimate first. Nothing here is noisy.
11
+ *
12
+ * **Off costs one comparison.** `uDofStrength` at zero is a branch on a uniform — provably uniform
13
+ * control flow, so it is not the 2026-08-07 case — and the frame is the frame that existed before
14
+ * the effect did, bit for bit.
15
+ *
16
+ * **The model, and why it is stated in metres.** A lens has a plane it is focused on and a depth
17
+ * either side of it that is acceptably sharp; past that, a point becomes a disc whose diameter
18
+ * grows with how far out of focus it is. So the two numbers a caller gives are a *distance* and a
19
+ * *range*, both in metres of the world, and the shader turns them into a radius in pixels. A
20
+ * formulation in depth-buffer units would be cheaper and would mean nothing to anyone: a camera
21
+ * focuses on a thing at a distance, not on a value of `gl_FragCoord.z`.
22
+ *
23
+ * **What the ramp is, exactly.** Zero inside `range` metres of the plane, reaching full blur one
24
+ * more `range` beyond it, clamped there. Linear rather than physical: a real circle of confusion
25
+ * grows without bound behind the plane and toward the lens in front of it, and reproducing that
26
+ * needs an aperture, a focal length and a sensor size — three numbers a game camera does not have
27
+ * and would have to invent. *What that gives up* is that a caller cannot reproduce a particular
28
+ * lens. *What would reverse it* is a consumer matching real optics, and the answer then is those
29
+ * three numbers rather than a different curve on these two.
30
+ *
31
+ * **The bleed, and the one line that handles it.** The classic artefact of a gather blur is a
32
+ * sharp foreground subject collecting colour from the blurred background behind it, so it wears a
33
+ * halo of whatever it is standing in front of. A tap here is weighted by whether it is *behind*
34
+ * the pixel it is blurring into — which it may always contribute to — or in front of it, where it
35
+ * contributes only as far as it is itself defocused. That is one compare per tap and it removes
36
+ * the halo. *What it does not do* is spread a blurred foreground *over* a sharp background, which
37
+ * a gather cannot do at all: no tap on the background ever reaches out to find it. A scatter pass
38
+ * or a separate near field is the answer, and neither is here.
39
+ */
40
+ /** How many taps the disc takes. Eight, fixed, so the cost of the effect is a constant. */
41
+ export const DOF_TAPS = 8;
42
+ export const DEPTH_OF_FIELD_GLSL = `
43
+ /** Where the lens is focused, in metres from the camera. */
44
+ uniform float uFocusDistance;
45
+ /**
46
+ * How many metres either side of that plane stay sharp, and over how many more the blur reaches
47
+ * full strength. One number for both, because two would be a second dial with no second question.
48
+ */
49
+ uniform float uFocusRange;
50
+ /**
51
+ * The widest the blur may reach, as a fraction of the frame's height. 0 turns the effect off and
52
+ * is the whole of the off path.
53
+ */
54
+ uniform float uDofStrength;
55
+ /**
56
+ * \`vec2(height / width, 1.0)\`, so a radius given in fractions of the frame's height traces a
57
+ * circle on screen rather than an ellipse stretched by the aspect.
58
+ */
59
+ uniform vec2 uDofAspect;
60
+ /**
61
+ * The four elements of the inverse projection that turn a depth sample into a view-space distance:
62
+ * \`(m[10], m[14], m[11], m[15])\` in gl-matrix's column-major order, which are \`M[2][2]\`,
63
+ * \`M[2][3]\`, \`M[3][2]\` and \`M[3][3]\`.
64
+ *
65
+ * Four floats rather than the whole matrix, because the other twelve are multiplied by the x and y
66
+ * of a clip position this never needs: a perspective projection's inverse has zeroes where they
67
+ * would land. \`ambientOcclusion.ts\` uploads the full \`uInvProjection\` because it reconstructs a
68
+ * *position* and needs them.
69
+ */
70
+ uniform vec4 uDepthToView;
71
+
72
+ /**
73
+ * Metres in front of the camera, from a depth sample.
74
+ *
75
+ * \`depth * 2.0 - 1.0\` is the same recovery \`cameraBlur\` makes and for the same reason: the depth
76
+ * attachment holds [0, 1] on both backends, the projection whose inverse this carries is the
77
+ * uncorrected OpenGL-convention one, and the engine settles the difference between the two clip
78
+ * spaces in the matrix rather than in the shaders.
79
+ */
80
+ float viewDepthOf(vec2 uv) {
81
+ float z = ${glslSceneDepthToNdc('textureLod(uDepth, uv, 0.0).r')};
82
+ return -(uDepthToView.x * z + uDepthToView.y) / (uDepthToView.z * z + uDepthToView.w);
83
+ }
84
+
85
+ /** 0 inside the sharp zone, 1 at full blur. See the header for the shape of the ramp. */
86
+ float circleOfConfusion(float viewDepth) {
87
+ float offPlane = abs(viewDepth - uFocusDistance) - uFocusRange;
88
+ return clamp(offPlane / uFocusRange, 0.0, 1.0);
89
+ }
90
+
91
+ /**
92
+ * The eight offsets of the disc, written out.
93
+ *
94
+ * A golden-angle spiral at radii spaced by \`sqrt((i + 0.5) / 8)\`, which fills a disc evenly
95
+ * rather than stacking the taps into a ring. Literals rather than a loop over \`cos\` and \`sin\`,
96
+ * because these are constants and evaluating them per pixel is eight transcendentals for a table.
97
+ * Successive taps turned by the golden angle never line up into spokes, which is the same
98
+ * property \`ambientOcclusion.ts\` picks it for.
99
+ *
100
+ * The colour comes back premultiplied by the weight and the weight rides in \`w\`, rather than an
101
+ * \`inout\` parameter — one value out of one function, which is what the generator translates most
102
+ * predictably.
103
+ */
104
+ vec4 dofTap(vec2 direction, float radius, float centreDepth) {
105
+ vec2 uv = vUv + direction * radius * uDofAspect;
106
+ float depth = viewDepthOf(uv);
107
+ /* Behind the pixel it is blurring into, or defocused enough to have spread this far. */
108
+ float weight = depth >= centreDepth ? 1.0 : circleOfConfusion(depth);
109
+ /* textureLod: this is reached through a branch on the circle of confusion, which varies across
110
+ the frame, so it is not uniform control flow. Identical output — one storage level. */
111
+ return vec4(textureLod(uScene, uv, 0.0).rgb * weight, weight);
112
+ }
113
+
114
+ /**
115
+ * The disc, gathered.
116
+ *
117
+ * The centre sample is the colour handed in rather than a fresh fetch, so a pixel that has already
118
+ * been camera-blurred keeps that blur at the middle of its own disc. *What that gives up* is that
119
+ * the eight taps read the unblurred scene, so the two effects compose approximately rather than
120
+ * exactly. *What would make it wrong* is a consumer running both at full strength and caring which
121
+ * order they were applied in, and the answer then is a second scene target for the intermediate.
122
+ */
123
+ vec3 depthOfField(vec3 centre) {
124
+ float depth = viewDepthOf(vUv);
125
+ float coc = circleOfConfusion(depth);
126
+ if (coc <= 0.0) return centre;
127
+ float radius = coc * uDofStrength;
128
+ vec4 sum = vec4(centre, 1.0);
129
+ sum += dofTap(vec2( 0.250000, 0.000000), radius, depth);
130
+ sum += dofTap(vec2(-0.319290, 0.292496), radius, depth);
131
+ sum += dofTap(vec2( 0.048872, -0.556877), radius, depth);
132
+ sum += dofTap(vec2( 0.402444, 0.524918), radius, depth);
133
+ sum += dofTap(vec2(-0.738535, -0.130636), radius, depth);
134
+ sum += dofTap(vec2( 0.699605, -0.445031), radius, depth);
135
+ sum += dofTap(vec2(-0.234004, 0.870484), radius, depth);
136
+ sum += dofTap(vec2(-0.446271, -0.859268), radius, depth);
137
+ return sum.rgb / sum.w;
138
+ }
139
+ `;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A thin, wet, iridescent film lying on a surface.
3
+ *
4
+ * The material an oil slick is made of, described without knowing what oil is.
5
+ * Flat dark geometry cannot do this job — it reads as a hole in the world, which
6
+ * is exactly how the first version looked. What makes a film read as *wet* is
7
+ * that it changes with the angle you see it from: almost black looking straight
8
+ * down, and a shifting sheen at a glance.
9
+ *
10
+ * Textureless, per the standing rule. The iridescence is a hue swept by the
11
+ * view angle plus a slow travelling ripple, both evaluated per fragment; the
12
+ * rainbow is generated rather than sampled.
13
+ */
14
+ export declare const FILM_VERT = "#version 300 es\nprecision highp float;\n\nlayout(location = 0) in vec3 aPosition;\nlayout(location = 1) in vec3 aNormal;\nlayout(location = 2) in vec3 aColor;\n/*\n * Coverage, on the attribute the mesh format calls emissive.\n *\n * A film has no use for self-illumination, and it very much needs an edge that\n * dissolves: the first oil was flat squares, and a hard straight edge is what made\n * it read as a decal dropped on the world rather than a puddle lying in it. One\n * float per vertex, 1 in the middle of a slick and 0 at its rim.\n */\nlayout(location = 3) in float aCoverage;\n\nuniform mat4 uViewProj;\n/* The mirrored camera's projection, so a film can sample the planar target the way water does. */\nuniform mat4 uReflectionViewProj;\n\nout vec3 vWorld;\nout vec3 vNormal;\nout vec3 vTint;\nout vec4 vReflectionClip;\nout float vCoverage;\n\nvoid main() {\n vWorld = aPosition;\n vNormal = normalize(aNormal);\n vTint = aColor;\n vCoverage = aCoverage;\n vReflectionClip = uReflectionViewProj * vec4(aPosition, 1.0);\n gl_Position = uViewProj * vec4(aPosition, 1.0);\n}\n";
15
+ export declare const FILM_FRAG = "#version 300 es\nprecision highp float;\n\nin vec3 vWorld;\nin vec3 vNormal;\nin vec3 vTint;\nin vec4 vReflectionClip;\n/*\n * The scene mirrored across the plane this film lies on, and how much of it to show.\n *\n * **Sheen is iridescence and this is the image**, which is the split a consumer asked for after\n * finding that raising sheen to make a road wetter only made it oilier. A wet street at night is\n * defined by everything above it appearing twice, and no amount of interference pattern is that.\n *\n * The projection is the water shader's, unchanged and deliberately so: reproducing it outside the\n * engine is the piece most likely to be subtly wrong and least likely to be noticed, since a\n * mirror off by a small skew looks like a wet road until somebody puts a straight line across it.\n */\nuniform sampler2D uReflectionMap;\nuniform int uReflectionEnabled;\nuniform float uReflectionStrength;\nin float vCoverage;\n\nuniform vec3 uCameraPos;\nuniform float uTime;\n/*\n * The mirrored pass clips at the water plane, and it does so **in the fragment\n * shader** rather than with gl_ClipDistance.\n *\n * That is not a style choice. Clip distances in WebGL2 need\n * EXT_clip_cull_distance both enabled on the context and declared with an\n * #extension line, and without the declaration the shader fails to *compile* \u2014\n * which, since programs are built when the renderer is constructed, takes the\n * whole boot with it and leaves a black screen. This shader had never been\n * compiled when it was written, so the mistake sat harmlessly in the file until\n * the day it was wired to something. Discarding is what flat.ts does, it needs\n * no extension, and a film is a thin translucent layer where the cost of a\n * discarded fragment is nothing.\n */\nuniform vec4 uClipPlane;\nuniform int uClipEnabled;\n\nuniform vec3 uFogColor;\n/** Extinction per metre **at the camera's own height**, not at the base. */\nuniform float uFogDensity;\n/** Reciprocal scale height of the haze, per metre. 0 is a uniform medium. */\nuniform float uFogHeightFalloff;\n/** The camera's height, so a fragment's own height is one subtraction away. */\nuniform float uFogEyeY;\nuniform vec3 uUnderwaterColor;\nuniform float uUnderwaterFogDensity;\nuniform float uUnderwaterFactor;\n/** 0 integrates a medium (Beer-Lambert); 1 ramps linearly between near and far. */\nuniform int uFogMode;\n/** Linear mode only: where haze begins, and where it is total. */\nuniform float uFogNear;\nuniform float uFogFar;\n\n/** What distance converges toward: the day's haze, or the water column. */\nvec3 mediumColor() {\n return mix(uFogColor, uUnderwaterColor, uUnderwaterFactor);\n}\n\n/**\n * How much of a surface standing at height pointY, dist metres away, is lost to\n * the medium in between. 0 is perfectly clear, 1 is the medium's own colour.\n */\nfloat mediumFog(float dist, float pointY) {\n /*\n * A depth ramp rather than a medium, for worlds authored against one.\n *\n * Beer-Lambert is the honest model and stays the default: it integrates something\n * physically there, so extinction begins at the eye and never stops. A linear near/far\n * fog is not that \u2014 it is a *look*, with a hard start distance before which the air is\n * perfectly clear, and it is what the fixed-function pipeline offered and what several\n * renderers still expose. Approximating one with the other is not a matter of tuning:\n * matched at half occlusion, the exponential curve still lays haze over everything\n * inside near, where the ramp lays none, and near-field colour desaturates toward the\n * fog colour with nothing to show for it.\n *\n * Height falloff has no meaning here and is ignored: a ramp is defined on distance\n * alone.\n */\n if (uFogMode == 1) {\n float span = max(uFogFar - uFogNear, 1e-4);\n float ramp = clamp((dist - uFogNear) / span, 0.0, 1.0);\n if (uUnderwaterFactor <= 0.0) return ramp;\n float wetLinear = uUnderwaterFogDensity * dist;\n return mix(ramp, 1.0 - exp2(-wetLinear * wetLinear * 1.442695), uUnderwaterFactor);\n }\n\n float t = (pointY - uFogEyeY) * uFogHeightFalloff;\n // (1 - e^-t)/t, which tends to 1 as the ray levels out. Guarded rather than\n // branched: at t = 0 the quotient is 0/0, and 1e-4 of a scale height is 8 mm.\n float denom = abs(t) < 1e-4 ? 1e-4 : t;\n float air = 1.0 - exp(-uFogDensity * dist * (1.0 - exp(-denom)) / denom);\n if (uUnderwaterFactor <= 0.0) return air;\n // Water is its own medium and keeps its own curve, so crossing the surface\n // changes nothing about how the water column reads.\n float wet = uUnderwaterFogDensity * dist;\n return mix(air, 1.0 - exp2(-wet * wet * 1.442695), uUnderwaterFactor);\n}\n\n/** How strong the sheen is. Zero leaves a plain dark film. */\nuniform float uSheen;\n\n/**\n * How rough the film's own surface is, 0 to 1, and how coarse that roughness is.\n *\n * **A film had exactly one finish before this: mirror.** That is right for standing water and\n * wrong for the thing this pass is most used for, because a wet road is not a mirror \u2014 it is\n * water lying *in* aggregate, and the stone underneath breaks the reflection into a smear. With\n * no way to say so, a patch of film over a textured road met it at a hard rim: mirror on one\n * side, stone on the other, with nothing able to cross it. Feathering the coverage cannot fix\n * that, and it was tried \u2014 the alpha was never what the eye was reading.\n *\n * So the reflection is displaced by a noise field rather than blurred. **Displaced, because a\n * blur is the wrong phenomenon**: a rough surface does not soften what it reflects, it scatters\n * it, and a lamp on wet tarmac smears into a streak rather than becoming a soft disc. It is also\n * what a blur cannot afford here \u2014 the mirror has no mip chain (see the `textureLod` note\n * below), so softening it honestly would cost several taps where this costs none.\n *\n * `uFilmRoughnessCycles` is bumps to the metre, and it is the same quantity\n * `Renderer.setSurfaceRelief` takes. **Matching it to the surface underneath is the point**:\n * given the same field at the same scale, the water is broken up by the aggregate that the dry\n * road beside it is showing, and the two stop being different materials.\n *\n * Zero is the mirror this pass has always been, exactly, so nothing that does not ask for\n * roughness renders differently.\n */\nuniform float uFilmRoughness;\nuniform float uFilmRoughnessCycles;\n\nout vec4 fragColor;\n\n/** A hue wheel, without a texture. Standard 6-segment ramp. */\nvec3 hue(float h) {\n h = fract(h) * 6.0;\n vec3 c = clamp(vec3(abs(h - 3.0) - 1.0, 2.0 - abs(h - 2.0), 2.0 - abs(h - 4.0)), 0.0, 1.0);\n return c;\n}\n\n/**\n * The same value noise `flat.ts` builds its relief from, and deliberately the same.\n *\n * Copied rather than shared because these two shaders have no common include beyond the fog, and\n * a film that used a *different* field would defeat the whole purpose of taking a cycle count:\n * the water would be broken up by one pattern and the road by another, which is two materials\n * again with extra steps.\n */\nfloat filmHash(vec3 p) {\n p = fract(p * 0.1031);\n p += dot(p, p.zyx + 31.32);\n return fract((p.x + p.y) * p.z);\n}\n\nfloat filmNoise(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n vec3 u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(\n mix(filmHash(i + vec3(0.0, 0.0, 0.0)), filmHash(i + vec3(1.0, 0.0, 0.0)), u.x),\n mix(filmHash(i + vec3(0.0, 1.0, 0.0)), filmHash(i + vec3(1.0, 1.0, 0.0)), u.x),\n u.y\n ),\n mix(\n mix(filmHash(i + vec3(0.0, 0.0, 1.0)), filmHash(i + vec3(1.0, 0.0, 1.0)), u.x),\n mix(filmHash(i + vec3(0.0, 1.0, 1.0)), filmHash(i + vec3(1.0, 1.0, 1.0)), u.x),\n u.y\n ),\n u.z\n );\n}\n\nvoid main() {\n if (uClipEnabled != 0 && dot(vec4(vWorld, 1.0), uClipPlane) < 0.0) discard;\n\n vec3 view = normalize(uCameraPos - vWorld);\n float facing = max(dot(normalize(vNormal), view), 0.0);\n /*\n * Fresnel-ish: dark looking straight down at it, bright at a grazing angle.\n * This is the whole effect \u2014 it is what makes a wet patch look wet rather\n * than looking like a patch of dark paint.\n */\n float grazing = pow(1.0 - facing, 3.0);\n\n /*\n * A slow travelling interference, so the sheen crawls rather than sitting\n * still. Two frequencies that do not divide each other, or the pattern\n * repeats visibly across a long slick.\n */\n float ripple =\n sin(vWorld.x * 0.73 + vWorld.z * 0.41 + uTime * 0.55) *\n cos(vWorld.z * 0.91 - vWorld.x * 0.29 - uTime * 0.37);\n\n vec3 sheen = hue(grazing * 1.35 + ripple * 0.14 + 0.55);\n /*\n * Dark underneath, so the film always reads as *less* than the surface it lies on even where\n * the sheen is strongest \u2014 but not so dark that it disappears.\n *\n * A slick that has just launched somebody has to be findable afterwards. It was rounded,\n * feathered and iridescent \u2014 and at a fifth of an opaque tint on a pale deck at dusk,\n * invisible. A hazard you cannot find is not a hazard, it is a trap.\n *\n * So the base is darker and the sheen has a floor: even looking straight down, where the\n * Fresnel term is nearly nothing, a slick is a distinctly wet patch rather than a faint one.\n */\n vec3 base = vTint * 0.9;\n vec3 color = base + sheen * uSheen * (0.22 + grazing * 0.75);\n\n /*\n * The mirrored scene, under the sheen rather than instead of it.\n *\n * Screen-space from the mirrored clip position, exactly as the water pass does it, with the\n * same fade as the sample leaves the target: a reflection that stopped dead at the edge of its\n * own buffer would draw a line across the road where nothing is.\n *\n * Weighted by the grazing term as well as by strength, because that is what a reflection does:\n * a wet surface underfoot shows almost nothing and the same surface down the street shows the\n * whole scene. Added before the fog so the image recedes with everything else in the frame.\n */\n if (uReflectionEnabled != 0 && uReflectionStrength > 0.0 && vReflectionClip.w > 0.0) {\n vec2 reflectionUv = vReflectionClip.xy / vReflectionClip.w * 0.5 + 0.5;\n vec2 border = min(reflectionUv, 1.0 - reflectionUv);\n float valid = smoothstep(0.0, 0.025, min(border.x, border.y));\n /*\n * An explicit level, not an implicit one, and the branch above is the whole reason.\n *\n * An implicit derivative inside control flow that is not provably uniform is what lets a\n * compiler flatten the branch and pay for every arm \u2014 AGENTS.md, 2026-08-07 \u2014 and WGSL\n * does not merely warn: the module fails to compile with \"textureSample must only be\n * called from uniform control flow\", which invalidates the pipeline, which invalidates\n * the command buffer, and the frame still presents. The fifth time on this branch. The\n * mirror has no mip chain, so level 0 is the only level there is; the water shader\n * reaches the same conclusion for the same lookup.\n */\n /*\n * The aggregate under the water, as a displacement of what the water shows.\n *\n * The gradient of the same field the road's relief uses, taken across the surface and used\n * to push the lookup. **Stretched along the reflection rather than isotropic**, and that is\n * the half that makes it read as a road: a reflection on a rough horizontal surface smears\n * *towards the viewer*, because a bump tilts the ray in the plane it is already travelling\n * in. Displacing in a circle gives frosted glass instead, which is a different wet thing.\n *\n * Scaled by the grazing term for the same reason the mirror is: looking straight down at a\n * puddle the reflection is compressed into almost nothing and a displacement of it would be\n * enormous, so the scatter has to fall off exactly where the image does.\n */\n if (uFilmRoughness > 0.0) {\n vec3 at = vWorld * uFilmRoughnessCycles;\n float here = filmNoise(at);\n vec2 slope = vec2(\n filmNoise(at + vec3(0.5, 0.0, 0.0)) - here,\n filmNoise(at + vec3(0.0, 0.0, 0.5)) - here\n );\n /* Along the view, which on a horizontal film is where the image runs. */\n vec2 along = normalize(vec2(view.x, view.z) + vec2(1e-5, 0.0));\n vec2 smear = along * dot(slope, along) * 3.0 + slope * 0.35;\n reflectionUv += smear * uFilmRoughness * 0.016 * (0.2 + grazing * 0.8);\n /* Re-fade at the border: a displaced sample can leave the target the original did not. */\n vec2 movedBorder = min(reflectionUv, 1.0 - reflectionUv);\n valid = min(valid, smoothstep(0.0, 0.025, min(movedBorder.x, movedBorder.y)));\n }\n vec3 mirrored = textureLod(uReflectionMap, clamp(reflectionUv, 0.0, 1.0), 0.0).rgb;\n color = mix(color, mirrored, valid * uReflectionStrength * (0.25 + grazing * 0.75));\n }\n\n // The same fog every other pass applies \u2014 and now literally the same code, which\n // it was not: this ran its own curve while claiming otherwise, so a slick receded\n // at a different rate than the deck it was lying on.\n float fog = mediumFog(length(uCameraPos - vWorld), vWorld.y);\n color = mix(color, mediumColor(), fog);\n\n /*\n * Alpha from coverage, squared.\n *\n * Squared because a linear ramp across the rim still reads as a visible band \u2014\n * the eye finds the constant-gradient edge. Squaring pushes the falloff outward\n * so the slick has a soft shoulder and no perceptible boundary. The sheen fades\n * with it, which is right: the thinnest part of a film is the least iridescent.\n */\n /*\n * Alpha from coverage, and the rim is what is squared \u2014 not the whole patch.\n *\n * Squaring the coverage outright made the *middle* translucent too, which is most of why a\n * slick could not be found. The shoulder still needs to be soft, so the square is mixed in\n * near the edge only: solid through the body, dissolving at the rim.\n */\n float coverage = clamp(vCoverage, 0.0, 1.0);\n float alpha = mix(coverage * coverage, coverage, 0.65) * 0.92;\n fragColor = vec4(color, alpha);\n}\n";