@flighthq/materials 0.1.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.
Files changed (60) hide show
  1. package/dist/classicMaterials.d.ts +5 -0
  2. package/dist/classicMaterials.d.ts.map +1 -0
  3. package/dist/classicMaterials.js +39 -0
  4. package/dist/classicMaterials.js.map +1 -0
  5. package/dist/color.d.ts +23 -0
  6. package/dist/color.d.ts.map +1 -0
  7. package/dist/color.js +291 -0
  8. package/dist/color.js.map +1 -0
  9. package/dist/colorTransform.d.ts +18 -0
  10. package/dist/colorTransform.d.ts.map +1 -0
  11. package/dist/colorTransform.js +119 -0
  12. package/dist/colorTransform.js.map +1 -0
  13. package/dist/colorTransformMaterial.d.ts +4 -0
  14. package/dist/colorTransformMaterial.d.ts.map +1 -0
  15. package/dist/colorTransformMaterial.js +18 -0
  16. package/dist/colorTransformMaterial.js.map +1 -0
  17. package/dist/index.d.ts +12 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +12 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/material.d.ts +6 -0
  22. package/dist/material.d.ts.map +1 -0
  23. package/dist/material.js +73 -0
  24. package/dist/material.js.map +1 -0
  25. package/dist/materialPresets.d.ts +13 -0
  26. package/dist/materialPresets.d.ts.map +1 -0
  27. package/dist/materialPresets.js +118 -0
  28. package/dist/materialPresets.js.map +1 -0
  29. package/dist/materialValidation.d.ts +7 -0
  30. package/dist/materialValidation.d.ts.map +1 -0
  31. package/dist/materialValidation.js +52 -0
  32. package/dist/materialValidation.js.map +1 -0
  33. package/dist/pbrExtensionMaterials.d.ts +9 -0
  34. package/dist/pbrExtensionMaterials.d.ts.map +1 -0
  35. package/dist/pbrExtensionMaterials.js +93 -0
  36. package/dist/pbrExtensionMaterials.js.map +1 -0
  37. package/dist/pbrMaterials.d.ts +6 -0
  38. package/dist/pbrMaterials.d.ts.map +1 -0
  39. package/dist/pbrMaterials.js +134 -0
  40. package/dist/pbrMaterials.js.map +1 -0
  41. package/dist/surfaceMaterial.d.ts +7 -0
  42. package/dist/surfaceMaterial.d.ts.map +1 -0
  43. package/dist/surfaceMaterial.js +41 -0
  44. package/dist/surfaceMaterial.js.map +1 -0
  45. package/dist/unlitMaterials.d.ts +10 -0
  46. package/dist/unlitMaterials.d.ts.map +1 -0
  47. package/dist/unlitMaterials.js +66 -0
  48. package/dist/unlitMaterials.js.map +1 -0
  49. package/package.json +38 -0
  50. package/src/classicMaterials.test.ts +48 -0
  51. package/src/color.test.ts +383 -0
  52. package/src/colorTransform.test.ts +384 -0
  53. package/src/colorTransformMaterial.test.ts +26 -0
  54. package/src/material.test.ts +110 -0
  55. package/src/materialPresets.test.ts +125 -0
  56. package/src/materialValidation.test.ts +130 -0
  57. package/src/pbrExtensionMaterials.test.ts +123 -0
  58. package/src/pbrMaterials.test.ts +91 -0
  59. package/src/surfaceMaterial.test.ts +69 -0
  60. package/src/unlitMaterials.test.ts +127 -0
@@ -0,0 +1,130 @@
1
+ import {
2
+ clampStandardPbrMaterialProperties,
3
+ isValidMaterialClearcoat,
4
+ isValidMaterialIor,
5
+ isValidMaterialIridescenceThickness,
6
+ isValidMaterialWeight,
7
+ } from './materialValidation';
8
+ import { createStandardPbrMaterialProperties } from './pbrMaterials';
9
+
10
+ describe('clampStandardPbrMaterialProperties', () => {
11
+ it('returns the out instance', () => {
12
+ const props = createStandardPbrMaterialProperties();
13
+ expect(clampStandardPbrMaterialProperties(props)).toBe(props);
14
+ });
15
+ it('clamps metallic to [0, 1]', () => {
16
+ const props = createStandardPbrMaterialProperties({ metallic: 1.5 });
17
+ clampStandardPbrMaterialProperties(props);
18
+ expect(props.metallic).toBe(1);
19
+ props.metallic = -0.5;
20
+ clampStandardPbrMaterialProperties(props);
21
+ expect(props.metallic).toBe(0);
22
+ });
23
+ it('clamps roughness to [0, 1]', () => {
24
+ const props = createStandardPbrMaterialProperties({ roughness: 2 });
25
+ clampStandardPbrMaterialProperties(props);
26
+ expect(props.roughness).toBe(1);
27
+ props.roughness = -1;
28
+ clampStandardPbrMaterialProperties(props);
29
+ expect(props.roughness).toBe(0);
30
+ });
31
+ it('clamps occlusionStrength to [0, 1]', () => {
32
+ const props = createStandardPbrMaterialProperties({ occlusionStrength: 3 });
33
+ clampStandardPbrMaterialProperties(props);
34
+ expect(props.occlusionStrength).toBe(1);
35
+ props.occlusionStrength = -1;
36
+ clampStandardPbrMaterialProperties(props);
37
+ expect(props.occlusionStrength).toBe(0);
38
+ });
39
+ it('clamps emissiveStrength to [0, ∞) — allows values above 1 for HDR emissive', () => {
40
+ const props = createStandardPbrMaterialProperties({ emissiveStrength: -1 });
41
+ clampStandardPbrMaterialProperties(props);
42
+ expect(props.emissiveStrength).toBe(0);
43
+ props.emissiveStrength = 10;
44
+ clampStandardPbrMaterialProperties(props);
45
+ expect(props.emissiveStrength).toBe(10);
46
+ });
47
+ it('clamps normalScale to [0, ∞) — allows values above 1 for exaggerated normals', () => {
48
+ const props = createStandardPbrMaterialProperties({ normalScale: -2 });
49
+ clampStandardPbrMaterialProperties(props);
50
+ expect(props.normalScale).toBe(0);
51
+ props.normalScale = 5;
52
+ clampStandardPbrMaterialProperties(props);
53
+ expect(props.normalScale).toBe(5);
54
+ });
55
+ it('leaves a valid block unchanged', () => {
56
+ const props = createStandardPbrMaterialProperties({ metallic: 0.5, roughness: 0.3 });
57
+ clampStandardPbrMaterialProperties(props);
58
+ expect(props.metallic).toBe(0.5);
59
+ expect(props.roughness).toBe(0.3);
60
+ });
61
+ });
62
+
63
+ describe('isValidMaterialClearcoat', () => {
64
+ it('returns true for values in [0, 1]', () => {
65
+ expect(isValidMaterialClearcoat(0)).toBe(true);
66
+ expect(isValidMaterialClearcoat(0.5)).toBe(true);
67
+ expect(isValidMaterialClearcoat(1)).toBe(true);
68
+ });
69
+ it('returns false for values outside [0, 1]', () => {
70
+ expect(isValidMaterialClearcoat(-0.1)).toBe(false);
71
+ expect(isValidMaterialClearcoat(1.1)).toBe(false);
72
+ });
73
+ it('returns false for NaN and Infinity', () => {
74
+ expect(isValidMaterialClearcoat(NaN)).toBe(false);
75
+ expect(isValidMaterialClearcoat(Infinity)).toBe(false);
76
+ });
77
+ });
78
+
79
+ describe('isValidMaterialIor', () => {
80
+ it('returns true for valid IOR values', () => {
81
+ expect(isValidMaterialIor(1.0)).toBe(true);
82
+ expect(isValidMaterialIor(1.5)).toBe(true);
83
+ expect(isValidMaterialIor(2.4)).toBe(true);
84
+ expect(isValidMaterialIor(5.0)).toBe(true);
85
+ });
86
+ it('returns false for IOR below 1', () => {
87
+ expect(isValidMaterialIor(0.9)).toBe(false);
88
+ expect(isValidMaterialIor(0)).toBe(false);
89
+ });
90
+ it('returns false for IOR above 5', () => {
91
+ expect(isValidMaterialIor(5.1)).toBe(false);
92
+ expect(isValidMaterialIor(100)).toBe(false);
93
+ });
94
+ it('returns false for NaN and Infinity', () => {
95
+ expect(isValidMaterialIor(NaN)).toBe(false);
96
+ expect(isValidMaterialIor(Infinity)).toBe(false);
97
+ });
98
+ });
99
+
100
+ describe('isValidMaterialIridescenceThickness', () => {
101
+ it('returns true for non-negative finite values', () => {
102
+ expect(isValidMaterialIridescenceThickness(0)).toBe(true);
103
+ expect(isValidMaterialIridescenceThickness(100)).toBe(true);
104
+ expect(isValidMaterialIridescenceThickness(400)).toBe(true);
105
+ expect(isValidMaterialIridescenceThickness(2000)).toBe(true);
106
+ });
107
+ it('returns false for negative values', () => {
108
+ expect(isValidMaterialIridescenceThickness(-1)).toBe(false);
109
+ });
110
+ it('returns false for NaN and Infinity', () => {
111
+ expect(isValidMaterialIridescenceThickness(NaN)).toBe(false);
112
+ expect(isValidMaterialIridescenceThickness(Infinity)).toBe(false);
113
+ });
114
+ });
115
+
116
+ describe('isValidMaterialWeight', () => {
117
+ it('returns true for values in [0, 1]', () => {
118
+ expect(isValidMaterialWeight(0)).toBe(true);
119
+ expect(isValidMaterialWeight(0.5)).toBe(true);
120
+ expect(isValidMaterialWeight(1)).toBe(true);
121
+ });
122
+ it('returns false for values outside [0, 1]', () => {
123
+ expect(isValidMaterialWeight(-0.001)).toBe(false);
124
+ expect(isValidMaterialWeight(1.001)).toBe(false);
125
+ });
126
+ it('returns false for NaN and Infinity', () => {
127
+ expect(isValidMaterialWeight(NaN)).toBe(false);
128
+ expect(isValidMaterialWeight(Infinity)).toBe(false);
129
+ });
130
+ });
@@ -0,0 +1,123 @@
1
+ import {
2
+ AnisotropyPbrMaterialKind,
3
+ ClearcoatPbrMaterialKind,
4
+ IridescencePbrMaterialKind,
5
+ SheenPbrMaterialKind,
6
+ SpecularPbrMaterialKind,
7
+ SubsurfacePbrMaterialKind,
8
+ TransmissionVolumePbrMaterialKind,
9
+ } from '@flighthq/types';
10
+
11
+ import {
12
+ createAnisotropyPbrMaterial,
13
+ createClearcoatPbrMaterial,
14
+ createIridescencePbrMaterial,
15
+ createSheenPbrMaterial,
16
+ createSpecularPbrMaterial,
17
+ createSubsurfacePbrMaterial,
18
+ createTransmissionVolumePbrMaterial,
19
+ } from './pbrExtensionMaterials';
20
+ import { createStandardPbrMaterialProperties } from './pbrMaterials';
21
+
22
+ describe('createAnisotropyPbrMaterial', () => {
23
+ it('creates an isotropic anisotropy material with a default standard block', () => {
24
+ const material = createAnisotropyPbrMaterial();
25
+ expect(material.kind).toBe(AnisotropyPbrMaterialKind);
26
+ expect(material.anisotropyStrength).toBe(0);
27
+ expect(material.anisotropyRotation).toBe(0);
28
+ expect(material.standard.baseColor).toBe(0xffffffff);
29
+ });
30
+
31
+ it('composes a provided standard block', () => {
32
+ const standard = createStandardPbrMaterialProperties({ metallic: 1 });
33
+ expect(createAnisotropyPbrMaterial({ standard }).standard).toBe(standard);
34
+ });
35
+ });
36
+
37
+ describe('createClearcoatPbrMaterial', () => {
38
+ it('creates a disabled clearcoat material with a default standard block', () => {
39
+ const material = createClearcoatPbrMaterial();
40
+ expect(material.kind).toBe(ClearcoatPbrMaterialKind);
41
+ expect(material.clearcoat).toBe(0);
42
+ expect(material.clearcoatRoughness).toBe(0);
43
+ expect(material.standard.roughness).toBe(1);
44
+ });
45
+
46
+ it('applies overrides', () => {
47
+ expect(createClearcoatPbrMaterial({ clearcoat: 1 }).clearcoat).toBe(1);
48
+ });
49
+ });
50
+
51
+ describe('createIridescencePbrMaterial', () => {
52
+ it('creates a disabled iridescence material with glTF thickness defaults', () => {
53
+ const material = createIridescencePbrMaterial();
54
+ expect(material.kind).toBe(IridescencePbrMaterialKind);
55
+ expect(material.iridescence).toBe(0);
56
+ expect(material.iridescenceIor).toBe(1.3);
57
+ expect(material.iridescenceThicknessMin).toBe(100);
58
+ expect(material.iridescenceThicknessMax).toBe(400);
59
+ });
60
+
61
+ it('applies overrides', () => {
62
+ expect(createIridescencePbrMaterial({ iridescence: 1 }).iridescence).toBe(1);
63
+ });
64
+ });
65
+
66
+ describe('createSheenPbrMaterial', () => {
67
+ it('creates a disabled sheen material with a default standard block', () => {
68
+ const material = createSheenPbrMaterial();
69
+ expect(material.kind).toBe(SheenPbrMaterialKind);
70
+ expect(material.sheenColor).toBe(0x000000ff);
71
+ expect(material.sheenRoughness).toBe(0);
72
+ expect(material.standard.baseColor).toBe(0xffffffff);
73
+ });
74
+
75
+ it('applies overrides', () => {
76
+ expect(createSheenPbrMaterial({ sheenColor: 0xffffffff }).sheenColor).toBe(0xffffffff);
77
+ });
78
+ });
79
+
80
+ describe('createSpecularPbrMaterial', () => {
81
+ it('creates a full-specular white-tint material with a default standard block', () => {
82
+ const material = createSpecularPbrMaterial();
83
+ expect(material.kind).toBe(SpecularPbrMaterialKind);
84
+ expect(material.specular).toBe(1);
85
+ expect(material.specularColor).toBe(0xffffffff);
86
+ expect(material.standard.metallic).toBe(0);
87
+ });
88
+
89
+ it('applies overrides', () => {
90
+ expect(createSpecularPbrMaterial({ specular: 0.5 }).specular).toBe(0.5);
91
+ });
92
+ });
93
+
94
+ describe('createSubsurfacePbrMaterial', () => {
95
+ it('creates a disabled subsurface material with a default standard block', () => {
96
+ const material = createSubsurfacePbrMaterial();
97
+ expect(material.kind).toBe(SubsurfacePbrMaterialKind);
98
+ expect(material.subsurface).toBe(0);
99
+ expect(material.subsurfaceColor).toBe(0xffffffff);
100
+ expect(material.thickness).toBe(0);
101
+ expect(material.standard.roughness).toBe(1);
102
+ });
103
+
104
+ it('applies overrides', () => {
105
+ expect(createSubsurfacePbrMaterial({ subsurface: 1 }).subsurface).toBe(1);
106
+ });
107
+ });
108
+
109
+ describe('createTransmissionVolumePbrMaterial', () => {
110
+ it('creates an opaque transmission material with glTF ior and no absorption', () => {
111
+ const material = createTransmissionVolumePbrMaterial();
112
+ expect(material.kind).toBe(TransmissionVolumePbrMaterialKind);
113
+ expect(material.transmission).toBe(0);
114
+ expect(material.ior).toBe(1.5);
115
+ expect(material.attenuationColor).toBe(0xffffffff);
116
+ expect(material.attenuationDistance).toBe(Infinity);
117
+ expect(material.standard.baseColor).toBe(0xffffffff);
118
+ });
119
+
120
+ it('applies overrides', () => {
121
+ expect(createTransmissionVolumePbrMaterial({ transmission: 1 }).transmission).toBe(1);
122
+ });
123
+ });
@@ -0,0 +1,91 @@
1
+ import { SpecularGlossinessPbrMaterialKind, StandardPbrMaterialKind } from '@flighthq/types';
2
+
3
+ import {
4
+ convertSpecularGlossinessToStandardPbr,
5
+ createSpecularGlossinessPbrMaterial,
6
+ createStandardPbrMaterial,
7
+ createStandardPbrMaterialProperties,
8
+ } from './pbrMaterials';
9
+
10
+ describe('convertSpecularGlossinessToStandardPbr', () => {
11
+ it('maps glossiness to roughness as 1 - glossiness', () => {
12
+ const source = createSpecularGlossinessPbrMaterial({ glossiness: 0.75 });
13
+ const out = createStandardPbrMaterialProperties();
14
+ convertSpecularGlossinessToStandardPbr(out, source);
15
+ expect(out.roughness).toBeCloseTo(0.25, 5);
16
+ });
17
+ it('produces metallic=0 for a dielectric (black specular)', () => {
18
+ const source = createSpecularGlossinessPbrMaterial({ specular: 0x000000ff });
19
+ const out = createStandardPbrMaterialProperties();
20
+ convertSpecularGlossinessToStandardPbr(out, source);
21
+ expect(out.metallic).toBe(0);
22
+ });
23
+ it('produces metallic=1 for a full metallic (white specular, white diffuse)', () => {
24
+ const source = createSpecularGlossinessPbrMaterial({ specular: 0xffffffff, diffuse: 0xffffffff });
25
+ const out = createStandardPbrMaterialProperties();
26
+ convertSpecularGlossinessToStandardPbr(out, source);
27
+ expect(out.metallic).toBeCloseTo(1, 1);
28
+ });
29
+ it('forwards emissive, normalMap, and occlusionMap unchanged', () => {
30
+ const source = createSpecularGlossinessPbrMaterial({ emissive: 0xff000000, emissiveStrength: 2.5 });
31
+ const out = createStandardPbrMaterialProperties();
32
+ convertSpecularGlossinessToStandardPbr(out, source);
33
+ expect(out.emissive).toBe(0xff000000);
34
+ expect(out.emissiveStrength).toBe(2.5);
35
+ });
36
+ it('is alias-safe when out is used as a different object from source', () => {
37
+ const source = createSpecularGlossinessPbrMaterial({ glossiness: 0.5, diffuse: 0xff0000ff });
38
+ const out = createStandardPbrMaterialProperties();
39
+ convertSpecularGlossinessToStandardPbr(out, source);
40
+ // glossiness=0.5 → roughness=0.5
41
+ expect(out.roughness).toBeCloseTo(0.5, 5);
42
+ });
43
+ });
44
+
45
+ describe('createSpecularGlossinessPbrMaterial', () => {
46
+ it('creates a white spec-gloss material at full glossiness', () => {
47
+ const material = createSpecularGlossinessPbrMaterial();
48
+ expect(material.kind).toBe(SpecularGlossinessPbrMaterialKind);
49
+ expect(material.diffuse).toBe(0xffffffff);
50
+ expect(material.specular).toBe(0xffffffff);
51
+ expect(material.glossiness).toBe(1);
52
+ expect(material.specularGlossinessMap).toBeNull();
53
+ });
54
+
55
+ it('applies overrides', () => {
56
+ expect(createSpecularGlossinessPbrMaterial({ glossiness: 0.25 }).glossiness).toBe(0.25);
57
+ });
58
+ });
59
+
60
+ describe('createStandardPbrMaterial', () => {
61
+ it('creates a white, dielectric, fully-rough material', () => {
62
+ const material = createStandardPbrMaterial();
63
+ expect(material.kind).toBe(StandardPbrMaterialKind);
64
+ expect(material.baseColor).toBe(0xffffffff);
65
+ expect(material.metallic).toBe(0);
66
+ expect(material.roughness).toBe(1);
67
+ expect(material.emissive).toBe(0x000000ff);
68
+ expect(material.baseColorMap).toBeNull();
69
+ });
70
+
71
+ it('applies overrides', () => {
72
+ const material = createStandardPbrMaterial({ metallic: 1, roughness: 0.2 });
73
+ expect(material.metallic).toBe(1);
74
+ expect(material.roughness).toBe(0.2);
75
+ });
76
+ });
77
+
78
+ describe('createStandardPbrMaterialProperties', () => {
79
+ it('creates the property block with no kind or trailer', () => {
80
+ const properties = createStandardPbrMaterialProperties();
81
+ expect(properties.baseColor).toBe(0xffffffff);
82
+ expect(properties.metallic).toBe(0);
83
+ expect(properties.roughness).toBe(1);
84
+ expect((properties as { kind?: unknown }).kind).toBeUndefined();
85
+ expect((properties as { alphaMode?: unknown }).alphaMode).toBeUndefined();
86
+ });
87
+
88
+ it('applies overrides', () => {
89
+ expect(createStandardPbrMaterialProperties({ roughness: 0.5 }).roughness).toBe(0.5);
90
+ });
91
+ });
@@ -0,0 +1,69 @@
1
+ import { BlendMode } from '@flighthq/types';
2
+
3
+ import {
4
+ createSurfaceMaterial,
5
+ getMaterialAlphaMode,
6
+ isMaterialBlended,
7
+ isMaterialMasked,
8
+ isMaterialOpaque,
9
+ } from './surfaceMaterial';
10
+
11
+ const TestSurfaceMaterialKind = 'TestSurfaceMaterial';
12
+
13
+ describe('createSurfaceMaterial', () => {
14
+ it('carries the given kind', () => {
15
+ expect(createSurfaceMaterial(TestSurfaceMaterialKind).kind).toBe(TestSurfaceMaterialKind);
16
+ });
17
+
18
+ it('defaults the shared trailer to an opaque, single-sided surface', () => {
19
+ const material = createSurfaceMaterial(TestSurfaceMaterialKind);
20
+ expect(material.alphaMode).toBe('opaque');
21
+ expect(material.alphaCutoff).toBe(0.5);
22
+ expect(material.alphaType).toBe('straight');
23
+ expect(material.blendMode).toBe(BlendMode.Normal);
24
+ expect(material.doubleSided).toBe(false);
25
+ });
26
+ });
27
+
28
+ describe('getMaterialAlphaMode', () => {
29
+ it('returns the alphaMode of the material', () => {
30
+ const opaque = createSurfaceMaterial(TestSurfaceMaterialKind);
31
+ expect(getMaterialAlphaMode(opaque)).toBe('opaque');
32
+ const blended = createSurfaceMaterial(TestSurfaceMaterialKind);
33
+ blended.alphaMode = 'blend';
34
+ expect(getMaterialAlphaMode(blended)).toBe('blend');
35
+ const masked = createSurfaceMaterial(TestSurfaceMaterialKind);
36
+ masked.alphaMode = 'mask';
37
+ expect(getMaterialAlphaMode(masked)).toBe('mask');
38
+ });
39
+ });
40
+
41
+ describe('isMaterialBlended', () => {
42
+ it('returns true only for blend mode', () => {
43
+ const opaque = createSurfaceMaterial(TestSurfaceMaterialKind);
44
+ expect(isMaterialBlended(opaque)).toBe(false);
45
+ const blended = createSurfaceMaterial(TestSurfaceMaterialKind);
46
+ blended.alphaMode = 'blend';
47
+ expect(isMaterialBlended(blended)).toBe(true);
48
+ });
49
+ });
50
+
51
+ describe('isMaterialMasked', () => {
52
+ it('returns true only for mask mode', () => {
53
+ const opaque = createSurfaceMaterial(TestSurfaceMaterialKind);
54
+ expect(isMaterialMasked(opaque)).toBe(false);
55
+ const masked = createSurfaceMaterial(TestSurfaceMaterialKind);
56
+ masked.alphaMode = 'mask';
57
+ expect(isMaterialMasked(masked)).toBe(true);
58
+ });
59
+ });
60
+
61
+ describe('isMaterialOpaque', () => {
62
+ it('returns true only for opaque mode', () => {
63
+ const opaque = createSurfaceMaterial(TestSurfaceMaterialKind);
64
+ expect(isMaterialOpaque(opaque)).toBe(true);
65
+ const blended = createSurfaceMaterial(TestSurfaceMaterialKind);
66
+ blended.alphaMode = 'blend';
67
+ expect(isMaterialOpaque(blended)).toBe(false);
68
+ });
69
+ });
@@ -0,0 +1,127 @@
1
+ import {
2
+ DepthMaterialKind,
3
+ EmissiveMaterialKind,
4
+ MatcapMaterialKind,
5
+ NormalMaterialKind,
6
+ ToonMaterialKind,
7
+ UnlitMaterialKind,
8
+ VertexColorMaterialKind,
9
+ WireframeMaterialKind,
10
+ } from '@flighthq/types';
11
+
12
+ import {
13
+ createDepthMaterial,
14
+ createEmissiveMaterial,
15
+ createMatcapMaterial,
16
+ createNormalMaterial,
17
+ createToonMaterial,
18
+ createUnlitMaterial,
19
+ createVertexColorMaterial,
20
+ createWireframeMaterial,
21
+ } from './unlitMaterials';
22
+
23
+ describe('createDepthMaterial', () => {
24
+ it('creates a depth material with a unit range', () => {
25
+ const material = createDepthMaterial();
26
+ expect(material.kind).toBe(DepthMaterialKind);
27
+ expect(material.near).toBe(0);
28
+ expect(material.far).toBe(1);
29
+ });
30
+
31
+ it('applies overrides', () => {
32
+ expect(createDepthMaterial({ far: 100, near: 0.1 }).far).toBe(100);
33
+ });
34
+ });
35
+
36
+ describe('createEmissiveMaterial', () => {
37
+ it('creates a white emissive material at unit strength', () => {
38
+ const material = createEmissiveMaterial();
39
+ expect(material.kind).toBe(EmissiveMaterialKind);
40
+ expect(material.emissive).toBe(0xffffffff);
41
+ expect(material.emissiveMap).toBeNull();
42
+ expect(material.emissiveStrength).toBe(1);
43
+ });
44
+
45
+ it('applies overrides', () => {
46
+ expect(createEmissiveMaterial({ emissiveStrength: 4 }).emissiveStrength).toBe(4);
47
+ });
48
+ });
49
+
50
+ describe('createMatcapMaterial', () => {
51
+ it('creates a matcap material with a white tint and no capture', () => {
52
+ const material = createMatcapMaterial();
53
+ expect(material.kind).toBe(MatcapMaterialKind);
54
+ expect(material.matcap).toBeNull();
55
+ expect(material.tint).toBe(0xffffffff);
56
+ });
57
+
58
+ it('applies overrides', () => {
59
+ expect(createMatcapMaterial({ tint: 0xff0000ff }).tint).toBe(0xff0000ff);
60
+ });
61
+ });
62
+
63
+ describe('createNormalMaterial', () => {
64
+ it('creates a normal material at unit scale with no map', () => {
65
+ const material = createNormalMaterial();
66
+ expect(material.kind).toBe(NormalMaterialKind);
67
+ expect(material.normalMap).toBeNull();
68
+ expect(material.normalScale).toBe(1);
69
+ });
70
+
71
+ it('applies overrides', () => {
72
+ expect(createNormalMaterial({ normalScale: 0.5 }).normalScale).toBe(0.5);
73
+ });
74
+ });
75
+
76
+ describe('createToonMaterial', () => {
77
+ it('creates a white toon material with three bands', () => {
78
+ const material = createToonMaterial();
79
+ expect(material.kind).toBe(ToonMaterialKind);
80
+ expect(material.baseColor).toBe(0xffffffff);
81
+ expect(material.baseColorMap).toBeNull();
82
+ expect(material.ramp).toBeNull();
83
+ expect(material.steps).toBe(3);
84
+ });
85
+
86
+ it('applies overrides', () => {
87
+ expect(createToonMaterial({ steps: 5 }).steps).toBe(5);
88
+ });
89
+ });
90
+
91
+ describe('createUnlitMaterial', () => {
92
+ it('creates a white unlit material with no map', () => {
93
+ const material = createUnlitMaterial();
94
+ expect(material.kind).toBe(UnlitMaterialKind);
95
+ expect(material.baseColor).toBe(0xffffffff);
96
+ expect(material.baseColorMap).toBeNull();
97
+ });
98
+
99
+ it('applies overrides', () => {
100
+ expect(createUnlitMaterial({ baseColor: 0x00ff00ff }).baseColor).toBe(0x00ff00ff);
101
+ });
102
+ });
103
+
104
+ describe('createVertexColorMaterial', () => {
105
+ it('creates a vertex-color material with a white tint', () => {
106
+ const material = createVertexColorMaterial();
107
+ expect(material.kind).toBe(VertexColorMaterialKind);
108
+ expect(material.tint).toBe(0xffffffff);
109
+ });
110
+
111
+ it('applies overrides', () => {
112
+ expect(createVertexColorMaterial({ tint: 0x808080ff }).tint).toBe(0x808080ff);
113
+ });
114
+ });
115
+
116
+ describe('createWireframeMaterial', () => {
117
+ it('creates a white wireframe material one pixel thick', () => {
118
+ const material = createWireframeMaterial();
119
+ expect(material.kind).toBe(WireframeMaterialKind);
120
+ expect(material.color).toBe(0xffffffff);
121
+ expect(material.thickness).toBe(1);
122
+ });
123
+
124
+ it('applies overrides', () => {
125
+ expect(createWireframeMaterial({ thickness: 2 }).thickness).toBe(2);
126
+ });
127
+ });