@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.
- package/CHANGELOG.json +133 -11
- package/README.md +43 -38
- package/dist/index.d.ts +7 -4
- package/dist/index.js +5 -4
- package/dist/render/ambientHarmonics.d.ts +1 -1
- package/dist/render/ambientHarmonics.js +1 -1
- package/dist/render/areaLights.d.ts +4 -4
- package/dist/render/areaLights.js +1 -1
- package/dist/render/backend/api.d.ts +10 -3
- package/dist/render/backend/select.js +11 -5
- package/dist/render/backend/webgl2/boneAnimations.d.ts +29 -0
- package/dist/render/backend/webgl2/boneAnimations.js +80 -0
- package/dist/render/backend/webgl2/instanced.d.ts +5 -1
- package/dist/render/backend/webgl2/instanced.js +13 -1
- package/dist/render/backend/webgl2/renderer.d.ts +189 -4
- package/dist/render/backend/webgl2/renderer.js +614 -66
- package/dist/render/backend/webgl2/skinPaletteTexture.d.ts +5 -3
- package/dist/render/backend/webgl2/skinPaletteTexture.js +6 -4
- package/dist/render/backend/webgpu/boneAnimations.d.ts +34 -0
- package/dist/render/backend/webgpu/boneAnimations.js +76 -0
- package/dist/render/backend/webgpu/buffers.d.ts +24 -4
- package/dist/render/backend/webgpu/buffers.js +116 -59
- package/dist/render/backend/webgpu/clothKernels.d.ts +8 -0
- package/dist/render/backend/webgpu/clothKernels.js +76 -0
- package/dist/render/backend/webgpu/clothOps.d.ts +39 -0
- package/dist/render/backend/webgpu/clothOps.js +78 -0
- package/dist/render/backend/webgpu/clothSetLayout.d.ts +25 -0
- package/dist/render/backend/webgpu/clothSetLayout.js +84 -0
- package/dist/render/backend/webgpu/clothSetPack.d.ts +33 -0
- package/dist/render/backend/webgpu/clothSetPack.js +144 -0
- package/dist/render/backend/webgpu/compressedUpload.d.ts +0 -1
- package/dist/render/backend/webgpu/compressedUpload.js +53 -8
- package/dist/render/backend/webgpu/depthPass.d.ts +59 -3
- package/dist/render/backend/webgpu/depthPass.js +49 -14
- package/dist/render/backend/webgpu/drawCommand.d.ts +20 -4
- package/dist/render/backend/webgpu/drawCommand.js +11 -3
- package/dist/render/backend/webgpu/flatPass.d.ts +85 -42
- package/dist/render/backend/webgpu/flatPass.js +137 -20
- package/dist/render/backend/webgpu/gpuClothSet.d.ts +80 -0
- package/dist/render/backend/webgpu/gpuClothSet.js +462 -0
- package/dist/render/backend/webgpu/instanced.d.ts +14 -1
- package/dist/render/backend/webgpu/instanced.js +24 -1
- package/dist/render/backend/webgpu/latePass.js +1 -0
- package/dist/render/backend/webgpu/materialStore.d.ts +101 -0
- package/dist/render/backend/webgpu/materialStore.js +265 -0
- package/dist/render/backend/webgpu/motionPass.js +15 -6
- package/dist/render/backend/webgpu/pipelineCache.d.ts +28 -1
- package/dist/render/backend/webgpu/pipelineCache.js +46 -1
- package/dist/render/backend/webgpu/postPass.d.ts +1 -1
- package/dist/render/backend/webgpu/renderer.d.ts +200 -35
- package/dist/render/backend/webgpu/renderer.js +993 -168
- package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.d.ts +9 -2
- package/dist/render/backend/webgpu/shaders/clothSolve.wgsl.js +121 -47
- package/dist/render/backend/webgpu/skinPaletteRing.d.ts +7 -3
- package/dist/render/backend/webgpu/skinPaletteRing.js +13 -7
- package/dist/render/backend/webgpu/skinPaletteTexture.d.ts +6 -0
- package/dist/render/backend/webgpu/skinPaletteTexture.js +7 -1
- package/dist/render/backend/webgpu/staticBundles.d.ts +125 -0
- package/dist/render/backend/webgpu/staticBundles.js +242 -0
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +10 -3
- package/dist/render/backend/webgpu/surfaceTexturePass.js +20 -2
- package/dist/render/backend/webgpu/uniformRing.d.ts +21 -0
- package/dist/render/backend/webgpu/uniformRing.js +9 -1
- package/dist/render/backend/webgpu/vertexFormats.d.ts +22 -0
- package/dist/render/backend/webgpu/vertexFormats.js +97 -0
- package/dist/render/bloomChain.d.ts +3 -3
- package/dist/render/boneAnimation.d.ts +92 -0
- package/dist/render/boneAnimation.js +133 -0
- package/dist/render/compressedSource.d.ts +33 -13
- package/dist/render/compressedSource.js +70 -25
- package/dist/render/glCompressed.js +83 -0
- package/dist/render/globalMediumPass.d.ts +2 -0
- package/dist/render/globalMediumPass.js +1 -0
- package/dist/render/indexWidth.d.ts +17 -0
- package/dist/render/indexWidth.js +23 -0
- package/dist/render/instances.d.ts +26 -0
- package/dist/render/lightBudget.d.ts +10 -0
- package/dist/render/lightBudget.js +10 -0
- package/dist/render/lightMatrix.d.ts +11 -0
- package/dist/render/lightMatrix.js +14 -0
- package/dist/render/lightmap.d.ts +1 -1
- package/dist/render/mesh.d.ts +14 -0
- package/dist/render/mesh.js +44 -14
- package/dist/render/pointLightSelection.d.ts +4 -4
- package/dist/render/renderQuality.d.ts +30 -0
- package/dist/render/renderQuality.js +5 -0
- package/dist/render/rendererHarness.d.ts +7 -0
- package/dist/render/rendererHarness.js +12 -0
- package/dist/render/screenSpaceReflection.d.ts +2 -1
- package/dist/render/shader.d.ts +15 -0
- package/dist/render/shader.js +41 -0
- package/dist/render/shaders/boneAnimation.d.ts +19 -0
- package/dist/render/shaders/boneAnimation.js +63 -0
- package/dist/render/shaders/depth.d.ts +7 -0
- package/dist/render/shaders/depth.js +35 -10
- package/dist/render/shaders/flat/directionalShadow.js +84 -10
- package/dist/render/shaders/flat/glassTint.d.ts +1 -1
- package/dist/render/shaders/flat/glassTint.js +3 -0
- package/dist/render/shaders/flat/index.d.ts +21 -0
- package/dist/render/shaders/flat/index.js +42 -7
- package/dist/render/shaders/flat/layered.d.ts +19 -0
- package/dist/render/shaders/flat/layered.js +115 -0
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +58 -21
- package/dist/render/shaders/flat/mapReads.d.ts +10 -0
- package/dist/render/shaders/flat/mapReads.js +38 -0
- package/dist/render/shaders/flat/models.js +1 -1
- package/dist/render/shaders/flat/movingSun.d.ts +21 -0
- package/dist/render/shaders/flat/movingSun.js +46 -0
- package/dist/render/shaders/flat/normalMap.d.ts +6 -2
- package/dist/render/shaders/flat/normalMap.js +14 -3
- package/dist/render/shaders/flat/overlay.d.ts +3 -2
- package/dist/render/shaders/flat/overlay.js +42 -20
- package/dist/render/shaders/flat/pointShadow.js +2 -2
- package/dist/render/shaders/flat/preamble.js +59 -27
- package/dist/render/shaders/flat/worldUv.d.ts +22 -0
- package/dist/render/shaders/flat/worldUv.js +113 -0
- package/dist/render/shaders/generated/depth.wgsl.d.ts +93 -0
- package/dist/render/shaders/generated/depth.wgsl.js +93 -0
- package/dist/render/shaders/generated/flat.wgsl.d.ts +3616 -3042
- package/dist/render/shaders/generated/flat.wgsl.js +3688 -3113
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +8 -3
- package/dist/render/shaders/generated/globalMedium.wgsl.js +8 -3
- package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +15 -10
- package/dist/render/shaders/generated/lightVolume.wgsl.js +16 -11
- package/dist/render/shaders/globalMedium.js +9 -1
- package/dist/render/shaders/lightVolume.js +9 -1
- package/dist/render/shaders/outputTransform.d.ts +7 -0
- package/dist/render/shaders/outputTransform.js +28 -14
- package/dist/render/shaders/tangentFrame.d.ts +1 -1
- package/dist/render/shaders/tangentFrame.js +16 -3
- package/dist/render/shaders/vertexChannel.d.ts +7 -0
- package/dist/render/shaders/vertexChannel.js +26 -0
- package/dist/render/skinnedClothRun.d.ts +28 -0
- package/dist/render/skinnedClothRun.js +103 -35
- package/dist/render/staticDraws.d.ts +47 -0
- package/dist/render/staticDraws.js +43 -0
- package/dist/render/surfaceLayers.d.ts +39 -0
- package/dist/render/surfaceLayers.js +26 -0
- package/dist/render/surfaceOverlay.d.ts +16 -3
- package/dist/render/surfaceOverlay.js +11 -6
- package/dist/render/surfaceProjection.d.ts +34 -0
- package/dist/render/surfaceProjection.js +30 -0
- package/dist/render/surfaceTexture.d.ts +68 -7
- package/dist/render/surfaceTexture.js +56 -17
- package/dist/render/vertexPacking.d.ts +48 -0
- package/dist/render/vertexPacking.js +68 -0
- package/package.json +6 -6
- package/src/index.ts +12 -4
- package/src/render/ambientHarmonics.ts +1 -1
- package/src/render/areaLights.ts +4 -4
- package/src/render/backend/api.ts +13 -3
- package/src/render/backend/select.ts +10 -5
- package/src/render/backend/webgl2/boneAnimations.ts +105 -0
- package/src/render/backend/webgl2/instanced.ts +20 -1
- package/src/render/backend/webgl2/renderer.ts +723 -79
- package/src/render/backend/webgl2/skinPaletteTexture.ts +6 -4
- package/src/render/backend/webgpu/boneAnimations.ts +97 -0
- package/src/render/backend/webgpu/buffers.ts +195 -70
- package/src/render/backend/webgpu/clothKernels.ts +86 -0
- package/src/render/backend/webgpu/clothOps.ts +86 -0
- package/src/render/backend/webgpu/clothSetLayout.ts +102 -0
- package/src/render/backend/webgpu/clothSetPack.ts +197 -0
- package/src/render/backend/webgpu/compressedUpload.ts +59 -9
- package/src/render/backend/webgpu/depthPass.ts +51 -10
- package/src/render/backend/webgpu/drawCommand.ts +25 -4
- package/src/render/backend/webgpu/flatPass.ts +212 -41
- package/src/render/backend/webgpu/gpuClothSet.ts +564 -0
- package/src/render/backend/webgpu/instanced.ts +32 -1
- package/src/render/backend/webgpu/latePass.ts +1 -0
- package/src/render/backend/webgpu/materialStore.ts +276 -0
- package/src/render/backend/webgpu/motionPass.ts +18 -7
- package/src/render/backend/webgpu/pipelineCache.ts +53 -7
- package/src/render/backend/webgpu/renderer.ts +1201 -202
- package/src/render/backend/webgpu/shaders/clothSolve.wgsl.ts +121 -47
- package/src/render/backend/webgpu/skinPaletteRing.ts +13 -7
- package/src/render/backend/webgpu/skinPaletteTexture.ts +7 -1
- package/src/render/backend/webgpu/staticBundles.ts +364 -0
- package/src/render/backend/webgpu/surfaceTexturePass.ts +29 -3
- package/src/render/backend/webgpu/uniformRing.ts +10 -1
- package/src/render/backend/webgpu/vertexFormats.ts +113 -0
- package/src/render/bloomChain.ts +3 -3
- package/src/render/boneAnimation.ts +223 -0
- package/src/render/compressedSource.ts +121 -29
- package/src/render/glCompressed.ts +83 -0
- package/src/render/globalMediumPass.ts +7 -0
- package/src/render/indexWidth.ts +27 -0
- package/src/render/instances.ts +27 -0
- package/src/render/lightBudget.ts +11 -0
- package/src/render/lightMatrix.ts +15 -0
- package/src/render/lightmap.ts +1 -1
- package/src/render/mesh.ts +72 -14
- package/src/render/pointLightSelection.ts +4 -4
- package/src/render/renderQuality.ts +38 -0
- package/src/render/rendererHarness.ts +15 -0
- package/src/render/screenSpaceReflection.ts +2 -1
- package/src/render/shader.ts +59 -0
- package/src/render/shaders/boneAnimation.ts +63 -0
- package/src/render/shaders/depth.ts +45 -10
- package/src/render/shaders/flat/directionalShadow.ts +84 -10
- package/src/render/shaders/flat/glassTint.ts +7 -1
- package/src/render/shaders/flat/index.ts +63 -7
- package/src/render/shaders/flat/layered.ts +115 -0
- package/src/render/shaders/flat/main.ts +58 -21
- package/src/render/shaders/flat/mapReads.ts +38 -0
- package/src/render/shaders/flat/models.ts +1 -1
- package/src/render/shaders/flat/movingSun.ts +46 -0
- package/src/render/shaders/flat/normalMap.ts +14 -3
- package/src/render/shaders/flat/overlay.ts +42 -20
- package/src/render/shaders/flat/pointShadow.ts +2 -2
- package/src/render/shaders/flat/preamble.ts +59 -27
- package/src/render/shaders/flat/worldUv.ts +113 -0
- package/src/render/shaders/generated/depth.wgsl.ts +95 -0
- package/src/render/shaders/generated/flat.wgsl.ts +3688 -3113
- package/src/render/shaders/generated/globalMedium.wgsl.ts +8 -3
- package/src/render/shaders/generated/lightVolume.wgsl.ts +16 -11
- package/src/render/shaders/globalMedium.ts +9 -1
- package/src/render/shaders/lightVolume.ts +9 -1
- package/src/render/shaders/outputTransform.ts +30 -14
- package/src/render/shaders/tangentFrame.ts +16 -3
- package/src/render/shaders/vertexChannel.ts +27 -0
- package/src/render/skinnedClothRun.ts +138 -38
- package/src/render/staticDraws.ts +95 -0
- package/src/render/surfaceLayers.ts +57 -0
- package/src/render/surfaceOverlay.ts +24 -7
- package/src/render/surfaceProjection.ts +57 -0
- package/src/render/surfaceTexture.ts +124 -27
- package/src/render/vertexPacking.ts +109 -0
- package/dist/render/backend/webgpu/gpuSkinnedCloth.d.ts +0 -74
- package/dist/render/backend/webgpu/gpuSkinnedCloth.js +0 -452
- package/src/render/backend/webgpu/gpuSkinnedCloth.ts +0 -502
|
@@ -52,9 +52,13 @@ const FRAGMENT_BINDINGS = FLAT_BINDINGS.flatFrag;
|
|
|
52
52
|
*/
|
|
53
53
|
const VERTEX_BINDINGS = FLAT_BINDINGS.flatVert;
|
|
54
54
|
/** The key for a set of vertex flags: the same rule `variantKey` uses, flags on, sorted, joined. */
|
|
55
|
-
export function flatVertexKey(skinned, morphed, instanced = false
|
|
55
|
+
export function flatVertexKey(skinned, morphed, instanced = false,
|
|
56
|
+
/** Whether an instanced variant plays a bone animation. See `shaders/boneAnimation.ts`. */
|
|
57
|
+
animated = false) {
|
|
56
58
|
const on = [];
|
|
57
59
|
/* Alphabetical, because the generator's own `variantKey` sorts and the two keys must agree. */
|
|
60
|
+
if (animated)
|
|
61
|
+
on.push('animated');
|
|
58
62
|
if (instanced)
|
|
59
63
|
on.push('instanced');
|
|
60
64
|
if (morphed)
|
|
@@ -64,8 +68,8 @@ export function flatVertexKey(skinned, morphed, instanced = false) {
|
|
|
64
68
|
return on.length === 0 ? 'none' : on.join('+');
|
|
65
69
|
}
|
|
66
70
|
/** Everything the generator recorded about one variant of the vertex stage. */
|
|
67
|
-
export function flatVertexBindings(skinned, morphed = false, instanced = false) {
|
|
68
|
-
const key = flatVertexKey(skinned, morphed, instanced);
|
|
71
|
+
export function flatVertexBindings(skinned, morphed = false, instanced = false, animated = false) {
|
|
72
|
+
const key = flatVertexKey(skinned, morphed, instanced, animated);
|
|
69
73
|
const found = VERTEX_BINDINGS[key];
|
|
70
74
|
if (found === undefined)
|
|
71
75
|
throw new Error(`flatPass: no vertex bindings for variant "${key}"`);
|
|
@@ -136,6 +140,8 @@ for (const [key, bindings] of Object.entries(VERTEX_BINDINGS)) {
|
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
export const FLAT_VERT_FIELDS = FLAT_BINDINGS.flatVert.none.fields;
|
|
143
|
+
/** The animated instanced variant's block: the instanced fields, and the clip's `uBoneClip`. */
|
|
144
|
+
export const FLAT_ANIMATED_VERT_FIELDS = FLAT_BINDINGS.flatVert['animated+instanced'].fields;
|
|
139
145
|
/**
|
|
140
146
|
* The **largest** variant's block, because one ring serves every draw.
|
|
141
147
|
*
|
|
@@ -145,6 +151,30 @@ export const FLAT_VERT_FIELDS = FLAT_BINDINGS.flatVert.none.fields;
|
|
|
145
151
|
*/
|
|
146
152
|
export const FLAT_VERT_SIZE = Math.max(...Object.values(VERTEX_BINDINGS).map((bindings) => bindings.uniformSize));
|
|
147
153
|
const FLAT_VERT_BINDING = PLAIN_VERTEX.uniforms;
|
|
154
|
+
/*
|
|
155
|
+
* **The view block may be shorter in a variant, never different.** One slot serves every lit draw
|
|
156
|
+
* of a pass, plain and instanced alike, so every field a variant's view block declares must sit
|
|
157
|
+
* where the plain variant has it. The instanced variant declares no wind, and its block is the plain
|
|
158
|
+
* one's first two matrices.
|
|
159
|
+
*/
|
|
160
|
+
const PLAIN_VIEW_FIELDS = PLAIN_VERTEX.viewFields ?? {};
|
|
161
|
+
for (const [key, bindings] of Object.entries(VERTEX_BINDINGS)) {
|
|
162
|
+
if (bindings.viewUniforms !== PLAIN_VERTEX.viewUniforms) {
|
|
163
|
+
throw new Error(`flatPass: vertex variant "${key}" binds its view block elsewhere`);
|
|
164
|
+
}
|
|
165
|
+
for (const [field, here] of Object.entries(bindings.viewFields ?? {})) {
|
|
166
|
+
if (PLAIN_VIEW_FIELDS[field]?.offset !== here.offset) {
|
|
167
|
+
throw new Error(`flatPass: vertex variant "${key}" puts view field ${field} at ${here.offset} where the ` +
|
|
168
|
+
`plain variant has it at ${PLAIN_VIEW_FIELDS[field]?.offset}.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** The view block's fields, binding and size: the largest variant's, as `FLAT_VERT_SIZE` is. */
|
|
173
|
+
export const FLAT_VIEW_FIELDS = PLAIN_VIEW_FIELDS;
|
|
174
|
+
export const FLAT_VIEW_SIZE = Math.max(...Object.values(VERTEX_BINDINGS).map((bindings) => bindings.viewSize ?? 0));
|
|
175
|
+
const FLAT_VIEW_BINDING = PLAIN_VERTEX.viewUniforms ?? -1;
|
|
176
|
+
if (FLAT_VIEW_BINDING < 0)
|
|
177
|
+
throw new Error('flatPass: the lit vertex stage declares no view block');
|
|
148
178
|
/**
|
|
149
179
|
* The most sampled textures and distinct samplers any lit variant carrying the environment probe
|
|
150
180
|
* binds in its fragment stage, counted from the generated bindings: what a device must allow per
|
|
@@ -170,6 +200,26 @@ export function flatFragmentBindings(variant) {
|
|
|
170
200
|
throw new Error(`flatPass: no bindings for variant "${variant}"`);
|
|
171
201
|
return found;
|
|
172
202
|
}
|
|
203
|
+
export function flatFragmentScratch(variant) {
|
|
204
|
+
const bindings = flatFragmentBindings(variant);
|
|
205
|
+
const { materialUniforms, materialSize, materialFields } = bindings;
|
|
206
|
+
if (materialUniforms === undefined ||
|
|
207
|
+
materialSize === undefined ||
|
|
208
|
+
materialFields === undefined) {
|
|
209
|
+
throw new Error(`flatPass: variant "${variant}" has no material block`);
|
|
210
|
+
}
|
|
211
|
+
const fields = { ...bindings.fields };
|
|
212
|
+
for (const [name, field] of Object.entries(materialFields)) {
|
|
213
|
+
fields[name] = { ...field, offset: bindings.uniformSize + field.offset };
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
fields,
|
|
217
|
+
passSize: bindings.uniformSize,
|
|
218
|
+
passBinding: bindings.uniforms,
|
|
219
|
+
materialSize,
|
|
220
|
+
materialBinding: materialUniforms,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
173
223
|
/**
|
|
174
224
|
* The lit fragment stage's constants, set from the cache's switches, keyed by each one's **id**.
|
|
175
225
|
*
|
|
@@ -209,6 +259,13 @@ function flatFragmentConstants(variant, cache, model, skinPass = 'whole', reflec
|
|
|
209
259
|
}
|
|
210
260
|
return constants;
|
|
211
261
|
}
|
|
262
|
+
/** The material block's binding, which every lit variant declares. */
|
|
263
|
+
function materialBinding(fragment) {
|
|
264
|
+
if (fragment.materialUniforms === undefined) {
|
|
265
|
+
throw new Error('flatPass: the lit fragment stage declares no material block');
|
|
266
|
+
}
|
|
267
|
+
return fragment.materialUniforms;
|
|
268
|
+
}
|
|
212
269
|
/** The depth format both backends compare with. */
|
|
213
270
|
/* Re-exported so the twenty passes that already import it from here do not each learn a new
|
|
214
271
|
module; `depthConvention.ts` is where the decision lives and why. */
|
|
@@ -218,11 +275,15 @@ const VISIBILITY_FRAGMENT = 0x2;
|
|
|
218
275
|
/**
|
|
219
276
|
* The layout this variant binds against.
|
|
220
277
|
*
|
|
221
|
-
*
|
|
222
|
-
* from its own slot of one buffer
|
|
223
|
-
*
|
|
278
|
+
* All four blocks are **dynamic**: the vertex block because every draw supplies its own model
|
|
279
|
+
* matrix and tint from its own slot of one buffer; the fragment stage's pass block — the lights, the
|
|
280
|
+
* fog, the camera — and the vertex stage's view block because a frame binds more than one pass; and
|
|
281
|
+
* the material block because a material changes between draws. Their dynamic offsets go in binding
|
|
282
|
+
* order: the draw's, the pass's, the material's, the view's.
|
|
224
283
|
*/
|
|
225
|
-
export function createFlatBindGroupLayout(device, variant, skinned = false, morphed = false
|
|
284
|
+
export function createFlatBindGroupLayout(device, variant, skinned = false, morphed = false,
|
|
285
|
+
/** The instanced variant that plays a bone animation: its three vertex textures. */
|
|
286
|
+
animated = false) {
|
|
226
287
|
const fragment = flatFragmentBindings(variant);
|
|
227
288
|
const entries = [
|
|
228
289
|
{
|
|
@@ -230,15 +291,31 @@ export function createFlatBindGroupLayout(device, variant, skinned = false, morp
|
|
|
230
291
|
visibility: VISIBILITY_VERTEX,
|
|
231
292
|
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: FLAT_VERT_SIZE },
|
|
232
293
|
},
|
|
294
|
+
{
|
|
295
|
+
binding: FLAT_VIEW_BINDING,
|
|
296
|
+
visibility: VISIBILITY_VERTEX,
|
|
297
|
+
/* Dynamic, a slot a pass, for the reason the fragment stage's pass block is. */
|
|
298
|
+
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: FLAT_VIEW_SIZE },
|
|
299
|
+
},
|
|
233
300
|
{
|
|
234
301
|
binding: fragment.uniforms,
|
|
235
302
|
visibility: VISIBILITY_FRAGMENT,
|
|
236
303
|
/*
|
|
237
|
-
* Dynamic, because
|
|
238
|
-
*
|
|
304
|
+
* Dynamic, because a pass's lights and camera change between passes of one frame — a
|
|
305
|
+
* mirror's, a capture's — and one buffer cannot hold two answers. See `WebGPURenderer.passRing`.
|
|
239
306
|
*/
|
|
240
307
|
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: fragment.uniformSize },
|
|
241
308
|
},
|
|
309
|
+
{
|
|
310
|
+
binding: materialBinding(fragment),
|
|
311
|
+
visibility: VISIBILITY_FRAGMENT,
|
|
312
|
+
/* Dynamic, because a material changes between draws. See `MaterialStore`. */
|
|
313
|
+
buffer: {
|
|
314
|
+
type: 'uniform',
|
|
315
|
+
hasDynamicOffset: true,
|
|
316
|
+
minBindingSize: fragment.materialSize ?? 0,
|
|
317
|
+
},
|
|
318
|
+
},
|
|
242
319
|
];
|
|
243
320
|
/** What each sampler binding was declared as, so a shared one is declared once and agrees. */
|
|
244
321
|
const samplerKind = new Map();
|
|
@@ -379,11 +456,33 @@ export function createFlatBindGroupLayout(device, variant, skinned = false, morp
|
|
|
379
456
|
});
|
|
380
457
|
}
|
|
381
458
|
}
|
|
459
|
+
/* A bone animation's places, turns and the batch's clocks, read by index as the palette is. */
|
|
460
|
+
if (animated) {
|
|
461
|
+
for (const binding of animationBindings()) {
|
|
462
|
+
entries.push({
|
|
463
|
+
binding,
|
|
464
|
+
visibility: VISIBILITY_VERTEX,
|
|
465
|
+
texture: { sampleType: 'unfilterable-float' },
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
}
|
|
382
469
|
return device.createBindGroupLayout({
|
|
383
|
-
label: `flat.layout:${variant}|${flatVertexKey(skinned, morphed)}`,
|
|
470
|
+
label: `flat.layout:${variant}|${flatVertexKey(skinned, morphed, animated, animated)}`,
|
|
384
471
|
entries,
|
|
385
472
|
});
|
|
386
473
|
}
|
|
474
|
+
/** The three textures a bone animation binds, in the order `AnimationViews` holds them. */
|
|
475
|
+
function animationBindings() {
|
|
476
|
+
const textures = flatVertexBindings(false, false, true, true).textures;
|
|
477
|
+
const at = (name) => {
|
|
478
|
+
const found = textures[name];
|
|
479
|
+
if (found === undefined) {
|
|
480
|
+
throw new Error(`flatPass: the animated vertex shader declares no ${name}`);
|
|
481
|
+
}
|
|
482
|
+
return found.texture;
|
|
483
|
+
};
|
|
484
|
+
return [at('uBonePlaces'), at('uBoneTurns'), at('uInstanceClocks')];
|
|
485
|
+
}
|
|
387
486
|
/**
|
|
388
487
|
* Bind the buffers and one view per declared texture.
|
|
389
488
|
*
|
|
@@ -393,20 +492,27 @@ export function createFlatBindGroupLayout(device, variant, skinned = false, morp
|
|
|
393
492
|
* and WebGPU still requires something there, which is why `renderer.ts` keeps an
|
|
394
493
|
* `emptyTexture2D` for the same reason on the other side.
|
|
395
494
|
*/
|
|
396
|
-
export function createFlatBindGroup(device, layout, variant, perDraw,
|
|
495
|
+
export function createFlatBindGroup(device, layout, variant, perDraw, passes, materials, views, resolve,
|
|
397
496
|
/** The palette view for a skinned bind group, or null for an unskinned one. */
|
|
398
497
|
palette = null,
|
|
399
498
|
/** The delta view for a morphed bind group, or null for an unmorphed one. */
|
|
400
499
|
deltas = null,
|
|
401
500
|
/** A skinned bind group's cloth views — the draw's, or the stand-in where it sets none. */
|
|
402
|
-
cloth = null
|
|
501
|
+
cloth = null,
|
|
502
|
+
/** An animated instanced group's views. See `AnimationViews`. */
|
|
503
|
+
animation = null) {
|
|
403
504
|
const fragment = flatFragmentBindings(variant);
|
|
404
505
|
const entries = [
|
|
405
506
|
{
|
|
406
507
|
binding: FLAT_VERT_BINDING,
|
|
407
508
|
resource: { buffer: perDraw, size: FLAT_VERT_SIZE },
|
|
408
509
|
},
|
|
409
|
-
{ binding:
|
|
510
|
+
{ binding: FLAT_VIEW_BINDING, resource: { buffer: views, size: FLAT_VIEW_SIZE } },
|
|
511
|
+
{ binding: fragment.uniforms, resource: { buffer: passes, size: fragment.uniformSize } },
|
|
512
|
+
{
|
|
513
|
+
binding: materialBinding(fragment),
|
|
514
|
+
resource: { buffer: materials, size: fragment.materialSize ?? 0 },
|
|
515
|
+
},
|
|
410
516
|
];
|
|
411
517
|
/* The same dedupe the layout does, and for the same reason: the shadow bindings share one
|
|
412
518
|
sampler, and a bind group that filled it fifteen times would be rejected. Every member
|
|
@@ -441,8 +547,14 @@ cloth = null) {
|
|
|
441
547
|
entries.push({ binding: particlesAt, resource: cloth.particles });
|
|
442
548
|
entries.push({ binding: restAt, resource: cloth.rest });
|
|
443
549
|
}
|
|
550
|
+
if (animation !== null) {
|
|
551
|
+
const [places, turns, clocks] = animationBindings();
|
|
552
|
+
entries.push({ binding: places, resource: animation.places });
|
|
553
|
+
entries.push({ binding: turns, resource: animation.turns });
|
|
554
|
+
entries.push({ binding: clocks, resource: animation.clocks });
|
|
555
|
+
}
|
|
444
556
|
return device.createBindGroup({
|
|
445
|
-
label: `flat.bindGroup:${variant}|${flatVertexKey(palette !== null, deltas !== null)}`,
|
|
557
|
+
label: `flat.bindGroup:${variant}|${flatVertexKey(palette !== null, deltas !== null, animation !== null, animation !== null)}`,
|
|
446
558
|
layout,
|
|
447
559
|
entries,
|
|
448
560
|
});
|
|
@@ -510,8 +622,11 @@ skinPass = 'whole',
|
|
|
510
622
|
* The reflection pass's surface half: the draw again, against its own depth, into the two
|
|
511
623
|
* targets `reflectionSurfacePass.ts` holds. The key must carry it: `|rs`.
|
|
512
624
|
*/
|
|
513
|
-
reflectionSurface = false
|
|
514
|
-
|
|
625
|
+
reflectionSurface = false,
|
|
626
|
+
/** An instanced pipeline that plays a bone animation. The key must carry it: `|anim`. */
|
|
627
|
+
animated = false) {
|
|
628
|
+
/* None where draws skip a compile and this one has not landed: see `PipelineCache.lit`. */
|
|
629
|
+
return cache.lit(key, () => flatDescriptor(cache, device, layout, variant, key, present, translucent, skinned, morphed, depthWrite, depthLayer, instanced, oit, doubleSided, alphaToCoverage, skinEight, cloth, model, skinPass, reflectionSurface, animated));
|
|
515
630
|
}
|
|
516
631
|
/**
|
|
517
632
|
* The same pipeline, compiled off the main thread.
|
|
@@ -591,7 +706,9 @@ oit = 'none',
|
|
|
591
706
|
/** Culls nothing: a surface seen from both faces. */
|
|
592
707
|
doubleSided = false, alphaToCoverage = false, skinEight = false,
|
|
593
708
|
/** Whether its vertex stage places vertices by a cloth binding. See `clothBinding.ts`. */
|
|
594
|
-
cloth = false, model = null, skinPass = 'whole', reflectionSurface = false
|
|
709
|
+
cloth = false, model = null, skinPass = 'whole', reflectionSurface = false,
|
|
710
|
+
/** An instanced pipeline that plays a bone animation. See `shaders/boneAnimation.ts`. */
|
|
711
|
+
animated = false) {
|
|
595
712
|
const offset = depthOffsetForLayer(depthLayer);
|
|
596
713
|
/* The diffuse and colour halves are the same surface again, into the blur's targets; and so is
|
|
597
714
|
the reflection pass's surface half, into its two. */
|
|
@@ -606,12 +723,12 @@ cloth = false, model = null, skinPass = 'whole', reflectionSurface = false) {
|
|
|
606
723
|
* layout validates, draws, and is wrong, exactly as this file's header says.
|
|
607
724
|
*/
|
|
608
725
|
module: shaderModule(device, {
|
|
609
|
-
label: `flat.vert:${flatVertexKey(skinned, morphed, instanced)}`,
|
|
610
|
-
code: FLAT_VERT_WGSL[flatVertexKey(skinned, morphed, instanced)] ?? '',
|
|
726
|
+
label: `flat.vert:${flatVertexKey(skinned, morphed, instanced, animated)}`,
|
|
727
|
+
code: FLAT_VERT_WGSL[flatVertexKey(skinned, morphed, instanced, animated)] ?? '',
|
|
611
728
|
}),
|
|
612
729
|
entryPoint: 'main',
|
|
613
730
|
buffers: vertexBufferLayouts(present, instanced),
|
|
614
|
-
constants: vertexConstants(flatVertexBindings(skinned, morphed, instanced), skinEight, cloth, model === 'lightmap'),
|
|
731
|
+
constants: vertexConstants(flatVertexBindings(skinned, morphed, instanced, animated), skinEight, cloth, model === 'lightmap'),
|
|
615
732
|
},
|
|
616
733
|
fragment: {
|
|
617
734
|
module: shaderModule(device, {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { SkinnedClothSetup } from '@driftengine/physics';
|
|
2
|
+
import { GpuClothParticles } from './clothTextures.ts';
|
|
3
|
+
export declare class GpuClothSet {
|
|
4
|
+
private readonly device;
|
|
5
|
+
private readonly garments;
|
|
6
|
+
private readonly packed;
|
|
7
|
+
private readonly kernels;
|
|
8
|
+
private readonly buffers;
|
|
9
|
+
private readonly state;
|
|
10
|
+
private readonly frameData;
|
|
11
|
+
private readonly paces;
|
|
12
|
+
private readonly group;
|
|
13
|
+
/** One round's records, every garment's: the head an op's, the rest each garment's own. */
|
|
14
|
+
private readonly staging;
|
|
15
|
+
private readonly stagingWords;
|
|
16
|
+
private readonly stagingFloats;
|
|
17
|
+
/** Each kind's first batch slot, and the first garment's publishing slot. */
|
|
18
|
+
private readonly batchSlot;
|
|
19
|
+
private readonly groups;
|
|
20
|
+
private readonly substeps;
|
|
21
|
+
private readonly iterations;
|
|
22
|
+
private encoder;
|
|
23
|
+
private pass;
|
|
24
|
+
private round;
|
|
25
|
+
constructor(device: GPUDevice, setups: readonly SkinnedClothSetup[]);
|
|
26
|
+
/** How many garments the set holds. */
|
|
27
|
+
get size(): number;
|
|
28
|
+
/** Garment `g`'s particles, what `setCloth` draws its bound meshes by. */
|
|
29
|
+
particles(g: number): GpuClothParticles;
|
|
30
|
+
/** Garment `g`'s rig for the steps to come; see `ClothControl.setPose`. */
|
|
31
|
+
setPose(g: number, globals: Float32Array, model: Float32Array): void;
|
|
32
|
+
/** The frame's sample of the scene's wind for garment `g`. See `SkinnedCloth.setWind`. */
|
|
33
|
+
setWind(g: number, x: number, y: number, z: number): void;
|
|
34
|
+
/** Garment `g` back to its skinned pose, settled; the next `step` publishes it. */
|
|
35
|
+
reset(g: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* `dt` of the caller's time in whole fixed steps for every garment, and each garment's particles
|
|
38
|
+
* at its `alpha` published for the draws that follow, as the particles of `frame`.
|
|
39
|
+
*/
|
|
40
|
+
step(dt: number, frame: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Garment `g`'s particles where its last step left them, three floats each: for the parity check,
|
|
43
|
+
* which compares them with the CPU solver's positions. Not for a frame — it waits on the device.
|
|
44
|
+
*/
|
|
45
|
+
read(g: number): Promise<Float32Array>;
|
|
46
|
+
/** Its buffers; the particle textures are the renderer's to retire with the frame. */
|
|
47
|
+
dispose(): void;
|
|
48
|
+
private at;
|
|
49
|
+
/** Garment `g`: its schedule over a device that queues, its particles and its own numbers. */
|
|
50
|
+
private garment;
|
|
51
|
+
/**
|
|
52
|
+
* A garment's own words of its record, which every round carries: its colliders, its texture's
|
|
53
|
+
* width and its constants. Its limits ride in the head beside `live`, written as it joins a round.
|
|
54
|
+
*/
|
|
55
|
+
private writeOwn;
|
|
56
|
+
/** Garments that cannot step together, refused by the first number they disagree on. */
|
|
57
|
+
private refuseStrangers;
|
|
58
|
+
private targetsChanged;
|
|
59
|
+
private queueOp;
|
|
60
|
+
private queueStep;
|
|
61
|
+
/** Every op every garment is waiting on, a round of one kind at a time, in each garment's order. */
|
|
62
|
+
private run;
|
|
63
|
+
/** Whether any garment has `kind` next. */
|
|
64
|
+
private waiting;
|
|
65
|
+
/** One round: every garment with `kind` next takes part, and the rest sit it out. */
|
|
66
|
+
private runRound;
|
|
67
|
+
private stepRound;
|
|
68
|
+
/** Every colour of one kind across the set, in colour order, each a dispatch over its range. */
|
|
69
|
+
private batches;
|
|
70
|
+
private dispatch;
|
|
71
|
+
private passFor;
|
|
72
|
+
/** A round's slot, sending what is recorded first where the slots are spent: its byte offset. */
|
|
73
|
+
private takeRound;
|
|
74
|
+
/** Where the records of the round at `roundAt` sit in `paces`. */
|
|
75
|
+
private paceOffset;
|
|
76
|
+
/** Send what has been recorded: every slot it reads was written ahead of it on the queue. */
|
|
77
|
+
private flush;
|
|
78
|
+
/** A garment's skin matrices — or its model, with no rig — and its colliders, into the set's. */
|
|
79
|
+
private writeFrameData;
|
|
80
|
+
}
|