@driftengine/core 3.63.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 +111 -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 +69 -4
  9. package/dist/index.js +112 -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 +19 -9
  42. package/dist/render/backend/webgpu/surfaceTexturePass.js +58 -32
  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 +246 -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 +63 -36
  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,239 @@
1
+ /** Composing the world's distance field, on the device, because 707 ms is not a frame. */
2
+
3
+ /**
4
+ * **This is the only version of `composeGlobalField` that can run in a frame.**
5
+ *
6
+ * The TypeScript in `gi/globalField.ts` is the reference and says so in its own header: it visits
7
+ * every sample of every cascade for every instance it cannot cull outright, deliberately, because
8
+ * a reference that was already accelerated would be a second thing to be wrong rather than the
9
+ * thing the first is checked by. Measured by `scripts/gi-schemes.mjs`, that costs **707 ms a
10
+ * frame** for 32 instances over four cascades of 65 cubed — 35 million inverse transforms and
11
+ * trilinear reads, which is exactly the shape a GPU is for and exactly the shape a CPU is not.
12
+ *
13
+ * **One invocation a sample, and no culling at all.** The reference culls an instance further from
14
+ * a cascade than that cascade's reach, and the measurement that justified it there — 19.4 ms
15
+ * against 150.2 — is a statement about a serial loop. Here every sample is already parallel, so
16
+ * what the cull would save is a branch per instance per thread and what it would cost is a
17
+ * divergent one. It is left out, and `scripts/gi-parity.mjs` is what proves that changes no answer:
18
+ * the cull cannot change a result, only the time taken to reach it, because a culled instance is
19
+ * one whose contribution the minimum would have discarded.
20
+ *
21
+ * **The layouts are the reference's, restated rather than shared, and that is the hazard.** A
22
+ * shader and a TypeScript function cannot import a struct from each other, so the eight-corner
23
+ * blend below and `read()` in `globalField.ts` are two spellings of one decision. `gi-parity.mjs`
24
+ * runs both over generated input and compares every sample, which is the arrangement
25
+ * `gpu-parity.mjs` established for exactly this reason.
26
+ */
27
+
28
+ /** Floats per instance in the `instances` buffer. See `INSTANCE_*` below for what they are. */
29
+ export const COMPOSE_INSTANCE_FLOATS = 32;
30
+
31
+ /** Where each field of an instance record starts, in floats. */
32
+ export const INSTANCE_INVERSE = 0;
33
+ export const INSTANCE_SCALE = 16;
34
+ export const INSTANCE_BOUNDS = 17;
35
+ export const INSTANCE_DIMS = 23;
36
+ export const INSTANCE_OFFSET = 26;
37
+ /** The instance's own colour, three floats. White where a consumer declared none. */
38
+ export const INSTANCE_ALBEDO = 28;
39
+
40
+ /**
41
+ * Floats in the `params` buffer: cascade origin, step, dims, reach, instance count, output base.
42
+ *
43
+ * **Every cascade has its own copy, at its own 256-byte-aligned offset.** `queue.writeBuffer` is a
44
+ * queue operation and is not ordered against the commands of an encoder, so rewriting one params
45
+ * buffer between dispatches gives every dispatch the *last* write — three cascades composed with
46
+ * the outermost one's origin and step, which looks like a field that is simply wrong everywhere.
47
+ */
48
+ export const COMPOSE_PARAM_FLOATS = 12;
49
+
50
+ /** Where a cascade's samples start in the shared output, in floats. `params[9]`. */
51
+ export const COMPOSE_OUTPUT_BASE = 9;
52
+
53
+ /**
54
+ * Bytes between one cascade's params and the next.
55
+ *
56
+ * A storage binding's offset must be a multiple of `minStorageBufferOffsetAlignment`, which is 256
57
+ * on every device this targets — the same limit the GPU-driven pyramid's levels are padded to.
58
+ */
59
+ export const COMPOSE_PARAM_STRIDE = 256;
60
+
61
+ /** Invocations a workgroup. 64 is this backend's default everywhere else. */
62
+ export const COMPOSE_WORKGROUP = 64;
63
+
64
+ export const COMPOSE_FIELD_WGSL = /* wgsl */ `
65
+ struct Params {
66
+ originX: f32,
67
+ originY: f32,
68
+ originZ: f32,
69
+ step: f32,
70
+ countX: f32,
71
+ countY: f32,
72
+ countZ: f32,
73
+ reach: f32,
74
+ instances: f32,
75
+ padA: f32,
76
+ padB: f32,
77
+ padC: f32,
78
+ };
79
+
80
+ @group(0) @binding(0) var<storage, read> params: array<f32>;
81
+ @group(0) @binding(1) var<storage, read> instances: array<f32>;
82
+ @group(0) @binding(2) var<storage, read> sources: array<f32>;
83
+ @group(0) @binding(3) var<storage, read_write> field: array<f32>;
84
+ /* The colour of whatever won the union at each sample, three floats. See GlobalFieldCascade. */
85
+ @group(0) @binding(4) var<storage, read_write> albedo: array<f32>;
86
+
87
+ /*
88
+ * The eight-corner blend of one object's field, at a point already in that object's space.
89
+ *
90
+ * Clamped at the grid's edge, exactly as the reference is: a sample past the last plane takes that
91
+ * plane rather than extrapolating, and the index stops one short so the pair it interpolates
92
+ * between is always inside.
93
+ */
94
+ fn sourceAt(base: u32, bounds0: vec3<f32>, bounds1: vec3<f32>, dims: vec3<f32>, p: vec3<f32>) -> f32 {
95
+ /* One step for all three axes, because an object's voxels are cubic. bakeObjectSdf is why. */
96
+ let step = (bounds1.x - bounds0.x) / (dims.x - 1.0);
97
+
98
+ var low = vec3<f32>(0.0, 0.0, 0.0);
99
+ var frac = vec3<f32>(0.0, 0.0, 0.0);
100
+ for (var axis = 0u; axis < 3u; axis = axis + 1u) {
101
+ let count = dims[axis];
102
+ let local = (p[axis] - bounds0[axis]) / step;
103
+ let clamped = clamp(local, 0.0, count - 1.0);
104
+ let index = min(floor(clamped), count - 2.0);
105
+ low[axis] = index;
106
+ frac[axis] = clamped - index;
107
+ }
108
+
109
+ let nx = u32(dims.x);
110
+ let ny = u32(dims.y);
111
+ let lx = u32(low.x);
112
+ let ly = u32(low.y);
113
+ let lz = u32(low.z);
114
+
115
+ var total = 0.0;
116
+ for (var cz = 0u; cz < 2u; cz = cz + 1u) {
117
+ let wz = select(1.0 - frac.z, frac.z, cz == 1u);
118
+ for (var cy = 0u; cy < 2u; cy = cy + 1u) {
119
+ let wy = select(1.0 - frac.y, frac.y, cy == 1u);
120
+ for (var cx = 0u; cx < 2u; cx = cx + 1u) {
121
+ let wx = select(1.0 - frac.x, frac.x, cx == 1u);
122
+ let at = lx + cx + nx * (ly + cy + ny * (lz + cz));
123
+ total = total + sources[base + at] * wx * wy * wz;
124
+ }
125
+ }
126
+ }
127
+ return total;
128
+ }
129
+
130
+ @compute @workgroup_size(${COMPOSE_WORKGROUP})
131
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
132
+ let countX = u32(params[4]);
133
+ let countY = u32(params[5]);
134
+ let countZ = u32(params[6]);
135
+ let total = countX * countY * countZ;
136
+ let index = id.x;
137
+ if (index >= total) {
138
+ return;
139
+ }
140
+
141
+ let ix = index % countX;
142
+ let iy = (index / countX) % countY;
143
+ let iz = index / (countX * countY);
144
+ let step = params[3];
145
+ let world = vec3<f32>(
146
+ params[0] + f32(ix) * step,
147
+ params[1] + f32(iy) * step,
148
+ params[2] + f32(iz) * step,
149
+ );
150
+
151
+ /* The reach, which is both the initial value and a bound on what any instance can lower it to. */
152
+ var best = params[7];
153
+ /* White, so a sample no instance reached is neutral rather than a light that vanishes. */
154
+ var bestAlbedo = vec3<f32>(1.0, 1.0, 1.0);
155
+ let instanceCount = u32(params[8]);
156
+
157
+ for (var i = 0u; i < instanceCount; i = i + 1u) {
158
+ let base = i * ${COMPOSE_INSTANCE_FLOATS}u;
159
+
160
+ /*
161
+ * The world point carried into the object's space through the **inverse**. Column-major, the
162
+ * order gl-matrix stores a matrix in, which is the order the reference reads it in too.
163
+ */
164
+ let object = vec3<f32>(
165
+ instances[base + 0u] * world.x + instances[base + 4u] * world.y + instances[base + 8u] * world.z + instances[base + 12u],
166
+ instances[base + 1u] * world.x + instances[base + 5u] * world.y + instances[base + 9u] * world.z + instances[base + 13u],
167
+ instances[base + 2u] * world.x + instances[base + 6u] * world.y + instances[base + 10u] * world.z + instances[base + 14u],
168
+ );
169
+
170
+ let scale = instances[base + ${INSTANCE_SCALE}u];
171
+ let bounds0 = vec3<f32>(
172
+ instances[base + ${INSTANCE_BOUNDS}u],
173
+ instances[base + ${INSTANCE_BOUNDS}u + 1u],
174
+ instances[base + ${INSTANCE_BOUNDS}u + 2u],
175
+ );
176
+ let bounds1 = vec3<f32>(
177
+ instances[base + ${INSTANCE_BOUNDS}u + 3u],
178
+ instances[base + ${INSTANCE_BOUNDS}u + 4u],
179
+ instances[base + ${INSTANCE_BOUNDS}u + 5u],
180
+ );
181
+
182
+ /*
183
+ * **Outside the source's box, bounded two ways and the larger taken.** The distance to the box
184
+ * alone is a true bound and a useless one: just outside it says zero, so a sphere trace stops
185
+ * on a phantom shell around every instance. d(q) >= d(c) - |q - c| by the triangle
186
+ * inequality, against the field's own value at the nearest point of the box, is the bound that
187
+ * reports the real clearance. See sampleInstance in globalField.ts.
188
+ */
189
+ let clamped = clamp(object, bounds0, bounds1);
190
+ let outside = length(object - clamped);
191
+
192
+ var distance = 0.0;
193
+ if (outside > 0.0) {
194
+ let dims = vec3<f32>(
195
+ instances[base + 23u],
196
+ instances[base + 23u + 1u],
197
+ instances[base + 23u + 2u],
198
+ );
199
+ let sourceBase = u32(instances[base + 26u]);
200
+ let atBox = sourceAt(sourceBase, bounds0, bounds1, dims, clamped);
201
+ distance = max(outside, atBox - outside) * scale;
202
+ } else {
203
+ let dims = vec3<f32>(
204
+ instances[base + ${INSTANCE_DIMS}u],
205
+ instances[base + ${INSTANCE_DIMS}u + 1u],
206
+ instances[base + ${INSTANCE_DIMS}u + 2u],
207
+ );
208
+ let sourceBase = u32(instances[base + ${INSTANCE_OFFSET}u]);
209
+ distance = sourceAt(sourceBase, bounds0, bounds1, dims, object) * scale;
210
+ }
211
+
212
+ /*
213
+ * **The minimum, because the union of two solids is the nearer surface** — and the colour goes
214
+ * with it rather than beside it. Writing the albedo unconditionally would paint every sample
215
+ * with whichever instance happened to come last, which is a field of the right shape in the
216
+ * wrong colours and looks like a lighting bug rather than a composition one.
217
+ */
218
+ if (distance < best) {
219
+ best = distance;
220
+ bestAlbedo = vec3<f32>(
221
+ instances[base + ${INSTANCE_ALBEDO}u],
222
+ instances[base + ${INSTANCE_ALBEDO}u + 1u],
223
+ instances[base + ${INSTANCE_ALBEDO}u + 2u],
224
+ );
225
+ }
226
+ }
227
+
228
+ /*
229
+ * **Into this cascade's own region of one shared buffer.** Without the base every cascade writes
230
+ * the same samples and the last one wins, which reads as a field that has only its outermost
231
+ * level — the innermost detail simply absent, at the resolution a viewer is closest to.
232
+ */
233
+ field[u32(params[9]) + index] = best;
234
+ let colourAt = (u32(params[9]) + index) * 3u;
235
+ albedo[colourAt] = bestAlbedo.x;
236
+ albedo[colourAt + 1u] = bestAlbedo.y;
237
+ albedo[colourAt + 2u] = bestAlbedo.z;
238
+ }
239
+ `;
@@ -0,0 +1,146 @@
1
+ /** The composed field, drawn — so a pass that fills one can be looked at rather than trusted. */
2
+
3
+ import { SAMPLE_FIELD_WGSL } from './sampleField.wgsl.ts';
4
+
5
+ /**
6
+ * **A visualisation, and it is the honest first consumer of the field.**
7
+ *
8
+ * What Wave 4A's chain is eventually for is indirect light in the shading path, and that is a far
9
+ * larger integration than a pass. What a pass can do now is prove the composition runs on a device
10
+ * and say what it costs — and a distance field is a thing you can *see*, by sphere-tracing it from
11
+ * the camera. If the geometry in the picture is the geometry in the scene, in the right places and
12
+ * the right sizes, the composition is right; if a cascade boundary shows as a seam, the fade is
13
+ * wrong. Neither is available from a number.
14
+ *
15
+ * That is what `DRAFT_SCENES` is for, and it is the same shape the GPU-driven pipeline's three rigs
16
+ * took: a second path drawn beside the first, measured, and kept out of the published set until
17
+ * what it draws is the whole material.
18
+ *
19
+ * **The march is `traceField.ts`'s, minus the cone.** Step by the field's own value, which is a
20
+ * distance nothing can be nearer than; stop where it falls under an epsilon; give up where the ray
21
+ * leaves the outermost cascade, because past that there is no information and stepping on a clamped
22
+ * value converges on the boundary and reports a surface made of nothing.
23
+ */
24
+
25
+ /** Floats in the march's params: the inverse view-projection, the eye, and four scalars. */
26
+ export const MARCH_PARAM_FLOATS = 24;
27
+
28
+ /** Where each field starts. `INV_VIEW_PROJ` is column-major, as `gl-matrix` stores it. */
29
+ export const MARCH_INV_VIEW_PROJ = 0;
30
+ export const MARCH_EYE = 16;
31
+ export const MARCH_LEVELS = 20;
32
+ export const MARCH_SIDE = 21;
33
+ export const MARCH_STEPS = 22;
34
+ export const MARCH_EPSILON = 23;
35
+
36
+ export const MARCH_FIELD_WGSL = /* wgsl */ `
37
+ @group(0) @binding(0) var<storage, read> params: array<f32>;
38
+ @group(0) @binding(1) var<storage, read> cascades: array<f32>;
39
+ @group(0) @binding(2) var<storage, read> fields: array<f32>;
40
+
41
+ ${SAMPLE_FIELD_WGSL}
42
+
43
+ struct Varying {
44
+ @builtin(position) position: vec4<f32>,
45
+ @location(0) uv: vec2<f32>,
46
+ };
47
+
48
+ /*
49
+ * One triangle covering the frame, which is one fewer than two and has no diagonal for a
50
+ * derivative to straddle. Clip y of +1 is the top of the image on both backends — see
51
+ * CLIP_CORRECTION's own note, which spent months saying otherwise — so uv.y counts down from it.
52
+ */
53
+ @vertex
54
+ fn vertexMain(@builtin(vertex_index) index: u32) -> Varying {
55
+ var out: Varying;
56
+ let x = f32(i32(index) / 2) * 4.0 - 1.0;
57
+ let y = f32(i32(index) & 1) * 4.0 - 1.0;
58
+ out.position = vec4<f32>(x, y, 0.0, 1.0);
59
+ out.uv = vec2<f32>(x * 0.5 + 0.5, 0.5 - y * 0.5);
60
+ return out;
61
+ }
62
+
63
+ fn unproject(ndc: vec2<f32>) -> vec3<f32> {
64
+ let m = ${MARCH_INV_VIEW_PROJ}u;
65
+ let clip = vec4<f32>(ndc.x, ndc.y, 0.5, 1.0);
66
+ /*
67
+ * Column-major, so column c is params[c * 4 .. c * 4 + 3]. Any depth gives the same ray from the
68
+ * eye, which is why the z above is a half rather than a near or a far plane — this is the one
69
+ * place the depth convention does not have to be known.
70
+ */
71
+ var world = vec4<f32>(0.0, 0.0, 0.0, 0.0);
72
+ for (var row = 0u; row < 4u; row = row + 1u) {
73
+ world[row] =
74
+ params[m + row] * clip.x +
75
+ params[m + 4u + row] * clip.y +
76
+ params[m + 8u + row] * clip.z +
77
+ params[m + 12u + row] * clip.w;
78
+ }
79
+ return world.xyz / world.w;
80
+ }
81
+
82
+ /** The field's gradient, which for a distance field is the surface normal. */
83
+ fn normalAt(levels: u32, side: u32, p: vec3<f32>, h: f32) -> vec3<f32> {
84
+ let dx = sampleField(levels, side, p + vec3<f32>(h, 0.0, 0.0)) - sampleField(levels, side, p - vec3<f32>(h, 0.0, 0.0));
85
+ let dy = sampleField(levels, side, p + vec3<f32>(0.0, h, 0.0)) - sampleField(levels, side, p - vec3<f32>(0.0, h, 0.0));
86
+ let dz = sampleField(levels, side, p + vec3<f32>(0.0, 0.0, h)) - sampleField(levels, side, p - vec3<f32>(0.0, 0.0, h));
87
+ let g = vec3<f32>(dx, dy, dz);
88
+ let length2 = dot(g, g);
89
+ return select(vec3<f32>(0.0, 1.0, 0.0), g * inverseSqrt(length2), length2 > 1e-12);
90
+ }
91
+
92
+ /** Whether a point is still inside the outermost cascade, which is all the field knows about. */
93
+ fn withinField(levels: u32, p: vec3<f32>) -> bool {
94
+ let base = (levels - 1u) * 8u;
95
+ let low = vec3<f32>(cascades[base], cascades[base + 1u], cascades[base + 2u]);
96
+ let high = vec3<f32>(cascades[base + 3u], cascades[base + 4u], cascades[base + 5u]);
97
+ return all(p >= low) && all(p <= high);
98
+ }
99
+
100
+ @fragment
101
+ fn fragmentMain(vary: Varying) -> @location(0) vec4<f32> {
102
+ let levels = u32(params[${MARCH_LEVELS}]);
103
+ let side = u32(params[${MARCH_SIDE}]);
104
+ let steps = u32(params[${MARCH_STEPS}]);
105
+ let epsilon = params[${MARCH_EPSILON}];
106
+ let eye = vec3<f32>(
107
+ params[${MARCH_EYE}],
108
+ params[${MARCH_EYE} + 1u],
109
+ params[${MARCH_EYE} + 2u],
110
+ );
111
+
112
+ let ndc = vec2<f32>(vary.uv.x * 2.0 - 1.0, 1.0 - vary.uv.y * 2.0);
113
+ let direction = normalize(unproject(ndc) - eye);
114
+
115
+ /* The finest cascade's step, which is the smallest move worth making. */
116
+ let floorStep = cascades[6] * 0.25;
117
+ var travelled = 0.0;
118
+ var hit = false;
119
+ var at = eye;
120
+ for (var i = 0u; i < steps; i = i + 1u) {
121
+ at = eye + direction * travelled;
122
+ if (!withinField(levels, at)) {
123
+ break;
124
+ }
125
+ let distance = sampleField(levels, side, at);
126
+ if (distance <= epsilon) {
127
+ hit = true;
128
+ break;
129
+ }
130
+ travelled = travelled + max(distance, floorStep);
131
+ }
132
+
133
+ if (!hit) {
134
+ /* Nothing here, so the frame keeps whatever drew before this. */
135
+ discard;
136
+ }
137
+
138
+ let normal = normalAt(levels, side, at, cascades[6] * 0.5);
139
+ let sun = normalize(vec3<f32>(0.4, 0.8, 0.45));
140
+ let lambert = max(dot(normal, sun), 0.0);
141
+ /* A hemispheric fill under it, so a face turned away is readable rather than black. */
142
+ let ambient = 0.18 + 0.12 * (normal.y * 0.5 + 0.5);
143
+ let shade = vec3<f32>(0.62, 0.66, 0.72) * (lambert * 0.85 + ambient);
144
+ return vec4<f32>(shade, 1.0);
145
+ }
146
+ `;