@driftengine/core 4.8.5 → 4.8.7

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 (214) hide show
  1. package/CHANGELOG.json +4392 -4250
  2. package/README.md +1 -1
  3. package/dist/index.d.ts +12 -4
  4. package/dist/index.js +12 -2
  5. package/dist/render/ambientHarmonics.d.ts +46 -0
  6. package/dist/render/ambientHarmonics.js +80 -0
  7. package/dist/render/anisotropicLobe.d.ts +10 -0
  8. package/dist/render/anisotropicLobe.js +19 -0
  9. package/dist/render/areaLights.d.ts +54 -0
  10. package/dist/render/areaLights.js +55 -0
  11. package/dist/render/backend/api.d.ts +43 -2
  12. package/dist/render/backend/webgl2/instanced.d.ts +2 -0
  13. package/dist/render/backend/webgl2/instanced.js +11 -2
  14. package/dist/render/backend/webgl2/renderer.d.ts +120 -11
  15. package/dist/render/backend/webgl2/renderer.js +356 -53
  16. package/dist/render/backend/webgl2/sceneCaptureTarget.d.ts +29 -0
  17. package/dist/render/backend/webgl2/sceneCaptureTarget.js +96 -0
  18. package/dist/render/backend/webgl2/skinScatter.d.ts +14 -0
  19. package/dist/render/backend/webgl2/skinScatter.js +88 -26
  20. package/dist/render/backend/webgpu/buffers.js +2 -1
  21. package/dist/render/backend/webgpu/clusterBinner.js +3 -2
  22. package/dist/render/backend/webgpu/flatPass.d.ts +7 -5
  23. package/dist/render/backend/webgpu/flatPass.js +15 -13
  24. package/dist/render/backend/webgpu/particlePass.d.ts +37 -4
  25. package/dist/render/backend/webgpu/particlePass.js +81 -12
  26. package/dist/render/backend/webgpu/postPass.d.ts +6 -1
  27. package/dist/render/backend/webgpu/postPass.js +7 -2
  28. package/dist/render/backend/webgpu/renderer.d.ts +93 -8
  29. package/dist/render/backend/webgpu/renderer.js +483 -93
  30. package/dist/render/backend/webgpu/sceneCaptureTarget.d.ts +24 -0
  31. package/dist/render/backend/webgpu/sceneCaptureTarget.js +59 -0
  32. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.d.ts +1 -1
  33. package/dist/render/backend/webgpu/shaders/clusterBin.wgsl.js +41 -1
  34. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +40 -28
  35. package/dist/render/backend/webgpu/skinPaletteRing.js +69 -32
  36. package/dist/render/backend/webgpu/skinScatterPass.d.ts +10 -2
  37. package/dist/render/backend/webgpu/skinScatterPass.js +59 -9
  38. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +5 -1
  39. package/dist/render/backend/webgpu/surfaceTexturePass.js +45 -5
  40. package/dist/render/backend/webgpu/waterPass.d.ts +1 -1
  41. package/dist/render/bloomChain.d.ts +44 -0
  42. package/dist/render/bloomChain.js +28 -0
  43. package/dist/render/bloomPass.d.ts +3 -1
  44. package/dist/render/bloomPass.js +16 -2
  45. package/dist/render/clusteredLights.d.ts +78 -6
  46. package/dist/render/clusteredLights.js +214 -13
  47. package/dist/render/driftLight/bake.d.ts +2 -0
  48. package/dist/render/driftLight/bake.js +1 -1
  49. package/dist/render/driftLight/falloff.d.ts +4 -2
  50. package/dist/render/driftLight/falloff.js +8 -2
  51. package/dist/render/fixtureAtlas.js +1 -1
  52. package/dist/render/gi/bounceLights.d.ts +3 -2
  53. package/dist/render/gi/bounceLights.js +8 -3
  54. package/dist/render/instanceCull.js +12 -0
  55. package/dist/render/instances.d.ts +47 -11
  56. package/dist/render/instances.js +24 -9
  57. package/dist/render/lightBudget.d.ts +38 -2
  58. package/dist/render/lightBudget.js +48 -5
  59. package/dist/render/lightmap.d.ts +116 -0
  60. package/dist/render/lightmap.js +140 -0
  61. package/dist/render/mesh.js +2 -1
  62. package/dist/render/particleBatch.d.ts +59 -3
  63. package/dist/render/particleBatch.js +53 -2
  64. package/dist/render/particleMaterial.d.ts +6 -1
  65. package/dist/render/particleMaterial.js +10 -2
  66. package/dist/render/particlePool.d.ts +32 -0
  67. package/dist/render/particlePool.js +9 -0
  68. package/dist/render/particleSort.d.ts +34 -0
  69. package/dist/render/particleSort.js +96 -0
  70. package/dist/render/pointLightSelection.d.ts +13 -0
  71. package/dist/render/pointLightSelection.js +3 -1
  72. package/dist/render/renderQuality.d.ts +8 -7
  73. package/dist/render/rendererHarness.js +3 -0
  74. package/dist/render/rgb9e5.d.ts +22 -0
  75. package/dist/render/rgb9e5.js +47 -0
  76. package/dist/render/sceneCapture.d.ts +29 -0
  77. package/dist/render/sceneCapture.js +36 -0
  78. package/dist/render/sceneTarget.d.ts +5 -0
  79. package/dist/render/sceneTarget.js +8 -1
  80. package/dist/render/screenSpaceReflection.d.ts +27 -1
  81. package/dist/render/screenSpaceReflection.js +9 -0
  82. package/dist/render/shaders/bloom.d.ts +8 -4
  83. package/dist/render/shaders/bloom.js +20 -3
  84. package/dist/render/shaders/bolt.d.ts +1 -1
  85. package/dist/render/shaders/bolt.js +7 -1
  86. package/dist/render/shaders/depth.js +11 -0
  87. package/dist/render/shaders/flat/anisotropic.d.ts +1 -1
  88. package/dist/render/shaders/flat/anisotropic.js +37 -3
  89. package/dist/render/shaders/flat/areaLight.d.ts +10 -0
  90. package/dist/render/shaders/flat/areaLight.js +142 -0
  91. package/dist/render/shaders/flat/glassTint.d.ts +3 -2
  92. package/dist/render/shaders/flat/glassTint.js +3 -1
  93. package/dist/render/shaders/flat/index.d.ts +5 -0
  94. package/dist/render/shaders/flat/index.js +46 -6
  95. package/dist/render/shaders/flat/lobes.d.ts +6 -0
  96. package/dist/render/shaders/flat/lobes.js +49 -43
  97. package/dist/render/shaders/flat/main.d.ts +1 -1
  98. package/dist/render/shaders/flat/main.js +158 -121
  99. package/dist/render/shaders/flat/models.d.ts +21 -6
  100. package/dist/render/shaders/flat/models.js +161 -17
  101. package/dist/render/shaders/flat/normalMap.d.ts +10 -0
  102. package/dist/render/shaders/flat/normalMap.js +25 -0
  103. package/dist/render/shaders/flat/preamble.js +84 -40
  104. package/dist/render/shaders/flat/skin.js +6 -5
  105. package/dist/render/shaders/generated/bloom.wgsl.d.ts +13 -3
  106. package/dist/render/shaders/generated/bloom.wgsl.js +13 -3
  107. package/dist/render/shaders/generated/bolt.wgsl.d.ts +1 -1
  108. package/dist/render/shaders/generated/bolt.wgsl.js +1 -1
  109. package/dist/render/shaders/generated/depth.wgsl.d.ts +4 -4
  110. package/dist/render/shaders/generated/depth.wgsl.js +4 -4
  111. package/dist/render/shaders/generated/flat.wgsl.d.ts +1647 -2044
  112. package/dist/render/shaders/generated/flat.wgsl.js +1685 -2082
  113. package/dist/render/shaders/generated/particle.wgsl.d.ts +115 -1
  114. package/dist/render/shaders/generated/particle.wgsl.js +115 -1
  115. package/dist/render/shaders/generated/skinBlur.wgsl.d.ts +12 -2
  116. package/dist/render/shaders/generated/skinBlur.wgsl.js +12 -2
  117. package/dist/render/shaders/generated/ssrTrace.wgsl.d.ts +11 -6
  118. package/dist/render/shaders/generated/ssrTrace.wgsl.js +11 -6
  119. package/dist/render/shaders/generated/water.wgsl.d.ts +23 -16
  120. package/dist/render/shaders/generated/water.wgsl.js +23 -16
  121. package/dist/render/shaders/gi/probeBake.wgsl.js +9 -5
  122. package/dist/render/shaders/particle.d.ts +17 -1
  123. package/dist/render/shaders/particle.js +133 -1
  124. package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
  125. package/dist/render/shaders/recon/motion.wgsl.js +13 -2
  126. package/dist/render/shaders/skinBlur.js +25 -3
  127. package/dist/render/shaders/ssrTrace.js +20 -1
  128. package/dist/render/shaders/water.d.ts +1 -1
  129. package/dist/render/shaders/water.js +12 -3
  130. package/dist/render/skinBlur.d.ts +8 -5
  131. package/dist/render/skinBlur.js +8 -5
  132. package/dist/render/skinScatter.d.ts +3 -1
  133. package/dist/render/skinScatter.js +3 -1
  134. package/dist/render/ssrPass.js +1 -0
  135. package/dist/render/surfaceModel.d.ts +49 -8
  136. package/dist/render/surfaceModel.js +54 -8
  137. package/dist/render/surfaceTexture.d.ts +38 -1
  138. package/dist/render/surfaceTexture.js +37 -2
  139. package/package.json +6 -6
  140. package/src/index.ts +26 -3
  141. package/src/render/ambientHarmonics.ts +92 -0
  142. package/src/render/anisotropicLobe.ts +29 -0
  143. package/src/render/areaLights.ts +97 -0
  144. package/src/render/backend/api.ts +61 -1
  145. package/src/render/backend/webgl2/instanced.ts +12 -2
  146. package/src/render/backend/webgl2/renderer.ts +470 -59
  147. package/src/render/backend/webgl2/sceneCaptureTarget.ts +130 -0
  148. package/src/render/backend/webgl2/skinScatter.ts +120 -43
  149. package/src/render/backend/webgpu/buffers.ts +2 -1
  150. package/src/render/backend/webgpu/clusterBinner.ts +3 -1
  151. package/src/render/backend/webgpu/flatPass.ts +18 -13
  152. package/src/render/backend/webgpu/particlePass.ts +119 -12
  153. package/src/render/backend/webgpu/postPass.ts +7 -2
  154. package/src/render/backend/webgpu/renderer.ts +589 -113
  155. package/src/render/backend/webgpu/sceneCaptureTarget.ts +63 -0
  156. package/src/render/backend/webgpu/shaders/clusterBin.wgsl.ts +41 -1
  157. package/src/render/backend/webgpu/skinPaletteRing.ts +65 -33
  158. package/src/render/backend/webgpu/skinScatterPass.ts +59 -9
  159. package/src/render/backend/webgpu/surfaceTexturePass.ts +57 -6
  160. package/src/render/bloomChain.ts +69 -0
  161. package/src/render/bloomPass.ts +26 -2
  162. package/src/render/clusteredLights.ts +259 -12
  163. package/src/render/driftLight/bake.ts +3 -1
  164. package/src/render/driftLight/falloff.ts +13 -2
  165. package/src/render/fixtureAtlas.ts +1 -1
  166. package/src/render/gi/bounceLights.ts +12 -3
  167. package/src/render/instanceCull.ts +9 -0
  168. package/src/render/instances.ts +61 -12
  169. package/src/render/lightBudget.ts +88 -4
  170. package/src/render/lightmap.ts +243 -0
  171. package/src/render/mesh.ts +2 -1
  172. package/src/render/particleBatch.ts +95 -4
  173. package/src/render/particleMaterial.ts +11 -1
  174. package/src/render/particlePool.ts +36 -0
  175. package/src/render/particleSort.ts +133 -0
  176. package/src/render/pointLightSelection.ts +20 -1
  177. package/src/render/renderQuality.ts +8 -7
  178. package/src/render/rendererHarness.ts +3 -0
  179. package/src/render/rgb9e5.ts +52 -0
  180. package/src/render/sceneCapture.ts +56 -0
  181. package/src/render/sceneTarget.ts +18 -1
  182. package/src/render/screenSpaceReflection.ts +33 -1
  183. package/src/render/shaders/bloom.ts +20 -3
  184. package/src/render/shaders/bolt.ts +7 -1
  185. package/src/render/shaders/depth.ts +11 -0
  186. package/src/render/shaders/flat/anisotropic.ts +37 -3
  187. package/src/render/shaders/flat/areaLight.ts +142 -0
  188. package/src/render/shaders/flat/glassTint.ts +9 -2
  189. package/src/render/shaders/flat/index.ts +51 -6
  190. package/src/render/shaders/flat/lobes.ts +50 -43
  191. package/src/render/shaders/flat/main.ts +158 -121
  192. package/src/render/shaders/flat/models.ts +170 -21
  193. package/src/render/shaders/flat/normalMap.ts +25 -0
  194. package/src/render/shaders/flat/preamble.ts +84 -40
  195. package/src/render/shaders/flat/skin.ts +6 -5
  196. package/src/render/shaders/generated/bloom.wgsl.ts +13 -3
  197. package/src/render/shaders/generated/bolt.wgsl.ts +1 -1
  198. package/src/render/shaders/generated/depth.wgsl.ts +4 -4
  199. package/src/render/shaders/generated/flat.wgsl.ts +1685 -2082
  200. package/src/render/shaders/generated/particle.wgsl.ts +116 -1
  201. package/src/render/shaders/generated/skinBlur.wgsl.ts +12 -2
  202. package/src/render/shaders/generated/ssrTrace.wgsl.ts +11 -6
  203. package/src/render/shaders/generated/water.wgsl.ts +23 -16
  204. package/src/render/shaders/gi/probeBake.wgsl.ts +9 -5
  205. package/src/render/shaders/particle.ts +134 -1
  206. package/src/render/shaders/recon/motion.wgsl.ts +13 -2
  207. package/src/render/shaders/skinBlur.ts +25 -3
  208. package/src/render/shaders/ssrTrace.ts +20 -1
  209. package/src/render/shaders/water.ts +12 -3
  210. package/src/render/skinBlur.ts +8 -5
  211. package/src/render/skinScatter.ts +3 -1
  212. package/src/render/ssrPass.ts +1 -0
  213. package/src/render/surfaceModel.ts +82 -10
  214. package/src/render/surfaceTexture.ts +101 -3
@@ -2,6 +2,9 @@ import { DEPTH_COMPARE } from '../../depthConvention.js';
2
2
  import { particleShaders } from '../../particleMaterial.js';
3
3
  import { PARTICLE_BINDINGS } from '../../shaders/generated/particle.wgsl.js';
4
4
  import { PARTICLE_BLADES, PARTICLE_INDICES, PARTICLE_VERTS } from '../../shaders/particle.js';
5
+ import { DEVICE_PARTICLE_FLOATS } from '../../particlePool.js';
6
+ import { packSpriteStream } from '../../particleBatch.js';
7
+ import { createParticleSort } from '../../particleSort.js';
5
8
  import { DEPTH_FORMAT } from './flatPass.js';
6
9
  import { shaderModule } from './shaderModules.js';
7
10
  import { SCENE_ALPHA_COVERS } from '../../sceneCoverage.js';
@@ -22,7 +25,9 @@ export function particleFragBindings(material) {
22
25
  ? PARTICLE_BINDINGS.PARTICLE_SPARK_FRAG
23
26
  : material === 'mote'
24
27
  ? PARTICLE_BINDINGS.PARTICLE_MOTE_FRAG
25
- : PARTICLE_BINDINGS.PARTICLE_SMOKE_FRAG;
28
+ : material === 'sprite'
29
+ ? PARTICLE_BINDINGS.PARTICLE_SPRITE_FRAG
30
+ : PARTICLE_BINDINGS.PARTICLE_SMOKE_FRAG;
26
31
  return { fields: stage.fields, size: stage.uniformSize };
27
32
  }
28
33
  const VISIBILITY_VERTEX = 0x1;
@@ -31,17 +36,17 @@ const USAGE_VERTEX = 0x0020 | 0x0008;
31
36
  const USAGE_INDEX = 0x0010 | 0x0008;
32
37
  const USAGE_UNIFORM_DST = 0x0040 | 0x0008;
33
38
  /**
34
- * Ten attributes and eight slots, so the per-instance eight share one buffer.
39
+ * Eleven attributes and eight slots, so the per-instance nine share one buffer.
35
40
  *
36
- * **`maxVertexBuffers` is eight and this shader declares ten inputs**, so something has to
37
- * interleave. The per-instance streams are the ones that do: the engine holds them as eight
38
- * separate arrays and they are packed into one interleaved buffer per frame, which is a copy
39
- * the upload was already paying per stream rather than new work.
41
+ * **`maxVertexBuffers` is eight and this shader declares eleven inputs**, so something has to
42
+ * interleave. The per-instance streams are the ones that do: the engine holds them as separate
43
+ * arrays and they are packed into one interleaved buffer per frame, which is a copy the upload
44
+ * was already paying per stream rather than new work.
40
45
  *
41
46
  * Floats per instance, in the order they are packed: position 3, size 1, spin 1, colour 3,
42
- * alpha 1, age 1, seed 1, velocity 3.
47
+ * alpha 1, age 1, seed 1, velocity 3, and a sprite's frame and half-height 2.
43
48
  */
44
- const INSTANCE_FLOATS = 14;
49
+ const INSTANCE_FLOATS = DEVICE_PARTICLE_FLOATS;
45
50
  const INSTANCE_ATTRIBUTES = [
46
51
  { shaderLocation: 2, offset: 0, format: 'float32x3' },
47
52
  { shaderLocation: 3, offset: 12, format: 'float32' },
@@ -51,6 +56,7 @@ const INSTANCE_ATTRIBUTES = [
51
56
  { shaderLocation: 7, offset: 36, format: 'float32' },
52
57
  { shaderLocation: 8, offset: 40, format: 'float32' },
53
58
  { shaderLocation: 9, offset: 44, format: 'float32x3' },
59
+ { shaderLocation: 10, offset: 56, format: 'float32x2' },
54
60
  ];
55
61
  export function particleVertexLayouts() {
56
62
  return [
@@ -87,7 +93,7 @@ export function particleVertexLayouts() {
87
93
  * written last. `layout` still comes from the caller and is shared per material: it is
88
94
  * structural, not data, so nothing about sharing it can go stale mid-frame.
89
95
  */
90
- export function createGpuParticles(device, capacity, material, blend, stretchSec, facing, erosion, coreGain, fog, layout, fragFields, fragSize) {
96
+ export function createGpuParticles(device, capacity, material, blend, stretchSec, facing, erosion, coreGain, fog, layout, fragFields, fragSize, sprite = null) {
91
97
  /* The cross, built once: two blades of four corners, interleaved with the blade index. */
92
98
  const corners = new Float32Array(PARTICLE_VERTS * 3);
93
99
  const CORNERS = [
@@ -158,7 +164,17 @@ export function createGpuParticles(device, capacity, material, blend, stretchSec
158
164
  erosion,
159
165
  coreGain,
160
166
  fog,
167
+ texture: sprite?.texture ?? null,
168
+ cells: sprite?.cells ?? [1, 1],
169
+ blendCells: sprite?.blendCells ?? false,
170
+ softDepth: sprite?.softDepth ?? 0,
171
+ cameraFade: sprite?.cameraFade ?? 0,
172
+ cameraOffset: sprite?.cameraOffset ?? 0,
173
+ order: sprite?.sort === true ? createParticleSort(capacity) : null,
174
+ spriteGroup: null,
175
+ spriteGroupDepth: null,
161
176
  staging: new Float32Array(capacity * INSTANCE_FLOATS),
177
+ spriteStaging: new Float32Array(capacity * 2),
162
178
  vertUniforms,
163
179
  fragUniforms,
164
180
  vertStaging,
@@ -167,7 +183,9 @@ export function createGpuParticles(device, capacity, material, blend, stretchSec
167
183
  fragFloats: new Float32Array(fragStaging),
168
184
  fragInts: new Int32Array(fragStaging),
169
185
  fields: fragFields,
170
- bindGroup: createParticleBindGroup(device, layout, vertUniforms, fragUniforms, fragSize),
186
+ bindGroup: material === 'sprite'
187
+ ? null
188
+ : createParticleBindGroup(device, layout, vertUniforms, fragUniforms, fragSize),
171
189
  dispose() {
172
190
  cornerBuffer.destroy();
173
191
  instances.destroy();
@@ -186,6 +204,8 @@ export function createGpuParticles(device, capacity, material, blend, stretchSec
186
204
  export function packInstances(batch, data) {
187
205
  const n = Math.min(data.count, batch.capacity);
188
206
  const out = batch.staging;
207
+ /* The sprite's frame and half-height, two floats a particle, woven in below. */
208
+ packSpriteStream(data, n, batch.spriteStaging);
189
209
  for (let i = 0; i < n; i++) {
190
210
  const o = i * INSTANCE_FLOATS;
191
211
  const p = i * 3;
@@ -203,12 +223,17 @@ export function packInstances(batch, data) {
203
223
  out[o + 11] = data.velocities[p];
204
224
  out[o + 12] = data.velocities[p + 1];
205
225
  out[o + 13] = data.velocities[p + 2];
226
+ out[o + 14] = batch.spriteStaging[i * 2];
227
+ out[o + 15] = batch.spriteStaging[i * 2 + 1];
206
228
  }
207
229
  return n;
208
230
  }
209
- export function createParticleBindGroupLayout(device, fragSize) {
231
+ /** The floats `packInstances` writes per particle, for the caller's upload. */
232
+ export const PARTICLE_INSTANCE_FLOATS = INSTANCE_FLOATS;
233
+ export function createParticleBindGroupLayout(device, fragSize, sprite = false) {
234
+ const textures = PARTICLE_BINDINGS.PARTICLE_SPRITE_FRAG.textures;
210
235
  return device.createBindGroupLayout({
211
- label: 'particle.layout',
236
+ label: sprite ? 'particle.layout:sprite' : 'particle.layout',
212
237
  entries: [
213
238
  {
214
239
  binding: VERT_BINDING,
@@ -220,6 +245,50 @@ export function createParticleBindGroupLayout(device, fragSize) {
220
245
  visibility: VISIBILITY_FRAGMENT,
221
246
  buffer: { type: 'uniform', minBindingSize: fragSize },
222
247
  },
248
+ /* The image, filtered, and the frame's depth copy, read texel for texel. */
249
+ ...(sprite
250
+ ? [
251
+ {
252
+ binding: textures.uSprite.texture,
253
+ visibility: VISIBILITY_FRAGMENT,
254
+ texture: { sampleType: 'float', viewDimension: '2d-array' },
255
+ },
256
+ {
257
+ binding: textures.uSprite.sampler,
258
+ visibility: VISIBILITY_FRAGMENT,
259
+ sampler: { type: 'filtering' },
260
+ },
261
+ {
262
+ binding: textures.uDepth.texture,
263
+ visibility: VISIBILITY_FRAGMENT,
264
+ texture: { sampleType: 'unfilterable-float' },
265
+ },
266
+ {
267
+ binding: textures.uDepth.sampler,
268
+ visibility: VISIBILITY_FRAGMENT,
269
+ sampler: { type: 'non-filtering' },
270
+ },
271
+ ]
272
+ : []),
273
+ ],
274
+ });
275
+ }
276
+ /**
277
+ * A sprite batch's bind group: its uniforms, its image, and the frame's depth copy — or any
278
+ * single-sample float texture standing in, where the batch asks for no soft edge.
279
+ */
280
+ export function createSpriteBindGroup(device, layout, batch, fragSize, depth, linear, nearest) {
281
+ const textures = PARTICLE_BINDINGS.PARTICLE_SPRITE_FRAG.textures;
282
+ return device.createBindGroup({
283
+ label: 'particle.bindGroup:sprite',
284
+ layout,
285
+ entries: [
286
+ { binding: VERT_BINDING, resource: { buffer: batch.vertUniforms, size: PARTICLE_VERT_SIZE } },
287
+ { binding: FRAG_BINDING, resource: { buffer: batch.fragUniforms, size: fragSize } },
288
+ { binding: textures.uSprite.texture, resource: batch.texture },
289
+ { binding: textures.uSprite.sampler, resource: linear },
290
+ { binding: textures.uDepth.texture, resource: depth },
291
+ { binding: textures.uDepth.sampler, resource: nearest },
223
292
  ],
224
293
  });
225
294
  }
@@ -180,7 +180,12 @@ export declare const PREMULTIPLIED_OVER_BLEND: GPUBlendState;
180
180
  * the reflection's own and its alpha is the coverage this resolve reads.
181
181
  */
182
182
  export declare const REFLECTION_OVER_BLEND: GPUBlendState;
183
- export declare const ADDITIVE_BLEND: GPUBlendState;
183
+ /**
184
+ * The bloom pyramid's way back up: an octave added onto a level that the blend multiplies by that
185
+ * level's tint first — the blend constant, which white makes `one, one` exactly. Into the pyramid's
186
+ * own levels, never the scene. See `BloomResponse`.
187
+ */
188
+ export declare const TINTED_ADD_BLEND: GPUBlendState;
184
189
  /** A fullscreen pass over one or more inputs, writing to one colour target. */
185
190
  export declare function postPipeline(cache: PipelineCache, device: GPUDevice, layout: GPUBindGroupLayout, key: string, fragment: string, format: GPUTextureFormat, blend?: GPUBlendState): GPURenderPipeline;
186
191
  /**
@@ -252,8 +252,13 @@ export const REFLECTION_OVER_BLEND = {
252
252
  color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
253
253
  alpha: SCENE_ALPHA_KEEPS,
254
254
  };
255
- export const ADDITIVE_BLEND = {
256
- color: { srcFactor: 'one', dstFactor: 'one', operation: 'add' },
255
+ /**
256
+ * The bloom pyramid's way back up: an octave added onto a level that the blend multiplies by that
257
+ * level's tint first — the blend constant, which white makes `one, one` exactly. Into the pyramid's
258
+ * own levels, never the scene. See `BloomResponse`.
259
+ */
260
+ export const TINTED_ADD_BLEND = {
261
+ color: { srcFactor: 'one', dstFactor: 'constant', operation: 'add' },
257
262
  alpha: { srcFactor: 'one', dstFactor: 'one', operation: 'add' },
258
263
  };
259
264
  /** A fullscreen pass over one or more inputs, writing to one colour target. */
@@ -8,6 +8,8 @@ import type { RendererApi } from '../api.ts';
8
8
  import { GpuTimestamps } from './gpuTimestamps.ts';
9
9
  import type { Environment, FilmOptions, InsetRect, LightVolumeDrawOptions, SkyColors, TranslucentMeshOptions } from '../webgl2/renderer.ts';
10
10
  import type { IncrementalMeshHandle, MeshOptions } from '../api.ts';
11
+ import type { LightmapPage } from '../../lightmap.ts';
12
+ import { type BloomResponse } from '../../bloomChain.ts';
11
13
  import type { WaterBody } from '../../waterRenderer.ts';
12
14
  import type { WindStreakOptions } from '../../windStreakRenderer.ts';
13
15
  import type { WindField } from '../../windField.ts';
@@ -33,8 +35,8 @@ import type { CausticSheet } from '../../causticsRenderer.ts';
33
35
  import { type GpuCaustics } from './causticsPass.ts';
34
36
  import type { BoltSegments } from '../../boltPool.ts';
35
37
  import type { LineSegments } from '../../linePoints.ts';
36
- import type { ParticleBatchOptions } from '../../particleBatch.ts';
37
- import type { ParticleInstances } from '../../particlePool.ts';
38
+ import { type ParticleBatchOptions } from '../../particleBatch.ts';
39
+ import type { DeviceParticles, ParticleInstances } from '../../particlePool.ts';
38
40
  import type { PlumeOptions, PlumePlacement } from '../../plumeRenderer.ts';
39
41
  import type { InstanceData } from '../../instancedMesh.ts';
40
42
  import { type RenderQuality } from '../../renderQuality.ts';
@@ -518,6 +520,17 @@ export declare class WebGPURenderer implements RendererApi {
518
520
  /** Whether this frame has spread its skin: once, at its first blended draw or before its end. */
519
521
  private skinScattered;
520
522
  private readonly skinInverseProjection;
523
+ /** Scratch for a sprite's depth conversion, so a particle draw allocates nothing. */
524
+ private readonly spriteInverseProjection;
525
+ /** Said once: a sprite asked for a soft edge where no depth copy could be had. */
526
+ private warnedSpriteDepth;
527
+ /** Said once: more rectangles than the fixed arm shades, and no froxel table for the rest. */
528
+ private warnedAreaOverflow;
529
+ /** What a sprite's depth binding holds where no copy was taken. See `spriteDepthStandIn`. */
530
+ private spriteDepthEmpty;
531
+ /** The samplers every sprite batch binds: its image filtered, the depth copy texel for texel. */
532
+ private spriteLinearSampler;
533
+ private spriteNearestSampler;
521
534
  private sceneColorView;
522
535
  /** The multisampled twin, when the profile asks for samples. Resolved into `sceneColor`. */
523
536
  private sceneColorMsaa;
@@ -1171,6 +1184,29 @@ export declare class WebGPURenderer implements RendererApi {
1171
1184
  get compressedFormats(): readonly CompressedTextureFormat[];
1172
1185
  /** Several images of one size as an array's layers. See `RendererApi.createSurfaceTextureArray`. */
1173
1186
  createSurfaceTextureArray(sources: readonly SurfaceSource[], options?: SurfaceTextureOptions): GpuSurfaceTexture;
1187
+ /** A baked lightmap page, as a `lightmapModel` material's `modelMap`. See `RendererApi`. */
1188
+ createLightmap(page: LightmapPage): GpuSurfaceTexture;
1189
+ /**
1190
+ * A texture the scene can be drawn into, for a material to show. See `RendererApi` and
1191
+ * `sceneCapture.ts`. At the world's own format, which under `hdrScene` is half floats.
1192
+ */
1193
+ createSceneCapture(width: number, height: number): GpuSurfaceTexture;
1194
+ /** Each capture's attachments, beside the texture a material binds. */
1195
+ private readonly captureTargets;
1196
+ /**
1197
+ * Whether a scene capture is being drawn: an off-screen pass as a probe bake is, so the frame's
1198
+ * camera, jitter, motion, refraction copy, skin's spread and late routing are left alone, but
1199
+ * lit by the probes and DriftLight as the frame is. See `captureScene`.
1200
+ */
1201
+ private capturePassActive;
1202
+ /**
1203
+ * Draw the scene into a capture from `camera`. See `RendererApi.captureScene`.
1204
+ *
1205
+ * **Its own encoder, as a probe bake's**: the frame's pass is set aside and restored, the rings
1206
+ * are marked and rewound around the submit, and the frame graph is flushed at both boundaries so
1207
+ * no recorded draw crosses one. **Radiance**: the output transform and exposure are held off.
1208
+ */
1209
+ captureScene(capture: GpuSurfaceTexture, camera: Camera, clearColor: Vec3, draw: (camera: Camera) => void): boolean;
1174
1210
  /**
1175
1211
  * GPU textures an `updateSurfaceTexture` replaced, destroyed when the next frame begins.
1176
1212
  *
@@ -1278,6 +1314,11 @@ export declare class WebGPURenderer implements RendererApi {
1278
1314
  * it is on the public surface and removing it would break four repositories to save a method.
1279
1315
  */
1280
1316
  setEnvironmentAmbient(_amount: number): void;
1317
+ /**
1318
+ * The ambient the following draws take, nine spherical-harmonic coefficients or null for the
1319
+ * frame's. See `Renderer.setAmbientSH`: material state, so the next draw takes a slot of its own.
1320
+ */
1321
+ setAmbientSH(coefficients: ArrayLike<number> | null): void;
1281
1322
  /** How reflective the surfaces drawn next are. Clamped, as `renderer.ts` clamps it. */
1282
1323
  setSurfaceReflectivity(amount: number): void;
1283
1324
  /** How bright the environment the surfaces drawn next reflect is. See `renderer.ts`. */
@@ -1428,6 +1469,31 @@ export declare class WebGPURenderer implements RendererApi {
1428
1469
  private gradeCode;
1429
1470
  private gradeExposure;
1430
1471
  drawParticles(batch: GpuParticles, data: ParticleInstances, camera: Camera, env: Environment, timeSeconds: number): void;
1472
+ /**
1473
+ * Draw particles a caller's own compute wrote, where they lie. See `DeviceParticles`.
1474
+ *
1475
+ * **The pool's draw with its instance stream swapped**: the same material, blend, flipbook, soft
1476
+ * edge and fog, reading the caller's buffer in place of the one the pool uploads into — so nothing
1477
+ * crosses back to the CPU. Not sorted, and a count past what the buffer holds is cut to it rather
1478
+ * than handed to a draw the device would refuse with the frame.
1479
+ */
1480
+ drawDeviceParticles(batch: GpuParticles, particles: DeviceParticles, camera: Camera, env: Environment, timeSeconds: number): void;
1481
+ /** A pool's uniforms for this view, and its draw from `instances`: both entry points' tail. */
1482
+ private drawParticleInstances;
1483
+ /**
1484
+ * A sprite's flipbook and fades into its fragment block `f`, and the bind group holding the
1485
+ * frame's depth copy its soft edge reads — built again only when that copy is replaced.
1486
+ *
1487
+ * **The copy is the volume's**: `takeVolumeDepth` ends the frame's pass, resolves the opaque
1488
+ * depth and reopens, once a frame whoever asks. Only in the frame's own picture: in a mirror or
1489
+ * a probe's face it would be another view's depth, and the edge stays hard there, as on WebGL2.
1490
+ * Without a composite there is no copy, and the renderer says so once.
1491
+ */
1492
+ private spriteFades;
1493
+ /** A sprite's image sampler, repeating nothing and filtered, or its depth's, nearest. */
1494
+ private spriteSampler;
1495
+ /** A one-texel `r32float` for a sprite's depth binding where no copy was taken. */
1496
+ private spriteDepthStandIn;
1431
1497
  /**
1432
1498
  * The bind group layout for one particle material, built on first use.
1433
1499
  *
@@ -1733,6 +1799,8 @@ export declare class WebGPURenderer implements RendererApi {
1733
1799
  private writeWind;
1734
1800
  /** Refilled per frame rather than allocated; see `resolvePointLights`. */
1735
1801
  private readonly lights;
1802
+ /** The fixed arm's rectangles as `uAreaLightSize` holds them. See `packAreaSizesAndDoors`. */
1803
+ private readonly areaSizesAndDoors;
1736
1804
  /** Refilled per frame rather than allocated; see `resolveAtmosphere`. */
1737
1805
  private readonly medium;
1738
1806
  private readonly panelLayout;
@@ -2159,7 +2227,7 @@ export declare class WebGPURenderer implements RendererApi {
2159
2227
  * drawn. It also handed the caller a different object from the one the upload was filling.
2160
2228
  */
2161
2229
  private keyed;
2162
- createMesh(data: MeshData, options?: MeshOptions): GpuMesh;
2230
+ createMesh(given: MeshData, options?: MeshOptions): GpuMesh;
2163
2231
  /**
2164
2232
  * Geometry in, handle out — but the geometry lands over as many frames as the caller gives it.
2165
2233
  *
@@ -2169,7 +2237,7 @@ export declare class WebGPURenderer implements RendererApi {
2169
2237
  * straddle one, and going on writing to a dead device would raise validation errors a consumer
2170
2238
  * can do nothing about. Done with `complete` still false is the signal that it was abandoned.
2171
2239
  */
2172
- createMeshIncremental(data: MeshData, options?: MeshOptions): IncrementalMeshHandle;
2240
+ createMeshIncremental(given: MeshData, options?: MeshOptions): IncrementalMeshHandle;
2173
2241
  /**
2174
2242
  * Rewrite a mesh's positions, and its normals where the caller has them.
2175
2243
  *
@@ -2943,9 +3011,10 @@ export declare class WebGPURenderer implements RendererApi {
2943
3011
  */
2944
3012
  private skinSplits;
2945
3013
  /**
2946
- * A skin draw's diffuse half, kept for the spread: the frame's draw again, with the same slots,
2947
- * buffers and bind group, through the pipeline that writes the diffuse alone into the blur's
2948
- * target and tests for the depth its frame half wrote.
3014
+ * A skin draw's diffuse and colour halves, kept for the spread: the frame's draw again, twice,
3015
+ * with the same slots, buffers and bind group, through the pipelines that write the diffuse's
3016
+ * light alone and its colour alone into the blur's targets and test for the depth its frame half
3017
+ * wrote.
2949
3018
  */
2950
3019
  private keepSkinDiffuse;
2951
3020
  /**
@@ -3516,6 +3585,14 @@ export declare class WebGPURenderer implements RendererApi {
3516
3585
  /** This frame's exposure into the tone curve. Starts at the profile's own. */
3517
3586
  private exposure;
3518
3587
  private bloomScale;
3588
+ /** The draw's own ambient, as `packAmbientSH` writes it; zeros are the frame's. */
3589
+ private readonly ambientSH;
3590
+ /** The ramp and each level's tint, as `resolveBloomResponse` writes them; the subtraction and white. */
3591
+ private readonly bloomResponse;
3592
+ /** The response before the last `setBloom`, to tell whether the blocks need writing again. */
3593
+ private readonly bloomResponseNext;
3594
+ /** Each level's tint as a blend constant, rewritten in place: `setBlendConstant` takes a colour. */
3595
+ private readonly bloomConstants;
3519
3596
  /** In scene units, once `setBloom` has moved it; null reads the profile's. */
3520
3597
  private bloomThresholdSet;
3521
3598
  private rushStrength;
@@ -3579,7 +3656,7 @@ export declare class WebGPURenderer implements RendererApi {
3579
3656
  * a 3D write needs both and a wrong one silently shears the cube.
3580
3657
  */
3581
3658
  private uploadGrade;
3582
- setBloom(scale: number, threshold?: number): void;
3659
+ setBloom(scale: number, threshold?: number, response?: BloomResponse | null): void;
3583
3660
  /**
3584
3661
  * How thick the air is, this frame: a global participating medium filling the whole frustum.
3585
3662
  *
@@ -3883,6 +3960,14 @@ export declare class WebGPURenderer implements RendererApi {
3883
3960
  readonly height: number;
3884
3961
  readonly data: Float32Array;
3885
3962
  }, options?: ProbeBakeOptions): boolean;
3963
+ /** One layer of the declared grid from an image. See `Renderer.setProbeLayerImage`. */
3964
+ setProbeLayerImage(layer: number, image: {
3965
+ readonly width: number;
3966
+ readonly height: number;
3967
+ readonly data: Float32Array;
3968
+ }, options?: ProbeBakeOptions): boolean;
3969
+ /** An equirectangular image onto the capture cube's six faces, in the cube's own format. */
3970
+ private uploadProbeFaces;
3886
3971
  /**
3887
3972
  * Upload the photometric profiles a consumer loaded, and rebuild the bind group that holds them.
3888
3973
  *