@driftengine/core 4.8.3 → 4.8.4

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 (178) hide show
  1. package/CHANGELOG.json +71 -0
  2. package/README.md +1 -1
  3. package/dist/geometry/meshConcat.js +2 -0
  4. package/dist/index.d.ts +10 -4
  5. package/dist/index.js +16 -1
  6. package/dist/math/scalar.js +1 -1
  7. package/dist/render/anisotropicLobe.d.ts +7 -0
  8. package/dist/render/anisotropicLobe.js +33 -0
  9. package/dist/render/backend/api.d.ts +41 -4
  10. package/dist/render/backend/select.js +8 -0
  11. package/dist/render/backend/webgl2/clothTextures.d.ts +27 -0
  12. package/dist/render/backend/webgl2/clothTextures.js +93 -0
  13. package/dist/render/backend/webgl2/renderer.d.ts +136 -3
  14. package/dist/render/backend/webgl2/renderer.js +604 -63
  15. package/dist/render/backend/webgl2/skinScatter.d.ts +50 -0
  16. package/dist/render/backend/webgl2/skinScatter.js +256 -0
  17. package/dist/render/backend/webgpu/buffers.d.ts +25 -11
  18. package/dist/render/backend/webgpu/buffers.js +98 -49
  19. package/dist/render/backend/webgpu/clothSolvePack.d.ts +27 -0
  20. package/dist/render/backend/webgpu/clothSolvePack.js +129 -0
  21. package/dist/render/backend/webgpu/clothTextures.d.ts +68 -0
  22. package/dist/render/backend/webgpu/clothTextures.js +145 -0
  23. package/dist/render/backend/webgpu/compressedUpload.d.ts +18 -0
  24. package/dist/render/backend/webgpu/compressedUpload.js +38 -0
  25. package/dist/render/backend/webgpu/computeHost.d.ts +21 -0
  26. package/dist/render/backend/webgpu/computeHost.js +5 -0
  27. package/dist/render/backend/webgpu/depthPass.d.ts +16 -6
  28. package/dist/render/backend/webgpu/depthPass.js +39 -9
  29. package/dist/render/backend/webgpu/drawCommand.js +6 -2
  30. package/dist/render/backend/webgpu/flatPass.d.ts +38 -4
  31. package/dist/render/backend/webgpu/flatPass.js +109 -12
  32. package/dist/render/backend/webgpu/gpuSkinnedCloth.d.ts +74 -0
  33. package/dist/render/backend/webgpu/gpuSkinnedCloth.js +452 -0
  34. package/dist/render/backend/webgpu/motionPass.d.ts +20 -0
  35. package/dist/render/backend/webgpu/motionPass.js +106 -9
  36. package/dist/render/backend/webgpu/postPass.d.ts +3 -1
  37. package/dist/render/backend/webgpu/postPass.js +6 -3
  38. package/dist/render/backend/webgpu/renderer.d.ts +113 -5
  39. package/dist/render/backend/webgpu/renderer.js +498 -48
  40. package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.d.ts +33 -0
  41. package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.js +469 -0
  42. package/dist/render/backend/webgpu/skinScatterPass.d.ts +51 -0
  43. package/dist/render/backend/webgpu/skinScatterPass.js +253 -0
  44. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +4 -1
  45. package/dist/render/backend/webgpu/surfaceTexturePass.js +37 -12
  46. package/dist/render/clothBindingData.d.ts +41 -0
  47. package/dist/render/clothBindingData.js +72 -0
  48. package/dist/render/clothPlacement.d.ts +25 -0
  49. package/dist/render/clothPlacement.js +85 -0
  50. package/dist/render/compressedSource.d.ts +66 -0
  51. package/dist/render/compressedSource.js +138 -0
  52. package/dist/render/cutoutCaster.d.ts +2 -0
  53. package/dist/render/cutoutCaster.js +2 -0
  54. package/dist/render/cutoutDither.d.ts +51 -0
  55. package/dist/render/cutoutDither.js +90 -0
  56. package/dist/render/eyeRefraction.d.ts +35 -0
  57. package/dist/render/eyeRefraction.js +40 -0
  58. package/dist/render/glCompressed.d.ts +27 -0
  59. package/dist/render/glCompressed.js +53 -0
  60. package/dist/render/hairLobes.d.ts +70 -0
  61. package/dist/render/hairLobes.js +120 -0
  62. package/dist/render/lightBudget.d.ts +22 -0
  63. package/dist/render/lightBudget.js +22 -0
  64. package/dist/render/mesh.d.ts +7 -0
  65. package/dist/render/mesh.js +24 -0
  66. package/dist/render/recon/motionVectors.d.ts +4 -2
  67. package/dist/render/recon/motionVectors.js +6 -3
  68. package/dist/render/renderQuality.d.ts +20 -0
  69. package/dist/render/renderQuality.js +5 -0
  70. package/dist/render/rendererHarness.js +4 -0
  71. package/dist/render/sceneTarget.d.ts +12 -0
  72. package/dist/render/sceneTarget.js +14 -0
  73. package/dist/render/shaders/clothBinding.d.ts +22 -0
  74. package/dist/render/shaders/clothBinding.js +80 -0
  75. package/dist/render/shaders/depth.js +42 -6
  76. package/dist/render/shaders/flat/anisotropic.d.ts +15 -0
  77. package/dist/render/shaders/flat/anisotropic.js +68 -0
  78. package/dist/render/shaders/flat/eye.d.ts +1 -0
  79. package/dist/render/shaders/flat/eye.js +81 -0
  80. package/dist/render/shaders/flat/hair.d.ts +1 -0
  81. package/dist/render/shaders/flat/hair.js +101 -0
  82. package/dist/render/shaders/flat/index.js +36 -2
  83. package/dist/render/shaders/flat/main.d.ts +1 -1
  84. package/dist/render/shaders/flat/main.js +113 -17
  85. package/dist/render/shaders/flat/models.d.ts +14 -0
  86. package/dist/render/shaders/flat/models.js +273 -0
  87. package/dist/render/shaders/flat/preamble.js +26 -24
  88. package/dist/render/shaders/flat/skin.d.ts +1 -0
  89. package/dist/render/shaders/flat/skin.js +114 -0
  90. package/dist/render/shaders/generated/depth.wgsl.d.ts +38 -16
  91. package/dist/render/shaders/generated/depth.wgsl.js +38 -16
  92. package/dist/render/shaders/generated/flat.wgsl.d.ts +1790 -1704
  93. package/dist/render/shaders/generated/flat.wgsl.js +1828 -1742
  94. package/dist/render/shaders/generated/skinBlur.wgsl.d.ts +48 -0
  95. package/dist/render/shaders/generated/skinBlur.wgsl.js +54 -0
  96. package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
  97. package/dist/render/shaders/recon/motion.wgsl.js +102 -0
  98. package/dist/render/shaders/skinBlur.d.ts +1 -0
  99. package/dist/render/shaders/skinBlur.js +103 -0
  100. package/dist/render/shaders/skinning.d.ts +3 -1
  101. package/dist/render/shaders/skinning.js +31 -4
  102. package/dist/render/shadowCasters.d.ts +13 -1
  103. package/dist/render/skinBlur.d.ts +41 -0
  104. package/dist/render/skinBlur.js +49 -0
  105. package/dist/render/skinScatter.d.ts +67 -0
  106. package/dist/render/skinScatter.js +80 -0
  107. package/dist/render/skinnedClothRun.d.ts +26 -0
  108. package/dist/render/skinnedClothRun.js +84 -0
  109. package/dist/render/surfaceModel.d.ts +129 -0
  110. package/dist/render/surfaceModel.js +152 -0
  111. package/dist/render/surfaceTexture.d.ts +44 -4
  112. package/dist/render/surfaceTexture.js +60 -46
  113. package/dist/render/vertexDefaults.js +7 -0
  114. package/package.json +6 -6
  115. package/src/geometry/meshConcat.ts +2 -0
  116. package/src/index.ts +40 -1
  117. package/src/math/scalar.ts +1 -1
  118. package/src/render/anisotropicLobe.ts +41 -0
  119. package/src/render/backend/api.ts +52 -3
  120. package/src/render/backend/select.ts +8 -0
  121. package/src/render/backend/webgl2/clothTextures.ts +120 -0
  122. package/src/render/backend/webgl2/renderer.ts +693 -64
  123. package/src/render/backend/webgl2/skinScatter.ts +309 -0
  124. package/src/render/backend/webgpu/buffers.ts +137 -63
  125. package/src/render/backend/webgpu/clothSolvePack.ts +161 -0
  126. package/src/render/backend/webgpu/clothTextures.ts +194 -0
  127. package/src/render/backend/webgpu/compressedUpload.ts +65 -0
  128. package/src/render/backend/webgpu/computeHost.ts +25 -0
  129. package/src/render/backend/webgpu/depthPass.ts +39 -7
  130. package/src/render/backend/webgpu/drawCommand.ts +6 -2
  131. package/src/render/backend/webgpu/flatPass.ts +145 -7
  132. package/src/render/backend/webgpu/gpuSkinnedCloth.ts +502 -0
  133. package/src/render/backend/webgpu/motionPass.ts +128 -9
  134. package/src/render/backend/webgpu/postPass.ts +5 -1
  135. package/src/render/backend/webgpu/renderer.ts +663 -43
  136. package/src/render/backend/webgpu/shaders/clothSolve.wgsl.ts +470 -0
  137. package/src/render/backend/webgpu/skinScatterPass.ts +309 -0
  138. package/src/render/backend/webgpu/surfaceTexturePass.ts +42 -12
  139. package/src/render/clothBindingData.ts +89 -0
  140. package/src/render/clothPlacement.ts +114 -0
  141. package/src/render/compressedSource.ts +198 -0
  142. package/src/render/cutoutCaster.ts +5 -0
  143. package/src/render/cutoutDither.ts +99 -0
  144. package/src/render/eyeRefraction.ts +72 -0
  145. package/src/render/glCompressed.ts +86 -0
  146. package/src/render/hairLobes.ts +188 -0
  147. package/src/render/lightBudget.ts +25 -0
  148. package/src/render/mesh.ts +23 -0
  149. package/src/render/recon/motionVectors.ts +6 -3
  150. package/src/render/renderQuality.ts +28 -0
  151. package/src/render/rendererHarness.ts +4 -0
  152. package/src/render/sceneTarget.ts +21 -0
  153. package/src/render/shaders/clothBinding.ts +81 -0
  154. package/src/render/shaders/depth.ts +42 -6
  155. package/src/render/shaders/flat/anisotropic.ts +68 -0
  156. package/src/render/shaders/flat/eye.ts +82 -0
  157. package/src/render/shaders/flat/hair.ts +102 -0
  158. package/src/render/shaders/flat/index.ts +36 -2
  159. package/src/render/shaders/flat/main.ts +113 -17
  160. package/src/render/shaders/flat/models.ts +286 -0
  161. package/src/render/shaders/flat/preamble.ts +26 -24
  162. package/src/render/shaders/flat/skin.ts +116 -0
  163. package/src/render/shaders/generated/depth.wgsl.ts +38 -16
  164. package/src/render/shaders/generated/flat.wgsl.ts +1828 -1742
  165. package/src/render/shaders/generated/skinBlur.wgsl.ts +56 -0
  166. package/src/render/shaders/recon/motion.wgsl.ts +102 -0
  167. package/src/render/shaders/skinBlur.ts +105 -0
  168. package/src/render/shaders/skinning.ts +31 -4
  169. package/src/render/shadowCasters.ts +13 -0
  170. package/src/render/skinBlur.ts +53 -0
  171. package/src/render/skinScatter.ts +92 -0
  172. package/src/render/skinnedClothRun.ts +128 -0
  173. package/src/render/surfaceModel.ts +274 -0
  174. package/src/render/surfaceTexture.ts +123 -63
  175. package/src/render/vertexDefaults.ts +7 -0
  176. package/dist/math/exact.d.ts +0 -76
  177. package/dist/math/exact.js +0 -327
  178. package/src/math/exact.ts +0 -340
@@ -188,7 +188,9 @@ export declare function postPipeline(cache: PipelineCache, device: GPUDevice, la
188
188
  * writes its picture and each pixel's flicker record in one pass. `targets` is the caller's, held
189
189
  * rather than built per call, since this is asked for every frame.
190
190
  */
191
- export declare function postPipelineTargets(cache: PipelineCache, device: GPUDevice, layout: GPUBindGroupLayout, key: string, fragment: string, targets: GPUColorTargetState[]): GPURenderPipeline;
191
+ export declare function postPipelineTargets(cache: PipelineCache, device: GPUDevice, layout: GPUBindGroupLayout, key: string, fragment: string, targets: GPUColorTargetState[],
192
+ /** For a pass drawn into the frame's own multisampled colour, which must match its count. */
193
+ sampleCount?: number): GPURenderPipeline;
192
194
  /**
193
195
  * The temporal resolve's block and its four inputs.
194
196
  *
@@ -267,11 +267,14 @@ export function postPipeline(cache, device, layout, key, fragment, format, blend
267
267
  * writes its picture and each pixel's flicker record in one pass. `targets` is the caller's, held
268
268
  * rather than built per call, since this is asked for every frame.
269
269
  */
270
- export function postPipelineTargets(cache, device, layout, key, fragment, targets) {
271
- return cache.get(key, () => describePost(device, layout, key, fragment, targets));
270
+ export function postPipelineTargets(cache, device, layout, key, fragment, targets,
271
+ /** For a pass drawn into the frame's own multisampled colour, which must match its count. */
272
+ sampleCount = 1) {
273
+ return cache.get(key, () => describePost(device, layout, key, fragment, targets, sampleCount));
272
274
  }
273
- function describePost(device, layout, key, fragment, targets) {
275
+ function describePost(device, layout, key, fragment, targets, sampleCount = 1) {
274
276
  return {
277
+ ...(sampleCount > 1 ? { multisample: { count: sampleCount } } : {}),
275
278
  label: key,
276
279
  layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }),
277
280
  vertex: {
@@ -19,6 +19,10 @@ import { type ShadowLight } from '../../pointShadowSystem.ts';
19
19
  import { GpuText } from './textPass.ts';
20
20
  import type { TextStyle } from '../../textLayout.ts';
21
21
  import { GpuSurfaceTexture } from './surfaceTexturePass.ts';
22
+ import { GpuClothBinding, GpuClothParticles } from './clothTextures.ts';
23
+ import type { ComputeHost } from './computeHost.ts';
24
+ import type { ClothBindingData } from '../../clothBindingData.ts';
25
+ import type { CompressedTextureFormat, SurfaceSource } from '../../compressedSource.ts';
22
26
  import { GpuSdfText } from './sdfTextPass.ts';
23
27
  import type { SdfFont } from '../../sdfFont.ts';
24
28
  import type { SdfTextStyle } from '../../sdfTextLayout.ts';
@@ -151,6 +155,12 @@ export declare class WebGPURenderer implements RendererApi {
151
155
  private readonly skinnedGroupsBeside;
152
156
  private readonly skinnedGroupsPalette;
153
157
  private readonly skinnedGroupsDeltas;
158
+ /** The cloth views each skinned twin was built with, compared by identity like the palette. */
159
+ private readonly skinnedGroupsCloth;
160
+ private readonly skinnedGroupsClothBinding;
161
+ /** The cloth the next skinned draws are placed by, or null. See `setCloth`. */
162
+ private cloth;
163
+ private clothStandCache;
154
164
  /**
155
165
  * Which palette slot the following draws skin by, or -1 for none.
156
166
  *
@@ -498,6 +508,16 @@ export declare class WebGPURenderer implements RendererApi {
498
508
  private refractSnapshotView;
499
509
  /** Whether this frame has taken it. One snapshot serves every refracting draw. */
500
510
  private refractSnapshotTaken;
511
+ /**
512
+ * Skin's screen-space scattering, made where the profile asks for it and has a composite to add
513
+ * into, and null otherwise — which is every profile by default. See `SkinScatterPass`.
514
+ */
515
+ private readonly skinScatter;
516
+ /** The pipelines skin's diffuse half is built for: the blur target's format, the frame's samples. */
517
+ private readonly skinPipelines;
518
+ /** Whether this frame has spread its skin: once, at its first blended draw or before its end. */
519
+ private skinScattered;
520
+ private readonly skinInverseProjection;
501
521
  private sceneColorView;
502
522
  /** The multisampled twin, when the profile asks for samples. Resolved into `sceneColor`. */
503
523
  private sceneColorMsaa;
@@ -676,6 +696,17 @@ export declare class WebGPURenderer implements RendererApi {
676
696
  private temporalJitterX;
677
697
  private temporalJitterY;
678
698
  private temporalJittering;
699
+ /**
700
+ * The frame a dithered cutout's pattern is offset by, advanced at `beginFrame` and wrapped at 64.
701
+ * See `cutoutDither.ts`.
702
+ */
703
+ private cutoutFrame;
704
+ /**
705
+ * How the current material's cutout edge is drawn this frame, decided when the material is staged
706
+ * — after `bindMeshPass` has settled whether the frame is temporal — and read by every draw: a
707
+ * coverage edge is pipeline state here (`|a2c`), and a blended draw tests hard.
708
+ */
709
+ private cutoutResolveStaged;
679
710
  /**
680
711
  * Whether this frame is being reconstructed, settled once in `bindMeshPass`.
681
712
  *
@@ -1082,6 +1113,12 @@ export declare class WebGPURenderer implements RendererApi {
1082
1113
  private ormMap;
1083
1114
  /** The caller's emissive map, or null for the stand-in. See `setMaterial`. */
1084
1115
  private emissiveMap;
1116
+ /** The material's model map, or null for the stand-in. See `setMaterial` and `surfaceModel.ts`. */
1117
+ private modelMap;
1118
+ /** The material's shading model, which picks the lit pipeline: null the standard. */
1119
+ private materialModel;
1120
+ /** Its numbers, `uModelParams`, packed by `packModel`. */
1121
+ private readonly modelParams;
1085
1122
  /**
1086
1123
  * The flat group for a material, keyed on **all four** of its maps.
1087
1124
  *
@@ -1124,9 +1161,16 @@ export declare class WebGPURenderer implements RendererApi {
1124
1161
  private materialDoubleSided;
1125
1162
  /** Whether the bound material has a map, for the warning a mesh with no coordinates earns. */
1126
1163
  private materialHasMaps;
1127
- createSurfaceTexture(source: TexImageSource, options?: SurfaceTextureOptions): GpuSurfaceTexture;
1164
+ createSurfaceTexture(source: SurfaceSource, options?: SurfaceTextureOptions): GpuSurfaceTexture;
1165
+ private compressedCache;
1166
+ /**
1167
+ * The BC formats this device takes as blocks: every one where the device carries
1168
+ * `texture-compression-bc`, which `select.ts` asks for wherever the adapter offers it, and none
1169
+ * where it does not. See `Renderer.compressedFormats`.
1170
+ */
1171
+ get compressedFormats(): readonly CompressedTextureFormat[];
1128
1172
  /** Several images of one size as an array's layers. See `RendererApi.createSurfaceTextureArray`. */
1129
- createSurfaceTextureArray(sources: readonly TexImageSource[], options?: SurfaceTextureOptions): GpuSurfaceTexture;
1173
+ createSurfaceTextureArray(sources: readonly SurfaceSource[], options?: SurfaceTextureOptions): GpuSurfaceTexture;
1130
1174
  /**
1131
1175
  * GPU textures an `updateSurfaceTexture` replaced, destroyed when the next frame begins.
1132
1176
  *
@@ -1159,6 +1203,40 @@ export declare class WebGPURenderer implements RendererApi {
1159
1203
  * surface must be answered by every backend, and answered honestly, per the 2026-08-13 rule.
1160
1204
  */
1161
1205
  setSkinPalette(palette: Float32Array | null): void;
1206
+ /**
1207
+ * A mesh's cloth binding. See `RendererApi.createClothBinding`. The pipelines that draw it bound
1208
+ * are warmed here, every way this mesh can be drawn, so none compiles inside the first frame
1209
+ * that draws a garment.
1210
+ */
1211
+ createClothBinding(mesh: GpuMesh, data: ClothBindingData): GpuClothBinding;
1212
+ /** One character's particles. See `RendererApi.createClothParticles`. */
1213
+ createClothParticles(count: number): GpuClothParticles;
1214
+ /**
1215
+ * This frame's particles. **Once a frame, before the character's draws**: a texture write lands
1216
+ * ahead of every draw of the frame, so a second update between two draws would reach both.
1217
+ */
1218
+ updateClothParticles(particles: GpuClothParticles, positions: Float32Array): void;
1219
+ /** Place the following skinned draws by a cloth, or by none. See `RendererApi.setCloth`. */
1220
+ setCloth(binding: GpuClothBinding | null, particles?: GpuClothParticles | null): void;
1221
+ /** Retired rather than destroyed: a draw recorded earlier in this frame may still read them. */
1222
+ disposeClothBinding(binding: GpuClothBinding): void;
1223
+ disposeClothParticles(particles: GpuClothParticles): void;
1224
+ /**
1225
+ * The device and the frame's bookkeeping, for compute a consumer opts into by importing it —
1226
+ * `createSkinnedCloth` — rather than for anything this renderer runs itself. See `computeHost.ts`.
1227
+ */
1228
+ computeHost(): ComputeHost;
1229
+ private readonly computeHostCache;
1230
+ /**
1231
+ * An eye's axis in the world for this draw, into the open material's \`uModelParams\`, and a new
1232
+ * material slot when it moved: the axis is per draw, and a slot already taken by an earlier draw
1233
+ * of the same eye must not be written under it. See \`eyeAxisInWorld\`.
1234
+ */
1235
+ private writeEyeAxis;
1236
+ /** The views the draw's cloth binds, or the stand-in's where no cloth is set. */
1237
+ private clothViews;
1238
+ /** The one-texel stand-in a skinned group binds where there is no cloth, made on first need. */
1239
+ private clothStand;
1162
1240
  /**
1163
1241
  * Choose the morph weights the following `drawMesh` calls deform by, or null for none.
1164
1242
  *
@@ -1725,6 +1803,8 @@ export declare class WebGPURenderer implements RendererApi {
1725
1803
  private readonly shadowSkinnedGroups;
1726
1804
  private readonly shadowSkinnedGroupsBeside;
1727
1805
  private readonly shadowSkinnedGroupsPalette;
1806
+ private readonly shadowSkinnedGroupsCloth;
1807
+ private readonly shadowSkinnedGroupsClothBinding;
1728
1808
  /** Held from construction so the skinned group can be rebuilt without them being threaded. */
1729
1809
  private shadowBlankView;
1730
1810
  private shadowBlankSampler;
@@ -2093,9 +2173,9 @@ export declare class WebGPURenderer implements RendererApi {
2093
2173
  /**
2094
2174
  * Rewrite a mesh's positions, and its normals where the caller has them.
2095
2175
  *
2096
- * Refused in words on a mesh that did not declare itself dynamic, because the thing that makes
2097
- * an update possible on this backend — the interleaved array the vertex data was built from —
2098
- * is only kept when a consumer asked for it. See `GpuMesh.update`.
2176
+ * Refused in words on a mesh that did not declare itself dynamic, because what makes an update
2177
+ * cheap on this backend — positions and normals in buffers of their own — is a layout chosen at
2178
+ * creation. See `GpuMesh.update`.
2099
2179
  */
2100
2180
  updateMesh(mesh: GpuMesh, positions: Float32Array, normals?: Float32Array): void;
2101
2181
  /**
@@ -2675,6 +2755,13 @@ export declare class WebGPURenderer implements RendererApi {
2675
2755
  * it before the motion pass reads it. See `SkinPaletteRing`.
2676
2756
  */
2677
2757
  private recordSkinnedMotion;
2758
+ /**
2759
+ * A cloth-bound draw's motion. **Recorded even where the caller named no previous place**, as a
2760
+ * rewritten mesh's is: the particles carry their own past, and a garment swinging on a character
2761
+ * standing still is motion nobody else can see. Where the rig is a `Mover` its last pose is taken
2762
+ * as a skinned mover's is; otherwise the rig is taken not to have moved.
2763
+ */
2764
+ private recordClothMotion;
2678
2765
  private warnMoverTwice;
2679
2766
  /**
2680
2767
  * Where every mover was last frame, into the motion target. See `MotionPass`.
@@ -2849,6 +2936,27 @@ export declare class WebGPURenderer implements RendererApi {
2849
2936
  * glass, and a frame that refracts nothing breaks no pass at all.
2850
2937
  */
2851
2938
  private takeRefractSnapshot;
2939
+ /**
2940
+ * Whether a skin draw now draws its two halves: the profile asked, the frame has not spread its
2941
+ * skin yet, and this is the frame's own picture — not a mirror's, a probe's, an overlay after
2942
+ * the frame, or an order-independent set, none of which the spread reads.
2943
+ */
2944
+ private skinSplits;
2945
+ /**
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.
2949
+ */
2950
+ private keepSkinDiffuse;
2951
+ /**
2952
+ * Spread the frame's skin and add it back: once, at the first blended draw or before the frame's
2953
+ * last flush. **A fifth instance of the boundary `takeRefractSnapshot` describes** — flush, end
2954
+ * the pass, work between passes, reopen with `loadOp: 'load'` — and refused where that one is,
2955
+ * for its reasons. Between the passes: the kept diffuse halves into their target against the
2956
+ * frame's depth, the depth resolved, and `SkinScatterPass.spread` across and then down into the
2957
+ * frame's colour.
2958
+ */
2959
+ private runSkinScatter;
2852
2960
  private takeVolumeDepth;
2853
2961
  /**
2854
2962
  * The pass to record into, reopening one on the canvas if the frame has already gone.