@driftengine/core 3.62.0 → 4.0.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 (428) hide show
  1. package/CHANGELOG.json +122 -0
  2. package/NOTICE +20 -0
  3. package/README.md +1 -1
  4. package/dist/core/loop.js +18 -2
  5. package/dist/core/storage.js +5 -0
  6. package/dist/geometry/meshBuilder.d.ts +1 -1
  7. package/dist/geometry/meshBuilder.js +6 -2
  8. package/dist/index.d.ts +70 -4
  9. package/dist/index.js +123 -2
  10. package/dist/input/input.js +6 -1
  11. package/dist/math/exact.d.ts +13 -3
  12. package/dist/math/exact.js +68 -3
  13. package/dist/math/frustum.d.ts +17 -2
  14. package/dist/math/frustum.js +24 -0
  15. package/dist/render/backend/api.d.ts +34 -1
  16. package/dist/render/backend/api.js +22 -1
  17. package/dist/render/backend/budget.d.ts +7 -6
  18. package/dist/render/backend/budget.js +7 -6
  19. package/dist/render/backend/createRenderer.d.ts +57 -0
  20. package/dist/render/backend/createRenderer.js +51 -2
  21. package/dist/render/backend/materialChanges.d.ts +41 -0
  22. package/dist/render/backend/materialChanges.js +38 -0
  23. package/dist/render/backend/select.js +8 -0
  24. package/dist/render/backend/webgl2/renderer.d.ts +80 -1
  25. package/dist/render/backend/webgl2/renderer.js +208 -10
  26. package/dist/render/backend/webgpu/buffers.d.ts +20 -1
  27. package/dist/render/backend/webgpu/buffers.js +116 -58
  28. package/dist/render/backend/webgpu/fieldCompose.d.ts +156 -0
  29. package/dist/render/backend/webgpu/fieldCompose.js +396 -0
  30. package/dist/render/backend/webgpu/giFieldPass.d.ts +66 -0
  31. package/dist/render/backend/webgpu/giFieldPass.js +137 -0
  32. package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +728 -0
  33. package/dist/render/backend/webgpu/gpuDrivenPass.js +2473 -0
  34. package/dist/render/backend/webgpu/linePass.d.ts +4 -14
  35. package/dist/render/backend/webgpu/linePass.js +4 -33
  36. package/dist/render/backend/webgpu/probeBake.d.ts +148 -0
  37. package/dist/render/backend/webgpu/probeBake.js +493 -0
  38. package/dist/render/backend/webgpu/renderer.d.ts +379 -24
  39. package/dist/render/backend/webgpu/renderer.js +1369 -76
  40. package/dist/render/backend/webgpu/scatterPass.js +15 -1
  41. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +47 -14
  42. package/dist/render/backend/webgpu/surfaceTexturePass.js +128 -80
  43. package/dist/render/causticsRenderer.d.ts +3 -1
  44. package/dist/render/causticsRenderer.js +4 -1
  45. package/dist/render/depthConvention.d.ts +12 -0
  46. package/dist/render/depthConvention.js +14 -0
  47. package/dist/render/deviceFeatures.d.ts +32 -0
  48. package/dist/render/deviceFeatures.js +41 -0
  49. package/dist/render/fog.d.ts +79 -0
  50. package/dist/render/fog.js +138 -0
  51. package/dist/render/frame/alias.d.ts +30 -0
  52. package/dist/render/frame/alias.js +61 -0
  53. package/dist/render/frame/deps.d.ts +37 -0
  54. package/dist/render/frame/deps.js +122 -0
  55. package/dist/render/frame/flushGraph.d.ts +43 -0
  56. package/dist/render/frame/flushGraph.js +84 -0
  57. package/dist/render/frame/graphSchedule.d.ts +49 -0
  58. package/dist/render/frame/graphSchedule.js +120 -0
  59. package/dist/render/frame/index.d.ts +15 -0
  60. package/dist/render/frame/index.js +8 -0
  61. package/dist/render/frame/lifetime.d.ts +24 -0
  62. package/dist/render/frame/lifetime.js +36 -0
  63. package/dist/render/frame/passTimings.d.ts +42 -0
  64. package/dist/render/frame/passTimings.js +38 -0
  65. package/dist/render/frame/validate.d.ts +15 -0
  66. package/dist/render/frame/validate.js +22 -0
  67. package/dist/render/frame/virtual.d.ts +44 -0
  68. package/dist/render/frame/virtual.js +61 -0
  69. package/dist/render/gi/chain.d.ts +82 -0
  70. package/dist/render/gi/chain.js +135 -0
  71. package/dist/render/gi/denoise.d.ts +114 -0
  72. package/dist/render/gi/denoise.js +169 -0
  73. package/dist/render/gi/fieldScene.d.ts +125 -0
  74. package/dist/render/gi/fieldScene.js +219 -0
  75. package/dist/render/gi/globalField.d.ts +157 -0
  76. package/dist/render/gi/globalField.js +373 -0
  77. package/dist/render/gi/probeGridFit.d.ts +24 -0
  78. package/dist/render/gi/probeGridFit.js +71 -0
  79. package/dist/render/gi/probeTrace.d.ts +82 -0
  80. package/dist/render/gi/probeTrace.js +128 -0
  81. package/dist/render/gi/probeVolume.d.ts +136 -0
  82. package/dist/render/gi/probeVolume.js +191 -0
  83. package/dist/render/gi/reflection.d.ts +73 -0
  84. package/dist/render/gi/reflection.js +109 -0
  85. package/dist/render/gi/traceField.d.ts +91 -0
  86. package/dist/render/gi/traceField.js +129 -0
  87. package/dist/render/gi/traceScreen.d.ts +68 -0
  88. package/dist/render/gi/traceScreen.js +82 -0
  89. package/dist/render/gpuScene.d.ts +38 -0
  90. package/dist/render/gpuScene.js +41 -0
  91. package/dist/render/gpudriven/alphaTest.d.ts +28 -0
  92. package/dist/render/gpudriven/alphaTest.js +32 -0
  93. package/dist/render/gpudriven/clusterUpload.d.ts +59 -0
  94. package/dist/render/gpudriven/clusterUpload.js +75 -0
  95. package/dist/render/gpudriven/clusterWorld.d.ts +57 -0
  96. package/dist/render/gpudriven/clusterWorld.js +155 -0
  97. package/dist/render/gpudriven/compact.d.ts +51 -0
  98. package/dist/render/gpudriven/compact.js +68 -0
  99. package/dist/render/gpudriven/cullClusters.d.ts +129 -0
  100. package/dist/render/gpudriven/cullClusters.js +237 -0
  101. package/dist/render/gpudriven/decodeTables.d.ts +64 -0
  102. package/dist/render/gpudriven/decodeTables.js +219 -0
  103. package/dist/render/gpudriven/frustum.d.ts +25 -0
  104. package/dist/render/gpudriven/frustum.js +59 -0
  105. package/dist/render/gpudriven/geometryHarness.d.ts +15 -0
  106. package/dist/render/gpudriven/geometryHarness.js +31 -0
  107. package/dist/render/gpudriven/hzb.d.ts +60 -0
  108. package/dist/render/gpudriven/hzb.js +97 -0
  109. package/dist/render/gpudriven/ibl.d.ts +85 -0
  110. package/dist/render/gpudriven/ibl.js +129 -0
  111. package/dist/render/gpudriven/indirect.d.ts +67 -0
  112. package/dist/render/gpudriven/indirect.js +77 -0
  113. package/dist/render/gpudriven/instances.d.ts +43 -0
  114. package/dist/render/gpudriven/instances.js +172 -0
  115. package/dist/render/gpudriven/lit.d.ts +165 -0
  116. package/dist/render/gpudriven/lit.js +165 -0
  117. package/dist/render/gpudriven/lodCut.d.ts +28 -0
  118. package/dist/render/gpudriven/lodCut.js +38 -0
  119. package/dist/render/gpudriven/materialBin.d.ts +60 -0
  120. package/dist/render/gpudriven/materialBin.js +108 -0
  121. package/dist/render/gpudriven/materialTable.d.ts +88 -0
  122. package/dist/render/gpudriven/materialTable.js +115 -0
  123. package/dist/render/gpudriven/pipeline.d.ts +135 -0
  124. package/dist/render/gpudriven/pipeline.js +237 -0
  125. package/dist/render/gpudriven/rangeAlloc.d.ts +50 -0
  126. package/dist/render/gpudriven/rangeAlloc.js +112 -0
  127. package/dist/render/gpudriven/sceneUpload.d.ts +96 -0
  128. package/dist/render/gpudriven/sceneUpload.js +115 -0
  129. package/dist/render/gpudriven/shadeBins.d.ts +92 -0
  130. package/dist/render/gpudriven/shadeBins.js +182 -0
  131. package/dist/render/gpudriven/shadow.d.ts +136 -0
  132. package/dist/render/gpudriven/shadow.js +224 -0
  133. package/dist/render/gpudriven/shadowCamera.d.ts +87 -0
  134. package/dist/render/gpudriven/shadowCamera.js +345 -0
  135. package/dist/render/gpudriven/streamScene.d.ts +194 -0
  136. package/dist/render/gpudriven/streamScene.js +459 -0
  137. package/dist/render/gpudriven/surfaceFrame.d.ts +25 -0
  138. package/dist/render/gpudriven/surfaceFrame.js +51 -0
  139. package/dist/render/gpudriven/twoPhase.d.ts +122 -0
  140. package/dist/render/gpudriven/twoPhase.js +160 -0
  141. package/dist/render/gpudriven/visbuffer.d.ts +25 -0
  142. package/dist/render/gpudriven/visbuffer.js +37 -0
  143. package/dist/render/halfFloat.d.ts +10 -0
  144. package/dist/render/halfFloat.js +23 -4
  145. package/dist/render/inference/attentionTiled.d.ts +27 -0
  146. package/dist/render/inference/attentionTiled.js +117 -0
  147. package/dist/render/inference/denseKernels.d.ts +29 -0
  148. package/dist/render/inference/denseKernels.js +312 -0
  149. package/dist/render/inference/device.d.ts +21 -0
  150. package/dist/render/inference/device.js +32 -0
  151. package/dist/render/inference/deviceGraph.d.ts +34 -0
  152. package/dist/render/inference/deviceGraph.js +17 -0
  153. package/dist/render/inference/fuse.d.ts +15 -0
  154. package/dist/render/inference/fuse.js +37 -0
  155. package/dist/render/inference/kernelKit.d.ts +52 -0
  156. package/dist/render/inference/kernelKit.js +70 -0
  157. package/dist/render/inference/kernels.d.ts +3 -0
  158. package/dist/render/inference/kernels.js +11 -0
  159. package/dist/render/inference/plan.d.ts +13 -0
  160. package/dist/render/inference/plan.js +18 -0
  161. package/dist/render/inference/reuse.d.ts +39 -0
  162. package/dist/render/inference/reuse.js +65 -0
  163. package/dist/render/inference/runner.d.ts +31 -0
  164. package/dist/render/inference/runner.js +175 -0
  165. package/dist/render/inference/schedule.d.ts +39 -0
  166. package/dist/render/inference/schedule.js +59 -0
  167. package/dist/render/inference/shapeKernels.d.ts +10 -0
  168. package/dist/render/inference/shapeKernels.js +80 -0
  169. package/dist/render/inference/spatialKernels.d.ts +21 -0
  170. package/dist/render/inference/spatialKernels.js +179 -0
  171. package/dist/render/inference/splatRaster.wgsl.d.ts +75 -0
  172. package/dist/render/inference/splatRaster.wgsl.js +337 -0
  173. package/dist/render/inference/splatTiles.d.ts +79 -0
  174. package/dist/render/inference/splatTiles.js +161 -0
  175. package/dist/render/lineBatch.d.ts +2 -5
  176. package/dist/render/lineBatch.js +4 -24
  177. package/dist/render/mesh.d.ts +4 -0
  178. package/dist/render/mesh.js +45 -1
  179. package/dist/render/pass.d.ts +145 -8
  180. package/dist/render/prefilterEnvMap.d.ts +22 -0
  181. package/dist/render/prefilterEnvMap.js +31 -0
  182. package/dist/render/readback.d.ts +30 -0
  183. package/dist/render/readback.js +47 -0
  184. package/dist/render/recon/clamp.d.ts +36 -0
  185. package/dist/render/recon/clamp.js +92 -0
  186. package/dist/render/recon/disocclusion.d.ts +60 -0
  187. package/dist/render/recon/disocclusion.js +109 -0
  188. package/dist/render/recon/frameGen.d.ts +81 -0
  189. package/dist/render/recon/frameGen.js +150 -0
  190. package/dist/render/recon/frameSizes.d.ts +34 -0
  191. package/dist/render/recon/frameSizes.js +58 -0
  192. package/dist/render/recon/jitter.d.ts +60 -0
  193. package/dist/render/recon/jitter.js +118 -0
  194. package/dist/render/recon/motionVectors.d.ts +55 -0
  195. package/dist/render/recon/motionVectors.js +107 -0
  196. package/dist/render/recon/reproject.d.ts +41 -0
  197. package/dist/render/recon/reproject.js +131 -0
  198. package/dist/render/recon/resolve.d.ts +90 -0
  199. package/dist/render/recon/resolve.js +313 -0
  200. package/dist/render/recon/tier.d.ts +24 -0
  201. package/dist/render/recon/tier.js +8 -0
  202. package/dist/render/reflectionProbe.d.ts +26 -0
  203. package/dist/render/reflectionProbe.js +33 -0
  204. package/dist/render/renderQuality.d.ts +69 -0
  205. package/dist/render/renderQuality.js +22 -0
  206. package/dist/render/screenSpaceReflection.d.ts +23 -0
  207. package/dist/render/screenSpaceReflection.js +22 -3
  208. package/dist/render/sdfFont.js +2 -0
  209. package/dist/render/segmentQuads.d.ts +13 -0
  210. package/dist/render/segmentQuads.js +32 -0
  211. package/dist/render/shaders/flat/lobes.d.ts +27 -0
  212. package/dist/render/shaders/flat/lobes.js +33 -3
  213. package/dist/render/shaders/flat/preamble.d.ts +7 -0
  214. package/dist/render/shaders/flat/preamble.js +24 -1
  215. package/dist/render/shaders/flat/probeGrid.d.ts +1 -1
  216. package/dist/render/shaders/flat/probeGrid.js +71 -2
  217. package/dist/render/shaders/generated/flat.wgsl.d.ts +48 -8
  218. package/dist/render/shaders/generated/flat.wgsl.js +64 -24
  219. package/dist/render/shaders/gi/composeField.wgsl.d.ts +56 -0
  220. package/dist/render/shaders/gi/composeField.wgsl.js +231 -0
  221. package/dist/render/shaders/gi/marchField.wgsl.d.ts +30 -0
  222. package/dist/render/shaders/gi/marchField.wgsl.js +141 -0
  223. package/dist/render/shaders/gi/probeBake.wgsl.d.ts +113 -0
  224. package/dist/render/shaders/gi/probeBake.wgsl.js +635 -0
  225. package/dist/render/shaders/gi/probeTrace.wgsl.d.ts +72 -0
  226. package/dist/render/shaders/gi/probeTrace.wgsl.js +261 -0
  227. package/dist/render/shaders/gi/probeVolume.wgsl.d.ts +49 -0
  228. package/dist/render/shaders/gi/probeVolume.wgsl.js +242 -0
  229. package/dist/render/shaders/gi/sampleField.wgsl.d.ts +32 -0
  230. package/dist/render/shaders/gi/sampleField.wgsl.js +134 -0
  231. package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +26 -0
  232. package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +339 -0
  233. package/dist/render/shaders/gpudriven/compact.wgsl.d.ts +29 -0
  234. package/dist/render/shaders/gpudriven/compact.wgsl.js +58 -0
  235. package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +90 -0
  236. package/dist/render/shaders/gpudriven/cull.wgsl.js +423 -0
  237. package/dist/render/shaders/gpudriven/decode.wgsl.d.ts +72 -0
  238. package/dist/render/shaders/gpudriven/decode.wgsl.js +349 -0
  239. package/dist/render/shaders/gpudriven/environment.wgsl.d.ts +44 -0
  240. package/dist/render/shaders/gpudriven/environment.wgsl.js +137 -0
  241. package/dist/render/shaders/gpudriven/fog.wgsl.d.ts +28 -0
  242. package/dist/render/shaders/gpudriven/fog.wgsl.js +107 -0
  243. package/dist/render/shaders/gpudriven/frameBlock.wgsl.d.ts +13 -0
  244. package/dist/render/shaders/gpudriven/frameBlock.wgsl.js +62 -0
  245. package/dist/render/shaders/gpudriven/materialBin.wgsl.d.ts +51 -0
  246. package/dist/render/shaders/gpudriven/materialBin.wgsl.js +112 -0
  247. package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +25 -0
  248. package/dist/render/shaders/gpudriven/materialTable.wgsl.js +43 -0
  249. package/dist/render/shaders/gpudriven/meshTransform.wgsl.d.ts +18 -0
  250. package/dist/render/shaders/gpudriven/meshTransform.wgsl.js +37 -0
  251. package/dist/render/shaders/gpudriven/present.wgsl.d.ts +43 -0
  252. package/dist/render/shaders/gpudriven/present.wgsl.js +127 -0
  253. package/dist/render/shaders/gpudriven/shade.wgsl.d.ts +127 -0
  254. package/dist/render/shaders/gpudriven/shade.wgsl.js +874 -0
  255. package/dist/render/shaders/gpudriven/shadow.wgsl.d.ts +44 -0
  256. package/dist/render/shaders/gpudriven/shadow.wgsl.js +308 -0
  257. package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.d.ts +28 -0
  258. package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.js +245 -0
  259. package/dist/render/shaders/network.wgsl.d.ts +101 -0
  260. package/dist/render/shaders/network.wgsl.js +206 -0
  261. package/dist/render/shaders/recon/motion.wgsl.d.ts +44 -0
  262. package/dist/render/shaders/recon/motion.wgsl.js +96 -0
  263. package/dist/render/shaders/recon/resolve.wgsl.d.ts +51 -0
  264. package/dist/render/shaders/recon/resolve.wgsl.js +733 -0
  265. package/dist/render/temporalAa.js +8 -33
  266. package/dist/render/textLayout.js +12 -6
  267. package/dist/render/textRenderer.d.ts +3 -1
  268. package/dist/render/textRenderer.js +4 -1
  269. package/dist/render/translucentQueue.d.ts +6 -0
  270. package/dist/render/translucentQueue.js +11 -0
  271. package/dist/render/windStreakRenderer.d.ts +2 -1
  272. package/dist/render/windStreakRenderer.js +3 -1
  273. package/dist/world/cell.d.ts +63 -0
  274. package/dist/world/cell.js +181 -0
  275. package/dist/world/cellStream.d.ts +103 -0
  276. package/dist/world/cellStream.js +198 -0
  277. package/dist/world/freeze.d.ts +81 -0
  278. package/dist/world/freeze.js +114 -0
  279. package/dist/world/rebase.d.ts +29 -0
  280. package/dist/world/rebase.js +41 -0
  281. package/package.json +8 -3
  282. package/scripts/frames.mjs +92 -0
  283. package/scripts/gpuCompute.mjs +323 -0
  284. package/scripts/png.d.mts +16 -0
  285. package/scripts/png.mjs +25 -0
  286. package/src/core/loop.ts +19 -2
  287. package/src/core/storage.ts +5 -0
  288. package/src/geometry/meshBuilder.ts +5 -1
  289. package/src/index.ts +261 -4
  290. package/src/input/input.ts +6 -1
  291. package/src/math/exact.ts +69 -3
  292. package/src/math/frustum.ts +52 -3
  293. package/src/render/backend/api.ts +42 -1
  294. package/src/render/backend/budget.ts +7 -6
  295. package/src/render/backend/createRenderer.ts +92 -3
  296. package/src/render/backend/materialChanges.ts +54 -0
  297. package/src/render/backend/select.ts +8 -0
  298. package/src/render/backend/webgl2/renderer.ts +211 -9
  299. package/src/render/backend/webgpu/buffers.ts +182 -69
  300. package/src/render/backend/webgpu/fieldCompose.ts +482 -0
  301. package/src/render/backend/webgpu/giFieldPass.ts +200 -0
  302. package/src/render/backend/webgpu/gpuDrivenPass.ts +2993 -0
  303. package/src/render/backend/webgpu/linePass.ts +4 -39
  304. package/src/render/backend/webgpu/probeBake.ts +588 -0
  305. package/src/render/backend/webgpu/renderer.ts +1481 -76
  306. package/src/render/backend/webgpu/scatterPass.ts +15 -1
  307. package/src/render/backend/webgpu/surfaceTexturePass.ts +158 -88
  308. package/src/render/causticsRenderer.ts +5 -2
  309. package/src/render/depthConvention.ts +15 -0
  310. package/src/render/deviceFeatures.ts +77 -0
  311. package/src/render/fog.ts +185 -0
  312. package/src/render/frame/alias.ts +97 -0
  313. package/src/render/frame/deps.ts +155 -0
  314. package/src/render/frame/flushGraph.ts +135 -0
  315. package/src/render/frame/graphSchedule.ts +170 -0
  316. package/src/render/frame/index.ts +52 -0
  317. package/src/render/frame/lifetime.ts +61 -0
  318. package/src/render/frame/passTimings.ts +69 -0
  319. package/src/render/frame/validate.ts +40 -0
  320. package/src/render/frame/virtual.ts +91 -0
  321. package/src/render/gi/chain.ts +225 -0
  322. package/src/render/gi/denoise.ts +276 -0
  323. package/src/render/gi/fieldScene.ts +264 -0
  324. package/src/render/gi/globalField.ts +543 -0
  325. package/src/render/gi/probeGridFit.ts +89 -0
  326. package/src/render/gi/probeTrace.ts +143 -0
  327. package/src/render/gi/probeVolume.ts +288 -0
  328. package/src/render/gi/reflection.ts +163 -0
  329. package/src/render/gi/traceField.ts +223 -0
  330. package/src/render/gi/traceScreen.ts +106 -0
  331. package/src/render/gpuScene.ts +80 -0
  332. package/src/render/gpudriven/alphaTest.ts +33 -0
  333. package/src/render/gpudriven/clusterUpload.ts +123 -0
  334. package/src/render/gpudriven/clusterWorld.ts +239 -0
  335. package/src/render/gpudriven/compact.ts +80 -0
  336. package/src/render/gpudriven/cullClusters.ts +333 -0
  337. package/src/render/gpudriven/decodeTables.ts +332 -0
  338. package/src/render/gpudriven/frustum.ts +70 -0
  339. package/src/render/gpudriven/geometryHarness.ts +51 -0
  340. package/src/render/gpudriven/hzb.ts +113 -0
  341. package/src/render/gpudriven/ibl.ts +147 -0
  342. package/src/render/gpudriven/indirect.ts +89 -0
  343. package/src/render/gpudriven/instances.ts +234 -0
  344. package/src/render/gpudriven/lit.ts +329 -0
  345. package/src/render/gpudriven/lodCut.ts +62 -0
  346. package/src/render/gpudriven/materialBin.ts +131 -0
  347. package/src/render/gpudriven/materialTable.ts +164 -0
  348. package/src/render/gpudriven/pipeline.ts +336 -0
  349. package/src/render/gpudriven/rangeAlloc.ts +122 -0
  350. package/src/render/gpudriven/sceneUpload.ts +173 -0
  351. package/src/render/gpudriven/shadeBins.ts +222 -0
  352. package/src/render/gpudriven/shadow.ts +285 -0
  353. package/src/render/gpudriven/shadowCamera.ts +406 -0
  354. package/src/render/gpudriven/streamScene.ts +575 -0
  355. package/src/render/gpudriven/surfaceFrame.ts +68 -0
  356. package/src/render/gpudriven/twoPhase.ts +214 -0
  357. package/src/render/gpudriven/visbuffer.ts +41 -0
  358. package/src/render/halfFloat.ts +22 -4
  359. package/src/render/inference/attentionTiled.ts +132 -0
  360. package/src/render/inference/denseKernels.ts +369 -0
  361. package/src/render/inference/device.ts +44 -0
  362. package/src/render/inference/deviceGraph.ts +39 -0
  363. package/src/render/inference/fuse.ts +47 -0
  364. package/src/render/inference/kernelKit.ts +120 -0
  365. package/src/render/inference/kernels.ts +18 -0
  366. package/src/render/inference/plan.ts +26 -0
  367. package/src/render/inference/reuse.ts +79 -0
  368. package/src/render/inference/runner.ts +204 -0
  369. package/src/render/inference/schedule.ts +80 -0
  370. package/src/render/inference/shapeKernels.ts +112 -0
  371. package/src/render/inference/spatialKernels.ts +220 -0
  372. package/src/render/inference/splatRaster.wgsl.ts +348 -0
  373. package/src/render/inference/splatTiles.ts +186 -0
  374. package/src/render/lineBatch.ts +4 -24
  375. package/src/render/mesh.ts +46 -1
  376. package/src/render/pass.ts +155 -10
  377. package/src/render/prefilterEnvMap.ts +33 -0
  378. package/src/render/readback.ts +73 -0
  379. package/src/render/recon/clamp.ts +113 -0
  380. package/src/render/recon/disocclusion.ts +143 -0
  381. package/src/render/recon/frameGen.ts +191 -0
  382. package/src/render/recon/frameSizes.ts +64 -0
  383. package/src/render/recon/jitter.ts +126 -0
  384. package/src/render/recon/motionVectors.ts +138 -0
  385. package/src/render/recon/reproject.ts +179 -0
  386. package/src/render/recon/resolve.ts +444 -0
  387. package/src/render/recon/tier.ts +31 -0
  388. package/src/render/reflectionProbe.ts +34 -0
  389. package/src/render/renderQuality.ts +87 -0
  390. package/src/render/screenSpaceReflection.ts +37 -3
  391. package/src/render/sdfFont.ts +2 -0
  392. package/src/render/segmentQuads.ts +39 -0
  393. package/src/render/shaders/flat/lobes.ts +35 -3
  394. package/src/render/shaders/flat/preamble.ts +25 -1
  395. package/src/render/shaders/flat/probeGrid.ts +77 -2
  396. package/src/render/shaders/generated/flat.wgsl.ts +64 -24
  397. package/src/render/shaders/gi/composeField.wgsl.ts +239 -0
  398. package/src/render/shaders/gi/marchField.wgsl.ts +146 -0
  399. package/src/render/shaders/gi/probeBake.wgsl.ts +649 -0
  400. package/src/render/shaders/gi/probeTrace.wgsl.ts +269 -0
  401. package/src/render/shaders/gi/probeVolume.wgsl.ts +246 -0
  402. package/src/render/shaders/gi/sampleField.wgsl.ts +140 -0
  403. package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +343 -0
  404. package/src/render/shaders/gpudriven/compact.wgsl.ts +59 -0
  405. package/src/render/shaders/gpudriven/cull.wgsl.ts +433 -0
  406. package/src/render/shaders/gpudriven/decode.wgsl.ts +373 -0
  407. package/src/render/shaders/gpudriven/environment.wgsl.ts +141 -0
  408. package/src/render/shaders/gpudriven/fog.wgsl.ts +110 -0
  409. package/src/render/shaders/gpudriven/frameBlock.wgsl.ts +62 -0
  410. package/src/render/shaders/gpudriven/materialBin.wgsl.ts +116 -0
  411. package/src/render/shaders/gpudriven/materialTable.wgsl.ts +46 -0
  412. package/src/render/shaders/gpudriven/meshTransform.wgsl.ts +37 -0
  413. package/src/render/shaders/gpudriven/present.wgsl.ts +129 -0
  414. package/src/render/shaders/gpudriven/shade.wgsl.ts +884 -0
  415. package/src/render/shaders/gpudriven/shadow.wgsl.ts +322 -0
  416. package/src/render/shaders/gpudriven/visbufferRaster.wgsl.ts +251 -0
  417. package/src/render/shaders/network.wgsl.ts +238 -0
  418. package/src/render/shaders/recon/motion.wgsl.ts +101 -0
  419. package/src/render/shaders/recon/resolve.wgsl.ts +741 -0
  420. package/src/render/temporalAa.ts +9 -33
  421. package/src/render/textLayout.ts +12 -6
  422. package/src/render/textRenderer.ts +5 -2
  423. package/src/render/translucentQueue.ts +11 -0
  424. package/src/render/windStreakRenderer.ts +4 -2
  425. package/src/world/cell.ts +231 -0
  426. package/src/world/cellStream.ts +278 -0
  427. package/src/world/freeze.ts +157 -0
  428. package/src/world/rebase.ts +56 -0
@@ -0,0 +1,728 @@
1
+ /**
2
+ * The GPU-driven frame, as commands on a real encoder.
3
+ *
4
+ * **Every stage this runs already existed, twice.** `gpudriven/*.ts` is the arithmetic in
5
+ * TypeScript, `shaders/gpudriven/*.wgsl.ts` is the same arithmetic in WGSL, and
6
+ * `scripts/gpu-parity.mjs` runs both over generated input on a real device until they agree —
7
+ * nine checks as this was written. `gpudriven/pipeline.ts` says what each stage reads and writes, as
8
+ * frame-graph edges, and **the frame is scheduled by it**: each `prepare` records the stages,
9
+ * `scheduleGraph` keeps the ones something reads, and this encodes those in the order kept. What
10
+ * was missing, and what this is, is the encoder: the buffers, the bind groups, the targets and the
11
+ * two indirect draws.
12
+ *
13
+ * **It is a contributed pass, not a branch inside the renderer, and that is the design.**
14
+ * `registerPass` hands a definition a `GPUDevice` at registration and a `GPUCommandEncoder` once a
15
+ * frame before the frame's own render pass opens — which is exactly the window a pipeline that
16
+ * fills its own targets needs, and it is the seam `pass.ts` exists to provide. The alternative is
17
+ * rerouting `drawMesh` through clusters, which would mean a second copy of the standard material
18
+ * to draw anything at all; the plan refuses that in the same words this file does.
19
+ * `createRenderer({ pipeline: 'gpu-driven' })` is the *permission* — it fails at boot on a backend
20
+ * that cannot run this — and this is the implementation. A consumer states both.
21
+ *
22
+ * **What it draws.** Vertex colour times a material tint, one directional term with its specular
23
+ * highlight and its shadow, the forward path's hemispheric ambient or a baked probe's irradiance,
24
+ * the room a surface reflects, metalness, a glow scaled by the frame's clock, and DriftTexture
25
+ * materials decoded per pixel — the standard material's subset, which `CAPABILITIES.md` §3 lists
26
+ * with what it leaves out. The rigs that draw it are `DRAFT_SCENES`, never `SCENES`.
27
+ *
28
+ * **A mesh wholly outside the view is dropped before the cut reads a cluster of it**, since
29
+ * 2026-09-17: `instanceCull` flags each mesh against the frustum, the cut leaves a flagged mesh's
30
+ * clusters unselected, and the cluster cull skips whatever the cut did not select. `instances.ts`
31
+ * says why the flag is read there and not by the cluster cull: eight storage bindings a stage, and
32
+ * the cluster cull already had seven.
33
+ *
34
+ * **The shadow is this pipeline's own, and it costs what it costs.** One depth-only draw of every
35
+ * cluster from the light, into a 2048 map: **0.46 ms** on a million triangles, which is nearly as
36
+ * much again as the frame itself. There is no culling in it — the frame's cull is against the
37
+ * camera and a caster behind the viewer still shadows what is in front of them — so the obvious
38
+ * next measurement is a cull against the light's own box.
39
+ *
40
+ * **The visibility buffer is copied to a buffer once a frame, and that is a real cost.** The
41
+ * binning passes read `array<u32>` and a render attachment cannot be bound as one. The copy is
42
+ * ordered and correct where a fragment shader writing storage is neither — two fragments passing
43
+ * the depth test for one pixel race, and the loser can land last. `width` is rounded up to a
44
+ * multiple of 64 so that `bytesPerRow` is a multiple of 256 with no padding, which is what keeps
45
+ * the buffer linear: a padded row would put undefined words where the binning reads pixels, and
46
+ * an undefined word that happens to be zero is triangle 0 of cluster 0 — a real triangle.
47
+ *
48
+ * **The shading's pixel centre is the flipped row, and this is the one convention trap here.**
49
+ * WebGPU's framebuffer origin is the top-left, so row zero is where clip `y` is `+1`; `screenOf`
50
+ * maps clip `y = +1` to `height`. So the pixel at framebuffer row `y` is at screen `height - y`,
51
+ * and the flip is applied to the pixel rather than to the shared function — which is checked
52
+ * against the reference and must not learn about a framebuffer. Flipping all four points of a
53
+ * barycentric evaluation leaves the weights unchanged, which is why this is the whole of it. It is
54
+ * true of either projection, because it is a property of the viewport transform and not of the
55
+ * matrix.
56
+ *
57
+ * **The projection is `depthCorrection` and not `clipCorrection`.** The Y negation in the latter
58
+ * cancels the one `naga` writes into every *generated* vertex entry point; nothing here was
59
+ * generated, so taking it mirrors the picture — and mirrors the winding with it, which is how it
60
+ * reads as a culling problem. `PassDevice` carries both matrices and says which is which.
61
+ */
62
+ import { type FogOptions } from '../../fog.ts';
63
+ import { StreamingScene } from '../../gpudriven/streamScene.ts';
64
+ import { type GpuDrivenTextures } from '../../gpudriven/materialTable.ts';
65
+ import type { PassContext, PassDefinition, PassDevice, PrepareContext } from '../../pass.ts';
66
+ /**
67
+ * Floats a material owns: tint rgb, emissive, roughness, specular, reflectivity, metalness.
68
+ *
69
+ * Five blocks since 2026-09-17 — the three texture programs, the UV scale and the map strengths
70
+ * joined the eight — and `gpudriven/materialTable.ts` writes them.
71
+ */
72
+ export declare const MATERIAL_FLOATS = 24;
73
+ /** Floats a vertex in the one interleaved buffer: position, normal, colour, uv. */
74
+ export declare const VERTEX_FLOATS = 12;
75
+ /**
76
+ * What the frame is timed in, one pair of timestamps each.
77
+ *
78
+ * **Measured rather than reasoned, because the whole wave rests on a cost claim.** A frame-time
79
+ * reading from `requestAnimationFrame` measures the submission loop and nothing else — with vsync
80
+ * off it reports half a millisecond for a scene of a million triangles, because the device is
81
+ * still working when the callback returns. These are the device's own clock.
82
+ *
83
+ * Only where the device has `timestamp-query`, which `createRenderer` asks for when
84
+ * `quality.gpuTiming` is set — `?gputiming=1` on the harness pages. Without it every figure is
85
+ * `null`, which is `gpuTimer.ts`'s rule: zero is a claim and unmeasured is not zero.
86
+ */
87
+ export declare const GPU_DRIVEN_STAGES: readonly ['shadow', 'instanceCull', 'cut', 'phaseOneDraw', 'pyramid', 'phaseTwoCull', 'phaseTwoDraw', 'blendCull', 'blendDraw', 'blendResolve', 'bin', 'shade'];
88
+ export type GpuDrivenStage = (typeof GPU_DRIVEN_STAGES)[number];
89
+ /**
90
+ * The frame's four draw lists, each counted by the clusters it drew: phase one (what was visible
91
+ * last frame and still is), phase two (what the pyramid found newly visible), the blended half, and
92
+ * the light's map.
93
+ *
94
+ * **The occlusion cull's own figure.** A cluster the cull kept is one instance of its list's
95
+ * indirect draw, so the second word of each list's arguments is that list's count — the number a
96
+ * city in a street and above its roofs is there to show. Read back only where `countDrawn` asks.
97
+ */
98
+ export declare const GPU_DRIVEN_LISTS: readonly ['phaseOne', 'phaseTwo', 'blend', 'shadow'];
99
+ export type GpuDrivenList = (typeof GPU_DRIVEN_LISTS)[number];
100
+ /** What a material tints and emits. */
101
+ export interface GpuDrivenMaterial {
102
+ readonly tint: readonly [number, number, number];
103
+ /** Added to the lit colour as `albedo * emissive`. Zero for an ordinary surface. */
104
+ readonly emissive: number;
105
+ /**
106
+ * 0 is a mirror and 1 is fully rough. Defaults to 1, which is the matte this pipeline had.
107
+ *
108
+ * **Below 0.1 the highlight gets *dimmer* as the surface gets smoother**, which is the forward
109
+ * path's own lobe and is recorded in `docs/IMPROVEMENTS.md` rather than fixed here — the
110
+ * published scenes are calibrated against the shader that has it.
111
+ */
112
+ readonly roughness?: number;
113
+ /**
114
+ * How much of the light the surface returns as a highlight. Defaults to 0.
115
+ *
116
+ * **Zero is what keeps this from moving anything**: a material that says nothing about shininess
117
+ * renders exactly the frame it rendered when the lit expression was four lines.
118
+ */
119
+ readonly specular?: number;
120
+ /**
121
+ * How much of the environment the surface returns, before angle and roughness. Defaults to 0.
122
+ *
123
+ * With no probe bound this reflects the same two-colour gradient the ambient comes from, which
124
+ * is what the forward path reflects in the same situation — see `gpudriven/ibl.ts` for the two
125
+ * weights and why the selector between them is exactly 0 or exactly 1.
126
+ */
127
+ readonly reflectivity?: number;
128
+ /**
129
+ * 0 is a dielectric and 1 is a metal. Defaults to 0.
130
+ *
131
+ * **One number a material, where `flat/main.ts` reads one texel of an ORM map.** That is the
132
+ * whole of the difference and it is a subset rather than a second opinion: every expression it
133
+ * enters is the forward path's with a constant standing in for a fetch. See `gpudriven/lit.ts`
134
+ * for the four of them.
135
+ *
136
+ * **A metal reflects whether or not `reflectivity` asked for it**, because a metal is nothing but
137
+ * its reflection — and with no probe bound, what it reflects is the sky-and-ground gradient. A
138
+ * metal in a scene with neither is a smooth gradient rather than a picture, which is a statement
139
+ * about the scene rather than about the material.
140
+ */
141
+ readonly metalness?: number;
142
+ /**
143
+ * The material's maps, as DriftTexture decode programs, decoded per shaded pixel on the device.
144
+ *
145
+ * **A material with none uploads exactly the entry it uploaded before textures existed**, so the
146
+ * frame it draws is unchanged — the promise every term in this pipeline makes. See
147
+ * `gpudriven/materialTable.ts` for what each program feeds and `decodeTables.ts` for the limits.
148
+ */
149
+ readonly textures?: GpuDrivenTextures;
150
+ /**
151
+ * Discard a fragment whose base-colour alpha is below this. Zero means no test.
152
+ *
153
+ * **The test happens in the raster rather than in the shading pass**, because that is where a
154
+ * pixel learns which triangle owns it: a discard in `shade` would come after the visibility
155
+ * buffer already held the leaf, and what stood behind it was never written.
156
+ *
157
+ * Zero is the default and it skips the fetch outright, so a material that says nothing about
158
+ * cutout draws exactly the frame it drew before — the promise every term in this pipeline has
159
+ * made since it was four lines. A cluster carries one material, so the branch is coherent across
160
+ * every fragment of a draw rather than divergent within one.
161
+ *
162
+ * **It needs a `textures.baseColour` program to mean anything.** With no base-colour map there is
163
+ * no alpha to test, and the raster reads 1 — so a cutoff at or below 1 keeps every fragment and
164
+ * one above 1 discards the whole surface. Both are what the material asked for, stated here
165
+ * because an invisible mesh is a hard thing to attribute.
166
+ */
167
+ readonly alphaCutoff?: number;
168
+ /**
169
+ * Draw this material's clusters blended instead of into the visibility buffer. Defaults to false.
170
+ *
171
+ * **A visibility buffer stores one surface a pixel, so it cannot hold a blend at all** — that is
172
+ * architecture rather than an omission. What a blended material asks for is that its clusters
173
+ * skip the opaque half entirely and be drawn again by a second raster that shades in its own
174
+ * fragment stage and writes the two weighted-transparency targets. The cut runs a second time to
175
+ * find them, and a scene with no blended material runs neither stage.
176
+ *
177
+ * **The opacity is `tint`'s fourth component, not this**; this only says which half of the frame
178
+ * the surface belongs to. See `blendRaster.wgsl.ts` for what the second half does with it, and
179
+ * `orderIndependent.ts` for the weight and what it approximates.
180
+ */
181
+ readonly blend?: boolean;
182
+ /**
183
+ * How much of a blended surface is its own colour rather than what is behind it. Defaults to 1.
184
+ *
185
+ * Read only where `blend` is set. One is a solid pane, which is what a material that asked to
186
+ * blend and said nothing else gets — visible, and therefore findable.
187
+ */
188
+ readonly opacity?: number;
189
+ }
190
+ /** What the pass needs told once a frame, before `beginFrame`. */
191
+ export interface GpuDrivenView {
192
+ /** The camera's view-projection, built the way the forward path builds one. */
193
+ readonly viewProj: ArrayLike<number>;
194
+ readonly eye: readonly [number, number, number];
195
+ /** Toward the light, normalised, as `Environment.directionalDir` is. */
196
+ readonly lightDir: readonly [number, number, number];
197
+ readonly lightColour: readonly [number, number, number];
198
+ readonly ambient: readonly [number, number, number];
199
+ readonly ambientGround: readonly [number, number, number];
200
+ /**
201
+ * The medium between the camera and everything this pass draws. Absent is no fog at all.
202
+ *
203
+ * **Absent means a density of zero and the medium mode**, which makes `mediumFog` exactly zero at
204
+ * every distance — arithmetically the frame this pipeline drew before it had a haze, which is the
205
+ * promise every term here has made since it was four lines. The three rigs pass nothing.
206
+ *
207
+ * **It is the same expression the forward path fogs with**, held to `render/fog.ts` by
208
+ * `scripts/gpu-parity.mjs`; a scene drawing through both pipelines at once — which is what the
209
+ * voxel sandbox's port is — would otherwise have its terrain recede at a different rate than its
210
+ * mobs do.
211
+ */
212
+ readonly fog?: FogOptions;
213
+ /**
214
+ * The projected error a cluster may carry before its children are drawn instead, in pixels.
215
+ *
216
+ * Larger keeps coarser clusters and draws fewer triangles. `lodCut.ts` is what reads it.
217
+ */
218
+ readonly lodThreshold: number;
219
+ /** The vertical field of view in radians, which the cut needs to project an error. */
220
+ readonly fovY: number;
221
+ /**
222
+ * How much of the directional light the shadow map may take away. 0 is off and 1 is the whole
223
+ * of it.
224
+ *
225
+ * **Off is exact rather than nearly**: `shadowFactor` returns 1 before any arithmetic at zero,
226
+ * so a frame that asks for none is the frame this pipeline drew before it had a map. Defaults
227
+ * to 1, because a pipeline that renders a map and then ignores it is a cost with no picture.
228
+ */
229
+ readonly shadowStrength?: number;
230
+ /**
231
+ * The simulation's clock, in seconds, which an animated DriftTexture reads. **Never a wall
232
+ * clock**: a flipbook read off one would replay differently. Defaults to 0.
233
+ */
234
+ readonly time?: number;
235
+ /**
236
+ * The frame's emissive gain and night factor, as `Environment` carries them. **Both default to
237
+ * 1**, which is the glow this pipeline drew before it read either.
238
+ *
239
+ * `flat/main.ts` scales every emission by their product, so a forward frame whose clock says it
240
+ * is day glows nowhere. A caller drawing both pipelines from one `Environment` passes its two
241
+ * numbers here, or the second pipeline glows where the first does not.
242
+ */
243
+ readonly emissiveGain?: number;
244
+ readonly nightFactor?: number;
245
+ }
246
+ /**
247
+ * What the pass is told once, at construction, about the map it renders.
248
+ *
249
+ * **Its own defaults rather than a `RenderQuality`**, because a contributed pass is handed a
250
+ * device and not the frame's settings — `PassDevice` is the whole of what it gets. The numbers are
251
+ * the forward path's, taken from `DEFAULT_RENDER_QUALITY` so the two pipelines fade a shadow out
252
+ * over the same distance and give up on the same low sun rather than nearly.
253
+ */
254
+ export interface GpuDrivenShadowOptions {
255
+ /** Texels a side. 2048 is `directionalShadowMapSize`, and a draft can afford it. */
256
+ readonly mapSize?: number;
257
+ /** Metres a shadow travels along the ground before it has dissolved. */
258
+ readonly maxDistance?: number;
259
+ /** The steepest sun that still casts, as horizontal metres per vertical one. */
260
+ readonly maxSlope?: number;
261
+ /** Taps of the twelve the filter may take. Fewer is cheaper and harder-edged. */
262
+ readonly taps?: number;
263
+ /**
264
+ * Hand the frame this pass's depth as well as its colour, so both pipelines share one.
265
+ *
266
+ * **Off by default, because every consumer before 2026-09-18 drew nothing but this pipeline.**
267
+ * For them the frame's depth is something nothing reads and a write into it is a change to a
268
+ * frame they did not ask to change; the three GPU-driven rigs leave it alone, which is what keeps
269
+ * them 0 of 921,600 and keeps them the control.
270
+ *
271
+ * **On, it is what lets a forward-path mesh stand behind GPU-driven geometry.** Without it the
272
+ * two have no depth relationship at all and no ordering of them produces one — which is the gap
273
+ * the voxel sandbox's port found, where mobs, particles, falling blocks and the block highlight
274
+ * all draw on the forward path. `scripts/depth-share-check.mjs` is the gate.
275
+ *
276
+ * It costs one more sampled texture in the blit and a fragment depth write over the pixels this
277
+ * pipeline covered. A pixel it did not cover is discarded before either, so the sky keeps the
278
+ * depth the frame already had.
279
+ */
280
+ readonly presentDepth?: boolean;
281
+ /**
282
+ * Metres around the eye the map covers once the scene is larger than that. See `fitShadow`.
283
+ *
284
+ * **Unset, the map is fitted to the whole scene, as it always was** — right for rigs a few
285
+ * metres across and the fit all three were photographed with. A world sets it: the voxel
286
+ * sandbox's port at radius 14 is a sphere hundreds of metres across, over which one map has
287
+ * texels a quarter of a metre wide. Past the radius the map follows the eye, snapped to whole
288
+ * texels, and reaches toward the sun as far as the scene does.
289
+ */
290
+ readonly followRadius?: number;
291
+ }
292
+ export declare class GpuDrivenPass implements PassDefinition {
293
+ readonly label = "driftengine.gpu-driven";
294
+ private readonly scene;
295
+ private readonly materials;
296
+ private device;
297
+ private width;
298
+ private height;
299
+ /** The width the targets are actually allocated at: `width` rounded up. See `WIDTH_ALIGN`. */
300
+ private stride;
301
+ private readonly frameParams;
302
+ private readonly planes;
303
+ /** The light's box as six planes, from the matrix the lookup reads. */
304
+ private readonly lightPlanes;
305
+ private readonly cullSettings;
306
+ private readonly lodParams;
307
+ private readonly binSettings;
308
+ private readonly viewProj;
309
+ private readonly corrected;
310
+ /** The light's own, in the OpenGL convention, and the two corrections of it. */
311
+ private readonly light;
312
+ private readonly lightRaster;
313
+ private readonly lightLookup;
314
+ /** The scene's bounding sphere, computed once: centre and radius. */
315
+ private readonly bounds;
316
+ /** Which programs each material names, and the programs themselves, once each. */
317
+ private readonly programs;
318
+ /** Those programs flattened into what the shading pass binds. */
319
+ private readonly decode;
320
+ /**
321
+ * Every cluster's bounds, cone and error **through the transform of the mesh it belongs to**.
322
+ *
323
+ * Computed at construction and held, because it is what both the cull buffer and the LOD buffer
324
+ * are written from and what the light's box is fitted to — one transform, read three times. This
325
+ * pipeline never moves a mesh, so it is a property of the scene; a pipeline that did would have
326
+ * to rewrite these two buffers on the frame it moved one.
327
+ */
328
+ /**
329
+ * Each mesh's world sphere, round its clusters' world spheres — `instances.ts`. Fitted here
330
+ * rather than at mount so a cluster naming a mesh the transforms do not have is refused where the
331
+ * scene was handed in.
332
+ */
333
+ private readonly meshCount;
334
+ private shadowSpan;
335
+ private readonly shadowSize;
336
+ /** What the frame offered this time, or null. Read in `writeFrame` and nowhere else. */
337
+ private environment;
338
+ private readonly shadowMaxDistance;
339
+ private readonly shadowMaxSlope;
340
+ private readonly shadowTaps;
341
+ private clipCorrection;
342
+ private view;
343
+ private clusterCull;
344
+ private clusterLod;
345
+ private clusterMeta;
346
+ private instanceSpheres;
347
+ private indices;
348
+ private vertices;
349
+ private transformBuffer;
350
+ private materialOf;
351
+ private materialTable;
352
+ private jobs;
353
+ /**
354
+ * **The light's own front half, in the camera's two phases**: the camera's cut with no mesh
355
+ * hidden, a cull against the light's box from the sun's side, and a compaction into the list each
356
+ * half of the map draws — phase one what the light kept last frame, phase two the rest against a
357
+ * pyramid of what phase one drew. Every buffer the light writes is its own. See `drawShadow`.
358
+ */
359
+ private shadowList;
360
+ private shadowListTwo;
361
+ private shadowArgs;
362
+ private shadowArgsTwo;
363
+ private shadowSelected;
364
+ private shadowKeep;
365
+ private shadowPlanes;
366
+ private shadowCullSettings;
367
+ private shadowCullSettingsTwo;
368
+ /**
369
+ * The light's cull settings: its cone eye, stood `LIGHT_CONE_DISTANCE` toward the sun from the
370
+ * camera's (`lightConeEye`), whether to read the pyramid, the pyramid's shape, the count and the
371
+ * cones, which are on. One array, written into phase one's buffer and then phase two's.
372
+ */
373
+ private readonly shadowCullValues;
374
+ private readonly shadowConeEye;
375
+ private shadowCompactSettings;
376
+ private shadowCompactSettingsTwo;
377
+ /**
378
+ * **The light's history, one word a cluster, in two halves that swap each frame the map is
379
+ * drawn** — and only then, so a frame with no shadow leaves the next one reading what the last
380
+ * one wrote. One history per view, as `twoPhase.ts` says: the camera's would put what the camera
381
+ * saw into the light's phase one.
382
+ */
383
+ private shadowHistories;
384
+ private shadowFlipped;
385
+ /**
386
+ * The light's pyramid: half its map and every level below it (`shadowPyramidBase`), stored
387
+ * turned over so the camera's reduction and cull read it, and where each level starts.
388
+ */
389
+ private shadowHzb;
390
+ private shadowLevels;
391
+ private shadowLevelStart;
392
+ private shadowSeedSize;
393
+ /** The raster's matrix with its depth turned over, which is what the light's cull projects by. */
394
+ private shadowCullMatrix;
395
+ private readonly lightCull;
396
+ private instanceNone;
397
+ private shadowLodGroup;
398
+ private shadowCullGroups;
399
+ /** Each half's compaction, for each way round the history is: `[flipped][phase]`. */
400
+ private shadowCompactGroups;
401
+ private shadowSeedGroup;
402
+ private shadowReduceGroups;
403
+ private shadowSeedPipeline;
404
+ private shadowMatrix;
405
+ private shadowTexture;
406
+ private decodeNodes;
407
+ private decodeWeights;
408
+ private latents;
409
+ private latentsView;
410
+ private latentClamp;
411
+ private latentRepeat;
412
+ private shadowView;
413
+ /**
414
+ * What is bound as the probe where the frame has none.
415
+ *
416
+ * **One texel, one layer, and it exists because a bind group must supply every binding.** The
417
+ * alternative is a second pipeline and a second layout for the unlit case, which is two copies
418
+ * of the shading pass to avoid one 4-byte texture. The renderer binds a stand-in in exactly the
419
+ * same situation and for exactly the same reason — see `depthPass.ts` on the peel.
420
+ */
421
+ private emptyEnvironment;
422
+ private emptyEnvironmentView;
423
+ private emptySampler;
424
+ /** The probe the last frame offered, so the bind group is rebuilt only when it changes. */
425
+ private environmentView;
426
+ private environmentSampler;
427
+ private planesBuffer;
428
+ private viewProjBuffer;
429
+ /**
430
+ * The two numbers the raster's alpha test needs and nothing else in that stage carries.
431
+ *
432
+ * **A buffer of its own rather than four more floats on `viewProjBuffer`**, which the instance
433
+ * cull also binds and declares as `array<f32, 16>`: growing a buffer two shaders read means both
434
+ * have an opinion about what is past the sixteenth float, and one of them would be wrong on the
435
+ * day somebody used the spare.
436
+ */
437
+ private rasterParams;
438
+ /**
439
+ * The transparent half's own buffers, textures and pipelines.
440
+ *
441
+ * **`zeroHistory` is what makes the cut's second run see every cluster.** The compaction
442
+ * filters on `history[i] != 0` against its phase, which is how the two occlusion phases divide
443
+ * the scene between them; the blended set is not divided, so it is compacted as phase one against
444
+ * a history that is all zeros — every cluster then lands on the side that draws. `historySink` is
445
+ * the history that run writes and nothing reads, which is the price of leaving the compaction
446
+ * shader alone rather than growing it a third phase nothing else would ever take.
447
+ */
448
+ private blendList;
449
+ private blendArgs;
450
+ private blendLodBuffer;
451
+ private blendCompactSettings;
452
+ private zeroHistory;
453
+ private historySink;
454
+ private oitAccum;
455
+ private oitReveal;
456
+ private oitAccumView;
457
+ private oitRevealView;
458
+ private blendPipeline;
459
+ private blendResolvePipeline;
460
+ private blendLodGroup;
461
+ private blendCompactGroup;
462
+ private blendRasterGroup;
463
+ private blendResolveGroup;
464
+ /** Seven floats: the cut's six, and a seventh saying which half of the frame it is selecting. */
465
+ private readonly lodParamsBlend;
466
+ private readonly rasterParamValues;
467
+ /** One a phase, for the reason `writeFrame` gives. */
468
+ /** Phase one, phase two, and the blended run: see `CULL_CONES` for why the third exists. */
469
+ private cullBuffers;
470
+ private lodBuffer;
471
+ /** One word a mesh, written by the instance cull and read by the cut. */
472
+ private instanceFlags;
473
+ private frameBuffer;
474
+ private selected;
475
+ private keep;
476
+ private history;
477
+ private drawn;
478
+ private lists;
479
+ private args;
480
+ private phaseSettings;
481
+ private visibilityTexture;
482
+ private depthTexture;
483
+ private colourTexture;
484
+ private colourView;
485
+ private visibility;
486
+ private hzb;
487
+ private levelStart;
488
+ private levels;
489
+ private binCounts;
490
+ private binOffsets;
491
+ private binCursors;
492
+ private binDispatch;
493
+ private binPixels;
494
+ private binSettingsBuffer;
495
+ private instancePipeline;
496
+ private lodPipeline;
497
+ private cullPipeline;
498
+ private compactPipeline;
499
+ private seedPipeline;
500
+ private reducePipeline;
501
+ private countPipeline;
502
+ private offsetsPipeline;
503
+ private scatterPipeline;
504
+ private shadePipeline;
505
+ private rasterPipeline;
506
+ private shadowPipeline;
507
+ private blitPipeline;
508
+ /** See `GpuDrivenShadowOptions.presentDepth`: what the consumer asked for. */
509
+ private readonly presentDepthAsked;
510
+ /**
511
+ * Whether the blit hands the frame this pass's depth: when asked, and whenever the renderer
512
+ * reconstructs, which reprojects every pixel's history through that depth. Settled at `init`,
513
+ * where the device says which; the pipeline follows it.
514
+ */
515
+ private presentDepth;
516
+ /**
517
+ * The frame's jitter, as `prepare` was last handed it: zero until then, and on every frame that
518
+ * is not reconstructed. See `PrepareContext.jitter`.
519
+ */
520
+ private jitter;
521
+ /** See `GpuDrivenShadowOptions.followRadius`. Unset, the map is fitted to the whole scene. */
522
+ private readonly shadowFollow;
523
+ private frameDepthFormat;
524
+ private lodGroup;
525
+ private instanceGroup;
526
+ private compactGroups;
527
+ private rasterGroups;
528
+ private shadowGroup;
529
+ private shadowGroupTwo;
530
+ private jobGroups;
531
+ private cullGroups;
532
+ private seedGroup;
533
+ private reduceGroups;
534
+ private countGroup;
535
+ private offsetsGroup;
536
+ private scatterGroup;
537
+ private shadeGroup;
538
+ private blitGroup;
539
+ private queries;
540
+ private queryResolve;
541
+ private queryRead;
542
+ private queryCopied;
543
+ private queryMapping;
544
+ private readonly stageMs;
545
+ private timed;
546
+ /**
547
+ * **Whether phase two and the blended run test clusters against the depth pyramid** — the
548
+ * occlusion cull — **and the light's second half against its own.** On by default and off only
549
+ * to measure it: the instance cull is the frustum alone and phase one never reads a pyramid, so
550
+ * with this off each view draws every cluster its frustum and cones keep, and the drawn count's
551
+ * difference is the occlusion cull's own share. The pyramids are still built; a frame that
552
+ * measures does not also save their cost.
553
+ */
554
+ occlusion: boolean;
555
+ /**
556
+ * **Whether the pass reads back how many clusters each list drew.** Off, it encodes nothing for
557
+ * it and makes no buffer, which is why it is asked for rather than always on: the figure is a
558
+ * demo's readout and a measurement's, and a consumer who reads neither pays nothing.
559
+ */
560
+ countDrawn: boolean;
561
+ private counts;
562
+ private countsCopied;
563
+ private countsMapping;
564
+ private readonly drawnCounts;
565
+ private counted;
566
+ /** Whether `history` and `drawn` have been swapped an odd number of times. */
567
+ private flipped;
568
+ private readonly graph;
569
+ private readonly scheduled;
570
+ private readonly graphScratch;
571
+ private readonly shape;
572
+ private gradeWarned;
573
+ constructor(scene: StreamingScene, materials: readonly GpuDrivenMaterial[], shadow?: GpuDrivenShadowOptions);
574
+ /** How many clusters the scene holds, which every per-cluster dispatch is sized by. */
575
+ get clusterCount(): number;
576
+ /**
577
+ * What this frame is looking at. Called before `beginFrame`, once, by the caller.
578
+ *
579
+ * Held by reference rather than copied: the caller owns a `GpuDrivenView` it fills each frame,
580
+ * and copying it here would allocate on a per-frame path for no gain.
581
+ */
582
+ setView(view: GpuDrivenView): void;
583
+ /**
584
+ * Size the targets. Called on mount and whenever the frame's own size changes.
585
+ *
586
+ * **Dispose and recreate rather than resize**, which is `passTarget.ts`'s rule and is right for
587
+ * the same reason: a resize is not a per-frame path and a mutable target is one more thing to
588
+ * keep consistent.
589
+ */
590
+ resize(width: number, height: number): void;
591
+ init(device: PassDevice): void;
592
+ private storage;
593
+ private empty;
594
+ /**
595
+ * Every buffer the scene lives in, at its declared capacity.
596
+ *
597
+ * **Called `buildStatic` until 2026-09-18**, and the word was the whole of what changed: these
598
+ * are sized by `scene.capacity` rather than by what the scene currently holds, so there is room
599
+ * for a mesh that has not arrived yet. A static scene declares a capacity equal to its content,
600
+ * so nothing about it moves.
601
+ *
602
+ * **The scene writes two of them itself and keeps no copy of either.** `vertices` and `indices`
603
+ * are made empty at capacity and handed to the scene as a `GeometrySink`; the interleave —
604
+ * twelve floats a vertex, position, normal, colour, uv and glow — is the scene's. It is one
605
+ * buffer rather than five because of a device limit: a compute stage may bind eight storage
606
+ * buffers by default, and the shading pass wanted twelve and was refused at pipeline creation.
607
+ *
608
+ * **The two culling buffers are already in the world.** What a bake writes is a cluster in its
609
+ * mesh's own space, and this pass used to upload that — while the raster and the shading both
610
+ * multiplied by `transforms[mesh]`. A mesh placed anywhere but the origin was then frustum-culled
611
+ * against the wrong region, cone-culled with the wrong orientation, LOD-cut on a misprojected
612
+ * error and occlusion-tested on the wrong rectangle, and every rig in `DRAFT_SCENES` stood at the
613
+ * origin so nothing ever said so. `StreamingScene` computes them when a mesh is placed.
614
+ */
615
+ private buildBuffers;
616
+ private buildPipelines;
617
+ /**
618
+ * The groups that name `history` and `drawn`, rebuilt when the two swap.
619
+ *
620
+ * **Two sets rather than a copy**, because the alternative is copying a buffer the size of the
621
+ * cluster count every frame to keep one binding pointing at the right half. A bind group is
622
+ * cheap to build and this happens once a frame; making it twice and alternating would be
623
+ * cheaper still, and is what this does — `flipped` picks the pair.
624
+ */
625
+ private buildSwappedGroups;
626
+ private disposeTargets;
627
+ /**
628
+ * A pyramid's levels over a base this size, down to one texel: each level padded so its byte
629
+ * offset is one a bind group may name, with its own size block — the source's shape, where it
630
+ * starts, and where its output goes, because the reduction addresses both ends of one buffer
631
+ * itself (see `HZB_REDUCE_WGSL`). The camera's is over the frame; the light's over half its map.
632
+ */
633
+ private pyramidLevels;
634
+ private buildTargets;
635
+ private buildSizedGroups;
636
+ /**
637
+ * Take the frame's probe, and say whether the shading pass's bind group has to be rebuilt.
638
+ *
639
+ * **Compared by identity rather than copied**, because a texture view is the thing that changes
640
+ * when a grid is rebaked at a different size and nothing else in the block does. A frame that
641
+ * offers the same view as the last one rebuilds nothing.
642
+ */
643
+ private adoptEnvironment;
644
+ /** Fill the per-frame blocks from the view the caller set. */
645
+ /**
646
+ * Upload the records the scene has changed since the last frame (its geometry went up when it
647
+ * was placed), and nothing else.
648
+ *
649
+ * **Before anything is recorded into the encoder, because a dispatch reads what a queue write
650
+ * has not landed.** `queue.writeBuffer` is ordered against other queue work and *not* against an
651
+ * encoder's commands, which this backend has already paid for once: rewriting one params buffer
652
+ * between dispatches gave every dispatch the last write, and the fix there was one bind group per
653
+ * dispatch at a 256-aligned offset. Here the ordering is simply respected.
654
+ *
655
+ * **A frame that changed nothing uploads nothing**, which is what makes a static scene cost what
656
+ * it cost before this existed.
657
+ */
658
+ private applyStream;
659
+ /** The radius of the sphere the shadow camera is fitted to. Diagnostic, and a test reads it. */
660
+ shadowExtent(): number;
661
+ private writeFrame;
662
+ prepare(ctx: PrepareContext): void;
663
+ /**
664
+ * One stage of the frame, onto the encoder. `pipeline.ts` says what each reads and writes, and
665
+ * the schedule says whether it runs; this is what it issues.
666
+ */
667
+ private encodeStage;
668
+ /**
669
+ * The device milliseconds each stage took, or null where nothing measured them.
670
+ *
671
+ * One frame behind, because a timestamp is read back and a readback that blocked would be the
672
+ * measurement changing what it measures. `null` until a frame has completed a map.
673
+ */
674
+ stageTime(stage: GpuDrivenStage): number | null;
675
+ /** Every stage added up, which is what the pipeline costs the device. */
676
+ get totalMs(): number | null;
677
+ /** The pair of slots a stage writes, or nothing where the device cannot time. */
678
+ private writesFor;
679
+ /**
680
+ * Ask for last frame's figures, once the frame that recorded them has been submitted.
681
+ *
682
+ * **At the start of the next frame rather than at the end of this one**, which is the whole of
683
+ * the care this needs: `mapAsync` settles against the work already enqueued, and the copy is
684
+ * still sitting in an encoder the renderer has not submitted yet.
685
+ */
686
+ private readTimings;
687
+ /**
688
+ * How many clusters `list` drew, one frame behind as the stage times are, or null until a frame
689
+ * has been read — and null always where `countDrawn` was not asked for.
690
+ */
691
+ drawnClusters(list: GpuDrivenList): number | null;
692
+ /**
693
+ * Each list's count into the read buffer, **after the whole frame**, so every draw that reads an
694
+ * argument block has been encoded before the copy out of it. The buffer is cleared first, so a
695
+ * list the frame did not draw — no blended material, no shadow — reads as none rather than as
696
+ * whatever the last frame that drew it left. Nothing while a read is in flight: a buffer that is
697
+ * mapped cannot be copied into. (A copy not yet read cannot be here: `readCounts` runs at the top
698
+ * of every frame this ends, and maps whatever was copied.)
699
+ */
700
+ private copyCounts;
701
+ /** Last frame's counts, asked for as `readTimings` asks for its figures and for its reason. */
702
+ private readCounts;
703
+ /** How many workgroups one dispatch over every cluster takes. */
704
+ private clusterGroups;
705
+ /** The half of the ping-pong this frame writes, which next frame will read. */
706
+ private writeHistory;
707
+ /**
708
+ * The map: what the light's own cull kept, drawn from the light, depth only — **in the camera's
709
+ * two halves.**
710
+ *
711
+ * **The front half's three pipelines over buffers of the light's, twice**: the cut, the cull
712
+ * against the light's box from the sun's side, and a compaction of what the light kept last
713
+ * frame, drawn; then a pyramid of that depth, the same cull against it, and a compaction of the
714
+ * rest, drawn over it. A three-degree sun over a city sees a strip of it a kilometre deep, and
715
+ * everything behind the first row toward the sun is in that row's shadow — which is exactly what
716
+ * the pyramid of the first half says, and what the frustum and the cones alone could not.
717
+ * `CLUSTER_INDEX_CAP` vertices by one instance a listed cluster, as in the frame's own draw.
718
+ *
719
+ * **One figure for the stage**: the first compute pass writes where the stage began and the
720
+ * second render pass where it ended, so `shadow` in the stage times is all of it.
721
+ */
722
+ private drawShadow;
723
+ /** One half of the map: the first clears it, the second draws over it and closes the stage's time. */
724
+ private drawShadowHalf;
725
+ private drawPhase;
726
+ draw(ctx: PassContext): void;
727
+ dispose(device: PassDevice): void;
728
+ }