@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,58 @@
1
+ /**
2
+ * The two sizes a reconstructed frame has.
3
+ *
4
+ * **A frame with a reconstruction has a render size and an output size, and every texel size is
5
+ * taken from the target it belongs to.** The scene, its depth, the multisampled pair, decals,
6
+ * reflections, the translucent set, the medium and the motion target are the render size; the
7
+ * resolve, the history, bloom and the composite are the output size. The two are one number apart
8
+ * and confusing them does not fail — it draws a picture that is subtly the wrong shape.
9
+ *
10
+ * **The projection is built from the output's aspect and never from the render's.** Each axis is
11
+ * rounded up on its own, so a render size's aspect differs from its output's by up to a texel's
12
+ * worth: at 1280 by 720 and a ratio of 1.7 that is 753 by 424, an aspect of 1.7759 against 1.7778.
13
+ * A projection built from the render size stretches the picture by that much — a fraction of a per
14
+ * cent, invisible in a screenshot and visible as a wobble every time the drawing buffer resizes.
15
+ */
16
+ /**
17
+ * Why a multisampled frame is not reconstructed, in words, so both backends read the same sentence.
18
+ *
19
+ * **The motion pass is what forbids it.** That pass draws the frame's movers again with the depth
20
+ * the scene left, testing for equality so only the pixels the scene kept are written — and an
21
+ * attachment's sample count has to agree with every other attachment in its pass, so a
22
+ * multisampled depth wants a multisampled motion target, a resolve of it, and a second set of
23
+ * everything downstream.
24
+ *
25
+ * It is also a choice nobody should want. A reconstruction's own accumulation is what antialiases
26
+ * the picture; paying for a second antialiasing at four times the fragment work, and then throwing
27
+ * three quarters of it away in a resolve, is the cost this feature exists to avoid.
28
+ */
29
+ export const RECONSTRUCTION_MULTISAMPLE_REFUSAL = 'driftengine: a reconstruction draws its movers again against the depth the scene left, and ' +
30
+ 'every attachment in a pass must agree about its sample count — so reconstruction is off ' +
31
+ 'wherever `sceneSamples` is above one. The accumulation is the antialiasing; the two are a ' +
32
+ 'choice of one.';
33
+ /** The render size for an output size and a `quality.reconstruction` ratio; 0 is off. */
34
+ export function reconRenderSize(outputWidth, outputHeight, ratio) {
35
+ const width = Math.max(1, Math.floor(outputWidth));
36
+ const height = Math.max(1, Math.floor(outputHeight));
37
+ /*
38
+ * **Anything that is not a ratio above one draws at the output size**: off, a ratio of exactly
39
+ * one, and — the case that matters — a ratio *below* one, which divides the other way and would
40
+ * ask the renderer to draw more pixels than it shows. `resolveRenderQuality` never produces one,
41
+ * and this is a public function that a caller reaches with whatever number they have. `NaN`
42
+ * lands here too, which `ratio <= 0` would have sent through the divide to a size of `NaN`.
43
+ */
44
+ if (!(ratio > 1))
45
+ return { width, height };
46
+ /*
47
+ * Up, never down: rounding down draws fewer pixels than the ratio says, which is a frame-rate win
48
+ * nobody asked for and a softer picture they did not agree to.
49
+ *
50
+ * **The floor of one is not redundant**, which taking it out and watching nothing fail suggested
51
+ * it was. A ceiling of a positive quotient is at least one for every finite ratio — and an
52
+ * infinite one divides to zero, so the size comes back zero by zero, which a device refuses.
53
+ */
54
+ return {
55
+ width: Math.max(1, Math.ceil(width / ratio)),
56
+ height: Math.max(1, Math.ceil(height / ratio)),
57
+ };
58
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The sub-pixel sequence a frame is rasterised along, for the temporal resolve and for
3
+ * reconstruction.
4
+ *
5
+ * **One sequence, two consumers.** `temporalAa.ts` jitters a frame at its output size along eight
6
+ * phases; DriftTR jitters a frame rendered below its output size, and needs more phases for the
7
+ * same reason a smaller render needs more frames to cover the output — each render pixel stands
8
+ * for several output pixels, and the sequence has to visit each of their positions before it
9
+ * repeats. The eight-phase sequence is the numbers the temporal resolve always used, so its
10
+ * captures do not move.
11
+ *
12
+ * **What is reused rather than rebuilt**, from `temporalAa.ts`: Halton in bases two and three, each
13
+ * period centred on its own mean, and `jitterProjection`, which puts the offset into clip space
14
+ * rather than into the projection's third column. See that function for why the third column is
15
+ * wrong for the combined view-projection this engine draws with.
16
+ */
17
+ /**
18
+ * The radical inverse of `index` in `base`: the digits of `index` mirrored about the point.
19
+ *
20
+ * Consecutive indices land as far from each other as the base allows, which is what lets eight of
21
+ * them cover a pixel evenly where eight random ones leave holes and pairs.
22
+ */
23
+ export declare function halton(index: number, base: number): number;
24
+ /**
25
+ * The period's offsets, centred so they sum to zero.
26
+ *
27
+ * **Halton's own mean is not the middle of the pixel** — eight points in base two average 57/128 —
28
+ * and accumulating towards an off-centre mean resolves to a picture displaced from the depth
29
+ * buffer it is tested against and from every pass that did not jitter. Subtracting the period's
30
+ * own mean costs nothing and makes the property exact.
31
+ */
32
+ export declare function jitterTable(phases: number): Float64Array;
33
+ /**
34
+ * Where in its pixel frame `frame` samples, in pixels and centred on zero, on a sequence of
35
+ * `phases` positions. Written into `out`, two floats.
36
+ */
37
+ export declare function jitterOffset(frame: number, phases: number, out: Float32Array): void;
38
+ /**
39
+ * How many phases a reconstruction from `renderWidth` to `outputWidth` takes: eight for every
40
+ * output pixel one render pixel covers, rounded up — and eight where the render is not smaller.
41
+ *
42
+ * The count the published temporal upscalers use, and the reason is coverage rather than taste: a
43
+ * render pixel two thirds of an output pixel wide stands for 2.25 output pixels, and eight positions
44
+ * an output pixel is what the temporal resolve already found enough.
45
+ */
46
+ export declare function reconJitterPhases(renderWidth: number, outputWidth: number): number;
47
+ /**
48
+ * `source` moved in clip space by `jitter`, which is what a contributed pass does with the frame's
49
+ * jitter (`PrepareContext.jitter`) to draw where the renderer's own verbs drew this frame.
50
+ *
51
+ * **In the camera's own convention, before any correction**: `jitter` is a fraction of the clip
52
+ * square, x rightward and y upward as `mat4.perspective` has them, so the matrix it applies to is
53
+ * the one the consumer built — a pass then multiplies by `clipCorrection` or `depthCorrection`
54
+ * exactly as it would have, and the offset arrives on screen where the renderer's did. Scaled by w,
55
+ * as `jitterProjection` is, so it is a constant screen offset at every depth.
56
+ *
57
+ * **A zero jitter leaves a finite matrix bit for bit** — each term gains a zero — so a frame that is
58
+ * not reconstructed draws exactly what it drew before this existed.
59
+ */
60
+ export declare function jitterClip(out: Float32Array, source: ArrayLike<number>, jitter: ArrayLike<number>): Float32Array;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The sub-pixel sequence a frame is rasterised along, for the temporal resolve and for
3
+ * reconstruction.
4
+ *
5
+ * **One sequence, two consumers.** `temporalAa.ts` jitters a frame at its output size along eight
6
+ * phases; DriftTR jitters a frame rendered below its output size, and needs more phases for the
7
+ * same reason a smaller render needs more frames to cover the output — each render pixel stands
8
+ * for several output pixels, and the sequence has to visit each of their positions before it
9
+ * repeats. The eight-phase sequence is the numbers the temporal resolve always used, so its
10
+ * captures do not move.
11
+ *
12
+ * **What is reused rather than rebuilt**, from `temporalAa.ts`: Halton in bases two and three, each
13
+ * period centred on its own mean, and `jitterProjection`, which puts the offset into clip space
14
+ * rather than into the projection's third column. See that function for why the third column is
15
+ * wrong for the combined view-projection this engine draws with.
16
+ */
17
+ /**
18
+ * The radical inverse of `index` in `base`: the digits of `index` mirrored about the point.
19
+ *
20
+ * Consecutive indices land as far from each other as the base allows, which is what lets eight of
21
+ * them cover a pixel evenly where eight random ones leave holes and pairs.
22
+ */
23
+ export function halton(index, base) {
24
+ let result = 0;
25
+ let fraction = 1;
26
+ let i = index;
27
+ while (i > 0) {
28
+ fraction /= base;
29
+ result += fraction * (i % base);
30
+ i = Math.floor(i / base);
31
+ }
32
+ return result;
33
+ }
34
+ /* One table a phase count, built once: x then y a phase. */
35
+ const TABLES = new Map();
36
+ /**
37
+ * The period's offsets, centred so they sum to zero.
38
+ *
39
+ * **Halton's own mean is not the middle of the pixel** — eight points in base two average 57/128 —
40
+ * and accumulating towards an off-centre mean resolves to a picture displaced from the depth
41
+ * buffer it is tested against and from every pass that did not jitter. Subtracting the period's
42
+ * own mean costs nothing and makes the property exact.
43
+ */
44
+ export function jitterTable(phases) {
45
+ const count = Math.max(1, Math.floor(phases));
46
+ let table = TABLES.get(count);
47
+ if (table !== undefined)
48
+ return table;
49
+ table = new Float64Array(count * 2);
50
+ let meanX = 0;
51
+ let meanY = 0;
52
+ for (let i = 0; i < count; i += 1) {
53
+ table[i * 2] = halton(i + 1, 2);
54
+ table[i * 2 + 1] = halton(i + 1, 3);
55
+ meanX += table[i * 2];
56
+ meanY += table[i * 2 + 1];
57
+ }
58
+ meanX /= count;
59
+ meanY /= count;
60
+ for (let i = 0; i < count; i += 1) {
61
+ table[i * 2] = table[i * 2] - meanX;
62
+ table[i * 2 + 1] = table[i * 2 + 1] - meanY;
63
+ }
64
+ TABLES.set(count, table);
65
+ return table;
66
+ }
67
+ /**
68
+ * Where in its pixel frame `frame` samples, in pixels and centred on zero, on a sequence of
69
+ * `phases` positions. Written into `out`, two floats.
70
+ */
71
+ export function jitterOffset(frame, phases, out) {
72
+ const table = jitterTable(phases);
73
+ const count = table.length / 2;
74
+ const at = ((frame % count) + count) % count;
75
+ out[0] = table[at * 2];
76
+ out[1] = table[at * 2 + 1];
77
+ }
78
+ /** The temporal resolve's own count, and the fewest a reconstruction takes. */
79
+ const BASE_PHASES = 8;
80
+ /**
81
+ * How many phases a reconstruction from `renderWidth` to `outputWidth` takes: eight for every
82
+ * output pixel one render pixel covers, rounded up — and eight where the render is not smaller.
83
+ *
84
+ * The count the published temporal upscalers use, and the reason is coverage rather than taste: a
85
+ * render pixel two thirds of an output pixel wide stands for 2.25 output pixels, and eight positions
86
+ * an output pixel is what the temporal resolve already found enough.
87
+ */
88
+ export function reconJitterPhases(renderWidth, outputWidth) {
89
+ if (!(renderWidth > 0) || !(outputWidth > renderWidth))
90
+ return BASE_PHASES;
91
+ const ratio = outputWidth / renderWidth;
92
+ return Math.ceil(BASE_PHASES * ratio * ratio);
93
+ }
94
+ /**
95
+ * `source` moved in clip space by `jitter`, which is what a contributed pass does with the frame's
96
+ * jitter (`PrepareContext.jitter`) to draw where the renderer's own verbs drew this frame.
97
+ *
98
+ * **In the camera's own convention, before any correction**: `jitter` is a fraction of the clip
99
+ * square, x rightward and y upward as `mat4.perspective` has them, so the matrix it applies to is
100
+ * the one the consumer built — a pass then multiplies by `clipCorrection` or `depthCorrection`
101
+ * exactly as it would have, and the offset arrives on screen where the renderer's did. Scaled by w,
102
+ * as `jitterProjection` is, so it is a constant screen offset at every depth.
103
+ *
104
+ * **A zero jitter leaves a finite matrix bit for bit** — each term gains a zero — so a frame that is
105
+ * not reconstructed draws exactly what it drew before this existed.
106
+ */
107
+ export function jitterClip(out, source, jitter) {
108
+ for (let i = 0; i < 16; i += 1)
109
+ out[i] = source[i];
110
+ const x = jitter[0];
111
+ const y = jitter[1];
112
+ for (let column = 0; column < 4; column += 1) {
113
+ const w = source[column * 4 + 3];
114
+ out[column * 4] = out[column * 4] + x * w;
115
+ out[column * 4 + 1] = out[column * 4 + 1] + y * w;
116
+ }
117
+ return out;
118
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Where each pixel's surface was last frame.
3
+ *
4
+ * **A motion vector is the offset from this frame's pixel to where its surface was, in the
5
+ * coordinates of an unjittered frame**, and every step of the reconstruction after this reads it
6
+ * that way. The history is a picture of the unjittered scene; a vector that carried either frame's
7
+ * jitter would look every sample up a fraction of a pixel away, in a pattern that repeats with the
8
+ * jitter period — which reads as shimmer and is diagnosed as everything except its cause. So the
9
+ * jitter is taken out of where a pixel was *observed* (`unjitteredUv`) and never put into the
10
+ * matrices a vector is built from.
11
+ *
12
+ * **Two sources, one meaning.** Most of a frame did not move: its motion is the camera's, derived in
13
+ * the resolve from depth through the reprojection matrix both renderers already build
14
+ * (`cameraMotion`). A draw that states where it was last frame — a previous model matrix, a
15
+ * previous skin palette — is drawn again into a motion target, and there the vector is the
16
+ * difference of the vertex's two clip positions (`objectMotion`). A skinned vertex's previous
17
+ * position comes from its previous *pose*, not from its previous model matrix: a character standing
18
+ * still and swinging an arm has the same model both frames.
19
+ *
20
+ * **What this does not follow**: wind bending (`channelBend`) and morph targets move vertices by the
21
+ * clock and by weights nothing keeps a previous value of. Their surfaces take the model's motion,
22
+ * and the neighbourhood clip catches what is left.
23
+ *
24
+ * Coordinates are clip-up throughout: `u` and `v` run 0 to 1, with `v = 0` where clip y is -1.
25
+ */
26
+ /** The motion target's format: the vector in two channels, and a flag where a draw wrote one. */
27
+ export declare const MOTION_FORMAT: 'rgba16float';
28
+ /**
29
+ * The camera's motion at a pixel: where the surface at `(u, v)` and `clipDepth` was last frame,
30
+ * less where it is. `reprojection` is `previousViewProj × inverse(currentViewProj)`, unjittered,
31
+ * in whatever depth convention `clipDepth` is given in.
32
+ *
33
+ * Returns false, and a zero vector, where the surface was behind last frame's eye: there is no
34
+ * position to have been at, and a vector through the eye points anywhere.
35
+ */
36
+ export declare function cameraMotion(reprojection: ArrayLike<number>, u: number, v: number, clipDepth: number, out: Float32Array): boolean;
37
+ /**
38
+ * A drawn vertex's motion: its previous clip position less its current one, in uv units.
39
+ *
40
+ * Both positions are unjittered — the motion pass draws with the frame's unjittered matrices and
41
+ * the vertex's two transforms. Returns false, and a zero vector, where either is behind its eye.
42
+ */
43
+ export declare function objectMotion(currentClip: ArrayLike<number>, previousClip: ArrayLike<number>, out: Float32Array): boolean;
44
+ /**
45
+ * A vertex through a skin palette: the four joints' matrices weighted and summed, then applied —
46
+ * `SKINNING_GLSL`'s `skinMatrix()` times the position, in model space, before the model matrix.
47
+ * `palette` is sixteen floats a joint, column-major. Written into `out`, four values.
48
+ */
49
+ export declare function skinVertex(palette: ArrayLike<number>, joints: ArrayLike<number>, weights: ArrayLike<number>, position: ArrayLike<number>, out: Float64Array): void;
50
+ /**
51
+ * Where a sample observed at `(u, v)` in a frame jittered by `jitterX`, `jitterY` pixels of a
52
+ * `width` by `height` target stands in the unjittered frame. `jitterProjection` moved the picture by
53
+ * the jitter; this moves the observation back.
54
+ */
55
+ export declare function unjitteredUv(u: number, v: number, jitterX: number, jitterY: number, width: number, height: number, out: Float32Array): void;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Where each pixel's surface was last frame.
3
+ *
4
+ * **A motion vector is the offset from this frame's pixel to where its surface was, in the
5
+ * coordinates of an unjittered frame**, and every step of the reconstruction after this reads it
6
+ * that way. The history is a picture of the unjittered scene; a vector that carried either frame's
7
+ * jitter would look every sample up a fraction of a pixel away, in a pattern that repeats with the
8
+ * jitter period — which reads as shimmer and is diagnosed as everything except its cause. So the
9
+ * jitter is taken out of where a pixel was *observed* (`unjitteredUv`) and never put into the
10
+ * matrices a vector is built from.
11
+ *
12
+ * **Two sources, one meaning.** Most of a frame did not move: its motion is the camera's, derived in
13
+ * the resolve from depth through the reprojection matrix both renderers already build
14
+ * (`cameraMotion`). A draw that states where it was last frame — a previous model matrix, a
15
+ * previous skin palette — is drawn again into a motion target, and there the vector is the
16
+ * difference of the vertex's two clip positions (`objectMotion`). A skinned vertex's previous
17
+ * position comes from its previous *pose*, not from its previous model matrix: a character standing
18
+ * still and swinging an arm has the same model both frames.
19
+ *
20
+ * **What this does not follow**: wind bending (`channelBend`) and morph targets move vertices by the
21
+ * clock and by weights nothing keeps a previous value of. Their surfaces take the model's motion,
22
+ * and the neighbourhood clip catches what is left.
23
+ *
24
+ * Coordinates are clip-up throughout: `u` and `v` run 0 to 1, with `v = 0` where clip y is -1.
25
+ */
26
+ /** The motion target's format: the vector in two channels, and a flag where a draw wrote one. */
27
+ export const MOTION_FORMAT = 'rgba16float';
28
+ /**
29
+ * The camera's motion at a pixel: where the surface at `(u, v)` and `clipDepth` was last frame,
30
+ * less where it is. `reprojection` is `previousViewProj × inverse(currentViewProj)`, unjittered,
31
+ * in whatever depth convention `clipDepth` is given in.
32
+ *
33
+ * Returns false, and a zero vector, where the surface was behind last frame's eye: there is no
34
+ * position to have been at, and a vector through the eye points anywhere.
35
+ */
36
+ export function cameraMotion(reprojection, u, v, clipDepth, out) {
37
+ const x = u * 2 - 1;
38
+ const y = v * 2 - 1;
39
+ const m = reprojection;
40
+ const w = m[3] * x + m[7] * y + m[11] * clipDepth + m[15];
41
+ if (!(w > 0)) {
42
+ out[0] = 0;
43
+ out[1] = 0;
44
+ return false;
45
+ }
46
+ const px = m[0] * x + m[4] * y + m[8] * clipDepth + m[12];
47
+ const py = m[1] * x + m[5] * y + m[9] * clipDepth + m[13];
48
+ out[0] = (px / w) * 0.5 + 0.5 - u;
49
+ out[1] = (py / w) * 0.5 + 0.5 - v;
50
+ return true;
51
+ }
52
+ /**
53
+ * A drawn vertex's motion: its previous clip position less its current one, in uv units.
54
+ *
55
+ * Both positions are unjittered — the motion pass draws with the frame's unjittered matrices and
56
+ * the vertex's two transforms. Returns false, and a zero vector, where either is behind its eye.
57
+ */
58
+ export function objectMotion(currentClip, previousClip, out) {
59
+ const cw = currentClip[3];
60
+ const pw = previousClip[3];
61
+ if (!(cw > 0) || !(pw > 0)) {
62
+ out[0] = 0;
63
+ out[1] = 0;
64
+ return false;
65
+ }
66
+ out[0] = (previousClip[0] / pw - currentClip[0] / cw) * 0.5;
67
+ out[1] = (previousClip[1] / pw - currentClip[1] / cw) * 0.5;
68
+ return true;
69
+ }
70
+ /**
71
+ * A vertex through a skin palette: the four joints' matrices weighted and summed, then applied —
72
+ * `SKINNING_GLSL`'s `skinMatrix()` times the position, in model space, before the model matrix.
73
+ * `palette` is sixteen floats a joint, column-major. Written into `out`, four values.
74
+ */
75
+ export function skinVertex(palette, joints, weights, position, out) {
76
+ const px = position[0];
77
+ const py = position[1];
78
+ const pz = position[2];
79
+ out[0] = 0;
80
+ out[1] = 0;
81
+ out[2] = 0;
82
+ out[3] = 0;
83
+ for (let influence = 0; influence < 4; influence += 1) {
84
+ const weight = weights[influence];
85
+ if (weight === 0)
86
+ continue;
87
+ const at = joints[influence] * 16;
88
+ for (let row = 0; row < 4; row += 1) {
89
+ out[row] =
90
+ out[row] +
91
+ weight *
92
+ (palette[at + row] * px +
93
+ palette[at + 4 + row] * py +
94
+ palette[at + 8 + row] * pz +
95
+ palette[at + 12 + row]);
96
+ }
97
+ }
98
+ }
99
+ /**
100
+ * Where a sample observed at `(u, v)` in a frame jittered by `jitterX`, `jitterY` pixels of a
101
+ * `width` by `height` target stands in the unjittered frame. `jitterProjection` moved the picture by
102
+ * the jitter; this moves the observation back.
103
+ */
104
+ export function unjitteredUv(u, v, jitterX, jitterY, width, height, out) {
105
+ out[0] = u - jitterX / width;
106
+ out[1] = v - jitterY / height;
107
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Where a pixel's surface was, and the history sampled there.
3
+ *
4
+ * **Off the edge is a disocclusion, not a clamp.** A surface that was outside last frame's picture
5
+ * has no history; sampling the border instead drags one row of pixels inward as a smear for as long
6
+ * as the camera keeps turning. The temporal resolve already refuses it, and this keeps the rule.
7
+ *
8
+ * **The history is read bicubically**, because a bilinear read of an accumulated picture blurs it a
9
+ * little more every frame it is carried: a history reprojected by half a pixel sixty times a second
10
+ * is a history bilinearly filtered sixty times a second. Catmull-Rom interpolates — a texel centre
11
+ * returns that texel — and its weights sum to one, so the picture neither brightens nor darkens as
12
+ * it accumulates. Its negative lobes can undershoot beside a bright edge; a colour cannot be
13
+ * negative, so the sample is floored at zero, and the neighbourhood clip bounds the rest.
14
+ *
15
+ * **The shader uses five bilinear taps for the sixteen texels**: the middle pair of each axis folded
16
+ * into one tap, the four corners dropped, the weights renormalised. On an accumulated picture the
17
+ * corners carry almost nothing, and the test beside this says how little.
18
+ *
19
+ * Images are rows from `v = 0` upward, texel centres at whole texel coordinates, clamped at the
20
+ * border.
21
+ */
22
+ /**
23
+ * Reproject pixel `(x, y)` of a `width` by `height` target by a motion vector in uv units, into the
24
+ * texel coordinate its surface had. Returns false where that is off the picture — past the outer
25
+ * edge of the border texels, or not a number.
26
+ */
27
+ export declare function reprojectPixel(x: number, y: number, motion: ArrayLike<number>, width: number, height: number, out: Float32Array): boolean;
28
+ /** Catmull-Rom's four weights for the texels at -1, 0, 1 and 2 about a fraction `t`. */
29
+ export declare function catmullRomWeights(t: number, out: Float64Array): void;
30
+ /** A bilinear read at texel coordinate `(x, y)`, clamped at the border. */
31
+ export declare function sampleBilinear(image: ArrayLike<number>, x: number, y: number, width: number, height: number, channels: number, out: Float32Array): void;
32
+ /** The full sixteen-texel Catmull-Rom read at texel coordinate `(x, y)`, floored at zero. */
33
+ export declare function sampleHistoryBicubic(image: ArrayLike<number>, x: number, y: number, width: number, height: number, channels: number, out: Float32Array): void;
34
+ /**
35
+ * The five-tap approximation the shader uses, at texel coordinate `(x, y)`, floored at zero.
36
+ *
37
+ * Each axis's middle two texels are one bilinear tap placed at `w2 / (w1 + w2)` between them, which
38
+ * is exact for those four texels; the edge taps read a row or column the same way; the corners are
39
+ * dropped and the five weights renormalised.
40
+ */
41
+ export declare function sampleHistoryBicubic5(image: ArrayLike<number>, x: number, y: number, width: number, height: number, channels: number, out: Float32Array): void;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Where a pixel's surface was, and the history sampled there.
3
+ *
4
+ * **Off the edge is a disocclusion, not a clamp.** A surface that was outside last frame's picture
5
+ * has no history; sampling the border instead drags one row of pixels inward as a smear for as long
6
+ * as the camera keeps turning. The temporal resolve already refuses it, and this keeps the rule.
7
+ *
8
+ * **The history is read bicubically**, because a bilinear read of an accumulated picture blurs it a
9
+ * little more every frame it is carried: a history reprojected by half a pixel sixty times a second
10
+ * is a history bilinearly filtered sixty times a second. Catmull-Rom interpolates — a texel centre
11
+ * returns that texel — and its weights sum to one, so the picture neither brightens nor darkens as
12
+ * it accumulates. Its negative lobes can undershoot beside a bright edge; a colour cannot be
13
+ * negative, so the sample is floored at zero, and the neighbourhood clip bounds the rest.
14
+ *
15
+ * **The shader uses five bilinear taps for the sixteen texels**: the middle pair of each axis folded
16
+ * into one tap, the four corners dropped, the weights renormalised. On an accumulated picture the
17
+ * corners carry almost nothing, and the test beside this says how little.
18
+ *
19
+ * Images are rows from `v = 0` upward, texel centres at whole texel coordinates, clamped at the
20
+ * border.
21
+ */
22
+ /**
23
+ * Reproject pixel `(x, y)` of a `width` by `height` target by a motion vector in uv units, into the
24
+ * texel coordinate its surface had. Returns false where that is off the picture — past the outer
25
+ * edge of the border texels, or not a number.
26
+ */
27
+ export function reprojectPixel(x, y, motion, width, height, out) {
28
+ const u = (x + 0.5) / width + motion[0];
29
+ const v = (y + 0.5) / height + motion[1];
30
+ out[0] = u * width - 0.5;
31
+ out[1] = v * height - 0.5;
32
+ return u >= 0 && u <= 1 && v >= 0 && v <= 1;
33
+ }
34
+ /** Catmull-Rom's four weights for the texels at -1, 0, 1 and 2 about a fraction `t`. */
35
+ export function catmullRomWeights(t, out) {
36
+ const t2 = t * t;
37
+ const t3 = t2 * t;
38
+ out[0] = -0.5 * t3 + t2 - 0.5 * t;
39
+ out[1] = 1.5 * t3 - 2.5 * t2 + 1;
40
+ out[2] = -1.5 * t3 + 2 * t2 + 0.5 * t;
41
+ out[3] = 0.5 * t3 - 0.5 * t2;
42
+ }
43
+ function clampIndex(value, size) {
44
+ return value < 0 ? 0 : value >= size ? size - 1 : value;
45
+ }
46
+ /** One texel, clamped to the image. */
47
+ function texel(image, x, y, width, height, channels, c) {
48
+ return image[(clampIndex(y, height) * width + clampIndex(x, width)) * channels + c];
49
+ }
50
+ /** A bilinear read at texel coordinate `(x, y)`, clamped at the border. */
51
+ export function sampleBilinear(image, x, y, width, height, channels, out) {
52
+ const x0 = Math.floor(x);
53
+ const y0 = Math.floor(y);
54
+ const fx = x - x0;
55
+ const fy = y - y0;
56
+ for (let c = 0; c < channels; c += 1) {
57
+ const top = texel(image, x0, y0, width, height, channels, c) * (1 - fx) +
58
+ texel(image, x0 + 1, y0, width, height, channels, c) * fx;
59
+ const bottom = texel(image, x0, y0 + 1, width, height, channels, c) * (1 - fx) +
60
+ texel(image, x0 + 1, y0 + 1, width, height, channels, c) * fx;
61
+ out[c] = top * (1 - fy) + bottom * fy;
62
+ }
63
+ }
64
+ const WX = new Float64Array(4);
65
+ const WY = new Float64Array(4);
66
+ /** The full sixteen-texel Catmull-Rom read at texel coordinate `(x, y)`, floored at zero. */
67
+ export function sampleHistoryBicubic(image, x, y, width, height, channels, out) {
68
+ const x1 = Math.floor(x);
69
+ const y1 = Math.floor(y);
70
+ catmullRomWeights(x - x1, WX);
71
+ catmullRomWeights(y - y1, WY);
72
+ for (let c = 0; c < channels; c += 1) {
73
+ let sum = 0;
74
+ for (let j = 0; j < 4; j += 1) {
75
+ let row = 0;
76
+ for (let i = 0; i < 4; i += 1) {
77
+ row += WX[i] * texel(image, x1 - 1 + i, y1 - 1 + j, width, height, channels, c);
78
+ }
79
+ sum += WY[j] * row;
80
+ }
81
+ out[c] = Math.max(0, sum);
82
+ }
83
+ }
84
+ const TAP = new Float32Array(4);
85
+ /**
86
+ * The five-tap approximation the shader uses, at texel coordinate `(x, y)`, floored at zero.
87
+ *
88
+ * Each axis's middle two texels are one bilinear tap placed at `w2 / (w1 + w2)` between them, which
89
+ * is exact for those four texels; the edge taps read a row or column the same way; the corners are
90
+ * dropped and the five weights renormalised.
91
+ */
92
+ export function sampleHistoryBicubic5(image, x, y, width, height, channels, out) {
93
+ const x1 = Math.floor(x);
94
+ const y1 = Math.floor(y);
95
+ catmullRomWeights(x - x1, WX);
96
+ catmullRomWeights(y - y1, WY);
97
+ const wx12 = WX[1] + WX[2];
98
+ const wy12 = WY[1] + WY[2];
99
+ const x12 = x1 + WX[2] / wx12;
100
+ const y12 = y1 + WY[2] / wy12;
101
+ const x0 = x1 - 1;
102
+ const y0 = y1 - 1;
103
+ const x3 = x1 + 2;
104
+ const y3 = y1 + 2;
105
+ const weights = [
106
+ wx12 * WY[0],
107
+ WX[0] * wy12,
108
+ wx12 * wy12,
109
+ WX[3] * wy12,
110
+ wx12 * WY[3],
111
+ ];
112
+ const at = [
113
+ [x12, y0],
114
+ [x0, y12],
115
+ [x12, y12],
116
+ [x3, y12],
117
+ [x12, y3],
118
+ ];
119
+ const total = weights.reduce((sum, w) => sum + w, 0);
120
+ for (let c = 0; c < channels; c += 1)
121
+ out[c] = 0;
122
+ for (let k = 0; k < 5; k += 1) {
123
+ const place = at[k];
124
+ sampleBilinear(image, place[0], place[1], width, height, channels, TAP);
125
+ for (let c = 0; c < channels; c += 1) {
126
+ out[c] = out[c] + weights[k] * TAP[c];
127
+ }
128
+ }
129
+ for (let c = 0; c < channels; c += 1)
130
+ out[c] = Math.max(0, out[c] / total);
131
+ }
@@ -0,0 +1,90 @@
1
+ import type { DisocclusionParams } from './disocclusion.ts';
2
+ /** What a reconstruction is asked for. */
3
+ export interface ReconQuality {
4
+ /** Output size over render size, each axis. 1.3 to 2; 0 is off. */
5
+ readonly ratio: number;
6
+ /** The current frame's share of a fully trusted accumulation. */
7
+ readonly alpha: number;
8
+ /** How far the shown picture is sharpened, 0 to 1. */
9
+ readonly sharpen: number;
10
+ /** Standard deviations the neighbourhood box extends either side of its mean. */
11
+ readonly clampGamma: number;
12
+ }
13
+ /**
14
+ * A tenth of each frame kept, as the temporal resolve keeps; a box of a standard deviation and a
15
+ * quarter; a light sharpen. At two thirds of the output a side.
16
+ */
17
+ export declare const DEFAULT_RECON_QUALITY: ReconQuality;
18
+ /**
19
+ * The current colour and the clipped history mixed: the history's share is `weight × (1 − alpha)`.
20
+ *
21
+ * A weight of zero is the current colour exactly — no history — and a weight of one with an alpha of
22
+ * zero is the history exactly. A convex mixture, so repeated accumulation of one colour converges to
23
+ * it and never overshoots.
24
+ */
25
+ export declare function accumulate(out: Float32Array | Float64Array, current: ArrayLike<number>, history: ArrayLike<number>, weight: number, alpha: number): void;
26
+ /**
27
+ * The centre pushed away from its four neighbours' mean by `amount`, and **held inside the range of
28
+ * the five** — the halo a plain unsharp mask draws beside every edge is a value outside that range.
29
+ * A flat region has no difference to push, so it is unchanged.
30
+ */
31
+ export declare function sharpen(out: Float32Array | Float64Array, centre: ArrayLike<number>, neighbours: ArrayLike<number>, amount: number): void;
32
+ /** Everything one resolve reads. Images are rows from `v = 0` upward. */
33
+ export interface ResolveFrame {
34
+ readonly renderWidth: number;
35
+ readonly renderHeight: number;
36
+ readonly outputWidth: number;
37
+ readonly outputHeight: number;
38
+ /** Render size, three floats a texel, linear. */
39
+ readonly scene: ArrayLike<number>;
40
+ /** Render size, one clip depth a texel. */
41
+ readonly depth: ArrayLike<number>;
42
+ /**
43
+ * Render size, four floats a texel: a drawn object's motion in uv, its previous view depth, and a
44
+ * flag above one half where a draw wrote them.
45
+ */
46
+ readonly motion: ArrayLike<number>;
47
+ /** Last frame's `depth`. */
48
+ readonly previousDepth: ArrayLike<number>;
49
+ /** Output size, four floats a texel: last frame's unsharpened colour, and the weight it gathered. */
50
+ readonly history: ArrayLike<number>;
51
+ /** False on the first frame, after a resize and after a cut. */
52
+ readonly hasHistory: boolean;
53
+ /** This frame's inverse view-projection, unjittered. */
54
+ readonly inverseViewProj: ArrayLike<number>;
55
+ /** Last frame's view-projection and its inverse, unjittered. */
56
+ readonly previousViewProj: ArrayLike<number>;
57
+ readonly previousInverseViewProj: ArrayLike<number>;
58
+ readonly eye: ArrayLike<number>;
59
+ readonly previousEye: ArrayLike<number>;
60
+ /** This frame's and last frame's jitter, in render pixels. */
61
+ readonly jitter: ArrayLike<number>;
62
+ readonly previousJitter: ArrayLike<number>;
63
+ readonly quality: ReconQuality;
64
+ readonly disocclusion: DisocclusionParams;
65
+ }
66
+ /**
67
+ * How far a render sample's contribution reaches, in output pixels: a Gaussian's standard deviation.
68
+ *
69
+ * Just under half a pixel, so a sample on a pixel's centre counts fully and one a pixel away counts a
70
+ * tenth — the width a reconstruction filter needs to avoid both aliasing and a soft picture.
71
+ */
72
+ export declare const SAMPLE_SPREAD = 0.47;
73
+ /** A render sample's weight at `(dx, dy)` output pixels from an output pixel's centre. */
74
+ export declare function reconstructionWeight(dx: number, dy: number): number;
75
+ /**
76
+ * How much gathered weight counts as knowing a pixel. Below it, the render's bicubic read fills in —
77
+ * which is every pixel on the first frame at a large ratio, where the nearest sample can be most of a
78
+ * pixel away.
79
+ */
80
+ export declare const CONFIDENT_WEIGHT = 1;
81
+ /**
82
+ * One output pixel: the history's next colour, before sharpening, and the weight it has gathered —
83
+ * four values into `out`.
84
+ */
85
+ export declare function resolvePixel(frame: ResolveFrame, ox: number, oy: number, out: Float32Array): void;
86
+ /**
87
+ * The whole frame: the next history into `history`, four floats a pixel, and the picture shown into
88
+ * `shown`, three — the history sharpened against the four direct neighbours it has just been given.
89
+ */
90
+ export declare function resolveFrame(frame: ResolveFrame, history: Float32Array, shown: Float32Array): void;