@flighthq/scene3d-wgpu 0.2.1-next.840.857425c
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/dist/anisotropyPbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/anisotropyPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/anisotropyPbrWgpuMeshMaterialRenderer.js +52 -0
- package/dist/anisotropyPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/blinnPhongWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/blinnPhongWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/blinnPhongWgpuMeshMaterialRenderer.js +66 -0
- package/dist/blinnPhongWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/clearcoatPbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/clearcoatPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/clearcoatPbrWgpuMeshMaterialRenderer.js +52 -0
- package/dist/clearcoatPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/customShaderWgpuMeshMaterialRenderer.d.ts +7 -0
- package/dist/customShaderWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/customShaderWgpuMeshMaterialRenderer.js +225 -0
- package/dist/customShaderWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/depthWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/depthWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/depthWgpuMeshMaterialRenderer.js +42 -0
- package/dist/depthWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/drawWgpuScene3D.d.ts +4 -0
- package/dist/drawWgpuScene3D.d.ts.map +1 -0
- package/dist/drawWgpuScene3D.js +171 -0
- package/dist/drawWgpuScene3D.js.map +1 -0
- package/dist/emissiveWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/emissiveWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/emissiveWgpuMeshMaterialRenderer.js +51 -0
- package/dist/emissiveWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/enableWgpuScene3DCustomShaderGuards.d.ts +5 -0
- package/dist/enableWgpuScene3DCustomShaderGuards.d.ts.map +1 -0
- package/dist/enableWgpuScene3DCustomShaderGuards.js +56 -0
- package/dist/enableWgpuScene3DCustomShaderGuards.js.map +1 -0
- package/dist/enableWgpuScene3DForwardLightSelectionGuards.d.ts +4 -0
- package/dist/enableWgpuScene3DForwardLightSelectionGuards.d.ts.map +1 -0
- package/dist/enableWgpuScene3DForwardLightSelectionGuards.js +17 -0
- package/dist/enableWgpuScene3DForwardLightSelectionGuards.js.map +1 -0
- package/dist/explainWgpuScene3DForwardLightSelection.d.ts +3 -0
- package/dist/explainWgpuScene3DForwardLightSelection.d.ts.map +1 -0
- package/dist/explainWgpuScene3DForwardLightSelection.js +18 -0
- package/dist/explainWgpuScene3DForwardLightSelection.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/iridescencePbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/iridescencePbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/iridescencePbrWgpuMeshMaterialRenderer.js +60 -0
- package/dist/iridescencePbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/lambertWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/lambertWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/lambertWgpuMeshMaterialRenderer.js +61 -0
- package/dist/lambertWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/matcapWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/matcapWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/matcapWgpuMeshMaterialRenderer.js +54 -0
- package/dist/matcapWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/normalWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/normalWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/normalWgpuMeshMaterialRenderer.js +47 -0
- package/dist/normalWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/phongWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/phongWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/phongWgpuMeshMaterialRenderer.js +63 -0
- package/dist/phongWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/prepareWgpuScene3DForwardLights.d.ts +3 -0
- package/dist/prepareWgpuScene3DForwardLights.d.ts.map +1 -0
- package/dist/prepareWgpuScene3DForwardLights.js +110 -0
- package/dist/prepareWgpuScene3DForwardLights.js.map +1 -0
- package/dist/registerStandardPbrWgpuMaterial.d.ts +3 -0
- package/dist/registerStandardPbrWgpuMaterial.d.ts.map +1 -0
- package/dist/registerStandardPbrWgpuMaterial.js +11 -0
- package/dist/registerStandardPbrWgpuMaterial.js.map +1 -0
- package/dist/shadedWgpuMeshMaterialRenderer.d.ts +11 -0
- package/dist/shadedWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/shadedWgpuMeshMaterialRenderer.js +47 -0
- package/dist/shadedWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/sheenPbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/sheenPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/sheenPbrWgpuMeshMaterialRenderer.js +58 -0
- package/dist/sheenPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/specularGlossinessPbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularGlossinessPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularGlossinessPbrWgpuMeshMaterialRenderer.js +126 -0
- package/dist/specularGlossinessPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/specularPbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularPbrWgpuMeshMaterialRenderer.js +65 -0
- package/dist/specularPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/standardPbrWgpuMeshMaterialRenderer.d.ts +9 -0
- package/dist/standardPbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/standardPbrWgpuMeshMaterialRenderer.js +174 -0
- package/dist/standardPbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/subsurfacePbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/subsurfacePbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/subsurfacePbrWgpuMeshMaterialRenderer.js +68 -0
- package/dist/subsurfacePbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/toonWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/toonWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/toonWgpuMeshMaterialRenderer.js +71 -0
- package/dist/toonWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/transmissionVolumePbrWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/transmissionVolumePbrWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/transmissionVolumePbrWgpuMeshMaterialRenderer.js +74 -0
- package/dist/transmissionVolumePbrWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/unlitWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/unlitWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/unlitWgpuMeshMaterialRenderer.js +57 -0
- package/dist/unlitWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/vertexColorWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/vertexColorWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/vertexColorWgpuMeshMaterialRenderer.js +55 -0
- package/dist/vertexColorWgpuMeshMaterialRenderer.js.map +1 -0
- package/dist/wgpuClassicPrelude.d.ts +8 -0
- package/dist/wgpuClassicPrelude.d.ts.map +1 -0
- package/dist/wgpuClassicPrelude.js +319 -0
- package/dist/wgpuClassicPrelude.js.map +1 -0
- package/dist/wgpuCustomMaterialAbi.d.ts +3 -0
- package/dist/wgpuCustomMaterialAbi.d.ts.map +1 -0
- package/dist/wgpuCustomMaterialAbi.js +5 -0
- package/dist/wgpuCustomMaterialAbi.js.map +1 -0
- package/dist/wgpuDebugPrelude.d.ts +7 -0
- package/dist/wgpuDebugPrelude.d.ts.map +1 -0
- package/dist/wgpuDebugPrelude.js +133 -0
- package/dist/wgpuDebugPrelude.js.map +1 -0
- package/dist/wgpuEnvironmentCube.d.ts +4 -0
- package/dist/wgpuEnvironmentCube.d.ts.map +1 -0
- package/dist/wgpuEnvironmentCube.js +66 -0
- package/dist/wgpuEnvironmentCube.js.map +1 -0
- package/dist/wgpuEnvironmentIblBake.d.ts +4 -0
- package/dist/wgpuEnvironmentIblBake.d.ts.map +1 -0
- package/dist/wgpuEnvironmentIblBake.js +458 -0
- package/dist/wgpuEnvironmentIblBake.js.map +1 -0
- package/dist/wgpuEnvironmentSkybox.d.ts +3 -0
- package/dist/wgpuEnvironmentSkybox.d.ts.map +1 -0
- package/dist/wgpuEnvironmentSkybox.js +159 -0
- package/dist/wgpuEnvironmentSkybox.js.map +1 -0
- package/dist/wgpuMatcapPrelude.d.ts +7 -0
- package/dist/wgpuMatcapPrelude.d.ts.map +1 -0
- package/dist/wgpuMatcapPrelude.js +134 -0
- package/dist/wgpuMatcapPrelude.js.map +1 -0
- package/dist/wgpuMeshMaterialRegistry.d.ts +5 -0
- package/dist/wgpuMeshMaterialRegistry.d.ts.map +1 -0
- package/dist/wgpuMeshMaterialRegistry.js +29 -0
- package/dist/wgpuMeshMaterialRegistry.js.map +1 -0
- package/dist/wgpuMeshPipeline.d.ts +43 -0
- package/dist/wgpuMeshPipeline.d.ts.map +1 -0
- package/dist/wgpuMeshPipeline.js +1007 -0
- package/dist/wgpuMeshPipeline.js.map +1 -0
- package/dist/wgpuMeshUpload.d.ts +3 -0
- package/dist/wgpuMeshUpload.d.ts.map +1 -0
- package/dist/wgpuMeshUpload.js +58 -0
- package/dist/wgpuMeshUpload.js.map +1 -0
- package/dist/wgpuParticleEmitter3D.d.ts +4 -0
- package/dist/wgpuParticleEmitter3D.d.ts.map +1 -0
- package/dist/wgpuParticleEmitter3D.js +403 -0
- package/dist/wgpuParticleEmitter3D.js.map +1 -0
- package/dist/wgpuPbrPipelineCache.d.ts +4 -0
- package/dist/wgpuPbrPipelineCache.d.ts.map +1 -0
- package/dist/wgpuPbrPipelineCache.js +52 -0
- package/dist/wgpuPbrPipelineCache.js.map +1 -0
- package/dist/wgpuPbrPrelude.d.ts +7 -0
- package/dist/wgpuPbrPrelude.d.ts.map +1 -0
- package/dist/wgpuPbrPrelude.js +551 -0
- package/dist/wgpuPbrPrelude.js.map +1 -0
- package/dist/wgpuScene3DRuntime.d.ts +5 -0
- package/dist/wgpuScene3DRuntime.d.ts.map +1 -0
- package/dist/wgpuScene3DRuntime.js +81 -0
- package/dist/wgpuScene3DRuntime.js.map +1 -0
- package/dist/wgpuScene3DTestHelper.d.ts +14 -0
- package/dist/wgpuScene3DTestHelper.d.ts.map +1 -0
- package/dist/wgpuScene3DTestHelper.js +121 -0
- package/dist/wgpuScene3DTestHelper.js.map +1 -0
- package/dist/wgpuScene3DTime.d.ts +4 -0
- package/dist/wgpuScene3DTime.d.ts.map +1 -0
- package/dist/wgpuScene3DTime.js +11 -0
- package/dist/wgpuScene3DTime.js.map +1 -0
- package/dist/wgpuShadedModifierSnippet.d.ts +4 -0
- package/dist/wgpuShadedModifierSnippet.d.ts.map +1 -0
- package/dist/wgpuShadedModifierSnippet.js +18 -0
- package/dist/wgpuShadedModifierSnippet.js.map +1 -0
- package/dist/wgpuShadedPrelude.d.ts +16 -0
- package/dist/wgpuShadedPrelude.d.ts.map +1 -0
- package/dist/wgpuShadedPrelude.js +625 -0
- package/dist/wgpuShadedPrelude.js.map +1 -0
- package/dist/wgpuShadowMap.d.ts +4 -0
- package/dist/wgpuShadowMap.d.ts.map +1 -0
- package/dist/wgpuShadowMap.js +155 -0
- package/dist/wgpuShadowMap.js.map +1 -0
- package/dist/wgpuSkinPalette.d.ts +7 -0
- package/dist/wgpuSkinPalette.d.ts.map +1 -0
- package/dist/wgpuSkinPalette.js +173 -0
- package/dist/wgpuSkinPalette.js.map +1 -0
- package/dist/wgpuToonPrelude.d.ts +8 -0
- package/dist/wgpuToonPrelude.d.ts.map +1 -0
- package/dist/wgpuToonPrelude.js +192 -0
- package/dist/wgpuToonPrelude.js.map +1 -0
- package/dist/wgpuUnlitPrelude.d.ts +9 -0
- package/dist/wgpuUnlitPrelude.d.ts.map +1 -0
- package/dist/wgpuUnlitPrelude.js +142 -0
- package/dist/wgpuUnlitPrelude.js.map +1 -0
- package/dist/wgpuWireframePrelude.d.ts +6 -0
- package/dist/wgpuWireframePrelude.d.ts.map +1 -0
- package/dist/wgpuWireframePrelude.js +77 -0
- package/dist/wgpuWireframePrelude.js.map +1 -0
- package/dist/wgpuWireframeUpload.d.ts +3 -0
- package/dist/wgpuWireframeUpload.d.ts.map +1 -0
- package/dist/wgpuWireframeUpload.js +68 -0
- package/dist/wgpuWireframeUpload.js.map +1 -0
- package/dist/wireframeWgpuMeshMaterialRenderer.d.ts +4 -0
- package/dist/wireframeWgpuMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/wireframeWgpuMeshMaterialRenderer.js +69 -0
- package/dist/wireframeWgpuMeshMaterialRenderer.js.map +1 -0
- package/package.json +57 -0
- package/src/anisotropyPbrWgpuMeshMaterialRenderer.test.ts +90 -0
- package/src/blinnPhongWgpuMeshMaterialRenderer.test.ts +82 -0
- package/src/clearcoatPbrWgpuMeshMaterialRenderer.test.ts +90 -0
- package/src/customShaderWgpuMeshMaterialRenderer.test.ts +207 -0
- package/src/depthWgpuMeshMaterialRenderer.test.ts +69 -0
- package/src/drawWgpuScene3D.test.ts +247 -0
- package/src/emissiveWgpuMeshMaterialRenderer.test.ts +64 -0
- package/src/enableWgpuScene3DCustomShaderGuards.test.ts +73 -0
- package/src/enableWgpuScene3DForwardLightSelectionGuards.test.ts +39 -0
- package/src/explainWgpuScene3DForwardLightSelection.test.ts +15 -0
- package/src/iridescencePbrWgpuMeshMaterialRenderer.test.ts +90 -0
- package/src/lambertWgpuMeshMaterialRenderer.test.ts +77 -0
- package/src/matcapWgpuMeshMaterialRenderer.test.ts +69 -0
- package/src/normalWgpuMeshMaterialRenderer.test.ts +69 -0
- package/src/phongWgpuMeshMaterialRenderer.test.ts +79 -0
- package/src/prepareWgpuScene3DForwardLights.test.ts +84 -0
- package/src/registerStandardPbrWgpuMaterial.test.ts +15 -0
- package/src/shadedWgpuMeshMaterialRenderer.test.ts +63 -0
- package/src/sheenPbrWgpuMeshMaterialRenderer.test.ts +87 -0
- package/src/specularGlossinessPbrWgpuMeshMaterialRenderer.test.ts +100 -0
- package/src/specularPbrWgpuMeshMaterialRenderer.test.ts +90 -0
- package/src/standardPbrWgpuMeshMaterialRenderer.test.ts +172 -0
- package/src/subsurfacePbrWgpuMeshMaterialRenderer.test.ts +90 -0
- package/src/toonWgpuMeshMaterialRenderer.test.ts +89 -0
- package/src/transmissionVolumePbrWgpuMeshMaterialRenderer.test.ts +97 -0
- package/src/unlitWgpuMeshMaterialRenderer.test.ts +94 -0
- package/src/vertexColorWgpuMeshMaterialRenderer.test.ts +62 -0
- package/src/wgpuClassicPrelude.test.ts +176 -0
- package/src/wgpuDebugPrelude.test.ts +79 -0
- package/src/wgpuEnvironmentCube.test.ts +86 -0
- package/src/wgpuEnvironmentIblBake.test.ts +79 -0
- package/src/wgpuEnvironmentSkybox.test.ts +56 -0
- package/src/wgpuMatcapPrelude.test.ts +70 -0
- package/src/wgpuMeshMaterialRegistry.test.ts +55 -0
- package/src/wgpuMeshPipeline.test.ts +844 -0
- package/src/wgpuMeshUpload.test.ts +177 -0
- package/src/wgpuParticleEmitter3D.test.ts +200 -0
- package/src/wgpuPbrPipelineCache.test.ts +67 -0
- package/src/wgpuPbrPrelude.test.ts +162 -0
- package/src/wgpuScene3DRuntime.test.ts +35 -0
- package/src/wgpuScene3DTime.test.ts +20 -0
- package/src/wgpuShadedModifierSnippet.test.ts +33 -0
- package/src/wgpuShadedPrelude.test.ts +394 -0
- package/src/wgpuShadowMap.test.ts +169 -0
- package/src/wgpuSkinPalette.test.ts +88 -0
- package/src/wgpuToonPrelude.test.ts +93 -0
- package/src/wgpuUnlitPrelude.test.ts +102 -0
- package/src/wgpuWireframePrelude.test.ts +54 -0
- package/src/wgpuWireframeUpload.test.ts +36 -0
- package/src/wireframeWgpuMeshMaterialRenderer.test.ts +69 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { getWgpuScene3DRuntime } from './wgpuScene3DRuntime';
|
|
4
|
+
import { makeWgpuScene3DState } from './wgpuScene3DTestHelper';
|
|
5
|
+
import {
|
|
6
|
+
destroyWgpuSkinPalette,
|
|
7
|
+
ensureWgpuSkinDrawBindGroup,
|
|
8
|
+
ensureWgpuSkinDrawLayout,
|
|
9
|
+
registerWgpuGpuSkinning,
|
|
10
|
+
uploadWgpuSkinPalette,
|
|
11
|
+
} from './wgpuSkinPalette';
|
|
12
|
+
|
|
13
|
+
describe('destroyWgpuSkinPalette', () => {
|
|
14
|
+
it('clears every palette and draw-group cache slot', () => {
|
|
15
|
+
const { state } = makeWgpuScene3DState();
|
|
16
|
+
uploadWgpuSkinPalette(state, new Float32Array(16));
|
|
17
|
+
const runtime = getWgpuScene3DRuntime(state);
|
|
18
|
+
runtime.skinDrawBindGroup = {} as GPUBindGroup;
|
|
19
|
+
|
|
20
|
+
destroyWgpuSkinPalette(state);
|
|
21
|
+
|
|
22
|
+
expect(runtime.skinPaletteTexture).toBeNull();
|
|
23
|
+
expect(runtime.skinPaletteView).toBeNull();
|
|
24
|
+
expect(runtime.skinPaletteCapacity).toBe(0);
|
|
25
|
+
expect(runtime.skinDrawBindGroup).toBeNull();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('ensureWgpuSkinDrawBindGroup', () => {
|
|
30
|
+
it('caches the group and rebuilds it only when palette growth replaces its view', () => {
|
|
31
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
32
|
+
const first = ensureWgpuSkinDrawBindGroup(state, new Float32Array(16));
|
|
33
|
+
const groupCount = fake.calls.filter((call) => call.name === 'createBindGroup').length;
|
|
34
|
+
expect(ensureWgpuSkinDrawBindGroup(state, new Float32Array(16))).toBe(first);
|
|
35
|
+
expect(fake.calls.filter((call) => call.name === 'createBindGroup')).toHaveLength(groupCount);
|
|
36
|
+
|
|
37
|
+
ensureWgpuSkinDrawBindGroup(state, new Float32Array(32));
|
|
38
|
+
expect(fake.calls.filter((call) => call.name === 'createBindGroup')).toHaveLength(groupCount + 1);
|
|
39
|
+
expect(fake.calls.filter((call) => call.name === 'createTexture')).toHaveLength(2);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('ensureWgpuSkinDrawLayout', () => {
|
|
44
|
+
it('caches the state-owned skin draw layout', () => {
|
|
45
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
46
|
+
const layout = ensureWgpuSkinDrawLayout(state);
|
|
47
|
+
expect(ensureWgpuSkinDrawLayout(state)).toBe(layout);
|
|
48
|
+
expect(fake.calls.filter((call) => call.name === 'createBindGroupLayout')).toHaveLength(1);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('registerWgpuGpuSkinning', () => {
|
|
53
|
+
it('installs the opt-in adapter on only the requested render state', () => {
|
|
54
|
+
const { state } = makeWgpuScene3DState();
|
|
55
|
+
expect(getWgpuScene3DRuntime(state).skinningAdapter).toBeNull();
|
|
56
|
+
registerWgpuGpuSkinning(state);
|
|
57
|
+
expect(getWgpuScene3DRuntime(state).skinningAdapter).not.toBeNull();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('uploadWgpuSkinPalette', () => {
|
|
62
|
+
it('packs four rgba32float texels per joint into one row', () => {
|
|
63
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
64
|
+
const joints = new Float32Array(32);
|
|
65
|
+
const view = uploadWgpuSkinPalette(state, joints);
|
|
66
|
+
const texture = fake.calls.find((call) => call.name === 'createTexture');
|
|
67
|
+
const write = fake.calls.find((call) => call.name === 'writeTexture');
|
|
68
|
+
|
|
69
|
+
expect(view).toBe(getWgpuScene3DRuntime(state).skinPaletteView);
|
|
70
|
+
expect(texture?.args[0]).toMatchObject({
|
|
71
|
+
format: 'rgba32float',
|
|
72
|
+
size: [8, 1, 1],
|
|
73
|
+
});
|
|
74
|
+
expect(write?.args[2]).toEqual({ bytesPerRow: 128 });
|
|
75
|
+
expect(write?.args[3]).toEqual([8, 1, 1]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('reuses capacity and grows without a joint-count fallback gate', () => {
|
|
79
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
80
|
+
uploadWgpuSkinPalette(state, new Float32Array(16 * 80));
|
|
81
|
+
uploadWgpuSkinPalette(state, new Float32Array(16 * 40));
|
|
82
|
+
expect(fake.calls.filter((call) => call.name === 'createTexture')).toHaveLength(1);
|
|
83
|
+
|
|
84
|
+
uploadWgpuSkinPalette(state, new Float32Array(16 * 160));
|
|
85
|
+
expect(fake.calls.filter((call) => call.name === 'createTexture')).toHaveLength(2);
|
|
86
|
+
expect(getWgpuScene3DRuntime(state).skinPaletteCapacity).toBe(160);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { LinearColor, WgpuToonDefineKey } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { getWgpuScene3DRuntime } from './wgpuScene3DRuntime';
|
|
4
|
+
import { makeWgpuScene3DState, makeWgpuSkinningAdapter } from './wgpuScene3DTestHelper';
|
|
5
|
+
import {
|
|
6
|
+
bindWgpuToonSurface,
|
|
7
|
+
buildWgpuToonDefineKey,
|
|
8
|
+
compileWgpuToonPipeline,
|
|
9
|
+
ensureWgpuToonPipeline,
|
|
10
|
+
getWgpuToonModuleSourceForKey,
|
|
11
|
+
} from './wgpuToonPrelude';
|
|
12
|
+
|
|
13
|
+
const FLAT: WgpuToonDefineKey = { alphaMaskEnabled: false, doubleSided: false, hasBaseColorMap: false, hasRamp: false };
|
|
14
|
+
const COLOR: LinearColor = [0.5, 0.25, 0.1, 1];
|
|
15
|
+
|
|
16
|
+
describe('bindWgpuToonSurface', () => {
|
|
17
|
+
it('creates a material bind group once per key and writes its uniform', () => {
|
|
18
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
19
|
+
const pipeline = compileWgpuToonPipeline(state, FLAT, 'bgra8unorm');
|
|
20
|
+
const key = {};
|
|
21
|
+
bindWgpuToonSurface(state, pipeline, key, COLOR, 3, 0.5);
|
|
22
|
+
const groups = fake.calls.filter((c) => c.name === 'createBindGroup').length;
|
|
23
|
+
bindWgpuToonSurface(state, pipeline, key, COLOR, 3, 0.5);
|
|
24
|
+
expect(fake.calls.filter((c) => c.name === 'createBindGroup').length).toBe(groups);
|
|
25
|
+
expect(fake.calls.some((c) => c.name === 'writeBuffer')).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('buildWgpuToonDefineKey', () => {
|
|
30
|
+
it('produces distinct stable strings per flag set', () => {
|
|
31
|
+
expect(buildWgpuToonDefineKey(FLAT)).toBe('----');
|
|
32
|
+
expect(
|
|
33
|
+
buildWgpuToonDefineKey({ alphaMaskEnabled: true, doubleSided: true, hasBaseColorMap: true, hasRamp: true }),
|
|
34
|
+
).toBe('mdbr');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('compileWgpuToonPipeline', () => {
|
|
39
|
+
it('compiles a module and builds the pipeline with a 4-entry material layout', () => {
|
|
40
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
41
|
+
const pipeline = compileWgpuToonPipeline(state, FLAT, 'rgba16float');
|
|
42
|
+
expect(pipeline.pipeline).toBeDefined();
|
|
43
|
+
expect(fake.calls.some((c) => c.name === 'createShaderModule')).toBe(true);
|
|
44
|
+
const matLayout = fake.calls
|
|
45
|
+
.filter((c) => c.name === 'createBindGroupLayout')
|
|
46
|
+
.map((c) => c.args[0] as { entries: unknown[] })
|
|
47
|
+
.find((d) => d.entries.length === 4);
|
|
48
|
+
expect(matLayout).toBeDefined();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('compiles a cull-none pipeline for a double-sided key', () => {
|
|
52
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
53
|
+
compileWgpuToonPipeline(state, { ...FLAT, doubleSided: true }, 'bgra8unorm');
|
|
54
|
+
const pipelineCall = fake.calls.find((c) => c.name === 'createRenderPipeline');
|
|
55
|
+
const descriptor = pipelineCall!.args[0] as { primitive: { cullMode: string } };
|
|
56
|
+
expect(descriptor.primitive.cullMode).toBe('none');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('ensureWgpuToonPipeline', () => {
|
|
61
|
+
it('caches one pipeline per define key + format under the toon namespace', () => {
|
|
62
|
+
const { state } = makeWgpuScene3DState();
|
|
63
|
+
const a = ensureWgpuToonPipeline(state, FLAT, 'bgra8unorm');
|
|
64
|
+
const b = ensureWgpuToonPipeline(state, FLAT, 'bgra8unorm');
|
|
65
|
+
expect(a).toBe(b);
|
|
66
|
+
expect([...getWgpuScene3DRuntime(state).pipelineCache.keys()].some((k) => k.startsWith('toon:'))).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('getWgpuToonModuleSourceForKey', () => {
|
|
71
|
+
it('emits the feature consts and reads the shared light block', () => {
|
|
72
|
+
expect(getWgpuToonModuleSourceForKey(FLAT)).toContain('const HAS_RAMP : bool = false');
|
|
73
|
+
expect(getWgpuToonModuleSourceForKey({ ...FLAT, alphaMaskEnabled: true })).toContain(
|
|
74
|
+
'const ALPHA_MASK : bool = true',
|
|
75
|
+
);
|
|
76
|
+
const source = getWgpuToonModuleSourceForKey(FLAT);
|
|
77
|
+
expect(source).toContain('struct Frame');
|
|
78
|
+
expect(source).toContain('frame.directionalRadiance');
|
|
79
|
+
expect(source).toContain('fn fs_main');
|
|
80
|
+
expect(source).not.toContain('jointTexture');
|
|
81
|
+
expect(getWgpuToonModuleSourceForKey(FLAT, true, makeWgpuSkinningAdapter())).toContain('@location(4) joints0');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('declares the group(3) shadow bindings and shadow-maps the banded directional term', () => {
|
|
85
|
+
for (const key of [FLAT, { ...FLAT, hasRamp: true }]) {
|
|
86
|
+
const source = getWgpuToonModuleSourceForKey(key);
|
|
87
|
+
expect(source).toContain('@group(3) @binding(1) var shadowMap : texture_depth_2d;');
|
|
88
|
+
expect(source).toContain('@group(3) @binding(2) var shadowSampler : sampler_comparison;');
|
|
89
|
+
expect(source).toContain('direct * sampleDirectionalShadow(in.worldPosition)');
|
|
90
|
+
expect(source.match(/direct \* sampleDirectionalShadow\(in\.worldPosition\)/g)).toHaveLength(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { LinearColor, VideoTexture, WgpuUnlitDefineKey } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { getWgpuScene3DRuntime } from './wgpuScene3DRuntime';
|
|
4
|
+
import { makeWgpuScene3DState, makeWgpuSkinningAdapter } from './wgpuScene3DTestHelper';
|
|
5
|
+
import {
|
|
6
|
+
bindWgpuUnlitSurface,
|
|
7
|
+
bindWgpuUnlitVideoSurface,
|
|
8
|
+
buildWgpuUnlitDefineKey,
|
|
9
|
+
compileWgpuUnlitPipeline,
|
|
10
|
+
ensureWgpuUnlitPipeline,
|
|
11
|
+
getWgpuUnlitModuleSourceForKey,
|
|
12
|
+
} from './wgpuUnlitPrelude';
|
|
13
|
+
|
|
14
|
+
const FLAT: WgpuUnlitDefineKey = { alphaMaskEnabled: false, doubleSided: false, hasColorMap: false };
|
|
15
|
+
const COLOR: LinearColor = [0.5, 0.25, 0.1, 1];
|
|
16
|
+
|
|
17
|
+
describe('bindWgpuUnlitSurface', () => {
|
|
18
|
+
it('creates a material bind group once per key and writes its uniform', () => {
|
|
19
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
20
|
+
const pipeline = compileWgpuUnlitPipeline(state, FLAT, 'bgra8unorm');
|
|
21
|
+
const key = {};
|
|
22
|
+
bindWgpuUnlitSurface(state, pipeline, key, COLOR, 2, 0.5, null);
|
|
23
|
+
const groups = fake.calls.filter((c) => c.name === 'createBindGroup').length;
|
|
24
|
+
bindWgpuUnlitSurface(state, pipeline, key, COLOR, 2, 0.5, null);
|
|
25
|
+
expect(fake.calls.filter((c) => c.name === 'createBindGroup').length).toBe(groups);
|
|
26
|
+
expect(fake.calls.some((c) => c.name === 'writeBuffer')).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('bindWgpuUnlitVideoSurface', () => {
|
|
31
|
+
it('uploads the ready video frame into the same unlit material layout', () => {
|
|
32
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
33
|
+
const pipeline = compileWgpuUnlitPipeline(state, { ...FLAT, hasColorMap: true }, 'bgra8unorm');
|
|
34
|
+
const video = {
|
|
35
|
+
frameId: 1,
|
|
36
|
+
sampler: {
|
|
37
|
+
anisotropy: 1,
|
|
38
|
+
magFilter: 'linear',
|
|
39
|
+
minFilter: 'linear',
|
|
40
|
+
mipmaps: false,
|
|
41
|
+
wrapU: 'clamp-to-edge',
|
|
42
|
+
wrapV: 'clamp-to-edge',
|
|
43
|
+
},
|
|
44
|
+
source: {
|
|
45
|
+
element: { readyState: 4, videoHeight: 120, videoWidth: 160 } as HTMLVideoElement,
|
|
46
|
+
},
|
|
47
|
+
flipX: false,
|
|
48
|
+
flipY: false,
|
|
49
|
+
uvOffset: { x: 0, y: 0 },
|
|
50
|
+
uvRotation: 0,
|
|
51
|
+
uvScale: { x: 1, y: 1 },
|
|
52
|
+
} as unknown as VideoTexture;
|
|
53
|
+
bindWgpuUnlitVideoSurface(state, pipeline, {}, COLOR, 1, 0.5, video);
|
|
54
|
+
expect(fake.calls.some((c) => c.name === 'copyExternalImageToTexture')).toBe(true);
|
|
55
|
+
expect(fake.calls.some((c) => c.name === 'writeBuffer')).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('buildWgpuUnlitDefineKey', () => {
|
|
60
|
+
it('produces distinct stable strings per flag set', () => {
|
|
61
|
+
expect(buildWgpuUnlitDefineKey(FLAT)).toBe('---');
|
|
62
|
+
expect(buildWgpuUnlitDefineKey({ alphaMaskEnabled: true, doubleSided: true, hasColorMap: true })).toBe('mdc');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('compileWgpuUnlitPipeline', () => {
|
|
67
|
+
it('compiles a module and builds the pipeline with a 3-entry material layout', () => {
|
|
68
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
69
|
+
const pipeline = compileWgpuUnlitPipeline(state, FLAT, 'rgba16float');
|
|
70
|
+
expect(pipeline.pipeline).toBeDefined();
|
|
71
|
+
expect(fake.calls.some((c) => c.name === 'createShaderModule')).toBe(true);
|
|
72
|
+
const matLayout = fake.calls
|
|
73
|
+
.filter((c) => c.name === 'createBindGroupLayout')
|
|
74
|
+
.map((c) => c.args[0] as { entries: unknown[] })
|
|
75
|
+
.find((d) => d.entries.length === 3);
|
|
76
|
+
expect(matLayout).toBeDefined();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('ensureWgpuUnlitPipeline', () => {
|
|
81
|
+
it('caches one pipeline per define key + format under the unlit namespace', () => {
|
|
82
|
+
const { state } = makeWgpuScene3DState();
|
|
83
|
+
const a = ensureWgpuUnlitPipeline(state, FLAT, 'bgra8unorm');
|
|
84
|
+
const b = ensureWgpuUnlitPipeline(state, FLAT, 'bgra8unorm');
|
|
85
|
+
expect(a).toBe(b);
|
|
86
|
+
expect([...getWgpuScene3DRuntime(state).pipelineCache.keys()].some((k) => k.startsWith('unlit:'))).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('getWgpuUnlitModuleSourceForKey', () => {
|
|
91
|
+
it('emits the feature consts and includes the shared prelude + fs_main', () => {
|
|
92
|
+
expect(getWgpuUnlitModuleSourceForKey(FLAT)).toContain('const HAS_COLOR_MAP : bool = false');
|
|
93
|
+
expect(getWgpuUnlitModuleSourceForKey({ ...FLAT, alphaMaskEnabled: true })).toContain(
|
|
94
|
+
'const ALPHA_MASK : bool = true',
|
|
95
|
+
);
|
|
96
|
+
const source = getWgpuUnlitModuleSourceForKey(FLAT);
|
|
97
|
+
expect(source).toContain('struct Frame');
|
|
98
|
+
expect(source).toContain('fn fs_main');
|
|
99
|
+
expect(source).not.toContain('jointTexture');
|
|
100
|
+
expect(getWgpuUnlitModuleSourceForKey(FLAT, true, makeWgpuSkinningAdapter())).toContain('@location(5) weights0');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { LinearColor } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { getWgpuScene3DRuntime } from './wgpuScene3DRuntime';
|
|
4
|
+
import { makeWgpuScene3DState } from './wgpuScene3DTestHelper';
|
|
5
|
+
import {
|
|
6
|
+
bindWgpuWireframeColor,
|
|
7
|
+
compileWgpuWireframePipeline,
|
|
8
|
+
ensureWgpuWireframePipeline,
|
|
9
|
+
getWgpuWireframeModuleSource,
|
|
10
|
+
} from './wgpuWireframePrelude';
|
|
11
|
+
|
|
12
|
+
const COLOR: LinearColor = [1, 0, 0, 1];
|
|
13
|
+
|
|
14
|
+
describe('bindWgpuWireframeColor', () => {
|
|
15
|
+
it('creates a color bind group once per key and writes its uniform', () => {
|
|
16
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
17
|
+
const pipeline = compileWgpuWireframePipeline(state, 'bgra8unorm');
|
|
18
|
+
const key = {};
|
|
19
|
+
bindWgpuWireframeColor(state, pipeline, key, COLOR);
|
|
20
|
+
const groups = fake.calls.filter((c) => c.name === 'createBindGroup').length;
|
|
21
|
+
bindWgpuWireframeColor(state, pipeline, key, COLOR);
|
|
22
|
+
expect(fake.calls.filter((c) => c.name === 'createBindGroup').length).toBe(groups);
|
|
23
|
+
expect(fake.calls.some((c) => c.name === 'writeBuffer')).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('compileWgpuWireframePipeline', () => {
|
|
28
|
+
it('builds a line-list pipeline with a single-uniform material layout', () => {
|
|
29
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
30
|
+
const pipeline = compileWgpuWireframePipeline(state, 'rgba16float');
|
|
31
|
+
expect(pipeline.pipeline).toBeDefined();
|
|
32
|
+
const pipelineCall = fake.calls.find((c) => c.name === 'createRenderPipeline');
|
|
33
|
+
expect((pipelineCall!.args[0] as { primitive: { topology: string } }).primitive.topology).toBe('line-list');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('ensureWgpuWireframePipeline', () => {
|
|
38
|
+
it('caches one pipeline per format under the wireframe namespace', () => {
|
|
39
|
+
const { state } = makeWgpuScene3DState();
|
|
40
|
+
const a = ensureWgpuWireframePipeline(state, 'bgra8unorm');
|
|
41
|
+
const b = ensureWgpuWireframePipeline(state, 'bgra8unorm');
|
|
42
|
+
expect(a).toBe(b);
|
|
43
|
+
expect([...getWgpuScene3DRuntime(state).pipelineCache.keys()].some((k) => k.startsWith('wireframe:'))).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('getWgpuWireframeModuleSource', () => {
|
|
48
|
+
it('includes the shared prelude and a fs_main returning the color', () => {
|
|
49
|
+
const source = getWgpuWireframeModuleSource();
|
|
50
|
+
expect(source).toContain('struct Frame');
|
|
51
|
+
expect(source).toContain('fn fs_main');
|
|
52
|
+
expect(source).toContain('material.color');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
2
|
+
|
|
3
|
+
import { makeWgpuScene3DState } from './wgpuScene3DTestHelper';
|
|
4
|
+
import { ensureWgpuWireframeUpload } from './wgpuWireframeUpload';
|
|
5
|
+
|
|
6
|
+
describe('ensureWgpuWireframeUpload', () => {
|
|
7
|
+
it('builds a line-index buffer sized two indices per triangle edge', () => {
|
|
8
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
9
|
+
const geometry = createBoxMeshGeometry();
|
|
10
|
+
const upload = ensureWgpuWireframeUpload(state, geometry);
|
|
11
|
+
expect(upload).not.toBeNull();
|
|
12
|
+
expect(upload!.lineIndexBuffer).toBeDefined();
|
|
13
|
+
expect(upload!.indexFormat === 'uint16' || upload!.indexFormat === 'uint32').toBe(true);
|
|
14
|
+
|
|
15
|
+
// An INDEX buffer is created sized for the derived line list (6 indices per triangle).
|
|
16
|
+
const triangleCount = geometry.indices!.length / 3;
|
|
17
|
+
const bytesPerIndex = upload!.indexFormat === 'uint32' ? 4 : 2;
|
|
18
|
+
const lineBufferCreate = fake.calls.find(
|
|
19
|
+
(c) =>
|
|
20
|
+
c.name === 'createBuffer' &&
|
|
21
|
+
((c.args[0] as { usage: number; size: number }).usage & GPUBufferUsage.INDEX) !== 0 &&
|
|
22
|
+
(c.args[0] as { size: number }).size === triangleCount * 6 * bytesPerIndex,
|
|
23
|
+
);
|
|
24
|
+
expect(lineBufferCreate).toBeDefined();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns the cached upload without rebuilding when the version is unchanged', () => {
|
|
28
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
29
|
+
const geometry = createBoxMeshGeometry();
|
|
30
|
+
const first = ensureWgpuWireframeUpload(state, geometry);
|
|
31
|
+
const buffers = fake.calls.filter((c) => c.name === 'createBuffer').length;
|
|
32
|
+
const second = ensureWgpuWireframeUpload(state, geometry);
|
|
33
|
+
expect(second).toBe(first);
|
|
34
|
+
expect(fake.calls.filter((c) => c.name === 'createBuffer').length).toBe(buffers);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createWireframeMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { WireframeMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getWgpuMeshMaterialRenderer } from './wgpuMeshMaterialRegistry';
|
|
9
|
+
import { makeWgpuScene3DState } from './wgpuScene3DTestHelper';
|
|
10
|
+
import { registerWireframeWgpuMaterial, wireframeWgpuMeshMaterialRenderer } from './wireframeWgpuMeshMaterialRenderer';
|
|
11
|
+
|
|
12
|
+
function makeCamera(): Camera3D {
|
|
13
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const NO_LIGHTS: Scene3DLightBlock = {
|
|
17
|
+
ambientCount: 0,
|
|
18
|
+
data: new Float32Array(12),
|
|
19
|
+
directionalCount: 0,
|
|
20
|
+
hemisphereCount: 0,
|
|
21
|
+
pointCount: 0,
|
|
22
|
+
spotCount: 0,
|
|
23
|
+
version: 1,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
27
|
+
const geometry = createBoxMeshGeometry();
|
|
28
|
+
return {
|
|
29
|
+
material: createWireframeMaterial(),
|
|
30
|
+
normalMatrix: createMatrix3(),
|
|
31
|
+
subset: geometry.subsets[0],
|
|
32
|
+
worldMatrix: createMatrix4(),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('registerWireframeWgpuMaterial', () => {
|
|
37
|
+
it('installs the renderer for WireframeMaterialKind', () => {
|
|
38
|
+
const { state } = makeWgpuScene3DState();
|
|
39
|
+
registerWireframeWgpuMaterial(state);
|
|
40
|
+
expect(getWgpuMeshMaterialRenderer(state, WireframeMaterialKind)).toBe(wireframeWgpuMeshMaterialRenderer);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('wireframeWgpuMeshMaterialRenderer', () => {
|
|
45
|
+
it('bind selects a line-list pipeline and uploads the color', () => {
|
|
46
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
47
|
+
wireframeWgpuMeshMaterialRenderer.bind(state, createWireframeMaterial(), NO_LIGHTS, makeCamera());
|
|
48
|
+
expect(fake.calls.some((c) => c.name === 'setPipeline')).toBe(true);
|
|
49
|
+
expect(fake.calls.some((c) => c.name === 'writeBuffer')).toBe(true);
|
|
50
|
+
const pipelineCall = fake.calls.find((c) => c.name === 'createRenderPipeline');
|
|
51
|
+
expect((pipelineCall!.args[0] as { primitive: { topology: string } }).primitive.topology).toBe('line-list');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('draw issues a line-list indexed draw over the doubled subset range', () => {
|
|
55
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
56
|
+
const proxy = makeProxy();
|
|
57
|
+
wireframeWgpuMeshMaterialRenderer.bind(state, proxy.material, NO_LIGHTS, makeCamera());
|
|
58
|
+
wireframeWgpuMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
59
|
+
const drawCall = fake.calls.find((c) => c.name === 'drawIndexed');
|
|
60
|
+
expect(drawCall).toBeDefined();
|
|
61
|
+
expect(drawCall!.args[0]).toBe(proxy.subset.indexCount * 2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('draw is a no-op when bind has not selected a pipeline', () => {
|
|
65
|
+
const { fake, state } = makeWgpuScene3DState();
|
|
66
|
+
wireframeWgpuMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
67
|
+
expect(fake.calls.some((c) => c.name === 'drawIndexed')).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|