@driftengine/core 4.4.2 → 4.6.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 (339) hide show
  1. package/CHANGELOG.json +97 -0
  2. package/README.md +1 -1
  3. package/dist/geometry/boxCsg.d.ts +28 -0
  4. package/dist/geometry/boxCsg.js +139 -0
  5. package/dist/geometry/csg.d.ts +36 -0
  6. package/dist/geometry/csg.js +329 -0
  7. package/dist/geometry/meshBuilder.js +13 -0
  8. package/dist/geometry/meshConcat.js +1 -0
  9. package/dist/geometry/pixelFont.js +2 -0
  10. package/dist/geometry/solid.d.ts +61 -0
  11. package/dist/geometry/solid.js +152 -0
  12. package/dist/geometry/solidFlat.d.ts +35 -0
  13. package/dist/geometry/solidFlat.js +428 -0
  14. package/dist/geometry/solidHarness.d.ts +19 -0
  15. package/dist/geometry/solidHarness.js +66 -0
  16. package/dist/geometry/solidNormals.d.ts +17 -0
  17. package/dist/geometry/solidNormals.js +86 -0
  18. package/dist/geometry/solidRound.d.ts +41 -0
  19. package/dist/geometry/solidRound.js +323 -0
  20. package/dist/geometry/solidWriter.d.ts +16 -0
  21. package/dist/geometry/solidWriter.js +42 -0
  22. package/dist/index.d.ts +28 -3
  23. package/dist/index.js +20 -1
  24. package/dist/render/backend/api.d.ts +34 -14
  25. package/dist/render/backend/drawFog.d.ts +26 -0
  26. package/dist/render/backend/drawFog.js +30 -0
  27. package/dist/render/backend/materialChanges.d.ts +2 -1
  28. package/dist/render/backend/materialChanges.js +6 -1
  29. package/dist/render/backend/webgl2/glassTintPrograms.d.ts +13 -0
  30. package/dist/render/backend/webgl2/glassTintPrograms.js +38 -0
  31. package/dist/render/backend/webgl2/instanced.d.ts +24 -5
  32. package/dist/render/backend/webgl2/instanced.js +72 -15
  33. package/dist/render/backend/webgl2/renderer.d.ts +201 -16
  34. package/dist/render/backend/webgl2/renderer.js +596 -224
  35. package/dist/render/backend/webgpu/buffers.d.ts +29 -1
  36. package/dist/render/backend/webgpu/buffers.js +61 -4
  37. package/dist/render/backend/webgpu/depthPass.d.ts +1 -1
  38. package/dist/render/backend/webgpu/depthPass.js +7 -2
  39. package/dist/render/backend/webgpu/drawCommand.d.ts +5 -0
  40. package/dist/render/backend/webgpu/drawCommand.js +1 -0
  41. package/dist/render/backend/webgpu/flatPass.d.ts +6 -1
  42. package/dist/render/backend/webgpu/flatPass.js +57 -9
  43. package/dist/render/backend/webgpu/glassTintPass.d.ts +28 -0
  44. package/dist/render/backend/webgpu/glassTintPass.js +206 -0
  45. package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +60 -1
  46. package/dist/render/backend/webgpu/gpuDrivenPass.js +305 -5
  47. package/dist/render/backend/webgpu/instanceCullPass.d.ts +34 -0
  48. package/dist/render/backend/webgpu/instanceCullPass.js +144 -0
  49. package/dist/render/backend/webgpu/instanced.d.ts +23 -2
  50. package/dist/render/backend/webgpu/instanced.js +41 -4
  51. package/dist/render/backend/webgpu/latePass.d.ts +30 -0
  52. package/dist/render/backend/webgpu/latePass.js +140 -0
  53. package/dist/render/backend/webgpu/lightVolumePass.js +5 -1
  54. package/dist/render/backend/webgpu/motionPass.d.ts +95 -0
  55. package/dist/render/backend/webgpu/motionPass.js +491 -0
  56. package/dist/render/backend/webgpu/pipelineCache.d.ts +10 -1
  57. package/dist/render/backend/webgpu/pipelineCache.js +11 -1
  58. package/dist/render/backend/webgpu/pointGlassTintPass.d.ts +32 -0
  59. package/dist/render/backend/webgpu/pointGlassTintPass.js +193 -0
  60. package/dist/render/backend/webgpu/pointShadowPass.d.ts +35 -6
  61. package/dist/render/backend/webgpu/pointShadowPass.js +105 -20
  62. package/dist/render/backend/webgpu/postPass.d.ts +3 -13
  63. package/dist/render/backend/webgpu/renderer.d.ts +271 -64
  64. package/dist/render/backend/webgpu/renderer.js +1395 -580
  65. package/dist/render/backend/webgpu/scatterPass.js +2 -1
  66. package/dist/render/backend/webgpu/sdfTextPass.js +6 -1
  67. package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.d.ts +18 -0
  68. package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.js +59 -0
  69. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +4 -0
  70. package/dist/render/backend/webgpu/skinPaletteRing.js +4 -0
  71. package/dist/render/backend/webgpu/snapshotMips.d.ts +29 -0
  72. package/dist/render/backend/webgpu/snapshotMips.js +52 -0
  73. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +22 -3
  74. package/dist/render/backend/webgpu/surfaceTexturePass.js +78 -39
  75. package/dist/render/driftLight/bake.d.ts +7 -0
  76. package/dist/render/driftLight/bake.js +61 -56
  77. package/dist/render/driftLight/denseField.d.ts +46 -0
  78. package/dist/render/driftLight/denseField.js +109 -0
  79. package/dist/render/driftLight/lightField.d.ts +10 -5
  80. package/dist/render/driftLight/lightField.js +25 -19
  81. package/dist/render/driftLight/presence.d.ts +50 -0
  82. package/dist/render/driftLight/presence.js +43 -0
  83. package/dist/render/driftLight/uniforms.d.ts +3 -3
  84. package/dist/render/driftLight/uniforms.js +5 -6
  85. package/dist/render/driftLight/worldLightField.d.ts +41 -0
  86. package/dist/render/driftLight/worldLightField.js +66 -0
  87. package/dist/render/fixtureAtlas.d.ts +20 -0
  88. package/dist/render/fixtureAtlas.js +49 -0
  89. package/dist/render/glass.d.ts +45 -0
  90. package/dist/render/glass.js +39 -0
  91. package/dist/render/glassCasters.d.ts +40 -0
  92. package/dist/render/glassCasters.js +84 -0
  93. package/dist/render/glassShadow.d.ts +78 -0
  94. package/dist/render/glassShadow.js +125 -0
  95. package/dist/render/globalMediumPass.d.ts +2 -3
  96. package/dist/render/globalMediumPass.js +2 -8
  97. package/dist/render/gpudriven/lit.d.ts +12 -0
  98. package/dist/render/gpudriven/lit.js +23 -0
  99. package/dist/render/gpudriven/materialTable.d.ts +15 -5
  100. package/dist/render/gpudriven/materialTable.js +26 -6
  101. package/dist/render/gpudriven/pipeline.d.ts +1 -1
  102. package/dist/render/gpudriven/pipeline.js +4 -3
  103. package/dist/render/gpudriven/sunGlass.d.ts +35 -0
  104. package/dist/render/gpudriven/sunGlass.js +89 -0
  105. package/dist/render/instanceCull.d.ts +63 -0
  106. package/dist/render/instanceCull.js +160 -0
  107. package/dist/render/instances.d.ts +15 -0
  108. package/dist/render/lightBudget.d.ts +36 -35
  109. package/dist/render/lightBudget.js +38 -37
  110. package/dist/render/lightGrid.d.ts +42 -0
  111. package/dist/render/lightGrid.js +87 -0
  112. package/dist/render/mesh.d.ts +18 -24
  113. package/dist/render/mesh.js +51 -68
  114. package/dist/render/occlusion.d.ts +10 -0
  115. package/dist/render/occlusion.js +36 -7
  116. package/dist/render/pointGlassTint.d.ts +59 -0
  117. package/dist/render/pointGlassTint.js +198 -0
  118. package/dist/render/pointLightSelection.d.ts +7 -0
  119. package/dist/render/pointLightSelection.js +29 -4
  120. package/dist/render/pointShadowArray.d.ts +56 -3
  121. package/dist/render/pointShadowArray.js +127 -16
  122. package/dist/render/pointShadowMap.d.ts +23 -1
  123. package/dist/render/pointShadowMap.js +27 -1
  124. package/dist/render/rainField.d.ts +13 -0
  125. package/dist/render/rainField.js +27 -5
  126. package/dist/render/recon/changeFrames.d.ts +15 -0
  127. package/dist/render/recon/changeFrames.js +21 -0
  128. package/dist/render/recon/lateDepth.d.ts +11 -0
  129. package/dist/render/recon/lateDepth.js +70 -0
  130. package/dist/render/recon/lateRouting.d.ts +14 -0
  131. package/dist/render/recon/lateRouting.js +18 -0
  132. package/dist/render/recon/mover.d.ts +57 -0
  133. package/dist/render/recon/mover.js +86 -0
  134. package/dist/render/recon/resolve.d.ts +34 -4
  135. package/dist/render/recon/resolve.js +161 -20
  136. package/dist/render/renderQuality.d.ts +35 -0
  137. package/dist/render/renderQuality.js +7 -0
  138. package/dist/render/rendererHarness.js +16 -0
  139. package/dist/render/sceneTarget.d.ts +9 -1
  140. package/dist/render/sceneTarget.js +60 -12
  141. package/dist/render/shaders/depth.d.ts +16 -1
  142. package/dist/render/shaders/depth.js +94 -15
  143. package/dist/render/shaders/flat/directionalShadow.js +91 -6
  144. package/dist/render/shaders/flat/driftLight.d.ts +1 -1
  145. package/dist/render/shaders/flat/driftLight.js +32 -7
  146. package/dist/render/shaders/flat/glassTint.d.ts +6 -0
  147. package/dist/render/shaders/flat/glassTint.js +25 -0
  148. package/dist/render/shaders/flat/index.d.ts +13 -0
  149. package/dist/render/shaders/flat/index.js +9 -3
  150. package/dist/render/shaders/flat/lampGlass.d.ts +1 -0
  151. package/dist/render/shaders/flat/lampGlass.js +183 -0
  152. package/dist/render/shaders/flat/main.d.ts +1 -1
  153. package/dist/render/shaders/flat/main.js +190 -38
  154. package/dist/render/shaders/flat/pointShadow.d.ts +1 -1
  155. package/dist/render/shaders/flat/pointShadow.js +2 -0
  156. package/dist/render/shaders/flat/preamble.js +96 -26
  157. package/dist/render/shaders/flat/surfaceEffects.d.ts +29 -0
  158. package/dist/render/shaders/flat/surfaceEffects.js +152 -0
  159. package/dist/render/shaders/generated/depth.wgsl.d.ts +230 -7
  160. package/dist/render/shaders/generated/depth.wgsl.js +230 -7
  161. package/dist/render/shaders/generated/flat.wgsl.d.ts +1644 -1596
  162. package/dist/render/shaders/generated/flat.wgsl.js +1683 -1621
  163. package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +3 -13
  164. package/dist/render/shaders/generated/globalMedium.wgsl.js +3 -13
  165. package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +3 -13
  166. package/dist/render/shaders/generated/lightVolume.wgsl.js +21 -17
  167. package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +29 -0
  168. package/dist/render/shaders/generated/octahedralResolve.wgsl.js +29 -0
  169. package/dist/render/shaders/generated/rush.wgsl.d.ts +21 -16
  170. package/dist/render/shaders/generated/rush.wgsl.js +21 -16
  171. package/dist/render/shaders/generated/sdfText.wgsl.d.ts +2 -2
  172. package/dist/render/shaders/generated/sdfText.wgsl.js +2 -2
  173. package/dist/render/shaders/generated/text.wgsl.d.ts +1 -1
  174. package/dist/render/shaders/generated/text.wgsl.js +1 -1
  175. package/dist/render/shaders/gi/driftLight.wgsl.d.ts +1 -1
  176. package/dist/render/shaders/gi/driftLight.wgsl.js +27 -4
  177. package/dist/render/shaders/globalMedium.js +6 -6
  178. package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +7 -0
  179. package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +86 -1
  180. package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +1 -1
  181. package/dist/render/shaders/gpudriven/cull.wgsl.js +11 -2
  182. package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +1 -1
  183. package/dist/render/shaders/gpudriven/materialTable.wgsl.js +3 -1
  184. package/dist/render/shaders/gpudriven/shade.wgsl.js +50 -1
  185. package/dist/render/shaders/gpudriven/sunGlass.wgsl.d.ts +9 -0
  186. package/dist/render/shaders/gpudriven/sunGlass.wgsl.js +133 -0
  187. package/dist/render/shaders/lightVolume.js +6 -6
  188. package/dist/render/shaders/octahedralResolve.d.ts +8 -0
  189. package/dist/render/shaders/octahedralResolve.js +48 -17
  190. package/dist/render/shaders/recon/lateDepth.wgsl.d.ts +1 -0
  191. package/dist/render/shaders/recon/lateDepth.wgsl.js +69 -0
  192. package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
  193. package/dist/render/shaders/recon/motion.wgsl.js +84 -0
  194. package/dist/render/shaders/recon/resolve.wgsl.d.ts +8 -7
  195. package/dist/render/shaders/recon/resolve.wgsl.js +161 -27
  196. package/dist/render/shaders/rush.js +11 -1
  197. package/dist/render/shaders/sdfText.d.ts +1 -1
  198. package/dist/render/shaders/sdfText.js +3 -2
  199. package/dist/render/shaders/text.d.ts +1 -1
  200. package/dist/render/shaders/text.js +18 -9
  201. package/dist/render/shadowCasters.d.ts +20 -1
  202. package/dist/render/shadowCasters.js +15 -1
  203. package/dist/render/shadowMap.d.ts +54 -5
  204. package/dist/render/shadowMap.js +190 -36
  205. package/dist/render/sunGlassTint.d.ts +25 -0
  206. package/dist/render/sunGlassTint.js +79 -0
  207. package/dist/render/surfaceEffects.d.ts +83 -0
  208. package/dist/render/surfaceEffects.js +75 -0
  209. package/dist/render/surfaceScene.d.ts +8 -0
  210. package/dist/render/surfaceScene.js +8 -0
  211. package/dist/render/surfaceTexture.d.ts +18 -2
  212. package/dist/render/surfaceTexture.js +68 -15
  213. package/dist/render/temporalAa.d.ts +25 -6
  214. package/dist/render/temporalAa.js +45 -15
  215. package/dist/render/textureSource.d.ts +30 -0
  216. package/dist/render/textureSource.js +53 -0
  217. package/dist/render/translucentQueue.d.ts +6 -0
  218. package/dist/render/translucentQueue.js +15 -1
  219. package/dist/render/vertexDefaults.js +2 -0
  220. package/dist/world/hlod.d.ts +104 -0
  221. package/dist/world/hlod.js +214 -0
  222. package/package.json +6 -6
  223. package/src/geometry/boxCsg.ts +186 -0
  224. package/src/geometry/csg.ts +384 -0
  225. package/src/geometry/meshBuilder.ts +15 -0
  226. package/src/geometry/meshConcat.ts +1 -0
  227. package/src/geometry/pixelFont.ts +2 -0
  228. package/src/geometry/solid.ts +189 -0
  229. package/src/geometry/solidFlat.ts +522 -0
  230. package/src/geometry/solidHarness.ts +83 -0
  231. package/src/geometry/solidNormals.ts +103 -0
  232. package/src/geometry/solidRound.ts +443 -0
  233. package/src/geometry/solidWriter.ts +58 -0
  234. package/src/index.ts +61 -1
  235. package/src/render/backend/api.ts +36 -11
  236. package/src/render/backend/drawFog.ts +31 -0
  237. package/src/render/backend/materialChanges.ts +9 -2
  238. package/src/render/backend/webgl2/glassTintPrograms.ts +58 -0
  239. package/src/render/backend/webgl2/instanced.ts +80 -14
  240. package/src/render/backend/webgl2/renderer.ts +700 -250
  241. package/src/render/backend/webgpu/buffers.ts +92 -5
  242. package/src/render/backend/webgpu/depthPass.ts +7 -2
  243. package/src/render/backend/webgpu/drawCommand.ts +6 -0
  244. package/src/render/backend/webgpu/flatPass.ts +62 -11
  245. package/src/render/backend/webgpu/glassTintPass.ts +245 -0
  246. package/src/render/backend/webgpu/gpuDrivenPass.ts +349 -5
  247. package/src/render/backend/webgpu/instanceCullPass.ts +165 -0
  248. package/src/render/backend/webgpu/instanced.ts +42 -4
  249. package/src/render/backend/webgpu/latePass.ts +161 -0
  250. package/src/render/backend/webgpu/lightVolumePass.ts +5 -1
  251. package/src/render/backend/webgpu/motionPass.ts +535 -0
  252. package/src/render/backend/webgpu/pipelineCache.ts +12 -1
  253. package/src/render/backend/webgpu/pointGlassTintPass.ts +233 -0
  254. package/src/render/backend/webgpu/pointShadowPass.ts +158 -26
  255. package/src/render/backend/webgpu/renderer.ts +1671 -670
  256. package/src/render/backend/webgpu/scatterPass.ts +2 -1
  257. package/src/render/backend/webgpu/sdfTextPass.ts +6 -1
  258. package/src/render/backend/webgpu/shaders/instanceCull.wgsl.ts +61 -0
  259. package/src/render/backend/webgpu/skinPaletteRing.ts +4 -0
  260. package/src/render/backend/webgpu/snapshotMips.ts +80 -0
  261. package/src/render/backend/webgpu/surfaceTexturePass.ts +91 -51
  262. package/src/render/driftLight/bake.ts +85 -62
  263. package/src/render/driftLight/denseField.ts +149 -0
  264. package/src/render/driftLight/lightField.ts +33 -18
  265. package/src/render/driftLight/presence.ts +69 -0
  266. package/src/render/driftLight/uniforms.ts +8 -9
  267. package/src/render/driftLight/worldLightField.ts +83 -0
  268. package/src/render/fixtureAtlas.ts +63 -0
  269. package/src/render/glass.ts +74 -0
  270. package/src/render/glassCasters.ts +164 -0
  271. package/src/render/glassShadow.ts +153 -0
  272. package/src/render/globalMediumPass.ts +4 -11
  273. package/src/render/gpudriven/lit.ts +31 -0
  274. package/src/render/gpudriven/materialTable.ts +28 -6
  275. package/src/render/gpudriven/pipeline.ts +4 -3
  276. package/src/render/gpudriven/sunGlass.ts +117 -0
  277. package/src/render/instanceCull.ts +205 -0
  278. package/src/render/instances.ts +16 -0
  279. package/src/render/lightBudget.ts +41 -38
  280. package/src/render/lightGrid.ts +130 -0
  281. package/src/render/mesh.ts +59 -72
  282. package/src/render/occlusion.ts +51 -7
  283. package/src/render/pointGlassTint.ts +250 -0
  284. package/src/render/pointLightSelection.ts +72 -4
  285. package/src/render/pointShadowArray.ts +188 -22
  286. package/src/render/pointShadowMap.ts +41 -0
  287. package/src/render/rainField.ts +39 -5
  288. package/src/render/recon/changeFrames.ts +24 -0
  289. package/src/render/recon/lateDepth.ts +83 -0
  290. package/src/render/recon/lateRouting.ts +29 -0
  291. package/src/render/recon/mover.ts +118 -0
  292. package/src/render/recon/resolve.ts +206 -20
  293. package/src/render/renderQuality.ts +47 -0
  294. package/src/render/rendererHarness.ts +16 -0
  295. package/src/render/sceneTarget.ts +62 -11
  296. package/src/render/shaders/depth.ts +118 -15
  297. package/src/render/shaders/flat/directionalShadow.ts +97 -6
  298. package/src/render/shaders/flat/driftLight.ts +32 -7
  299. package/src/render/shaders/flat/glassTint.ts +25 -0
  300. package/src/render/shaders/flat/index.ts +22 -3
  301. package/src/render/shaders/flat/lampGlass.ts +185 -0
  302. package/src/render/shaders/flat/main.ts +190 -38
  303. package/src/render/shaders/flat/pointShadow.ts +2 -0
  304. package/src/render/shaders/flat/preamble.ts +96 -26
  305. package/src/render/shaders/flat/surfaceEffects.ts +152 -0
  306. package/src/render/shaders/generated/depth.wgsl.ts +237 -7
  307. package/src/render/shaders/generated/flat.wgsl.ts +1685 -1621
  308. package/src/render/shaders/generated/globalMedium.wgsl.ts +3 -13
  309. package/src/render/shaders/generated/lightVolume.wgsl.ts +23 -17
  310. package/src/render/shaders/generated/octahedralResolve.wgsl.ts +30 -0
  311. package/src/render/shaders/generated/rush.wgsl.ts +21 -16
  312. package/src/render/shaders/generated/sdfText.wgsl.ts +2 -2
  313. package/src/render/shaders/generated/text.wgsl.ts +1 -1
  314. package/src/render/shaders/gi/driftLight.wgsl.ts +27 -4
  315. package/src/render/shaders/globalMedium.ts +6 -6
  316. package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +88 -1
  317. package/src/render/shaders/gpudriven/cull.wgsl.ts +11 -2
  318. package/src/render/shaders/gpudriven/materialTable.wgsl.ts +3 -1
  319. package/src/render/shaders/gpudriven/shade.wgsl.ts +50 -1
  320. package/src/render/shaders/gpudriven/sunGlass.wgsl.ts +139 -0
  321. package/src/render/shaders/lightVolume.ts +6 -6
  322. package/src/render/shaders/octahedralResolve.ts +50 -17
  323. package/src/render/shaders/recon/lateDepth.wgsl.ts +72 -0
  324. package/src/render/shaders/recon/motion.wgsl.ts +84 -0
  325. package/src/render/shaders/recon/resolve.wgsl.ts +161 -27
  326. package/src/render/shaders/rush.ts +11 -1
  327. package/src/render/shaders/sdfText.ts +3 -2
  328. package/src/render/shaders/text.ts +18 -9
  329. package/src/render/shadowCasters.ts +28 -1
  330. package/src/render/shadowMap.ts +231 -37
  331. package/src/render/sunGlassTint.ts +86 -0
  332. package/src/render/surfaceEffects.ts +132 -0
  333. package/src/render/surfaceScene.ts +16 -0
  334. package/src/render/surfaceTexture.ts +110 -19
  335. package/src/render/temporalAa.ts +78 -14
  336. package/src/render/textureSource.ts +72 -0
  337. package/src/render/translucentQueue.ts +20 -1
  338. package/src/render/vertexDefaults.ts +2 -0
  339. package/src/world/hlod.ts +290 -0
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Instance culls on the device: a batch's instances tested against a view and compacted into an
3
+ * indirect draw, many batches in one compute submit.
4
+ *
5
+ * **Queued during the frame, dispatched in one submit from `flushRings`.** Every submit that can carry
6
+ * a culled draw — the frame, a mirror, a probe face — calls `flushRings` first, so the dispatch that
7
+ * fills a slot is always on the queue ahead of the pass that draws from it. The parameters and the
8
+ * zeroed instance count are written with `queue.writeBuffer` when the job is queued, which the queue
9
+ * orders ahead of both submits.
10
+ *
11
+ * **A slot is one (batch, view) pair in one frame.** A batch drawn from the camera, a mirror and a
12
+ * probe face needs three sets of survivors, so a batch holds up to `MAX_CULL_SLOTS`, taken in order
13
+ * each frame; past that the renderer draws every instance, which is right and merely slower. Each
14
+ * slot owns its buffers and a bind group built once, so queueing allocates nothing.
15
+ */
16
+ import { INSTANCE_STRIDE } from '../../instances.js';
17
+ import { INSTANCE_CULL_WGSL, INSTANCE_CULL_WORKGROUP } from './shaders/instanceCull.wgsl.js';
18
+ import { shaderModule } from './shaderModules.js';
19
+ /** Views a batch can be culled for in one frame. See the header. */
20
+ export const MAX_CULL_SLOTS = 4;
21
+ /** Jobs one frame may queue before the rest draw uncut. A ring size, not an opinion. */
22
+ const MAX_JOBS = 4096;
23
+ /** Bytes of `Params`: six planes, the mesh's sphere, and the instance count padded to 16. */
24
+ const PARAMS_BYTES = 6 * 16 + 16 + 16;
25
+ const USAGE = {
26
+ VERTEX: 0x0020,
27
+ UNIFORM: 0x0040,
28
+ STORAGE: 0x0080,
29
+ INDIRECT: 0x0100,
30
+ COPY_DST: 0x0008,
31
+ };
32
+ export class InstanceCullPass {
33
+ device;
34
+ pipeline;
35
+ layout;
36
+ jobs = new Array(MAX_JOBS).fill(null);
37
+ queued = 0;
38
+ paramsStaging = new ArrayBuffer(PARAMS_BYTES);
39
+ paramFloats = new Float32Array(this.paramsStaging);
40
+ paramWords = new Uint32Array(this.paramsStaging);
41
+ argsStaging = new Uint32Array(5);
42
+ constructor(device) {
43
+ this.device = device;
44
+ this.layout = device.createBindGroupLayout({
45
+ label: 'instances.cull',
46
+ entries: [
47
+ { binding: 0, visibility: 0x4, buffer: { type: 'uniform' } },
48
+ { binding: 1, visibility: 0x4, buffer: { type: 'read-only-storage' } },
49
+ { binding: 2, visibility: 0x4, buffer: { type: 'storage' } },
50
+ { binding: 3, visibility: 0x4, buffer: { type: 'storage' } },
51
+ ],
52
+ });
53
+ this.pipeline = device.createComputePipeline({
54
+ label: 'instances.cull',
55
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.layout] }),
56
+ compute: {
57
+ module: shaderModule(device, { label: 'instances.cull', code: INSTANCE_CULL_WGSL }),
58
+ entryPoint: 'main',
59
+ },
60
+ });
61
+ }
62
+ /** A slot reading `source`, a batch's full instance buffer of `capacity` instances. */
63
+ createSlot(source, capacity, label) {
64
+ const size = Math.max(1, capacity) * INSTANCE_STRIDE;
65
+ const instances = this.device.createBuffer({
66
+ label: `${label}.kept`,
67
+ size,
68
+ usage: USAGE.VERTEX | USAGE.STORAGE,
69
+ });
70
+ const args = this.device.createBuffer({
71
+ label: `${label}.args`,
72
+ size: 20,
73
+ usage: USAGE.INDIRECT | USAGE.STORAGE | USAGE.COPY_DST,
74
+ });
75
+ const params = this.device.createBuffer({
76
+ label: `${label}.params`,
77
+ size: PARAMS_BYTES,
78
+ usage: USAGE.UNIFORM | USAGE.COPY_DST,
79
+ });
80
+ const group = this.device.createBindGroup({
81
+ label: `${label}.cull`,
82
+ layout: this.layout,
83
+ entries: [
84
+ { binding: 0, resource: { buffer: params } },
85
+ { binding: 1, resource: { buffer: source, size } },
86
+ { binding: 2, resource: { buffer: instances } },
87
+ { binding: 3, resource: { buffer: args } },
88
+ ],
89
+ });
90
+ return { instances, args, params, group, count: 0 };
91
+ }
92
+ /**
93
+ * Queue a cull of `count` instances against six `planes`, the mesh's local sphere being
94
+ * (centre, radius). Returns false when the frame's job ring is full, and the caller draws uncut.
95
+ */
96
+ queue(slot, planes, centre, radius, count, indexCount) {
97
+ if (this.queued >= MAX_JOBS)
98
+ return false;
99
+ const floats = this.paramFloats;
100
+ for (let i = 0; i < 24; i++)
101
+ floats[i] = planes[i];
102
+ floats[24] = centre[0] ?? 0;
103
+ floats[25] = centre[1] ?? 0;
104
+ floats[26] = centre[2] ?? 0;
105
+ floats[27] = radius;
106
+ this.paramWords[28] = count;
107
+ this.device.queue.writeBuffer(slot.params, 0, this.paramsStaging);
108
+ const args = this.argsStaging;
109
+ args[0] = indexCount;
110
+ args[1] = 0;
111
+ args[2] = 0;
112
+ args[3] = 0;
113
+ args[4] = 0;
114
+ this.device.queue.writeBuffer(slot.args, 0, args);
115
+ slot.count = count;
116
+ this.jobs[this.queued++] = slot;
117
+ return true;
118
+ }
119
+ /** Dispatch everything queued, in one compute pass and one submit. Nothing queued is nothing done. */
120
+ flush() {
121
+ if (this.queued === 0)
122
+ return;
123
+ const encoder = this.device.createCommandEncoder({ label: 'instances.cull' });
124
+ const pass = encoder.beginComputePass({ label: 'instances.cull' });
125
+ pass.setPipeline(this.pipeline);
126
+ for (let i = 0; i < this.queued; i++) {
127
+ const slot = this.jobs[i];
128
+ if (slot === null || slot === undefined)
129
+ continue;
130
+ pass.setBindGroup(0, slot.group);
131
+ pass.dispatchWorkgroups(Math.ceil(slot.count / INSTANCE_CULL_WORKGROUP));
132
+ this.jobs[i] = null;
133
+ }
134
+ pass.end();
135
+ this.device.queue.submit([encoder.finish()]);
136
+ this.queued = 0;
137
+ }
138
+ }
139
+ /** Every buffer a slot owns, destroyed with its batch. */
140
+ export function destroySlot(slot) {
141
+ slot.instances.destroy();
142
+ slot.args.destroy();
143
+ slot.params.destroy();
144
+ }
@@ -1,3 +1,4 @@
1
+ import type { CullSlot } from './instanceCullPass.ts';
1
2
  import type { MeshInstances } from '../../instances.ts';
2
3
  import type { GpuMesh } from './buffers.ts';
3
4
  /**
@@ -15,13 +16,33 @@ export declare class GpuInstancedBatch {
15
16
  readonly mesh: GpuMesh;
16
17
  readonly capacity: number;
17
18
  private readonly staging;
18
- constructor(device: GPUDevice, mesh: GpuMesh, capacity: number, label: string);
19
+ /** Whether the camera draw culls this batch. See `InstancedOptions.cull`. */
20
+ readonly cull: boolean;
21
+ /** The world box around every live instance, fitted at upload. See `instancesBox`. */
22
+ readonly box: Float32Array<ArrayBuffer>;
23
+ /** One set of survivors per view drawn this frame. See `InstanceCullPass`. */
24
+ readonly slots: CullSlot[];
25
+ /** The frame the slots were last taken in, and how many were taken. */
26
+ slotFrame: number;
27
+ slotsTaken: number;
28
+ constructor(device: GPUDevice, mesh: GpuMesh, capacity: number, label: string, cull?: boolean);
29
+ /** Last frame's packed slots, for a reconstruction; made on first use by the renderer. */
30
+ previousBuffer: GPUBuffer | null;
31
+ /** How many slots the upload before the last one held, and how many the last one holds. */
32
+ previousCount: number;
33
+ liveCount: number;
34
+ /** The frame of the last upload. See `changeFrames.ts`. */
35
+ changed: number;
19
36
  /**
20
37
  * Pack and push `data.count` instances, in one write.
21
38
  *
22
39
  * Only the live prefix, for the reason `uploadScatter` gives: the rest is not drawn and
23
40
  * uploading it would be per-frame waste with nothing reading it.
41
+ *
42
+ * **Given `previous`, the placement still in the staging array — the last upload, which is last
43
+ * frame's — is written there first**, so a reconstruction can pair each slot with where it was.
44
+ * `writeBuffer` copies at the call, so packing afterwards cannot reach that copy.
24
45
  */
25
- upload(queue: GPUQueue, data: MeshInstances): void;
46
+ upload(queue: GPUQueue, data: MeshInstances, previous?: GPUBuffer | null): void;
26
47
  dispose(): void;
27
48
  }
@@ -1,6 +1,10 @@
1
+ import { instancesBox } from '../../instanceCull.js';
1
2
  import { INSTANCE_FLOATS, INSTANCE_STRIDE, packInstances } from '../../instances.js';
3
+ import { destroySlot } from './instanceCullPass.js';
2
4
  /** VERTEX | COPY_DST, spelled the way every other pass here spells it. */
3
5
  const USAGE_VERTEX = 0x0020 | 0x0008;
6
+ /** A culling batch's source is read by the cull as storage too. */
7
+ const USAGE_STORAGE = 0x0080;
4
8
  /**
5
9
  * One mesh's per-instance buffer on the device.
6
10
  *
@@ -16,9 +20,19 @@ export class GpuInstancedBatch {
16
20
  mesh;
17
21
  capacity;
18
22
  staging;
19
- constructor(device, mesh, capacity, label) {
23
+ /** Whether the camera draw culls this batch. See `InstancedOptions.cull`. */
24
+ cull;
25
+ /** The world box around every live instance, fitted at upload. See `instancesBox`. */
26
+ box = new Float32Array([1, 1, 1, -1, -1, -1]);
27
+ /** One set of survivors per view drawn this frame. See `InstanceCullPass`. */
28
+ slots = [];
29
+ /** The frame the slots were last taken in, and how many were taken. */
30
+ slotFrame = -1;
31
+ slotsTaken = 0;
32
+ constructor(device, mesh, capacity, label, cull = false) {
20
33
  this.mesh = mesh;
21
34
  this.capacity = capacity;
35
+ this.cull = cull;
22
36
  this.staging = new Float32Array(capacity * INSTANCE_FLOATS);
23
37
  this.buffer = device.createBuffer({
24
38
  /*
@@ -26,24 +40,47 @@ export class GpuInstancedBatch {
26
40
  * naming the resource it was about, and an unlabelled buffer names nothing.
27
41
  */
28
42
  label,
29
- size: capacity * INSTANCE_STRIDE,
30
- usage: USAGE_VERTEX,
43
+ size: Math.max(1, capacity) * INSTANCE_STRIDE,
44
+ usage: USAGE_VERTEX | (cull ? USAGE_STORAGE : 0),
31
45
  });
32
46
  }
47
+ /** Last frame's packed slots, for a reconstruction; made on first use by the renderer. */
48
+ previousBuffer = null;
49
+ /** How many slots the upload before the last one held, and how many the last one holds. */
50
+ previousCount = 0;
51
+ liveCount = 0;
52
+ /** The frame of the last upload. See `changeFrames.ts`. */
53
+ changed = -1;
33
54
  /**
34
55
  * Pack and push `data.count` instances, in one write.
35
56
  *
36
57
  * Only the live prefix, for the reason `uploadScatter` gives: the rest is not drawn and
37
58
  * uploading it would be per-frame waste with nothing reading it.
59
+ *
60
+ * **Given `previous`, the placement still in the staging array — the last upload, which is last
61
+ * frame's — is written there first**, so a reconstruction can pair each slot with where it was.
62
+ * `writeBuffer` copies at the call, so packing afterwards cannot reach that copy.
38
63
  */
39
- upload(queue, data) {
64
+ upload(queue, data, previous = null) {
65
+ if (this.cull)
66
+ instancesBox(data, this.mesh.bounds, this.box);
40
67
  const count = Math.min(data.count, this.capacity);
68
+ if (previous !== null) {
69
+ if (this.liveCount > 0) {
70
+ queue.writeBuffer(previous, 0, this.staging, 0, this.liveCount * INSTANCE_FLOATS);
71
+ }
72
+ this.previousCount = this.liveCount;
73
+ }
74
+ this.liveCount = count;
41
75
  if (count === 0)
42
76
  return;
43
77
  packInstances(data, this.staging);
44
78
  queue.writeBuffer(this.buffer, 0, this.staging, 0, count * INSTANCE_FLOATS);
45
79
  }
46
80
  dispose() {
81
+ this.previousBuffer?.destroy();
47
82
  this.buffer.destroy();
83
+ for (const slot of this.slots)
84
+ destroySlot(slot);
48
85
  }
49
86
  }
@@ -0,0 +1,30 @@
1
+ import type { DrawCommand } from './drawCommand.ts';
2
+ export declare class LatePass {
3
+ private readonly device;
4
+ private readonly commands;
5
+ private depth;
6
+ private depthTextureView;
7
+ private readonly layout;
8
+ private readonly pipeline;
9
+ private readonly sizes;
10
+ /** The render size and the output size, then the frame's jitter in render texels. */
11
+ private readonly sizeStaging;
12
+ private group;
13
+ private groupSource;
14
+ constructor(device: GPUDevice);
15
+ /** The output-size depth, (re)made when the output changes size. */
16
+ depthView(width: number, height: number): GPUTextureView;
17
+ /**
18
+ * Fill the output-size depth from `source`, the render's single-sample depth, drawn jittered by
19
+ * (`jitterX`, `jitterY`) render texels — which the fill takes back out (`recon/lateDepth.ts`).
20
+ */
21
+ upscale(encoder: GPUCommandEncoder, source: GPUTextureView, renderWidth: number, renderHeight: number, outputWidth: number, outputHeight: number, jitterX: number, jitterY: number): void;
22
+ /** A command slot for one late draw. Every field a caller uses it fills; see `takeCommand`. */
23
+ take(): DrawCommand;
24
+ /** Late draws recorded this frame. */
25
+ get pending(): number;
26
+ /** Every late draw, in the order it was recorded, through the renderer's own issue. */
27
+ replay(pass: GPURenderPassEncoder, issue: (pass: GPURenderPassEncoder, command: DrawCommand) => void): void;
28
+ reset(): void;
29
+ dispose(): void;
30
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * What a reconstructing frame draws after the upscale: its blended draws, at the output size.
3
+ *
4
+ * **Why late.** A blended surface writes no depth the motion pass could test against and has no
5
+ * single motion per pixel — a caption over a wall is two surfaces moving two ways — so a
6
+ * reconstruction can only smear it. Drawn after the resolve, at output resolution and unjittered,
7
+ * it is as sharp as a native frame and has no history to ghost.
8
+ *
9
+ * **What it holds**: a command pool of its own, because the frame graph's pool is spent at every
10
+ * scene flush and these must survive until the reconstruction has run; an output-size depth
11
+ * target; and the pass that fills it from the render's depth. Cost: translucent pixels are shaded
12
+ * at output resolution — 2.25x as many at ratio 1.5, only where translucency is — plus one
13
+ * full-screen depth pass.
14
+ */
15
+ import { DEPTH_CLEAR, DEPTH_FORMAT } from '../../depthConvention.js';
16
+ import { LATE_DEPTH_WGSL } from '../../shaders/recon/lateDepth.wgsl.js';
17
+ import { createCommandPool, resetPool, takeCommand } from './drawCommand.js';
18
+ export class LatePass {
19
+ device;
20
+ commands = createCommandPool(64);
21
+ depth = null;
22
+ depthTextureView = null;
23
+ layout;
24
+ pipeline;
25
+ sizes;
26
+ /** The render size and the output size, then the frame's jitter in render texels. */
27
+ sizeStaging = new Float32Array(8);
28
+ group = null;
29
+ groupSource = null;
30
+ constructor(device) {
31
+ this.device = device;
32
+ this.layout = device.createBindGroupLayout({
33
+ label: 'recon.lateDepth.layout',
34
+ entries: [
35
+ { binding: 0, visibility: 0x2, texture: { sampleType: 'depth' } },
36
+ { binding: 1, visibility: 0x2, buffer: { type: 'uniform' } },
37
+ ],
38
+ });
39
+ const module = device.createShaderModule({ label: 'recon.lateDepth', code: LATE_DEPTH_WGSL });
40
+ this.pipeline = device.createRenderPipeline({
41
+ label: 'recon.lateDepth',
42
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.layout] }),
43
+ vertex: { module, entryPoint: 'lateDepthVert' },
44
+ fragment: { module, entryPoint: 'lateDepthFrag', targets: [] },
45
+ primitive: { topology: 'triangle-list' },
46
+ depthStencil: { format: DEPTH_FORMAT, depthWriteEnabled: true, depthCompare: 'always' },
47
+ });
48
+ this.sizes = device.createBuffer({
49
+ label: 'recon.lateDepth.sizes',
50
+ size: 32,
51
+ usage: 0x40 | 0x8, // UNIFORM | COPY_DST
52
+ });
53
+ }
54
+ /** The output-size depth, (re)made when the output changes size. */
55
+ depthView(width, height) {
56
+ if (this.depth === null || this.depth.width !== width || this.depth.height !== height) {
57
+ this.depth?.destroy();
58
+ this.depth = this.device.createTexture({
59
+ label: 'recon.lateDepth',
60
+ size: [width, height],
61
+ format: DEPTH_FORMAT,
62
+ usage: 0x10, // RENDER_ATTACHMENT
63
+ });
64
+ this.depthTextureView = this.depth.createView();
65
+ }
66
+ return this.depthTextureView;
67
+ }
68
+ /**
69
+ * Fill the output-size depth from `source`, the render's single-sample depth, drawn jittered by
70
+ * (`jitterX`, `jitterY`) render texels — which the fill takes back out (`recon/lateDepth.ts`).
71
+ */
72
+ upscale(encoder, source, renderWidth, renderHeight, outputWidth, outputHeight, jitterX, jitterY) {
73
+ const target = this.depthView(outputWidth, outputHeight);
74
+ this.sizeStaging[0] = renderWidth;
75
+ this.sizeStaging[1] = renderHeight;
76
+ this.sizeStaging[2] = outputWidth;
77
+ this.sizeStaging[3] = outputHeight;
78
+ this.sizeStaging[4] = jitterX;
79
+ this.sizeStaging[5] = jitterY;
80
+ this.device.queue.writeBuffer(this.sizes, 0, this.sizeStaging);
81
+ if (this.group === null || this.groupSource !== source) {
82
+ this.group = this.device.createBindGroup({
83
+ label: 'recon.lateDepth.group',
84
+ layout: this.layout,
85
+ entries: [
86
+ { binding: 0, resource: source },
87
+ { binding: 1, resource: { buffer: this.sizes } },
88
+ ],
89
+ });
90
+ this.groupSource = source;
91
+ }
92
+ const pass = encoder.beginRenderPass({
93
+ label: 'recon.lateDepth',
94
+ colorAttachments: [],
95
+ depthStencilAttachment: {
96
+ view: target,
97
+ depthClearValue: DEPTH_CLEAR,
98
+ depthLoadOp: 'clear',
99
+ depthStoreOp: 'store',
100
+ },
101
+ });
102
+ pass.setPipeline(this.pipeline);
103
+ pass.setBindGroup(0, this.group);
104
+ pass.draw(3);
105
+ pass.end();
106
+ }
107
+ /** A command slot for one late draw. Every field a caller uses it fills; see `takeCommand`. */
108
+ take() {
109
+ const at = takeCommand(this.commands);
110
+ const command = this.commands.commands[at];
111
+ command.offsetCount = 0;
112
+ command.vertexCount = 0;
113
+ command.indexBuffer = null;
114
+ command.indexed = false;
115
+ command.instances = 1;
116
+ command.indirect = null;
117
+ return command;
118
+ }
119
+ /** Late draws recorded this frame. */
120
+ get pending() {
121
+ return this.commands.taken;
122
+ }
123
+ /** Every late draw, in the order it was recorded, through the renderer's own issue. */
124
+ replay(pass, issue) {
125
+ for (let i = 0; i < this.commands.taken; i += 1) {
126
+ const command = this.commands.commands[i];
127
+ if (command !== undefined)
128
+ issue(pass, command);
129
+ }
130
+ }
131
+ reset() {
132
+ resetPool(this.commands);
133
+ }
134
+ dispose() {
135
+ this.depth?.destroy();
136
+ this.depth = null;
137
+ this.depthTextureView = null;
138
+ this.sizes.destroy();
139
+ }
140
+ }
@@ -55,7 +55,11 @@ export function createLightVolumeBindGroupLayout(device, variant) {
55
55
  entries.push({
56
56
  binding: texture.texture,
57
57
  visibility: VISIBILITY_FRAGMENT,
58
- texture: { sampleType: 'unfilterable-float' },
58
+ texture: {
59
+ sampleType: 'unfilterable-float',
60
+ /* The sun's maps are one array since 4.5.0; see `shadowMap.ts`. */
61
+ ...(texture.type === 'sampler2DArray' ? { viewDimension: '2d-array' } : {}),
62
+ },
59
63
  });
60
64
  entries.push({
61
65
  binding: texture.sampler,
@@ -0,0 +1,95 @@
1
+ import type { GpuMesh } from './buffers.ts';
2
+ export declare class MotionPass {
3
+ private readonly device;
4
+ /** The frame's movers, in the order they were drawn. */
5
+ private readonly meshes;
6
+ /** Two matrices a mover — this frame's model and last frame's — at `MOTION_DRAW_FLOATS` apart. */
7
+ private matrices;
8
+ private count;
9
+ /** `RIGID` or `SKINNED` per record, grown beside `matrices`. */
10
+ private kinds;
11
+ /** A skinned record's two palettes, this frame's and last frame's, by record index. */
12
+ private readonly paletteNow;
13
+ private readonly paletteWas;
14
+ /** A rewritten record's last-frame rows, by record index. */
15
+ private readonly previousRows;
16
+ /** One pipeline per stride for rewritten meshes: current and previous rows at that stride. */
17
+ private readonly dynamicPipelines;
18
+ /** An instanced record's placement this frame and last frame, and how many slots pair. */
19
+ private readonly instancesNow;
20
+ private readonly instancesWas;
21
+ private instanceCounts;
22
+ private readonly instancedPipelines;
23
+ private layout;
24
+ private paletteLayout;
25
+ private skinnedLayout;
26
+ /** Keyed by stride and the two skin offsets, packed into one number so a lookup builds nothing. */
27
+ private readonly skinnedPipelines;
28
+ /**
29
+ * A bind group per pair of palette views. The ring keeps its textures from frame to frame, so a
30
+ * steady scene settles on a handful of pairs and builds nothing per frame.
31
+ */
32
+ private readonly paletteGroups;
33
+ private module;
34
+ private pipelineLayout;
35
+ private readonly pipelines;
36
+ private frameBuffer;
37
+ private drawBuffer;
38
+ private drawCapacity;
39
+ private group;
40
+ private readonly frameStaging;
41
+ private drawStaging;
42
+ /** A float view of `drawStaging`, made when it is, so a frame's upload allocates nothing. */
43
+ private drawFloats;
44
+ constructor(device: GPUDevice);
45
+ /** A frame states its movers afresh. */
46
+ reset(): void;
47
+ /** A rigid mover: the same positions under last frame's model. */
48
+ recordRigid(mesh: GpuMesh, model: ArrayLike<number>, previousModel: ArrayLike<number>): void;
49
+ /** A skinned mover: its positions under last frame's pose as well as last frame's model. */
50
+ recordSkinned(mesh: GpuMesh, model: ArrayLike<number>, previousModel: ArrayLike<number>, palette: GPUTextureView, previousPalette: GPUTextureView): void;
51
+ /** A rewritten mesh: its vertices as they were, read from `previous`, under last frame's model. */
52
+ recordDynamic(mesh: GpuMesh, model: ArrayLike<number>, previousModel: ArrayLike<number>, previous: GPUBuffer): void;
53
+ /** An instanced batch: its first `count` slots, each under last frame's placement of that slot. */
54
+ recordInstanced(mesh: GpuMesh, placement: GPUBuffer, previousPlacement: GPUBuffer, count: number): void;
55
+ /** One record's slot: its mesh, its two matrices and its kind. Returns the record's index. */
56
+ private take;
57
+ /**
58
+ * The pipeline layout and module, built once.
59
+ *
60
+ * **The position alone**, at offset zero of the mesh's interleaved rows: that is all the rigid
61
+ * stage reads, and positions are the layout's first attribute and never optional.
62
+ */
63
+ private buildLayout;
64
+ /**
65
+ * The skinned pipeline for one stride and one placement of the joints and weights in it.
66
+ *
67
+ * Same fragment stage, winding and depth test as the rigid one — see `pipelineFor` — with the two
68
+ * skinning attributes read from the interleaved rows at the offsets the mesh records.
69
+ */
70
+ private skinnedPipelineFor;
71
+ /** The rewritten pipeline for one stride: position from each of two buffers of that stride. */
72
+ private dynamicPipelineFor;
73
+ /**
74
+ * The instanced pipeline for one mesh stride: the mesh's positions, then this frame's and last
75
+ * frame's placements, one matrix an instance, as the scene's instanced stage reads them.
76
+ */
77
+ private instancedPipelineFor;
78
+ /** The bind group holding one pair of palettes, built the first time the pair is seen. */
79
+ private paletteGroup;
80
+ /** The pipeline for one vertex stride, built on first sight of it. */
81
+ private pipelineFor;
82
+ /**
83
+ * Every mover of the frame, into `target`, tested against the finished `depth`.
84
+ *
85
+ * **After everything that draws and before the resolve reads it.** `raster` is the scene's clip
86
+ * transform with the generated stages' y negation folded in; `viewProj` and `previousViewProj`
87
+ * are this frame's and last frame's unjittered view-projections.
88
+ *
89
+ * **Cleared every frame, even when nothing moved.** A texel left from last frame is a flag saying
90
+ * "a draw wrote this", and the resolve would take a motion belonging to a surface that is no
91
+ * longer there. The clear is the pass's own load operation, so an empty frame still runs it.
92
+ */
93
+ run(encoder: GPUCommandEncoder, target: GPUTextureView, depth: GPUTextureView, raster: Float32Array, viewProj: Float32Array, previousViewProj: Float32Array, timestampWrites: GPURenderPassTimestampWrites | undefined): void;
94
+ dispose(): void;
95
+ }