@flighthq/scene3d-gl 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/anisotropyPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.js +45 -0
- package/dist/anisotropyPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.js +102 -0
- package/dist/blinnPhongGlMeshMaterialRenderer.js.map +1 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.js +45 -0
- package/dist/clearcoatPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/customShaderGlMeshMaterialRenderer.d.ts +6 -0
- package/dist/customShaderGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/customShaderGlMeshMaterialRenderer.js +136 -0
- package/dist/customShaderGlMeshMaterialRenderer.js.map +1 -0
- package/dist/depthGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/depthGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/depthGlMeshMaterialRenderer.js +36 -0
- package/dist/depthGlMeshMaterialRenderer.js.map +1 -0
- package/dist/drawGlScene3D.d.ts +3 -0
- package/dist/drawGlScene3D.d.ts.map +1 -0
- package/dist/drawGlScene3D.js +251 -0
- package/dist/drawGlScene3D.js.map +1 -0
- package/dist/emissiveGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/emissiveGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/emissiveGlMeshMaterialRenderer.js +49 -0
- package/dist/emissiveGlMeshMaterialRenderer.js.map +1 -0
- package/dist/enableGlScene3DColorSpaceGuards.d.ts +4 -0
- package/dist/enableGlScene3DColorSpaceGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DColorSpaceGuards.js +22 -0
- package/dist/enableGlScene3DColorSpaceGuards.js.map +1 -0
- package/dist/enableGlScene3DCustomShaderGuards.d.ts +4 -0
- package/dist/enableGlScene3DCustomShaderGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DCustomShaderGuards.js +71 -0
- package/dist/enableGlScene3DCustomShaderGuards.js.map +1 -0
- package/dist/enableGlScene3DDeformGuards.d.ts +4 -0
- package/dist/enableGlScene3DDeformGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DDeformGuards.js +42 -0
- package/dist/enableGlScene3DDeformGuards.js.map +1 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.d.ts +4 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.d.ts.map +1 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.js +21 -0
- package/dist/enableGlScene3DForwardLightSelectionGuards.js.map +1 -0
- package/dist/explainGlScene3DForwardLightSelection.d.ts +3 -0
- package/dist/explainGlScene3DForwardLightSelection.d.ts.map +1 -0
- package/dist/explainGlScene3DForwardLightSelection.js +19 -0
- package/dist/explainGlScene3DForwardLightSelection.js.map +1 -0
- package/dist/glClassicPrelude.d.ts +9 -0
- package/dist/glClassicPrelude.d.ts.map +1 -0
- package/dist/glClassicPrelude.js +288 -0
- package/dist/glClassicPrelude.js.map +1 -0
- package/dist/glDebugPrelude.d.ts +9 -0
- package/dist/glDebugPrelude.d.ts.map +1 -0
- package/dist/glDebugPrelude.js +143 -0
- package/dist/glDebugPrelude.js.map +1 -0
- package/dist/glEnvironmentCube.d.ts +5 -0
- package/dist/glEnvironmentCube.d.ts.map +1 -0
- package/dist/glEnvironmentCube.js +65 -0
- package/dist/glEnvironmentCube.js.map +1 -0
- package/dist/glEnvironmentIblBake.d.ts +4 -0
- package/dist/glEnvironmentIblBake.d.ts.map +1 -0
- package/dist/glEnvironmentIblBake.js +365 -0
- package/dist/glEnvironmentIblBake.js.map +1 -0
- package/dist/glEnvironmentSkybox.d.ts +3 -0
- package/dist/glEnvironmentSkybox.d.ts.map +1 -0
- package/dist/glEnvironmentSkybox.js +95 -0
- package/dist/glEnvironmentSkybox.js.map +1 -0
- package/dist/glLitProgram.d.ts +5 -0
- package/dist/glLitProgram.d.ts.map +1 -0
- package/dist/glLitProgram.js +211 -0
- package/dist/glLitProgram.js.map +1 -0
- package/dist/glMatcapPrelude.d.ts +8 -0
- package/dist/glMatcapPrelude.d.ts.map +1 -0
- package/dist/glMatcapPrelude.js +118 -0
- package/dist/glMatcapPrelude.js.map +1 -0
- package/dist/glMeshMaterialRegistry.d.ts +5 -0
- package/dist/glMeshMaterialRegistry.d.ts.map +1 -0
- package/dist/glMeshMaterialRegistry.js +29 -0
- package/dist/glMeshMaterialRegistry.js.map +1 -0
- package/dist/glMeshProgram.d.ts +14 -0
- package/dist/glMeshProgram.d.ts.map +1 -0
- package/dist/glMeshProgram.js +193 -0
- package/dist/glMeshProgram.js.map +1 -0
- package/dist/glMeshUpload.d.ts +4 -0
- package/dist/glMeshUpload.d.ts.map +1 -0
- package/dist/glMeshUpload.js +190 -0
- package/dist/glMeshUpload.js.map +1 -0
- package/dist/glParticleEmitter3D.d.ts +4 -0
- package/dist/glParticleEmitter3D.d.ts.map +1 -0
- package/dist/glParticleEmitter3D.js +342 -0
- package/dist/glParticleEmitter3D.js.map +1 -0
- package/dist/glPbrPrelude.d.ts +8 -0
- package/dist/glPbrPrelude.d.ts.map +1 -0
- package/dist/glPbrPrelude.js +569 -0
- package/dist/glPbrPrelude.js.map +1 -0
- package/dist/glPbrProgramCache.d.ts +4 -0
- package/dist/glPbrProgramCache.d.ts.map +1 -0
- package/dist/glPbrProgramCache.js +63 -0
- package/dist/glPbrProgramCache.js.map +1 -0
- package/dist/glPbrStandardBlock.d.ts +13 -0
- package/dist/glPbrStandardBlock.d.ts.map +1 -0
- package/dist/glPbrStandardBlock.js +107 -0
- package/dist/glPbrStandardBlock.js.map +1 -0
- package/dist/glScene3DRuntime.d.ts +5 -0
- package/dist/glScene3DRuntime.d.ts.map +1 -0
- package/dist/glScene3DRuntime.js +99 -0
- package/dist/glScene3DRuntime.js.map +1 -0
- package/dist/glScene3DTestHelper.d.ts +20 -0
- package/dist/glScene3DTestHelper.d.ts.map +1 -0
- package/dist/glScene3DTestHelper.js +178 -0
- package/dist/glScene3DTestHelper.js.map +1 -0
- package/dist/glScene3DTime.d.ts +4 -0
- package/dist/glScene3DTime.d.ts.map +1 -0
- package/dist/glScene3DTime.js +18 -0
- package/dist/glScene3DTime.js.map +1 -0
- package/dist/glShadedBuiltInModifiers.d.ts +11 -0
- package/dist/glShadedBuiltInModifiers.d.ts.map +1 -0
- package/dist/glShadedBuiltInModifiers.js +386 -0
- package/dist/glShadedBuiltInModifiers.js.map +1 -0
- package/dist/glShadedModifierSnippet.d.ts +4 -0
- package/dist/glShadedModifierSnippet.d.ts.map +1 -0
- package/dist/glShadedModifierSnippet.js +24 -0
- package/dist/glShadedModifierSnippet.js.map +1 -0
- package/dist/glShadedPrelude.d.ts +5 -0
- package/dist/glShadedPrelude.d.ts.map +1 -0
- package/dist/glShadedPrelude.js +393 -0
- package/dist/glShadedPrelude.js.map +1 -0
- package/dist/glShadowMap.d.ts +3 -0
- package/dist/glShadowMap.d.ts.map +1 -0
- package/dist/glShadowMap.js +150 -0
- package/dist/glShadowMap.js.map +1 -0
- package/dist/glToonPrelude.d.ts +7 -0
- package/dist/glToonPrelude.d.ts.map +1 -0
- package/dist/glToonPrelude.js +172 -0
- package/dist/glToonPrelude.js.map +1 -0
- package/dist/glUnlitPrelude.d.ts +9 -0
- package/dist/glUnlitPrelude.d.ts.map +1 -0
- package/dist/glUnlitPrelude.js +160 -0
- package/dist/glUnlitPrelude.js.map +1 -0
- package/dist/glWireframePrelude.d.ts +6 -0
- package/dist/glWireframePrelude.d.ts.map +1 -0
- package/dist/glWireframePrelude.js +56 -0
- package/dist/glWireframePrelude.js.map +1 -0
- package/dist/glWireframeUpload.d.ts +4 -0
- package/dist/glWireframeUpload.d.ts.map +1 -0
- package/dist/glWireframeUpload.js +85 -0
- package/dist/glWireframeUpload.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.js +54 -0
- package/dist/iridescencePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/lambertGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/lambertGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/lambertGlMeshMaterialRenderer.js +70 -0
- package/dist/lambertGlMeshMaterialRenderer.js.map +1 -0
- package/dist/matcapGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/matcapGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/matcapGlMeshMaterialRenderer.js +49 -0
- package/dist/matcapGlMeshMaterialRenderer.js.map +1 -0
- package/dist/normalGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/normalGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/normalGlMeshMaterialRenderer.js +39 -0
- package/dist/normalGlMeshMaterialRenderer.js.map +1 -0
- package/dist/phongGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/phongGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/phongGlMeshMaterialRenderer.js +90 -0
- package/dist/phongGlMeshMaterialRenderer.js.map +1 -0
- package/dist/prepareGlScene3DForwardLights.d.ts +3 -0
- package/dist/prepareGlScene3DForwardLights.d.ts.map +1 -0
- package/dist/prepareGlScene3DForwardLights.js +117 -0
- package/dist/prepareGlScene3DForwardLights.js.map +1 -0
- package/dist/presentGlScene3D.d.ts +3 -0
- package/dist/presentGlScene3D.d.ts.map +1 -0
- package/dist/presentGlScene3D.js +21 -0
- package/dist/presentGlScene3D.js.map +1 -0
- package/dist/registerStandardPbrGlMaterial.d.ts +3 -0
- package/dist/registerStandardPbrGlMaterial.d.ts.map +1 -0
- package/dist/registerStandardPbrGlMaterial.js +11 -0
- package/dist/registerStandardPbrGlMaterial.js.map +1 -0
- package/dist/shadedGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/shadedGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/shadedGlMeshMaterialRenderer.js +135 -0
- package/dist/shadedGlMeshMaterialRenderer.js.map +1 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.js +54 -0
- package/dist/sheenPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.js +121 -0
- package/dist/specularGlossinessPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/specularPbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/specularPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/specularPbrGlMeshMaterialRenderer.js +55 -0
- package/dist/specularPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/standardPbrGlMeshMaterialRenderer.d.ts +3 -0
- package/dist/standardPbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/standardPbrGlMeshMaterialRenderer.js +35 -0
- package/dist/standardPbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.js +57 -0
- package/dist/subsurfacePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/toonGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/toonGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/toonGlMeshMaterialRenderer.js +81 -0
- package/dist/toonGlMeshMaterialRenderer.js.map +1 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.js +62 -0
- package/dist/transmissionVolumePbrGlMeshMaterialRenderer.js.map +1 -0
- package/dist/unlitGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/unlitGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/unlitGlMeshMaterialRenderer.js +61 -0
- package/dist/unlitGlMeshMaterialRenderer.js.map +1 -0
- package/dist/vertexColorGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/vertexColorGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/vertexColorGlMeshMaterialRenderer.js +54 -0
- package/dist/vertexColorGlMeshMaterialRenderer.js.map +1 -0
- package/dist/wireframeGlMeshMaterialRenderer.d.ts +4 -0
- package/dist/wireframeGlMeshMaterialRenderer.d.ts.map +1 -0
- package/dist/wireframeGlMeshMaterialRenderer.js +50 -0
- package/dist/wireframeGlMeshMaterialRenderer.js.map +1 -0
- package/package.json +58 -0
- package/src/anisotropyPbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/blinnPhongGlMeshMaterialRenderer.test.ts +94 -0
- package/src/clearcoatPbrGlMeshMaterialRenderer.test.ts +81 -0
- package/src/customShaderGlMeshMaterialRenderer.test.ts +169 -0
- package/src/depthGlMeshMaterialRenderer.test.ts +69 -0
- package/src/drawGlScene3D.test.ts +304 -0
- package/src/emissiveGlMeshMaterialRenderer.test.ts +60 -0
- package/src/enableGlScene3DColorSpaceGuards.test.ts +63 -0
- package/src/enableGlScene3DCustomShaderGuards.test.ts +85 -0
- package/src/enableGlScene3DDeformGuards.test.ts +98 -0
- package/src/enableGlScene3DForwardLightSelectionGuards.test.ts +84 -0
- package/src/explainGlScene3DForwardLightSelection.test.ts +32 -0
- package/src/glClassicPrelude.test.ts +214 -0
- package/src/glDebugPrelude.test.ts +94 -0
- package/src/glEnvironmentCube.test.ts +71 -0
- package/src/glEnvironmentIblBake.test.ts +31 -0
- package/src/glEnvironmentSkybox.test.ts +24 -0
- package/src/glLitProgram.test.ts +181 -0
- package/src/glMatcapPrelude.test.ts +74 -0
- package/src/glMeshMaterialRegistry.test.ts +52 -0
- package/src/glMeshProgram.test.ts +406 -0
- package/src/glMeshUpload.test.ts +311 -0
- package/src/glParticleEmitter3D.test.ts +280 -0
- package/src/glPbrPrelude.test.ts +178 -0
- package/src/glPbrProgramCache.test.ts +116 -0
- package/src/glPbrStandardBlock.test.ts +85 -0
- package/src/glScene3DRuntime.test.ts +108 -0
- package/src/glScene3DTime.test.ts +31 -0
- package/src/glShadedBuiltInModifiers.test.ts +377 -0
- package/src/glShadedModifierSnippet.test.ts +46 -0
- package/src/glShadedPrelude.test.ts +177 -0
- package/src/glShadowMap.test.ts +219 -0
- package/src/glToonPrelude.test.ts +118 -0
- package/src/glUnlitPrelude.test.ts +156 -0
- package/src/glWireframePrelude.test.ts +46 -0
- package/src/glWireframeUpload.test.ts +50 -0
- package/src/iridescencePbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/lambertGlMeshMaterialRenderer.test.ts +92 -0
- package/src/matcapGlMeshMaterialRenderer.test.ts +70 -0
- package/src/normalGlMeshMaterialRenderer.test.ts +69 -0
- package/src/phongGlMeshMaterialRenderer.test.ts +94 -0
- package/src/prepareGlScene3DForwardLights.test.ts +106 -0
- package/src/presentGlScene3D.test.ts +98 -0
- package/src/registerStandardPbrGlMaterial.test.ts +14 -0
- package/src/shadedGlMeshMaterialRenderer.test.ts +106 -0
- package/src/sheenPbrGlMeshMaterialRenderer.test.ts +83 -0
- package/src/specularGlossinessPbrGlMeshMaterialRenderer.test.ts +96 -0
- package/src/specularPbrGlMeshMaterialRenderer.test.ts +83 -0
- package/src/standardPbrGlMeshMaterialRenderer.test.ts +88 -0
- package/src/subsurfacePbrGlMeshMaterialRenderer.test.ts +86 -0
- package/src/toonGlMeshMaterialRenderer.test.ts +92 -0
- package/src/transmissionVolumePbrGlMeshMaterialRenderer.test.ts +93 -0
- package/src/unlitGlMeshMaterialRenderer.test.ts +88 -0
- package/src/vertexColorGlMeshMaterialRenderer.test.ts +60 -0
- package/src/wireframeGlMeshMaterialRenderer.test.ts +69 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createSheenPbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { SheenPbrMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
10
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
11
|
+
import { registerSheenPbrGlMaterial, sheenPbrGlMeshMaterialRenderer } from './sheenPbrGlMeshMaterialRenderer';
|
|
12
|
+
|
|
13
|
+
function makeCamera(): Camera3D {
|
|
14
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function makeLights(): Scene3DLightBlock {
|
|
18
|
+
const data = new Float32Array(12);
|
|
19
|
+
data[1] = -1;
|
|
20
|
+
data[4] = 1;
|
|
21
|
+
data[5] = 1;
|
|
22
|
+
data[6] = 1;
|
|
23
|
+
data[8] = 0.1;
|
|
24
|
+
data[9] = 0.1;
|
|
25
|
+
data[10] = 0.1;
|
|
26
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
30
|
+
const geometry = createBoxMeshGeometry();
|
|
31
|
+
return {
|
|
32
|
+
material: createSheenPbrMaterial(),
|
|
33
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
34
|
+
subset: geometry.subsets[0],
|
|
35
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('registerSheenPbrGlMaterial', () => {
|
|
40
|
+
it('installs the renderer for SheenPbrMaterialKind', () => {
|
|
41
|
+
const { state } = makeGlScene3DState();
|
|
42
|
+
registerSheenPbrGlMaterial(state);
|
|
43
|
+
expect(getGlMeshMaterialRenderer(state, SheenPbrMaterialKind)).toBe(sheenPbrGlMeshMaterialRenderer);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('sheenPbrGlMeshMaterialRenderer', () => {
|
|
48
|
+
it('bind uploads the light block, standard block, and sheen uniforms', () => {
|
|
49
|
+
const { state, gl } = makeGlScene3DState();
|
|
50
|
+
sheenPbrGlMeshMaterialRenderer.bind(
|
|
51
|
+
state,
|
|
52
|
+
createSheenPbrMaterial({ sheenColor: 0x80604000 }),
|
|
53
|
+
makeLights(),
|
|
54
|
+
makeCamera(),
|
|
55
|
+
);
|
|
56
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
57
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
58
|
+
expect(gl.calls.some((c) => c.name === 'uniform3f')).toBe(true);
|
|
59
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('caches the sheen program under the pbr: namespace', () => {
|
|
63
|
+
const { state } = makeGlScene3DState();
|
|
64
|
+
sheenPbrGlMeshMaterialRenderer.bind(state, createSheenPbrMaterial(), makeLights(), makeCamera());
|
|
65
|
+
const cache = getGlScene3DRuntime(state).programCache;
|
|
66
|
+
expect(cache.size).toBe(1);
|
|
67
|
+
expect([...cache.keys()][0].startsWith('pbr:')).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('draw issues an indexed draw after bind', () => {
|
|
71
|
+
const { state, gl } = makeGlScene3DState();
|
|
72
|
+
const proxy = makeProxy();
|
|
73
|
+
sheenPbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
74
|
+
sheenPbrGlMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
75
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('draw is a no-op before bind', () => {
|
|
79
|
+
const { state, gl } = makeGlScene3DState();
|
|
80
|
+
sheenPbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
81
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createSpecularGlossinessPbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { SpecularGlossinessPbrMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
10
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
11
|
+
import {
|
|
12
|
+
registerSpecularGlossinessPbrGlMaterial,
|
|
13
|
+
specularGlossinessPbrGlMeshMaterialRenderer,
|
|
14
|
+
} from './specularGlossinessPbrGlMeshMaterialRenderer';
|
|
15
|
+
|
|
16
|
+
function makeCamera(): Camera3D {
|
|
17
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function makeLights(): Scene3DLightBlock {
|
|
21
|
+
const data = new Float32Array(12);
|
|
22
|
+
data[1] = -1;
|
|
23
|
+
data[4] = 1;
|
|
24
|
+
data[5] = 1;
|
|
25
|
+
data[6] = 1;
|
|
26
|
+
data[8] = 0.1;
|
|
27
|
+
data[9] = 0.1;
|
|
28
|
+
data[10] = 0.1;
|
|
29
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
33
|
+
const geometry = createBoxMeshGeometry();
|
|
34
|
+
return {
|
|
35
|
+
material: createSpecularGlossinessPbrMaterial(),
|
|
36
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
37
|
+
subset: geometry.subsets[0],
|
|
38
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe('registerSpecularGlossinessPbrGlMaterial', () => {
|
|
43
|
+
it('installs the renderer for SpecularGlossinessPbrMaterialKind', () => {
|
|
44
|
+
const { state } = makeGlScene3DState();
|
|
45
|
+
registerSpecularGlossinessPbrGlMaterial(state);
|
|
46
|
+
expect(getGlMeshMaterialRenderer(state, SpecularGlossinessPbrMaterialKind)).toBe(
|
|
47
|
+
specularGlossinessPbrGlMeshMaterialRenderer,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('specularGlossinessPbrGlMeshMaterialRenderer', () => {
|
|
53
|
+
it('bind converts spec-gloss to a standard block and uploads it through the base PBR program', () => {
|
|
54
|
+
const { state, gl } = makeGlScene3DState();
|
|
55
|
+
specularGlossinessPbrGlMeshMaterialRenderer.bind(
|
|
56
|
+
state,
|
|
57
|
+
createSpecularGlossinessPbrMaterial({ diffuse: 0xc08040ff, glossiness: 0.7, specular: 0x404040ff }),
|
|
58
|
+
makeLights(),
|
|
59
|
+
makeCamera(),
|
|
60
|
+
);
|
|
61
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
62
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
63
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('binds the base PBR program (no extension define) under the pbr: namespace', () => {
|
|
67
|
+
const { state } = makeGlScene3DState();
|
|
68
|
+
specularGlossinessPbrGlMeshMaterialRenderer.bind(
|
|
69
|
+
state,
|
|
70
|
+
createSpecularGlossinessPbrMaterial(),
|
|
71
|
+
makeLights(),
|
|
72
|
+
makeCamera(),
|
|
73
|
+
);
|
|
74
|
+
const cache = getGlScene3DRuntime(state).programCache;
|
|
75
|
+
expect(cache.size).toBe(1);
|
|
76
|
+
const key = [...cache.keys()][0];
|
|
77
|
+
expect(key.startsWith('pbr:')).toBe(true);
|
|
78
|
+
// The extension half of the key (after ':') is all dashes — no extension lobe enabled, and the
|
|
79
|
+
// trailing dash is the (unset) skin flag.
|
|
80
|
+
expect(key.split(':')[2]).toBe('--------');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('draw issues an indexed draw after bind', () => {
|
|
84
|
+
const { state, gl } = makeGlScene3DState();
|
|
85
|
+
const proxy = makeProxy();
|
|
86
|
+
specularGlossinessPbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
87
|
+
specularGlossinessPbrGlMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
88
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('draw is a no-op before bind', () => {
|
|
92
|
+
const { state, gl } = makeGlScene3DState();
|
|
93
|
+
specularGlossinessPbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
94
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createSpecularPbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { SpecularPbrMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
10
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
11
|
+
import { registerSpecularPbrGlMaterial, specularPbrGlMeshMaterialRenderer } from './specularPbrGlMeshMaterialRenderer';
|
|
12
|
+
|
|
13
|
+
function makeCamera(): Camera3D {
|
|
14
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function makeLights(): Scene3DLightBlock {
|
|
18
|
+
const data = new Float32Array(12);
|
|
19
|
+
data[1] = -1;
|
|
20
|
+
data[4] = 1;
|
|
21
|
+
data[5] = 1;
|
|
22
|
+
data[6] = 1;
|
|
23
|
+
data[8] = 0.1;
|
|
24
|
+
data[9] = 0.1;
|
|
25
|
+
data[10] = 0.1;
|
|
26
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
30
|
+
const geometry = createBoxMeshGeometry();
|
|
31
|
+
return {
|
|
32
|
+
material: createSpecularPbrMaterial(),
|
|
33
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
34
|
+
subset: geometry.subsets[0],
|
|
35
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('registerSpecularPbrGlMaterial', () => {
|
|
40
|
+
it('installs the renderer for SpecularPbrMaterialKind', () => {
|
|
41
|
+
const { state } = makeGlScene3DState();
|
|
42
|
+
registerSpecularPbrGlMaterial(state);
|
|
43
|
+
expect(getGlMeshMaterialRenderer(state, SpecularPbrMaterialKind)).toBe(specularPbrGlMeshMaterialRenderer);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('specularPbrGlMeshMaterialRenderer', () => {
|
|
48
|
+
it('bind uploads the light block, standard block, and specular uniforms', () => {
|
|
49
|
+
const { state, gl } = makeGlScene3DState();
|
|
50
|
+
specularPbrGlMeshMaterialRenderer.bind(
|
|
51
|
+
state,
|
|
52
|
+
createSpecularPbrMaterial({ specular: 0.8, specularColor: 0x80a0c000 }),
|
|
53
|
+
makeLights(),
|
|
54
|
+
makeCamera(),
|
|
55
|
+
);
|
|
56
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
57
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
58
|
+
expect(gl.calls.some((c) => c.name === 'uniform3f')).toBe(true);
|
|
59
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('caches the specular program under the pbr: namespace', () => {
|
|
63
|
+
const { state } = makeGlScene3DState();
|
|
64
|
+
specularPbrGlMeshMaterialRenderer.bind(state, createSpecularPbrMaterial(), makeLights(), makeCamera());
|
|
65
|
+
const cache = getGlScene3DRuntime(state).programCache;
|
|
66
|
+
expect(cache.size).toBe(1);
|
|
67
|
+
expect([...cache.keys()][0].startsWith('pbr:')).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('draw issues an indexed draw after bind', () => {
|
|
71
|
+
const { state, gl } = makeGlScene3DState();
|
|
72
|
+
const proxy = makeProxy();
|
|
73
|
+
specularPbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
74
|
+
specularPbrGlMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
75
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('draw is a no-op before bind', () => {
|
|
79
|
+
const { state, gl } = makeGlScene3DState();
|
|
80
|
+
specularPbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
81
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createStandardPbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
|
|
7
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
8
|
+
import { standardPbrGlMeshMaterialRenderer } from './standardPbrGlMeshMaterialRenderer';
|
|
9
|
+
|
|
10
|
+
function makeCamera(): Camera3D {
|
|
11
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function makeLights(): Scene3DLightBlock {
|
|
15
|
+
// Directional { dir.xyz @0, _pad, radiance.rgb @4, _pad } + ambient { radiance.rgb @8 }.
|
|
16
|
+
const data = new Float32Array(12);
|
|
17
|
+
data[0] = 0;
|
|
18
|
+
data[1] = -1;
|
|
19
|
+
data[2] = 0;
|
|
20
|
+
data[4] = 1;
|
|
21
|
+
data[5] = 1;
|
|
22
|
+
data[6] = 1;
|
|
23
|
+
data[8] = 0.1;
|
|
24
|
+
data[9] = 0.1;
|
|
25
|
+
data[10] = 0.1;
|
|
26
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
30
|
+
const geometry = createBoxMeshGeometry();
|
|
31
|
+
return {
|
|
32
|
+
material: createStandardPbrMaterial(),
|
|
33
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
34
|
+
subset: geometry.subsets[0],
|
|
35
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('standardPbrGlMeshMaterialRenderer', () => {
|
|
40
|
+
it('bind selects a program, sets depth/cull state, and uploads camera + light + material uniforms', () => {
|
|
41
|
+
const { state, gl } = makeGlScene3DState();
|
|
42
|
+
standardPbrGlMeshMaterialRenderer.bind(state, createStandardPbrMaterial(), makeLights(), makeCamera());
|
|
43
|
+
|
|
44
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
45
|
+
expect(gl.calls.some((c) => c.name === 'enable' && c.args[0] === gl.DEPTH_TEST)).toBe(true);
|
|
46
|
+
expect(gl.calls.some((c) => c.name === 'depthFunc' && c.args[0] === gl.LESS)).toBe(true);
|
|
47
|
+
expect(gl.calls.some((c) => c.name === 'enable' && c.args[0] === gl.CULL_FACE)).toBe(true);
|
|
48
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
49
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('bind disables back-face culling for a double-sided material', () => {
|
|
53
|
+
const { state, gl } = makeGlScene3DState();
|
|
54
|
+
const material = createStandardPbrMaterial();
|
|
55
|
+
material.doubleSided = true;
|
|
56
|
+
standardPbrGlMeshMaterialRenderer.bind(state, material, makeLights(), makeCamera());
|
|
57
|
+
expect(gl.calls.some((c) => c.name === 'disable' && c.args[0] === gl.CULL_FACE)).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('draw uploads geometry and issues an indexed draw over the subset range', () => {
|
|
61
|
+
const { state, gl } = makeGlScene3DState();
|
|
62
|
+
const proxy = makeProxy();
|
|
63
|
+
const geometry = createBoxMeshGeometry();
|
|
64
|
+
standardPbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
65
|
+
standardPbrGlMeshMaterialRenderer.draw(state, proxy, geometry);
|
|
66
|
+
|
|
67
|
+
const drawCall = gl.calls.find((c) => c.name === 'drawElements');
|
|
68
|
+
expect(drawCall).toBeDefined();
|
|
69
|
+
expect(drawCall!.args[1]).toBe(proxy.subset.indexCount);
|
|
70
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix3fv')).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('draw is a no-op when bind has not selected a program', () => {
|
|
74
|
+
const { state, gl } = makeGlScene3DState();
|
|
75
|
+
standardPbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
76
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('bind uploads the full standard block including occlusion strength and emissive', () => {
|
|
80
|
+
const { state, gl } = makeGlScene3DState();
|
|
81
|
+
const material = createStandardPbrMaterial({ metallic: 0.25, occlusionStrength: 0.7, roughness: 0.4 });
|
|
82
|
+
standardPbrGlMeshMaterialRenderer.bind(state, material, makeLights(), makeCamera());
|
|
83
|
+
// The standard block uploads metallic + roughness + normalScale + emissiveStrength +
|
|
84
|
+
// occlusionStrength as uniform1f, so at least five scalar uploads land.
|
|
85
|
+
expect(gl.calls.filter((c) => c.name === 'uniform1f').length).toBeGreaterThanOrEqual(5);
|
|
86
|
+
expect(gl.calls.some((c) => c.name === 'uniform3f')).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createSubsurfacePbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { SubsurfacePbrMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
10
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
11
|
+
import {
|
|
12
|
+
registerSubsurfacePbrGlMaterial,
|
|
13
|
+
subsurfacePbrGlMeshMaterialRenderer,
|
|
14
|
+
} from './subsurfacePbrGlMeshMaterialRenderer';
|
|
15
|
+
|
|
16
|
+
function makeCamera(): Camera3D {
|
|
17
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function makeLights(): Scene3DLightBlock {
|
|
21
|
+
const data = new Float32Array(12);
|
|
22
|
+
data[1] = -1;
|
|
23
|
+
data[4] = 1;
|
|
24
|
+
data[5] = 1;
|
|
25
|
+
data[6] = 1;
|
|
26
|
+
data[8] = 0.1;
|
|
27
|
+
data[9] = 0.1;
|
|
28
|
+
data[10] = 0.1;
|
|
29
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
33
|
+
const geometry = createBoxMeshGeometry();
|
|
34
|
+
return {
|
|
35
|
+
material: createSubsurfacePbrMaterial(),
|
|
36
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
37
|
+
subset: geometry.subsets[0],
|
|
38
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe('registerSubsurfacePbrGlMaterial', () => {
|
|
43
|
+
it('installs the renderer for SubsurfacePbrMaterialKind', () => {
|
|
44
|
+
const { state } = makeGlScene3DState();
|
|
45
|
+
registerSubsurfacePbrGlMaterial(state);
|
|
46
|
+
expect(getGlMeshMaterialRenderer(state, SubsurfacePbrMaterialKind)).toBe(subsurfacePbrGlMeshMaterialRenderer);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('subsurfacePbrGlMeshMaterialRenderer', () => {
|
|
51
|
+
it('bind uploads the light block, standard block, and subsurface uniforms', () => {
|
|
52
|
+
const { state, gl } = makeGlScene3DState();
|
|
53
|
+
subsurfacePbrGlMeshMaterialRenderer.bind(
|
|
54
|
+
state,
|
|
55
|
+
createSubsurfacePbrMaterial({ subsurface: 0.6, subsurfaceColor: 0xc06040ff, thickness: 0.3 }),
|
|
56
|
+
makeLights(),
|
|
57
|
+
makeCamera(),
|
|
58
|
+
);
|
|
59
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
60
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
61
|
+
expect(gl.calls.some((c) => c.name === 'uniform3f')).toBe(true);
|
|
62
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('caches the subsurface program under the pbr: namespace', () => {
|
|
66
|
+
const { state } = makeGlScene3DState();
|
|
67
|
+
subsurfacePbrGlMeshMaterialRenderer.bind(state, createSubsurfacePbrMaterial(), makeLights(), makeCamera());
|
|
68
|
+
const cache = getGlScene3DRuntime(state).programCache;
|
|
69
|
+
expect(cache.size).toBe(1);
|
|
70
|
+
expect([...cache.keys()][0].startsWith('pbr:')).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('draw issues an indexed draw after bind', () => {
|
|
74
|
+
const { state, gl } = makeGlScene3DState();
|
|
75
|
+
const proxy = makeProxy();
|
|
76
|
+
subsurfacePbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
77
|
+
subsurfacePbrGlMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
78
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('draw is a no-op before bind', () => {
|
|
82
|
+
const { state, gl } = makeGlScene3DState();
|
|
83
|
+
subsurfacePbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
84
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createToonMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { ToonMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
10
|
+
import { registerToonGlMaterial, toonGlMeshMaterialRenderer } from './toonGlMeshMaterialRenderer';
|
|
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
|
+
function makeLights(): Scene3DLightBlock {
|
|
17
|
+
// Directional { dir.xyz @0, _pad, radiance.rgb @4, _pad } + ambient { radiance.rgb @8 }.
|
|
18
|
+
const data = new Float32Array(12);
|
|
19
|
+
data[0] = 0;
|
|
20
|
+
data[1] = -1;
|
|
21
|
+
data[2] = 0;
|
|
22
|
+
data[4] = 1;
|
|
23
|
+
data[5] = 1;
|
|
24
|
+
data[6] = 1;
|
|
25
|
+
data[8] = 0.1;
|
|
26
|
+
data[9] = 0.1;
|
|
27
|
+
data[10] = 0.1;
|
|
28
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
32
|
+
const geometry = createBoxMeshGeometry();
|
|
33
|
+
return {
|
|
34
|
+
material: createToonMaterial(),
|
|
35
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
36
|
+
subset: geometry.subsets[0],
|
|
37
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('registerToonGlMaterial', () => {
|
|
42
|
+
it('installs the renderer for ToonMaterialKind', () => {
|
|
43
|
+
const { state } = makeGlScene3DState();
|
|
44
|
+
registerToonGlMaterial(state);
|
|
45
|
+
expect(getGlMeshMaterialRenderer(state, ToonMaterialKind)).toBe(toonGlMeshMaterialRenderer);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('toonGlMeshMaterialRenderer', () => {
|
|
50
|
+
it('bind selects a program, sets depth/cull state, and uploads camera + light block + base color', () => {
|
|
51
|
+
const { state, gl } = makeGlScene3DState();
|
|
52
|
+
toonGlMeshMaterialRenderer.bind(state, createToonMaterial(), makeLights(), makeCamera());
|
|
53
|
+
|
|
54
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
55
|
+
expect(gl.calls.some((c) => c.name === 'enable' && c.args[0] === gl.DEPTH_TEST)).toBe(true);
|
|
56
|
+
expect(gl.calls.some((c) => c.name === 'depthFunc' && c.args[0] === gl.LESS)).toBe(true);
|
|
57
|
+
expect(gl.calls.some((c) => c.name === 'enable' && c.args[0] === gl.CULL_FACE)).toBe(true);
|
|
58
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
59
|
+
// Light block: directional + directional-radiance (uniform4f x2), ambient (uniform3f + camera
|
|
60
|
+
// position uniform3f), the two count gates (uniform1f), plus the base color (uniform4f).
|
|
61
|
+
expect(gl.calls.filter((c) => c.name === 'uniform4f').length).toBeGreaterThanOrEqual(3);
|
|
62
|
+
expect(gl.calls.filter((c) => c.name === 'uniform3f').length).toBeGreaterThanOrEqual(2);
|
|
63
|
+
expect(gl.calls.filter((c) => c.name === 'uniform1f').length).toBeGreaterThanOrEqual(2);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('bind disables back-face culling for a double-sided material', () => {
|
|
67
|
+
const { state, gl } = makeGlScene3DState();
|
|
68
|
+
const material = createToonMaterial();
|
|
69
|
+
material.doubleSided = true;
|
|
70
|
+
toonGlMeshMaterialRenderer.bind(state, material, makeLights(), makeCamera());
|
|
71
|
+
expect(gl.calls.some((c) => c.name === 'disable' && c.args[0] === gl.CULL_FACE)).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('draw uploads geometry and issues an indexed draw over the subset range', () => {
|
|
75
|
+
const { state, gl } = makeGlScene3DState();
|
|
76
|
+
const proxy = makeProxy();
|
|
77
|
+
const geometry = createBoxMeshGeometry();
|
|
78
|
+
toonGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
79
|
+
toonGlMeshMaterialRenderer.draw(state, proxy, geometry);
|
|
80
|
+
|
|
81
|
+
const drawCall = gl.calls.find((c) => c.name === 'drawElements');
|
|
82
|
+
expect(drawCall).toBeDefined();
|
|
83
|
+
expect(drawCall!.args[1]).toBe(proxy.subset.indexCount);
|
|
84
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix3fv')).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('draw is a no-op when bind has not selected a program', () => {
|
|
88
|
+
const { state, gl } = makeGlScene3DState();
|
|
89
|
+
toonGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
90
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createCamera3D } from '@flighthq/camera';
|
|
2
|
+
import { createMatrix3, createMatrix4 } from '@flighthq/geometry';
|
|
3
|
+
import { createTransmissionVolumePbrMaterial } from '@flighthq/materials';
|
|
4
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh';
|
|
5
|
+
import type { Camera3D, Matrix3, Matrix4, Scene3DLightBlock, Scene3DRenderProxy } from '@flighthq/types';
|
|
6
|
+
import { TransmissionVolumePbrMaterialKind } from '@flighthq/types';
|
|
7
|
+
|
|
8
|
+
import { getGlMeshMaterialRenderer } from './glMeshMaterialRegistry';
|
|
9
|
+
import { getGlScene3DRuntime } from './glScene3DRuntime';
|
|
10
|
+
import { makeGlScene3DState } from './glScene3DTestHelper';
|
|
11
|
+
import {
|
|
12
|
+
registerTransmissionVolumePbrGlMaterial,
|
|
13
|
+
transmissionVolumePbrGlMeshMaterialRenderer,
|
|
14
|
+
} from './transmissionVolumePbrGlMeshMaterialRenderer';
|
|
15
|
+
|
|
16
|
+
function makeCamera(): Camera3D {
|
|
17
|
+
return createCamera3D({ far: 100, near: 0.1, projection: { aspect: 1, fovY: Math.PI / 3, kind: 'perspective' } });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function makeLights(): Scene3DLightBlock {
|
|
21
|
+
const data = new Float32Array(12);
|
|
22
|
+
data[1] = -1;
|
|
23
|
+
data[4] = 1;
|
|
24
|
+
data[5] = 1;
|
|
25
|
+
data[6] = 1;
|
|
26
|
+
data[8] = 0.1;
|
|
27
|
+
data[9] = 0.1;
|
|
28
|
+
data[10] = 0.1;
|
|
29
|
+
return { ambientCount: 1, data, directionalCount: 1, hemisphereCount: 0, pointCount: 0, spotCount: 0, version: 1 };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeProxy(): Scene3DRenderProxy {
|
|
33
|
+
const geometry = createBoxMeshGeometry();
|
|
34
|
+
return {
|
|
35
|
+
material: createTransmissionVolumePbrMaterial(),
|
|
36
|
+
normalMatrix: createMatrix3() as Matrix3,
|
|
37
|
+
subset: geometry.subsets[0],
|
|
38
|
+
worldMatrix: createMatrix4() as Matrix4,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe('registerTransmissionVolumePbrGlMaterial', () => {
|
|
43
|
+
it('installs the renderer for TransmissionVolumePbrMaterialKind', () => {
|
|
44
|
+
const { state } = makeGlScene3DState();
|
|
45
|
+
registerTransmissionVolumePbrGlMaterial(state);
|
|
46
|
+
expect(getGlMeshMaterialRenderer(state, TransmissionVolumePbrMaterialKind)).toBe(
|
|
47
|
+
transmissionVolumePbrGlMeshMaterialRenderer,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('transmissionVolumePbrGlMeshMaterialRenderer', () => {
|
|
53
|
+
it('bind uploads the light block, standard block, and transmission uniforms', () => {
|
|
54
|
+
const { state, gl } = makeGlScene3DState();
|
|
55
|
+
transmissionVolumePbrGlMeshMaterialRenderer.bind(
|
|
56
|
+
state,
|
|
57
|
+
createTransmissionVolumePbrMaterial({ attenuationColor: 0x80c0ffff, transmission: 0.9 }),
|
|
58
|
+
makeLights(),
|
|
59
|
+
makeCamera(),
|
|
60
|
+
);
|
|
61
|
+
expect(gl.calls.some((c) => c.name === 'useProgram')).toBe(true);
|
|
62
|
+
expect(gl.calls.some((c) => c.name === 'uniform4f')).toBe(true);
|
|
63
|
+
expect(gl.calls.some((c) => c.name === 'uniform3f')).toBe(true);
|
|
64
|
+
expect(gl.calls.some((c) => c.name === 'uniformMatrix4fv')).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('caches the transmission program under the pbr: namespace', () => {
|
|
68
|
+
const { state } = makeGlScene3DState();
|
|
69
|
+
transmissionVolumePbrGlMeshMaterialRenderer.bind(
|
|
70
|
+
state,
|
|
71
|
+
createTransmissionVolumePbrMaterial(),
|
|
72
|
+
makeLights(),
|
|
73
|
+
makeCamera(),
|
|
74
|
+
);
|
|
75
|
+
const cache = getGlScene3DRuntime(state).programCache;
|
|
76
|
+
expect(cache.size).toBe(1);
|
|
77
|
+
expect([...cache.keys()][0].startsWith('pbr:')).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('draw issues an indexed draw after bind', () => {
|
|
81
|
+
const { state, gl } = makeGlScene3DState();
|
|
82
|
+
const proxy = makeProxy();
|
|
83
|
+
transmissionVolumePbrGlMeshMaterialRenderer.bind(state, proxy.material, makeLights(), makeCamera());
|
|
84
|
+
transmissionVolumePbrGlMeshMaterialRenderer.draw(state, proxy, createBoxMeshGeometry());
|
|
85
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('draw is a no-op before bind', () => {
|
|
89
|
+
const { state, gl } = makeGlScene3DState();
|
|
90
|
+
transmissionVolumePbrGlMeshMaterialRenderer.draw(state, makeProxy(), createBoxMeshGeometry());
|
|
91
|
+
expect(gl.calls.some((c) => c.name === 'drawElements')).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
});
|