@driftengine/core 4.9.0 → 4.11.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 (231) hide show
  1. package/CHANGELOG.json +133 -11
  2. package/README.md +43 -38
  3. package/dist/index.d.ts +7 -4
  4. package/dist/index.js +5 -4
  5. package/dist/render/ambientHarmonics.d.ts +1 -1
  6. package/dist/render/ambientHarmonics.js +1 -1
  7. package/dist/render/areaLights.d.ts +4 -4
  8. package/dist/render/areaLights.js +1 -1
  9. package/dist/render/backend/api.d.ts +10 -3
  10. package/dist/render/backend/select.js +11 -5
  11. package/dist/render/backend/webgl2/boneAnimations.d.ts +29 -0
  12. package/dist/render/backend/webgl2/boneAnimations.js +80 -0
  13. package/dist/render/backend/webgl2/instanced.d.ts +5 -1
  14. package/dist/render/backend/webgl2/instanced.js +13 -1
  15. package/dist/render/backend/webgl2/renderer.d.ts +189 -4
  16. package/dist/render/backend/webgl2/renderer.js +614 -66
  17. package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +5 -3
  18. package/dist/render/backend/webgl2/skinPaletteTexture.js +6 -4
  19. package/dist/render/backend/webgpu/boneAnimations.d.ts +34 -0
  20. package/dist/render/backend/webgpu/boneAnimations.js +76 -0
  21. package/dist/render/backend/webgpu/buffers.d.ts +24 -4
  22. package/dist/render/backend/webgpu/buffers.js +116 -59
  23. package/dist/render/backend/webgpu/clothKernels.d.ts +8 -0
  24. package/dist/render/backend/webgpu/clothKernels.js +76 -0
  25. package/dist/render/backend/webgpu/clothOps.d.ts +39 -0
  26. package/dist/render/backend/webgpu/clothOps.js +78 -0
  27. package/dist/render/backend/webgpu/clothSetLayout.d.ts +25 -0
  28. package/dist/render/backend/webgpu/clothSetLayout.js +84 -0
  29. package/dist/render/backend/webgpu/clothSetPack.d.ts +33 -0
  30. package/dist/render/backend/webgpu/clothSetPack.js +144 -0
  31. package/dist/render/backend/webgpu/compressedUpload.d.ts +0 -1
  32. package/dist/render/backend/webgpu/compressedUpload.js +53 -8
  33. package/dist/render/backend/webgpu/depthPass.d.ts +59 -3
  34. package/dist/render/backend/webgpu/depthPass.js +49 -14
  35. package/dist/render/backend/webgpu/drawCommand.d.ts +20 -4
  36. package/dist/render/backend/webgpu/drawCommand.js +11 -3
  37. package/dist/render/backend/webgpu/flatPass.d.ts +85 -42
  38. package/dist/render/backend/webgpu/flatPass.js +137 -20
  39. package/dist/render/backend/webgpu/gpuClothSet.d.ts +80 -0
  40. package/dist/render/backend/webgpu/gpuClothSet.js +462 -0
  41. package/dist/render/backend/webgpu/instanced.d.ts +14 -1
  42. package/dist/render/backend/webgpu/instanced.js +24 -1
  43. package/dist/render/backend/webgpu/latePass.js +1 -0
  44. package/dist/render/backend/webgpu/materialStore.d.ts +101 -0
  45. package/dist/render/backend/webgpu/materialStore.js +265 -0
  46. package/dist/render/backend/webgpu/motionPass.js +15 -6
  47. package/dist/render/backend/webgpu/pipelineCache.d.ts +28 -1
  48. package/dist/render/backend/webgpu/pipelineCache.js +46 -1
  49. package/dist/render/backend/webgpu/postPass.d.ts +1 -1
  50. package/dist/render/backend/webgpu/renderer.d.ts +200 -35
  51. package/dist/render/backend/webgpu/renderer.js +993 -168
  52. package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.d.ts +9 -2
  53. package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.js +121 -47
  54. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +7 -3
  55. package/dist/render/backend/webgpu/skinPaletteRing.js +13 -7
  56. package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +6 -0
  57. package/dist/render/backend/webgpu/skinPaletteTexture.js +7 -1
  58. package/dist/render/backend/webgpu/staticBundles.d.ts +125 -0
  59. package/dist/render/backend/webgpu/staticBundles.js +242 -0
  60. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +10 -3
  61. package/dist/render/backend/webgpu/surfaceTexturePass.js +20 -2
  62. package/dist/render/backend/webgpu/uniformRing.d.ts +21 -0
  63. package/dist/render/backend/webgpu/uniformRing.js +9 -1
  64. package/dist/render/backend/webgpu/vertexFormats.d.ts +22 -0
  65. package/dist/render/backend/webgpu/vertexFormats.js +97 -0
  66. package/dist/render/bloomChain.d.ts +3 -3
  67. package/dist/render/boneAnimation.d.ts +92 -0
  68. package/dist/render/boneAnimation.js +133 -0
  69. package/dist/render/compressedSource.d.ts +33 -13
  70. package/dist/render/compressedSource.js +70 -25
  71. package/dist/render/glCompressed.js +83 -0
  72. package/dist/render/globalMediumPass.d.ts +2 -0
  73. package/dist/render/globalMediumPass.js +1 -0
  74. package/dist/render/indexWidth.d.ts +17 -0
  75. package/dist/render/indexWidth.js +23 -0
  76. package/dist/render/instances.d.ts +26 -0
  77. package/dist/render/lightBudget.d.ts +10 -0
  78. package/dist/render/lightBudget.js +10 -0
  79. package/dist/render/lightMatrix.d.ts +11 -0
  80. package/dist/render/lightMatrix.js +14 -0
  81. package/dist/render/lightmap.d.ts +1 -1
  82. package/dist/render/mesh.d.ts +14 -0
  83. package/dist/render/mesh.js +44 -14
  84. package/dist/render/pointLightSelection.d.ts +4 -4
  85. package/dist/render/renderQuality.d.ts +30 -0
  86. package/dist/render/renderQuality.js +5 -0
  87. package/dist/render/rendererHarness.d.ts +7 -0
  88. package/dist/render/rendererHarness.js +12 -0
  89. package/dist/render/screenSpaceReflection.d.ts +2 -1
  90. package/dist/render/shader.d.ts +15 -0
  91. package/dist/render/shader.js +41 -0
  92. package/dist/render/shaders/boneAnimation.d.ts +19 -0
  93. package/dist/render/shaders/boneAnimation.js +63 -0
  94. package/dist/render/shaders/depth.d.ts +7 -0
  95. package/dist/render/shaders/depth.js +35 -10
  96. package/dist/render/shaders/flat/directionalShadow.js +84 -10
  97. package/dist/render/shaders/flat/glassTint.d.ts +1 -1
  98. package/dist/render/shaders/flat/glassTint.js +3 -0
  99. package/dist/render/shaders/flat/index.d.ts +21 -0
  100. package/dist/render/shaders/flat/index.js +42 -7
  101. package/dist/render/shaders/flat/layered.d.ts +19 -0
  102. package/dist/render/shaders/flat/layered.js +115 -0
  103. package/dist/render/shaders/flat/main.d.ts +1 -1
  104. package/dist/render/shaders/flat/main.js +58 -21
  105. package/dist/render/shaders/flat/mapReads.d.ts +10 -0
  106. package/dist/render/shaders/flat/mapReads.js +38 -0
  107. package/dist/render/shaders/flat/models.js +1 -1
  108. package/dist/render/shaders/flat/movingSun.d.ts +21 -0
  109. package/dist/render/shaders/flat/movingSun.js +46 -0
  110. package/dist/render/shaders/flat/normalMap.d.ts +6 -2
  111. package/dist/render/shaders/flat/normalMap.js +14 -3
  112. package/dist/render/shaders/flat/overlay.d.ts +3 -2
  113. package/dist/render/shaders/flat/overlay.js +42 -20
  114. package/dist/render/shaders/flat/pointShadow.js +2 -2
  115. package/dist/render/shaders/flat/preamble.js +59 -27
  116. package/dist/render/shaders/flat/worldUv.d.ts +22 -0
  117. package/dist/render/shaders/flat/worldUv.js +113 -0
  118. package/dist/render/shaders/generated/depth.wgsl.d.ts +93 -0
  119. package/dist/render/shaders/generated/depth.wgsl.js +93 -0
  120. package/dist/render/shaders/generated/flat.wgsl.d.ts +3616 -3042
  121. package/dist/render/shaders/generated/flat.wgsl.js +3688 -3113
  122. package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +8 -3
  123. package/dist/render/shaders/generated/globalMedium.wgsl.js +8 -3
  124. package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +15 -10
  125. package/dist/render/shaders/generated/lightVolume.wgsl.js +16 -11
  126. package/dist/render/shaders/globalMedium.js +9 -1
  127. package/dist/render/shaders/lightVolume.js +9 -1
  128. package/dist/render/shaders/outputTransform.d.ts +7 -0
  129. package/dist/render/shaders/outputTransform.js +28 -14
  130. package/dist/render/shaders/tangentFrame.d.ts +1 -1
  131. package/dist/render/shaders/tangentFrame.js +16 -3
  132. package/dist/render/shaders/vertexChannel.d.ts +7 -0
  133. package/dist/render/shaders/vertexChannel.js +26 -0
  134. package/dist/render/skinnedClothRun.d.ts +28 -0
  135. package/dist/render/skinnedClothRun.js +103 -35
  136. package/dist/render/staticDraws.d.ts +47 -0
  137. package/dist/render/staticDraws.js +43 -0
  138. package/dist/render/surfaceLayers.d.ts +39 -0
  139. package/dist/render/surfaceLayers.js +26 -0
  140. package/dist/render/surfaceOverlay.d.ts +16 -3
  141. package/dist/render/surfaceOverlay.js +11 -6
  142. package/dist/render/surfaceProjection.d.ts +34 -0
  143. package/dist/render/surfaceProjection.js +30 -0
  144. package/dist/render/surfaceTexture.d.ts +68 -7
  145. package/dist/render/surfaceTexture.js +56 -17
  146. package/dist/render/vertexPacking.d.ts +48 -0
  147. package/dist/render/vertexPacking.js +68 -0
  148. package/package.json +6 -6
  149. package/src/index.ts +12 -4
  150. package/src/render/ambientHarmonics.ts +1 -1
  151. package/src/render/areaLights.ts +4 -4
  152. package/src/render/backend/api.ts +13 -3
  153. package/src/render/backend/select.ts +10 -5
  154. package/src/render/backend/webgl2/boneAnimations.ts +105 -0
  155. package/src/render/backend/webgl2/instanced.ts +20 -1
  156. package/src/render/backend/webgl2/renderer.ts +723 -79
  157. package/src/render/backend/webgl2/skinPaletteTexture.ts +6 -4
  158. package/src/render/backend/webgpu/boneAnimations.ts +97 -0
  159. package/src/render/backend/webgpu/buffers.ts +195 -70
  160. package/src/render/backend/webgpu/clothKernels.ts +86 -0
  161. package/src/render/backend/webgpu/clothOps.ts +86 -0
  162. package/src/render/backend/webgpu/clothSetLayout.ts +102 -0
  163. package/src/render/backend/webgpu/clothSetPack.ts +197 -0
  164. package/src/render/backend/webgpu/compressedUpload.ts +59 -9
  165. package/src/render/backend/webgpu/depthPass.ts +51 -10
  166. package/src/render/backend/webgpu/drawCommand.ts +25 -4
  167. package/src/render/backend/webgpu/flatPass.ts +212 -41
  168. package/src/render/backend/webgpu/gpuClothSet.ts +564 -0
  169. package/src/render/backend/webgpu/instanced.ts +32 -1
  170. package/src/render/backend/webgpu/latePass.ts +1 -0
  171. package/src/render/backend/webgpu/materialStore.ts +276 -0
  172. package/src/render/backend/webgpu/motionPass.ts +18 -7
  173. package/src/render/backend/webgpu/pipelineCache.ts +53 -7
  174. package/src/render/backend/webgpu/renderer.ts +1201 -202
  175. package/src/render/backend/webgpu/shaders/clothSolve.wgsl.ts +121 -47
  176. package/src/render/backend/webgpu/skinPaletteRing.ts +13 -7
  177. package/src/render/backend/webgpu/skinPaletteTexture.ts +7 -1
  178. package/src/render/backend/webgpu/staticBundles.ts +364 -0
  179. package/src/render/backend/webgpu/surfaceTexturePass.ts +29 -3
  180. package/src/render/backend/webgpu/uniformRing.ts +10 -1
  181. package/src/render/backend/webgpu/vertexFormats.ts +113 -0
  182. package/src/render/bloomChain.ts +3 -3
  183. package/src/render/boneAnimation.ts +223 -0
  184. package/src/render/compressedSource.ts +121 -29
  185. package/src/render/glCompressed.ts +83 -0
  186. package/src/render/globalMediumPass.ts +7 -0
  187. package/src/render/indexWidth.ts +27 -0
  188. package/src/render/instances.ts +27 -0
  189. package/src/render/lightBudget.ts +11 -0
  190. package/src/render/lightMatrix.ts +15 -0
  191. package/src/render/lightmap.ts +1 -1
  192. package/src/render/mesh.ts +72 -14
  193. package/src/render/pointLightSelection.ts +4 -4
  194. package/src/render/renderQuality.ts +38 -0
  195. package/src/render/rendererHarness.ts +15 -0
  196. package/src/render/screenSpaceReflection.ts +2 -1
  197. package/src/render/shader.ts +59 -0
  198. package/src/render/shaders/boneAnimation.ts +63 -0
  199. package/src/render/shaders/depth.ts +45 -10
  200. package/src/render/shaders/flat/directionalShadow.ts +84 -10
  201. package/src/render/shaders/flat/glassTint.ts +7 -1
  202. package/src/render/shaders/flat/index.ts +63 -7
  203. package/src/render/shaders/flat/layered.ts +115 -0
  204. package/src/render/shaders/flat/main.ts +58 -21
  205. package/src/render/shaders/flat/mapReads.ts +38 -0
  206. package/src/render/shaders/flat/models.ts +1 -1
  207. package/src/render/shaders/flat/movingSun.ts +46 -0
  208. package/src/render/shaders/flat/normalMap.ts +14 -3
  209. package/src/render/shaders/flat/overlay.ts +42 -20
  210. package/src/render/shaders/flat/pointShadow.ts +2 -2
  211. package/src/render/shaders/flat/preamble.ts +59 -27
  212. package/src/render/shaders/flat/worldUv.ts +113 -0
  213. package/src/render/shaders/generated/depth.wgsl.ts +95 -0
  214. package/src/render/shaders/generated/flat.wgsl.ts +3688 -3113
  215. package/src/render/shaders/generated/globalMedium.wgsl.ts +8 -3
  216. package/src/render/shaders/generated/lightVolume.wgsl.ts +16 -11
  217. package/src/render/shaders/globalMedium.ts +9 -1
  218. package/src/render/shaders/lightVolume.ts +9 -1
  219. package/src/render/shaders/outputTransform.ts +30 -14
  220. package/src/render/shaders/tangentFrame.ts +16 -3
  221. package/src/render/shaders/vertexChannel.ts +27 -0
  222. package/src/render/skinnedClothRun.ts +138 -38
  223. package/src/render/staticDraws.ts +95 -0
  224. package/src/render/surfaceLayers.ts +57 -0
  225. package/src/render/surfaceOverlay.ts +24 -7
  226. package/src/render/surfaceProjection.ts +57 -0
  227. package/src/render/surfaceTexture.ts +124 -27
  228. package/src/render/vertexPacking.ts +109 -0
  229. package/dist/render/backend/webgpu/gpuSkinnedCloth.d.ts +0 -74
  230. package/dist/render/backend/webgpu/gpuSkinnedCloth.js +0 -452
  231. package/src/render/backend/webgpu/gpuSkinnedCloth.ts +0 -502
@@ -1,4 +1,4 @@
1
- import { DEPTH_BINDINGS, DEPTH_CUTOUT_FRAG_WGSL, DEPTH_CUTOUT_VERT_WGSL, DEPTH_FRAG_WGSL, DEPTH_INSTANCED_CUTOUT_VERT_WGSL, DEPTH_INSTANCED_VERT_WGSL, DEPTH_SKINNED_VERT_WGSL, DEPTH_VERT_WGSL, } from '../../shaders/generated/depth.wgsl.js';
1
+ import { DEPTH_BINDINGS, DEPTH_CUTOUT_FRAG_WGSL, DEPTH_CUTOUT_VERT_WGSL, DEPTH_FRAG_WGSL, DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_WGSL, DEPTH_INSTANCED_ANIMATED_VERT_WGSL, DEPTH_INSTANCED_CUTOUT_VERT_WGSL, DEPTH_INSTANCED_VERT_WGSL, DEPTH_SKINNED_VERT_WGSL, DEPTH_VERT_WGSL, } from '../../shaders/generated/depth.wgsl.js';
2
2
  import { vertexBufferLayouts } from './buffers.js';
3
3
  import { vertexConstants } from './flatPass.js';
4
4
  import { shaderModule } from './shaderModules.js';
@@ -37,6 +37,14 @@ const CLOTH_TEXTURES = [
37
37
  DEPTH_BINDINGS.DEPTH_SKINNED_VERT.textures.uClothParticles,
38
38
  DEPTH_BINDINGS.DEPTH_SKINNED_VERT.textures.uClothRest,
39
39
  ];
40
+ /** A bone animation's three textures, at the bindings both animated depth variants declare them. */
41
+ const ANIMATION_TEXTURES = [
42
+ DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uBonePlaces,
43
+ DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uBoneTurns,
44
+ DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uInstanceClocks,
45
+ ];
46
+ export const DEPTH_INSTANCED_ANIMATED_VERT_FIELDS = DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.fields;
47
+ export const DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_FIELDS = DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT.fields;
40
48
  const VISIBILITY_VERTEX = 0x1;
41
49
  const VISIBILITY_FRAGMENT = 0x2;
42
50
  /**
@@ -63,10 +71,19 @@ skinned = false,
63
71
  * Separate for the palette's reason: the plain layout stays exactly what it was, and a frame with
64
72
  * no cutout caster pays nothing.
65
73
  */
66
- cutout = false) {
74
+ cutout = false,
75
+ /** An instanced caster playing a bone animation: its three vertex textures. */
76
+ animated = false) {
67
77
  return device.createBindGroupLayout({
68
- label: skinned ? 'depth.layout.skinned' : cutout ? 'depth.layout.cutout' : 'depth.layout',
78
+ label: `${skinned ? 'depth.layout.skinned' : cutout ? 'depth.layout.cutout' : 'depth.layout'}${animated ? '.animated' : ''}`,
69
79
  entries: [
80
+ ...(animated
81
+ ? ANIMATION_TEXTURES.map((binding) => ({
82
+ binding: binding.texture,
83
+ visibility: VISIBILITY_VERTEX,
84
+ texture: { sampleType: 'unfilterable-float' },
85
+ }))
86
+ : []),
70
87
  /* The texture and no sampler: the shader reads the palette with `textureLoad`, an integer
71
88
  coordinate with nothing to filter, which is what `flatPass.ts` binds for the same
72
89
  palette. naga declares a sampler for it and nothing ever reads one. */
@@ -147,7 +164,9 @@ palette = null,
147
164
  /** The cutout map and its sampler, for a layout built with `cutout`. */
148
165
  cutout = null,
149
166
  /** A skinned group's cloth views: the caster's, or the stand-in where it has none. */
150
- cloth = null) {
167
+ cloth = null,
168
+ /** An animated caster's clip and clocks. See `AnimationViews`. */
169
+ animation = null) {
151
170
  return device.createBindGroup({
152
171
  label: palette !== null
153
172
  ? 'depth.bindGroup.skinned'
@@ -180,6 +199,13 @@ cloth = null) {
180
199
  { binding: CUTOUT_MAP.sampler, resource: cutout.sampler },
181
200
  ]
182
201
  : []),
202
+ ...(animation !== null
203
+ ? [
204
+ { binding: ANIMATION_TEXTURES[0].texture, resource: animation.places },
205
+ { binding: ANIMATION_TEXTURES[1].texture, resource: animation.turns },
206
+ { binding: ANIMATION_TEXTURES[2].texture, resource: animation.clocks },
207
+ ]
208
+ : []),
183
209
  ],
184
210
  });
185
211
  }
@@ -221,20 +247,29 @@ cutout = false,
221
247
  */
222
248
  skinEight = false,
223
249
  /** Whether a skinned caster is placed by a cloth binding, as its visible draw is. The key carries it. */
224
- cloth = false) {
250
+ cloth = false,
251
+ /** An instanced caster playing a bone animation. The key must carry it. */
252
+ animated = false) {
225
253
  return cache.get(key, () => ({
226
254
  label: key,
227
255
  layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }),
228
256
  vertex: {
229
- module: shaderModule(device, cutout
230
- ? instanced
231
- ? { label: 'depth.instanced.cutout.vert', code: DEPTH_INSTANCED_CUTOUT_VERT_WGSL }
232
- : { label: 'depth.cutout.vert', code: DEPTH_CUTOUT_VERT_WGSL }
233
- : instanced
234
- ? { label: 'depth.instanced.vert', code: DEPTH_INSTANCED_VERT_WGSL }
235
- : skinned
236
- ? { label: 'depth.skinned.vert', code: DEPTH_SKINNED_VERT_WGSL }
237
- : { label: 'depth.vert', code: DEPTH_VERT_WGSL }),
257
+ module: shaderModule(device, animated
258
+ ? cutout
259
+ ? {
260
+ label: 'depth.instanced.animated.cutout.vert',
261
+ code: DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_WGSL,
262
+ }
263
+ : { label: 'depth.instanced.animated.vert', code: DEPTH_INSTANCED_ANIMATED_VERT_WGSL }
264
+ : cutout
265
+ ? instanced
266
+ ? { label: 'depth.instanced.cutout.vert', code: DEPTH_INSTANCED_CUTOUT_VERT_WGSL }
267
+ : { label: 'depth.cutout.vert', code: DEPTH_CUTOUT_VERT_WGSL }
268
+ : instanced
269
+ ? { label: 'depth.instanced.vert', code: DEPTH_INSTANCED_VERT_WGSL }
270
+ : skinned
271
+ ? { label: 'depth.skinned.vert', code: DEPTH_SKINNED_VERT_WGSL }
272
+ : { label: 'depth.vert', code: DEPTH_VERT_WGSL }),
238
273
  entryPoint: 'main',
239
274
  buffers: vertexBufferLayouts(present, instanced),
240
275
  ...(skinned && !instanced && !cutout
@@ -2,7 +2,7 @@
2
2
  * One recorded draw, in the only shape this backend ever issues.
3
3
  *
4
4
  * Sampled across three unrelated verbs — panels, particles, wind streaks — the sequence is the
5
- * same every time: a pipeline, a bind group with up to two dynamic offsets, some vertex
5
+ * same every time: a pipeline, a bind group with up to four dynamic offsets, some vertex
6
6
  * buffers, perhaps an index buffer, then a draw. Nothing in it is specific to what is being
7
7
  * drawn except the values.
8
8
  *
@@ -13,14 +13,21 @@
13
13
  export interface DrawCommand {
14
14
  pipeline: GPURenderPipeline | null;
15
15
  bindGroup: GPUBindGroup | null;
16
- /** Dynamic offsets, held as two numbers rather than an array so a reset stays free. */
16
+ /**
17
+ * Dynamic offsets, held as numbers rather than an array so a reset stays free. Four only for a
18
+ * lit mesh: its draw's slot, its pass's, its material's and its view's, in binding order.
19
+ */
17
20
  offsetA: number;
18
21
  offsetB: number;
22
+ offsetC: number;
23
+ offsetD: number;
19
24
  offsetCount: number;
20
25
  /** Fixed length; `vertexCount` says how many slots are live. */
21
26
  readonly vertexBuffers: (GPUBuffer | null)[];
22
27
  vertexCount: number;
23
28
  indexBuffer: GPUBuffer | null;
29
+ /** How wide an index of `indexBuffer` is: a mesh's own, thirty-two bits for everything else. */
30
+ indexFormat: GPUIndexFormat;
24
31
  indexed: boolean;
25
32
  count: number;
26
33
  instances: number;
@@ -29,6 +36,12 @@ export interface DrawCommand {
29
36
  * cull's survivors, counted on the device. Null for every other draw.
30
37
  */
31
38
  indirect: GPUBuffer | null;
39
+ /**
40
+ * Render bundles to execute instead of everything above: a static list recorded once, replayed
41
+ * as one command. Held as the array `executeBundles` takes, kept by the list, so issuing it
42
+ * allocates nothing. Null for every other command, and put back to null by every take.
43
+ */
44
+ bundles: readonly GPURenderBundle[] | null;
32
45
  }
33
46
  export interface CommandPool {
34
47
  commands: DrawCommand[];
@@ -40,8 +53,11 @@ export declare function createCommandPool(capacity: number): CommandPool;
40
53
  /**
41
54
  * Hand out the next command, growing if a frame overruns.
42
55
  *
43
- * The entry is **not cleared**. Every caller fills every field it uses, and clearing here would
44
- * be a write per field per draw for no reader — the same reasoning the node arena uses.
56
+ * The entry is **not cleared**, but for `bundles`. Every caller fills every field it uses, and
57
+ * clearing here would be a write per field per draw for no reader — the same reasoning the node
58
+ * arena uses. `bundles` is the exception because almost no caller knows it exists: a pooled command
59
+ * that once carried a static list's bundles and was then taken for an ordinary draw would replay the
60
+ * list instead, so the one field nobody fills is the one field put back here.
45
61
  */
46
62
  export declare function takeCommand(pool: CommandPool): number;
47
63
  /** Empty the pool for a new frame. Keeps every entry; that is the whole point. */
@@ -2,7 +2,7 @@
2
2
  * One recorded draw, in the only shape this backend ever issues.
3
3
  *
4
4
  * Sampled across three unrelated verbs — panels, particles, wind streaks — the sequence is the
5
- * same every time: a pipeline, a bind group with up to two dynamic offsets, some vertex
5
+ * same every time: a pipeline, a bind group with up to four dynamic offsets, some vertex
6
6
  * buffers, perhaps an index buffer, then a draw. Nothing in it is specific to what is being
7
7
  * drawn except the values.
8
8
  *
@@ -22,14 +22,18 @@ function emptyCommand() {
22
22
  bindGroup: null,
23
23
  offsetA: 0,
24
24
  offsetB: 0,
25
+ offsetC: 0,
26
+ offsetD: 0,
25
27
  offsetCount: 0,
26
28
  vertexBuffers: new Array(VERTEX_BUFFER_SLOTS).fill(null),
27
29
  vertexCount: 0,
28
30
  indexBuffer: null,
31
+ indexFormat: 'uint32',
29
32
  indexed: false,
30
33
  count: 0,
31
34
  instances: 1,
32
35
  indirect: null,
36
+ bundles: null,
33
37
  };
34
38
  }
35
39
  export function createCommandPool(capacity) {
@@ -41,8 +45,11 @@ export function createCommandPool(capacity) {
41
45
  /**
42
46
  * Hand out the next command, growing if a frame overruns.
43
47
  *
44
- * The entry is **not cleared**. Every caller fills every field it uses, and clearing here would
45
- * be a write per field per draw for no reader — the same reasoning the node arena uses.
48
+ * The entry is **not cleared**, but for `bundles`. Every caller fills every field it uses, and
49
+ * clearing here would be a write per field per draw for no reader — the same reasoning the node
50
+ * arena uses. `bundles` is the exception because almost no caller knows it exists: a pooled command
51
+ * that once carried a static list's bundles and was then taken for an ordinary draw would replay the
52
+ * list instead, so the one field nobody fills is the one field put back here.
46
53
  */
47
54
  export function takeCommand(pool) {
48
55
  const at = pool.taken;
@@ -51,6 +58,7 @@ export function takeCommand(pool) {
51
58
  pool.taken = at + 1;
52
59
  if (pool.taken > pool.highWater)
53
60
  pool.highWater = pool.taken;
61
+ pool.commands[at].bundles = null;
54
62
  return at;
55
63
  }
56
64
  /** Empty the pool for a new frame. Keeps every entry; that is the whole point. */
@@ -63,11 +63,27 @@ export interface StageBindings {
63
63
  readonly textures: Readonly<Record<string, TextureBinding>>;
64
64
  /** Each pipeline-overridable constant's id, by the GLSL name it was declared under. */
65
65
  readonly overrides?: Readonly<Record<string, number>>;
66
+ /**
67
+ * The second block, of the uniforms marked `// wgsl:material`: its binding, size and fields.
68
+ * Absent from a stage that marks none, which is every stage but the lit fragment's.
69
+ */
70
+ readonly materialUniforms?: number;
71
+ readonly materialSize?: number;
72
+ readonly materialFields?: StageBindings['fields'];
73
+ /**
74
+ * The vertex stage's view block, of the uniforms marked `// wgsl:view`: the camera, the light's
75
+ * matrix and the wind, which a pass settles. Absent from every stage but the lit vertex one.
76
+ */
77
+ readonly viewUniforms?: number;
78
+ readonly viewSize?: number;
79
+ readonly viewFields?: StageBindings['fields'];
66
80
  }
67
81
  /** The key for a set of vertex flags: the same rule `variantKey` uses, flags on, sorted, joined. */
68
- export declare function flatVertexKey(skinned: boolean, morphed: boolean, instanced?: boolean): string;
82
+ export declare function flatVertexKey(skinned: boolean, morphed: boolean, instanced?: boolean,
83
+ /** Whether an instanced variant plays a bone animation. See `shaders/boneAnimation.ts`. */
84
+ animated?: boolean): string;
69
85
  /** Everything the generator recorded about one variant of the vertex stage. */
70
- export declare function flatVertexBindings(skinned: boolean, morphed?: boolean, instanced?: boolean): StageBindings;
86
+ export declare function flatVertexBindings(skinned: boolean, morphed?: boolean, instanced?: boolean, animated?: boolean): StageBindings;
71
87
  /**
72
88
  * A vertex stage's constants, keyed by each override's **id** as the fragment's are: `SKIN_EIGHT` and
73
89
  * `CLOTH_BOUND` in a skinned stage, `LIGHTMAP_REGIONS` in an instanced one, nothing in any other. Every override a stage declares is set, and one this does
@@ -78,63 +94,51 @@ export declare function vertexConstants(bindings: StageBindings, skinEight: bool
78
94
  /** Whether an instanced stage reads its tint lane as a lightmap region. See `lightmap.ts`. */
79
95
  lightmapRegions?: boolean): Record<string, number>;
80
96
  export declare const FLAT_VERT_FIELDS: {
81
- readonly uViewProj: {
82
- readonly offset: 0;
83
- readonly size: 64;
84
- readonly type: "mat4";
85
- };
86
97
  readonly uHasTangents: {
87
- readonly offset: 64;
98
+ readonly offset: 0;
88
99
  readonly size: 4;
89
100
  readonly type: "int";
90
101
  };
91
- readonly uLightViewProj: {
92
- readonly offset: 80;
93
- readonly size: 64;
94
- readonly type: "mat4";
95
- };
96
102
  readonly uUvScale: {
97
- readonly offset: 144;
103
+ readonly offset: 8;
98
104
  readonly size: 8;
99
105
  readonly type: "vec2";
100
106
  };
101
107
  readonly uUvOffset: {
102
- readonly offset: 152;
108
+ readonly offset: 16;
103
109
  readonly size: 8;
104
110
  readonly type: "vec2";
105
111
  };
106
112
  readonly uModel: {
107
- readonly offset: 160;
113
+ readonly offset: 32;
108
114
  readonly size: 64;
109
115
  readonly type: "mat4";
110
116
  };
111
117
  readonly uTint: {
112
- readonly offset: 224;
118
+ readonly offset: 96;
113
119
  readonly size: 12;
114
120
  readonly type: "vec3";
115
121
  };
116
- readonly uWindDirection: {
117
- readonly offset: 240;
118
- readonly size: 8;
119
- readonly type: "vec2";
120
- };
121
- readonly uWindSpeed: {
122
- readonly offset: 248;
122
+ };
123
+ /** The animated instanced variant's block: the instanced fields, and the clip's `uBoneClip`. */
124
+ export declare const FLAT_ANIMATED_VERT_FIELDS: {
125
+ readonly uHasTangents: {
126
+ readonly offset: 0;
123
127
  readonly size: 4;
124
- readonly type: "float";
128
+ readonly type: "int";
125
129
  };
126
- readonly uWindGust: {
127
- readonly offset: 252;
128
- readonly size: 4;
129
- readonly type: "float";
130
+ readonly uUvScale: {
131
+ readonly offset: 8;
132
+ readonly size: 8;
133
+ readonly type: "vec2";
130
134
  };
131
- readonly uWindTime: {
132
- readonly offset: 256;
133
- readonly size: 4;
134
- readonly type: "float";
135
+ readonly uUvOffset: {
136
+ readonly offset: 16;
137
+ readonly size: 8;
138
+ readonly type: "vec2";
135
139
  };
136
- readonly uWindSpatialPhase: {
137
- readonly offset: 264;
140
+ readonly uBoneClip: {
141
+ readonly offset: 24;
138
142
  readonly size: 8;
139
143
  readonly type: "vec2";
140
144
  };
@@ -147,6 +151,14 @@ export declare const FLAT_VERT_FIELDS: {
147
151
  * 144 bytes a slot and is what a single ring costs.
148
152
  */
149
153
  export declare const FLAT_VERT_SIZE: number;
154
+ /** The view block's fields, binding and size: the largest variant's, as `FLAT_VERT_SIZE` is. */
155
+ export declare const FLAT_VIEW_FIELDS: Readonly<Record<string, {
156
+ readonly offset: number;
157
+ readonly size: number;
158
+ readonly length?: number;
159
+ readonly stride?: number;
160
+ }>>;
161
+ export declare const FLAT_VIEW_SIZE: number;
150
162
  /**
151
163
  * The most sampled textures and distinct samplers any lit variant carrying the environment probe
152
164
  * binds in its fragment stage, counted from the generated bindings: what a device must allow per
@@ -159,16 +171,43 @@ export declare function probeStageCeilings(): {
159
171
  };
160
172
  /** Everything the generator recorded about one permutation of the fragment stage. */
161
173
  export declare function flatFragmentBindings(variant: FlatVariant): StageBindings;
174
+ /**
175
+ * The lit fragment stage's two blocks as the renderer keeps them on the CPU: the pass's, then the
176
+ * material's straight after it, in one scratch, with every field at its offset in that scratch.
177
+ *
178
+ * **One scratch rather than two, so no setter has to know which block its field is in.** A setter
179
+ * writes by name, as it always has; the draw copies the material's bytes — `passSize` onwards — into
180
+ * the store and the pass's bytes into a ring slot, each only when something has changed it.
181
+ */
182
+ export interface FlatFragmentScratch {
183
+ readonly fields: StageBindings['fields'];
184
+ /** Bytes of the pass's block, which is where the material's starts in the scratch. */
185
+ readonly passSize: number;
186
+ readonly passBinding: number;
187
+ readonly materialSize: number;
188
+ readonly materialBinding: number;
189
+ }
190
+ export declare function flatFragmentScratch(variant: FlatVariant): FlatFragmentScratch;
162
191
  /** The depth format both backends compare with. */
163
192
  export { DEPTH_FORMAT } from '../../depthConvention.ts';
164
193
  /**
165
194
  * The layout this variant binds against.
166
195
  *
167
- * The vertex block is **dynamic**, because every draw supplies its own model matrix and tint
168
- * from its own slot of one buffer. The fragment block is not: it holds the lights, the fog
169
- * and the camera, settled once by `bindMeshPass` and unchanged between draws.
196
+ * All four blocks are **dynamic**: the vertex block because every draw supplies its own model
197
+ * matrix and tint from its own slot of one buffer; the fragment stage's pass block — the lights, the
198
+ * fog, the camera — and the vertex stage's view block because a frame binds more than one pass; and
199
+ * the material block because a material changes between draws. Their dynamic offsets go in binding
200
+ * order: the draw's, the pass's, the material's, the view's.
170
201
  */
171
- export declare function createFlatBindGroupLayout(device: GPUDevice, variant: FlatVariant, skinned?: boolean, morphed?: boolean): GPUBindGroupLayout;
202
+ export declare function createFlatBindGroupLayout(device: GPUDevice, variant: FlatVariant, skinned?: boolean, morphed?: boolean,
203
+ /** The instanced variant that plays a bone animation: its three vertex textures. */
204
+ animated?: boolean): GPUBindGroupLayout;
205
+ /** What an animated draw binds besides its material: the clip's two textures and its batch's clocks. */
206
+ export interface AnimationViews {
207
+ readonly places: GPUTextureView;
208
+ readonly turns: GPUTextureView;
209
+ readonly clocks: GPUTextureView;
210
+ }
172
211
  /**
173
212
  * Bind the buffers and one view per declared texture.
174
213
  *
@@ -178,7 +217,7 @@ export declare function createFlatBindGroupLayout(device: GPUDevice, variant: Fl
178
217
  * and WebGPU still requires something there, which is why `renderer.ts` keeps an
179
218
  * `emptyTexture2D` for the same reason on the other side.
180
219
  */
181
- export declare function createFlatBindGroup(device: GPUDevice, layout: GPUBindGroupLayout, variant: FlatVariant, perDraw: GPUBuffer, perFrame: GPUBuffer, resolve: (name: string) => {
220
+ export declare function createFlatBindGroup(device: GPUDevice, layout: GPUBindGroupLayout, variant: FlatVariant, perDraw: GPUBuffer, passes: GPUBuffer, materials: GPUBuffer, views: GPUBuffer, resolve: (name: string) => {
182
221
  view: GPUTextureView;
183
222
  sampler: GPUSampler;
184
223
  },
@@ -187,7 +226,9 @@ palette?: GPUTextureView | null,
187
226
  /** The delta view for a morphed bind group, or null for an unmorphed one. */
188
227
  deltas?: GPUTextureView | null,
189
228
  /** A skinned bind group's cloth views — the draw's, or the stand-in where it sets none. */
190
- cloth?: ClothViews | null): GPUBindGroup;
229
+ cloth?: ClothViews | null,
230
+ /** An animated instanced group's views. See `AnimationViews`. */
231
+ animation?: AnimationViews | null): GPUBindGroup;
191
232
  /**
192
233
  * The pipeline, cached by the state that distinguishes it.
193
234
  *
@@ -251,7 +292,9 @@ skinPass?: SkinHalf,
251
292
  * The reflection pass's surface half: the draw again, against its own depth, into the two
252
293
  * targets `reflectionSurfacePass.ts` holds. The key must carry it: `|rs`.
253
294
  */
254
- reflectionSurface?: boolean): GPURenderPipeline;
295
+ reflectionSurface?: boolean,
296
+ /** An instanced pipeline that plays a bone animation. The key must carry it: `|anim`. */
297
+ animated?: boolean): GPURenderPipeline | null;
255
298
  /**
256
299
  * The same pipeline, compiled off the main thread.
257
300
  *