@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
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
DEPTH_CUTOUT_FRAG_WGSL,
|
|
4
4
|
DEPTH_CUTOUT_VERT_WGSL,
|
|
5
5
|
DEPTH_FRAG_WGSL,
|
|
6
|
+
DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_WGSL,
|
|
7
|
+
DEPTH_INSTANCED_ANIMATED_VERT_WGSL,
|
|
6
8
|
DEPTH_INSTANCED_CUTOUT_VERT_WGSL,
|
|
7
9
|
DEPTH_INSTANCED_VERT_WGSL,
|
|
8
10
|
DEPTH_SKINNED_VERT_WGSL,
|
|
@@ -13,6 +15,7 @@ import { vertexConstants } from './flatPass.ts';
|
|
|
13
15
|
import type { PipelineCache } from './pipelineCache.ts';
|
|
14
16
|
import { shaderModule } from './shaderModules.ts';
|
|
15
17
|
import type { ClothViews } from './clothTextures.ts';
|
|
18
|
+
import type { AnimationViews } from './flatPass.ts';
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* The shadow pass: the world drawn from the light, into a depth map.
|
|
@@ -52,6 +55,17 @@ const CLOTH_TEXTURES = [
|
|
|
52
55
|
DEPTH_BINDINGS.DEPTH_SKINNED_VERT.textures.uClothRest,
|
|
53
56
|
] as const;
|
|
54
57
|
|
|
58
|
+
/** A bone animation's three textures, at the bindings both animated depth variants declare them. */
|
|
59
|
+
const ANIMATION_TEXTURES = [
|
|
60
|
+
DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uBonePlaces,
|
|
61
|
+
DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uBoneTurns,
|
|
62
|
+
DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.textures.uInstanceClocks,
|
|
63
|
+
] as const;
|
|
64
|
+
export const DEPTH_INSTANCED_ANIMATED_VERT_FIELDS =
|
|
65
|
+
DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_VERT.fields;
|
|
66
|
+
export const DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_FIELDS =
|
|
67
|
+
DEPTH_BINDINGS.DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT.fields;
|
|
68
|
+
|
|
55
69
|
const VISIBILITY_VERTEX = 0x1;
|
|
56
70
|
const VISIBILITY_FRAGMENT = 0x2;
|
|
57
71
|
|
|
@@ -82,10 +96,19 @@ export function createDepthBindGroupLayout(
|
|
|
82
96
|
* no cutout caster pays nothing.
|
|
83
97
|
*/
|
|
84
98
|
cutout = false,
|
|
99
|
+
/** An instanced caster playing a bone animation: its three vertex textures. */
|
|
100
|
+
animated = false,
|
|
85
101
|
): GPUBindGroupLayout {
|
|
86
102
|
return device.createBindGroupLayout({
|
|
87
|
-
label: skinned ? 'depth.layout.skinned' : cutout ? 'depth.layout.cutout' : 'depth.layout'
|
|
103
|
+
label: `${skinned ? 'depth.layout.skinned' : cutout ? 'depth.layout.cutout' : 'depth.layout'}${animated ? '.animated' : ''}`,
|
|
88
104
|
entries: [
|
|
105
|
+
...(animated
|
|
106
|
+
? ANIMATION_TEXTURES.map((binding) => ({
|
|
107
|
+
binding: binding.texture,
|
|
108
|
+
visibility: VISIBILITY_VERTEX,
|
|
109
|
+
texture: { sampleType: 'unfilterable-float' as GPUTextureSampleType },
|
|
110
|
+
}))
|
|
111
|
+
: []),
|
|
89
112
|
/* The texture and no sampler: the shader reads the palette with `textureLoad`, an integer
|
|
90
113
|
coordinate with nothing to filter, which is what `flatPass.ts` binds for the same
|
|
91
114
|
palette. naga declares a sampler for it and nothing ever reads one. */
|
|
@@ -174,6 +197,8 @@ export function createDepthBindGroup(
|
|
|
174
197
|
cutout: { readonly view: GPUTextureView; readonly sampler: GPUSampler } | null = null,
|
|
175
198
|
/** A skinned group's cloth views: the caster's, or the stand-in where it has none. */
|
|
176
199
|
cloth: ClothViews | null = null,
|
|
200
|
+
/** An animated caster's clip and clocks. See `AnimationViews`. */
|
|
201
|
+
animation: AnimationViews | null = null,
|
|
177
202
|
): GPUBindGroup {
|
|
178
203
|
return device.createBindGroup({
|
|
179
204
|
label:
|
|
@@ -208,6 +233,13 @@ export function createDepthBindGroup(
|
|
|
208
233
|
{ binding: CUTOUT_MAP.sampler, resource: cutout.sampler },
|
|
209
234
|
]
|
|
210
235
|
: []),
|
|
236
|
+
...(animation !== null
|
|
237
|
+
? [
|
|
238
|
+
{ binding: ANIMATION_TEXTURES[0].texture, resource: animation.places },
|
|
239
|
+
{ binding: ANIMATION_TEXTURES[1].texture, resource: animation.turns },
|
|
240
|
+
{ binding: ANIMATION_TEXTURES[2].texture, resource: animation.clocks },
|
|
241
|
+
]
|
|
242
|
+
: []),
|
|
211
243
|
],
|
|
212
244
|
});
|
|
213
245
|
}
|
|
@@ -256,6 +288,8 @@ export function depthPipeline(
|
|
|
256
288
|
skinEight = false,
|
|
257
289
|
/** Whether a skinned caster is placed by a cloth binding, as its visible draw is. The key carries it. */
|
|
258
290
|
cloth = false,
|
|
291
|
+
/** An instanced caster playing a bone animation. The key must carry it. */
|
|
292
|
+
animated = false,
|
|
259
293
|
): GPURenderPipeline {
|
|
260
294
|
return cache.get(key, () => ({
|
|
261
295
|
label: key,
|
|
@@ -263,15 +297,22 @@ export function depthPipeline(
|
|
|
263
297
|
vertex: {
|
|
264
298
|
module: shaderModule(
|
|
265
299
|
device,
|
|
266
|
-
|
|
267
|
-
?
|
|
268
|
-
? {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
:
|
|
273
|
-
|
|
274
|
-
|
|
300
|
+
animated
|
|
301
|
+
? cutout
|
|
302
|
+
? {
|
|
303
|
+
label: 'depth.instanced.animated.cutout.vert',
|
|
304
|
+
code: DEPTH_INSTANCED_ANIMATED_CUTOUT_VERT_WGSL,
|
|
305
|
+
}
|
|
306
|
+
: { label: 'depth.instanced.animated.vert', code: DEPTH_INSTANCED_ANIMATED_VERT_WGSL }
|
|
307
|
+
: cutout
|
|
308
|
+
? instanced
|
|
309
|
+
? { label: 'depth.instanced.cutout.vert', code: DEPTH_INSTANCED_CUTOUT_VERT_WGSL }
|
|
310
|
+
: { label: 'depth.cutout.vert', code: DEPTH_CUTOUT_VERT_WGSL }
|
|
311
|
+
: instanced
|
|
312
|
+
? { label: 'depth.instanced.vert', code: DEPTH_INSTANCED_VERT_WGSL }
|
|
313
|
+
: skinned
|
|
314
|
+
? { label: 'depth.skinned.vert', code: DEPTH_SKINNED_VERT_WGSL }
|
|
315
|
+
: { label: 'depth.vert', code: DEPTH_VERT_WGSL },
|
|
275
316
|
),
|
|
276
317
|
entryPoint: 'main',
|
|
277
318
|
buffers: vertexBufferLayouts(present, instanced),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* One recorded draw, in the only shape this backend ever issues.
|
|
3
3
|
*
|
|
4
4
|
* Sampled across three unrelated verbs — panels, particles, wind streaks — the sequence is the
|
|
5
|
-
* same every time: a pipeline, a bind group with up to
|
|
5
|
+
* same every time: a pipeline, a bind group with up to four dynamic offsets, some vertex
|
|
6
6
|
* buffers, perhaps an index buffer, then a draw. Nothing in it is specific to what is being
|
|
7
7
|
* drawn except the values.
|
|
8
8
|
*
|
|
@@ -21,14 +21,21 @@ const VERTEX_BUFFER_SLOTS = 8;
|
|
|
21
21
|
export interface DrawCommand {
|
|
22
22
|
pipeline: GPURenderPipeline | null;
|
|
23
23
|
bindGroup: GPUBindGroup | null;
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Dynamic offsets, held as numbers rather than an array so a reset stays free. Four only for a
|
|
26
|
+
* lit mesh: its draw's slot, its pass's, its material's and its view's, in binding order.
|
|
27
|
+
*/
|
|
25
28
|
offsetA: number;
|
|
26
29
|
offsetB: number;
|
|
30
|
+
offsetC: number;
|
|
31
|
+
offsetD: number;
|
|
27
32
|
offsetCount: number;
|
|
28
33
|
/** Fixed length; `vertexCount` says how many slots are live. */
|
|
29
34
|
readonly vertexBuffers: (GPUBuffer | null)[];
|
|
30
35
|
vertexCount: number;
|
|
31
36
|
indexBuffer: GPUBuffer | null;
|
|
37
|
+
/** How wide an index of `indexBuffer` is: a mesh's own, thirty-two bits for everything else. */
|
|
38
|
+
indexFormat: GPUIndexFormat;
|
|
32
39
|
indexed: boolean;
|
|
33
40
|
count: number;
|
|
34
41
|
instances: number;
|
|
@@ -37,6 +44,12 @@ export interface DrawCommand {
|
|
|
37
44
|
* cull's survivors, counted on the device. Null for every other draw.
|
|
38
45
|
*/
|
|
39
46
|
indirect: GPUBuffer | null;
|
|
47
|
+
/**
|
|
48
|
+
* Render bundles to execute instead of everything above: a static list recorded once, replayed
|
|
49
|
+
* as one command. Held as the array `executeBundles` takes, kept by the list, so issuing it
|
|
50
|
+
* allocates nothing. Null for every other command, and put back to null by every take.
|
|
51
|
+
*/
|
|
52
|
+
bundles: readonly GPURenderBundle[] | null;
|
|
40
53
|
}
|
|
41
54
|
|
|
42
55
|
export interface CommandPool {
|
|
@@ -52,14 +65,18 @@ function emptyCommand(): DrawCommand {
|
|
|
52
65
|
bindGroup: null,
|
|
53
66
|
offsetA: 0,
|
|
54
67
|
offsetB: 0,
|
|
68
|
+
offsetC: 0,
|
|
69
|
+
offsetD: 0,
|
|
55
70
|
offsetCount: 0,
|
|
56
71
|
vertexBuffers: new Array<GPUBuffer | null>(VERTEX_BUFFER_SLOTS).fill(null),
|
|
57
72
|
vertexCount: 0,
|
|
58
73
|
indexBuffer: null,
|
|
74
|
+
indexFormat: 'uint32',
|
|
59
75
|
indexed: false,
|
|
60
76
|
count: 0,
|
|
61
77
|
instances: 1,
|
|
62
78
|
indirect: null,
|
|
79
|
+
bundles: null,
|
|
63
80
|
};
|
|
64
81
|
}
|
|
65
82
|
|
|
@@ -72,14 +89,18 @@ export function createCommandPool(capacity: number): CommandPool {
|
|
|
72
89
|
/**
|
|
73
90
|
* Hand out the next command, growing if a frame overruns.
|
|
74
91
|
*
|
|
75
|
-
* The entry is **not cleared
|
|
76
|
-
* be a write per field per draw for no reader — the same reasoning the node
|
|
92
|
+
* The entry is **not cleared**, but for `bundles`. Every caller fills every field it uses, and
|
|
93
|
+
* clearing here would be a write per field per draw for no reader — the same reasoning the node
|
|
94
|
+
* arena uses. `bundles` is the exception because almost no caller knows it exists: a pooled command
|
|
95
|
+
* that once carried a static list's bundles and was then taken for an ordinary draw would replay the
|
|
96
|
+
* list instead, so the one field nobody fills is the one field put back here.
|
|
77
97
|
*/
|
|
78
98
|
export function takeCommand(pool: CommandPool): number {
|
|
79
99
|
const at = pool.taken;
|
|
80
100
|
while (at >= pool.commands.length) pool.commands.push(emptyCommand());
|
|
81
101
|
pool.taken = at + 1;
|
|
82
102
|
if (pool.taken > pool.highWater) pool.highWater = pool.taken;
|
|
103
|
+
(pool.commands[at] as DrawCommand).bundles = null;
|
|
83
104
|
return at;
|
|
84
105
|
}
|
|
85
106
|
|
|
@@ -99,6 +99,20 @@ export interface StageBindings {
|
|
|
99
99
|
readonly textures: Readonly<Record<string, TextureBinding>>;
|
|
100
100
|
/** Each pipeline-overridable constant's id, by the GLSL name it was declared under. */
|
|
101
101
|
readonly overrides?: Readonly<Record<string, number>>;
|
|
102
|
+
/**
|
|
103
|
+
* The second block, of the uniforms marked `// wgsl:material`: its binding, size and fields.
|
|
104
|
+
* Absent from a stage that marks none, which is every stage but the lit fragment's.
|
|
105
|
+
*/
|
|
106
|
+
readonly materialUniforms?: number;
|
|
107
|
+
readonly materialSize?: number;
|
|
108
|
+
readonly materialFields?: StageBindings['fields'];
|
|
109
|
+
/**
|
|
110
|
+
* The vertex stage's view block, of the uniforms marked `// wgsl:view`: the camera, the light's
|
|
111
|
+
* matrix and the wind, which a pass settles. Absent from every stage but the lit vertex one.
|
|
112
|
+
*/
|
|
113
|
+
readonly viewUniforms?: number;
|
|
114
|
+
readonly viewSize?: number;
|
|
115
|
+
readonly viewFields?: StageBindings['fields'];
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
/*
|
|
@@ -130,9 +144,16 @@ const VERTEX_BINDINGS = FLAT_BINDINGS.flatVert as unknown as Readonly<
|
|
|
130
144
|
>;
|
|
131
145
|
|
|
132
146
|
/** The key for a set of vertex flags: the same rule `variantKey` uses, flags on, sorted, joined. */
|
|
133
|
-
export function flatVertexKey(
|
|
147
|
+
export function flatVertexKey(
|
|
148
|
+
skinned: boolean,
|
|
149
|
+
morphed: boolean,
|
|
150
|
+
instanced = false,
|
|
151
|
+
/** Whether an instanced variant plays a bone animation. See `shaders/boneAnimation.ts`. */
|
|
152
|
+
animated = false,
|
|
153
|
+
): string {
|
|
134
154
|
const on: string[] = [];
|
|
135
155
|
/* Alphabetical, because the generator's own `variantKey` sorts and the two keys must agree. */
|
|
156
|
+
if (animated) on.push('animated');
|
|
136
157
|
if (instanced) on.push('instanced');
|
|
137
158
|
if (morphed) on.push('morphed');
|
|
138
159
|
if (skinned) on.push('skinned');
|
|
@@ -144,8 +165,9 @@ export function flatVertexBindings(
|
|
|
144
165
|
skinned: boolean,
|
|
145
166
|
morphed = false,
|
|
146
167
|
instanced = false,
|
|
168
|
+
animated = false,
|
|
147
169
|
): StageBindings {
|
|
148
|
-
const key = flatVertexKey(skinned, morphed, instanced);
|
|
170
|
+
const key = flatVertexKey(skinned, morphed, instanced, animated);
|
|
149
171
|
const found = VERTEX_BINDINGS[key];
|
|
150
172
|
if (found === undefined) throw new Error(`flatPass: no vertex bindings for variant "${key}"`);
|
|
151
173
|
return found;
|
|
@@ -221,6 +243,8 @@ for (const [key, bindings] of Object.entries(VERTEX_BINDINGS)) {
|
|
|
221
243
|
}
|
|
222
244
|
|
|
223
245
|
export const FLAT_VERT_FIELDS = FLAT_BINDINGS.flatVert.none.fields;
|
|
246
|
+
/** The animated instanced variant's block: the instanced fields, and the clip's `uBoneClip`. */
|
|
247
|
+
export const FLAT_ANIMATED_VERT_FIELDS = FLAT_BINDINGS.flatVert['animated+instanced'].fields;
|
|
224
248
|
/**
|
|
225
249
|
* The **largest** variant's block, because one ring serves every draw.
|
|
226
250
|
*
|
|
@@ -233,6 +257,35 @@ export const FLAT_VERT_SIZE = Math.max(
|
|
|
233
257
|
);
|
|
234
258
|
const FLAT_VERT_BINDING = PLAIN_VERTEX.uniforms;
|
|
235
259
|
|
|
260
|
+
/*
|
|
261
|
+
* **The view block may be shorter in a variant, never different.** One slot serves every lit draw
|
|
262
|
+
* of a pass, plain and instanced alike, so every field a variant's view block declares must sit
|
|
263
|
+
* where the plain variant has it. The instanced variant declares no wind, and its block is the plain
|
|
264
|
+
* one's first two matrices.
|
|
265
|
+
*/
|
|
266
|
+
const PLAIN_VIEW_FIELDS = PLAIN_VERTEX.viewFields ?? {};
|
|
267
|
+
for (const [key, bindings] of Object.entries(VERTEX_BINDINGS)) {
|
|
268
|
+
if (bindings.viewUniforms !== PLAIN_VERTEX.viewUniforms) {
|
|
269
|
+
throw new Error(`flatPass: vertex variant "${key}" binds its view block elsewhere`);
|
|
270
|
+
}
|
|
271
|
+
for (const [field, here] of Object.entries(bindings.viewFields ?? {})) {
|
|
272
|
+
if (PLAIN_VIEW_FIELDS[field]?.offset !== here.offset) {
|
|
273
|
+
throw new Error(
|
|
274
|
+
`flatPass: vertex variant "${key}" puts view field ${field} at ${here.offset} where the ` +
|
|
275
|
+
`plain variant has it at ${PLAIN_VIEW_FIELDS[field]?.offset}.`,
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** The view block's fields, binding and size: the largest variant's, as `FLAT_VERT_SIZE` is. */
|
|
282
|
+
export const FLAT_VIEW_FIELDS = PLAIN_VIEW_FIELDS;
|
|
283
|
+
export const FLAT_VIEW_SIZE = Math.max(
|
|
284
|
+
...Object.values(VERTEX_BINDINGS).map((bindings) => bindings.viewSize ?? 0),
|
|
285
|
+
);
|
|
286
|
+
const FLAT_VIEW_BINDING = PLAIN_VERTEX.viewUniforms ?? -1;
|
|
287
|
+
if (FLAT_VIEW_BINDING < 0) throw new Error('flatPass: the lit vertex stage declares no view block');
|
|
288
|
+
|
|
236
289
|
/**
|
|
237
290
|
* The most sampled textures and distinct samplers any lit variant carrying the environment probe
|
|
238
291
|
* binds in its fragment stage, counted from the generated bindings: what a device must allow per
|
|
@@ -260,6 +313,46 @@ export function flatFragmentBindings(variant: FlatVariant): StageBindings {
|
|
|
260
313
|
return found;
|
|
261
314
|
}
|
|
262
315
|
|
|
316
|
+
/**
|
|
317
|
+
* The lit fragment stage's two blocks as the renderer keeps them on the CPU: the pass's, then the
|
|
318
|
+
* material's straight after it, in one scratch, with every field at its offset in that scratch.
|
|
319
|
+
*
|
|
320
|
+
* **One scratch rather than two, so no setter has to know which block its field is in.** A setter
|
|
321
|
+
* writes by name, as it always has; the draw copies the material's bytes — `passSize` onwards — into
|
|
322
|
+
* the store and the pass's bytes into a ring slot, each only when something has changed it.
|
|
323
|
+
*/
|
|
324
|
+
export interface FlatFragmentScratch {
|
|
325
|
+
readonly fields: StageBindings['fields'];
|
|
326
|
+
/** Bytes of the pass's block, which is where the material's starts in the scratch. */
|
|
327
|
+
readonly passSize: number;
|
|
328
|
+
readonly passBinding: number;
|
|
329
|
+
readonly materialSize: number;
|
|
330
|
+
readonly materialBinding: number;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function flatFragmentScratch(variant: FlatVariant): FlatFragmentScratch {
|
|
334
|
+
const bindings = flatFragmentBindings(variant);
|
|
335
|
+
const { materialUniforms, materialSize, materialFields } = bindings;
|
|
336
|
+
if (
|
|
337
|
+
materialUniforms === undefined ||
|
|
338
|
+
materialSize === undefined ||
|
|
339
|
+
materialFields === undefined
|
|
340
|
+
) {
|
|
341
|
+
throw new Error(`flatPass: variant "${variant}" has no material block`);
|
|
342
|
+
}
|
|
343
|
+
const fields: Record<string, StageBindings['fields'][string]> = { ...bindings.fields };
|
|
344
|
+
for (const [name, field] of Object.entries(materialFields)) {
|
|
345
|
+
fields[name] = { ...field, offset: bindings.uniformSize + field.offset };
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
fields,
|
|
349
|
+
passSize: bindings.uniformSize,
|
|
350
|
+
passBinding: bindings.uniforms,
|
|
351
|
+
materialSize,
|
|
352
|
+
materialBinding: materialUniforms,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
263
356
|
/**
|
|
264
357
|
* The lit fragment stage's constants, set from the cache's switches, keyed by each one's **id**.
|
|
265
358
|
*
|
|
@@ -306,6 +399,14 @@ function flatFragmentConstants(
|
|
|
306
399
|
return constants;
|
|
307
400
|
}
|
|
308
401
|
|
|
402
|
+
/** The material block's binding, which every lit variant declares. */
|
|
403
|
+
function materialBinding(fragment: StageBindings): number {
|
|
404
|
+
if (fragment.materialUniforms === undefined) {
|
|
405
|
+
throw new Error('flatPass: the lit fragment stage declares no material block');
|
|
406
|
+
}
|
|
407
|
+
return fragment.materialUniforms;
|
|
408
|
+
}
|
|
409
|
+
|
|
309
410
|
/** The depth format both backends compare with. */
|
|
310
411
|
/* Re-exported so the twenty passes that already import it from here do not each learn a new
|
|
311
412
|
module; `depthConvention.ts` is where the decision lives and why. */
|
|
@@ -317,15 +418,19 @@ const VISIBILITY_FRAGMENT = 0x2;
|
|
|
317
418
|
/**
|
|
318
419
|
* The layout this variant binds against.
|
|
319
420
|
*
|
|
320
|
-
*
|
|
321
|
-
* from its own slot of one buffer
|
|
322
|
-
*
|
|
421
|
+
* All four blocks are **dynamic**: the vertex block because every draw supplies its own model
|
|
422
|
+
* matrix and tint from its own slot of one buffer; the fragment stage's pass block — the lights, the
|
|
423
|
+
* fog, the camera — and the vertex stage's view block because a frame binds more than one pass; and
|
|
424
|
+
* the material block because a material changes between draws. Their dynamic offsets go in binding
|
|
425
|
+
* order: the draw's, the pass's, the material's, the view's.
|
|
323
426
|
*/
|
|
324
427
|
export function createFlatBindGroupLayout(
|
|
325
428
|
device: GPUDevice,
|
|
326
429
|
variant: FlatVariant,
|
|
327
430
|
skinned = false,
|
|
328
431
|
morphed = false,
|
|
432
|
+
/** The instanced variant that plays a bone animation: its three vertex textures. */
|
|
433
|
+
animated = false,
|
|
329
434
|
): GPUBindGroupLayout {
|
|
330
435
|
const fragment = flatFragmentBindings(variant);
|
|
331
436
|
const entries: GPUBindGroupLayoutEntry[] = [
|
|
@@ -334,15 +439,31 @@ export function createFlatBindGroupLayout(
|
|
|
334
439
|
visibility: VISIBILITY_VERTEX,
|
|
335
440
|
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: FLAT_VERT_SIZE },
|
|
336
441
|
},
|
|
442
|
+
{
|
|
443
|
+
binding: FLAT_VIEW_BINDING,
|
|
444
|
+
visibility: VISIBILITY_VERTEX,
|
|
445
|
+
/* Dynamic, a slot a pass, for the reason the fragment stage's pass block is. */
|
|
446
|
+
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: FLAT_VIEW_SIZE },
|
|
447
|
+
},
|
|
337
448
|
{
|
|
338
449
|
binding: fragment.uniforms,
|
|
339
450
|
visibility: VISIBILITY_FRAGMENT,
|
|
340
451
|
/*
|
|
341
|
-
* Dynamic, because
|
|
342
|
-
*
|
|
452
|
+
* Dynamic, because a pass's lights and camera change between passes of one frame — a
|
|
453
|
+
* mirror's, a capture's — and one buffer cannot hold two answers. See `WebGPURenderer.passRing`.
|
|
343
454
|
*/
|
|
344
455
|
buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: fragment.uniformSize },
|
|
345
456
|
},
|
|
457
|
+
{
|
|
458
|
+
binding: materialBinding(fragment),
|
|
459
|
+
visibility: VISIBILITY_FRAGMENT,
|
|
460
|
+
/* Dynamic, because a material changes between draws. See `MaterialStore`. */
|
|
461
|
+
buffer: {
|
|
462
|
+
type: 'uniform',
|
|
463
|
+
hasDynamicOffset: true,
|
|
464
|
+
minBindingSize: fragment.materialSize ?? 0,
|
|
465
|
+
},
|
|
466
|
+
},
|
|
346
467
|
];
|
|
347
468
|
|
|
348
469
|
/** What each sampler binding was declared as, so a shared one is declared once and agrees. */
|
|
@@ -489,12 +610,43 @@ export function createFlatBindGroupLayout(
|
|
|
489
610
|
}
|
|
490
611
|
}
|
|
491
612
|
|
|
613
|
+
/* A bone animation's places, turns and the batch's clocks, read by index as the palette is. */
|
|
614
|
+
if (animated) {
|
|
615
|
+
for (const binding of animationBindings()) {
|
|
616
|
+
entries.push({
|
|
617
|
+
binding,
|
|
618
|
+
visibility: VISIBILITY_VERTEX,
|
|
619
|
+
texture: { sampleType: 'unfilterable-float' },
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
492
624
|
return device.createBindGroupLayout({
|
|
493
|
-
label: `flat.layout:${variant}|${flatVertexKey(skinned, morphed)}`,
|
|
625
|
+
label: `flat.layout:${variant}|${flatVertexKey(skinned, morphed, animated, animated)}`,
|
|
494
626
|
entries,
|
|
495
627
|
});
|
|
496
628
|
}
|
|
497
629
|
|
|
630
|
+
/** The three textures a bone animation binds, in the order `AnimationViews` holds them. */
|
|
631
|
+
function animationBindings(): [number, number, number] {
|
|
632
|
+
const textures = flatVertexBindings(false, false, true, true).textures;
|
|
633
|
+
const at = (name: string): number => {
|
|
634
|
+
const found = textures[name];
|
|
635
|
+
if (found === undefined) {
|
|
636
|
+
throw new Error(`flatPass: the animated vertex shader declares no ${name}`);
|
|
637
|
+
}
|
|
638
|
+
return found.texture;
|
|
639
|
+
};
|
|
640
|
+
return [at('uBonePlaces'), at('uBoneTurns'), at('uInstanceClocks')];
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** What an animated draw binds besides its material: the clip's two textures and its batch's clocks. */
|
|
644
|
+
export interface AnimationViews {
|
|
645
|
+
readonly places: GPUTextureView;
|
|
646
|
+
readonly turns: GPUTextureView;
|
|
647
|
+
readonly clocks: GPUTextureView;
|
|
648
|
+
}
|
|
649
|
+
|
|
498
650
|
/**
|
|
499
651
|
* Bind the buffers and one view per declared texture.
|
|
500
652
|
*
|
|
@@ -509,7 +661,9 @@ export function createFlatBindGroup(
|
|
|
509
661
|
layout: GPUBindGroupLayout,
|
|
510
662
|
variant: FlatVariant,
|
|
511
663
|
perDraw: GPUBuffer,
|
|
512
|
-
|
|
664
|
+
passes: GPUBuffer,
|
|
665
|
+
materials: GPUBuffer,
|
|
666
|
+
views: GPUBuffer,
|
|
513
667
|
resolve: (name: string) => { view: GPUTextureView; sampler: GPUSampler },
|
|
514
668
|
/** The palette view for a skinned bind group, or null for an unskinned one. */
|
|
515
669
|
palette: GPUTextureView | null = null,
|
|
@@ -517,6 +671,8 @@ export function createFlatBindGroup(
|
|
|
517
671
|
deltas: GPUTextureView | null = null,
|
|
518
672
|
/** A skinned bind group's cloth views — the draw's, or the stand-in where it sets none. */
|
|
519
673
|
cloth: ClothViews | null = null,
|
|
674
|
+
/** An animated instanced group's views. See `AnimationViews`. */
|
|
675
|
+
animation: AnimationViews | null = null,
|
|
520
676
|
): GPUBindGroup {
|
|
521
677
|
const fragment = flatFragmentBindings(variant);
|
|
522
678
|
const entries: GPUBindGroupEntry[] = [
|
|
@@ -524,7 +680,12 @@ export function createFlatBindGroup(
|
|
|
524
680
|
binding: FLAT_VERT_BINDING,
|
|
525
681
|
resource: { buffer: perDraw, size: FLAT_VERT_SIZE },
|
|
526
682
|
},
|
|
527
|
-
{ binding:
|
|
683
|
+
{ binding: FLAT_VIEW_BINDING, resource: { buffer: views, size: FLAT_VIEW_SIZE } },
|
|
684
|
+
{ binding: fragment.uniforms, resource: { buffer: passes, size: fragment.uniformSize } },
|
|
685
|
+
{
|
|
686
|
+
binding: materialBinding(fragment),
|
|
687
|
+
resource: { buffer: materials, size: fragment.materialSize ?? 0 },
|
|
688
|
+
},
|
|
528
689
|
];
|
|
529
690
|
|
|
530
691
|
/* The same dedupe the layout does, and for the same reason: the shadow bindings share one
|
|
@@ -563,8 +724,15 @@ export function createFlatBindGroup(
|
|
|
563
724
|
entries.push({ binding: restAt, resource: cloth.rest });
|
|
564
725
|
}
|
|
565
726
|
|
|
727
|
+
if (animation !== null) {
|
|
728
|
+
const [places, turns, clocks] = animationBindings();
|
|
729
|
+
entries.push({ binding: places, resource: animation.places });
|
|
730
|
+
entries.push({ binding: turns, resource: animation.turns });
|
|
731
|
+
entries.push({ binding: clocks, resource: animation.clocks });
|
|
732
|
+
}
|
|
733
|
+
|
|
566
734
|
return device.createBindGroup({
|
|
567
|
-
label: `flat.bindGroup:${variant}|${flatVertexKey(palette !== null, deltas !== null)}`,
|
|
735
|
+
label: `flat.bindGroup:${variant}|${flatVertexKey(palette !== null, deltas !== null, animation !== null, animation !== null)}`,
|
|
568
736
|
layout,
|
|
569
737
|
entries,
|
|
570
738
|
});
|
|
@@ -641,33 +809,34 @@ export function flatPipeline(
|
|
|
641
809
|
* targets `reflectionSurfacePass.ts` holds. The key must carry it: `|rs`.
|
|
642
810
|
*/
|
|
643
811
|
reflectionSurface = false,
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
812
|
+
/** An instanced pipeline that plays a bone animation. The key must carry it: `|anim`. */
|
|
813
|
+
animated = false,
|
|
814
|
+
): GPURenderPipeline | null {
|
|
815
|
+
/* None where draws skip a compile and this one has not landed: see `PipelineCache.lit`. */
|
|
816
|
+
return cache.lit(key, () =>
|
|
817
|
+
flatDescriptor(
|
|
818
|
+
cache,
|
|
819
|
+
device,
|
|
820
|
+
layout,
|
|
821
|
+
variant,
|
|
822
|
+
key,
|
|
823
|
+
present,
|
|
824
|
+
translucent,
|
|
825
|
+
skinned,
|
|
826
|
+
morphed,
|
|
827
|
+
depthWrite,
|
|
828
|
+
depthLayer,
|
|
829
|
+
instanced,
|
|
830
|
+
oit,
|
|
831
|
+
doubleSided,
|
|
832
|
+
alphaToCoverage,
|
|
833
|
+
skinEight,
|
|
834
|
+
cloth,
|
|
835
|
+
model,
|
|
836
|
+
skinPass,
|
|
837
|
+
reflectionSurface,
|
|
838
|
+
animated,
|
|
839
|
+
),
|
|
671
840
|
);
|
|
672
841
|
}
|
|
673
842
|
|
|
@@ -799,6 +968,8 @@ function flatDescriptor(
|
|
|
799
968
|
model: SurfaceModelKind | null = null,
|
|
800
969
|
skinPass: SkinHalf = 'whole',
|
|
801
970
|
reflectionSurface = false,
|
|
971
|
+
/** An instanced pipeline that plays a bone animation. See `shaders/boneAnimation.ts`. */
|
|
972
|
+
animated = false,
|
|
802
973
|
): GPURenderPipelineDescriptor {
|
|
803
974
|
const offset = depthOffsetForLayer(depthLayer);
|
|
804
975
|
/* The diffuse and colour halves are the same surface again, into the blur's targets; and so is
|
|
@@ -814,13 +985,13 @@ function flatDescriptor(
|
|
|
814
985
|
* layout validates, draws, and is wrong, exactly as this file's header says.
|
|
815
986
|
*/
|
|
816
987
|
module: shaderModule(device, {
|
|
817
|
-
label: `flat.vert:${flatVertexKey(skinned, morphed, instanced)}`,
|
|
818
|
-
code: FLAT_VERT_WGSL[flatVertexKey(skinned, morphed, instanced)] ?? '',
|
|
988
|
+
label: `flat.vert:${flatVertexKey(skinned, morphed, instanced, animated)}`,
|
|
989
|
+
code: FLAT_VERT_WGSL[flatVertexKey(skinned, morphed, instanced, animated)] ?? '',
|
|
819
990
|
}),
|
|
820
991
|
entryPoint: 'main',
|
|
821
992
|
buffers: vertexBufferLayouts(present, instanced),
|
|
822
993
|
constants: vertexConstants(
|
|
823
|
-
flatVertexBindings(skinned, morphed, instanced),
|
|
994
|
+
flatVertexBindings(skinned, morphed, instanced, animated),
|
|
824
995
|
skinEight,
|
|
825
996
|
cloth,
|
|
826
997
|
model === 'lightmap',
|