@flighthq/materials 0.1.0 → 0.2.1-next.410.a23f189
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/customShaderMaterial.d.ts +3 -0
- package/dist/customShaderMaterial.d.ts.map +1 -0
- package/dist/customShaderMaterial.js +15 -0
- package/dist/customShaderMaterial.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/material.d.ts.map +1 -1
- package/dist/material.js +6 -19
- package/dist/material.js.map +1 -1
- package/dist/pbrMaterials.d.ts.map +1 -1
- package/dist/pbrMaterials.js +1 -1
- package/dist/pbrMaterials.js.map +1 -1
- package/dist/phongToPbr.d.ts +6 -0
- package/dist/phongToPbr.d.ts.map +1 -0
- package/dist/phongToPbr.js +53 -0
- package/dist/phongToPbr.js.map +1 -0
- package/dist/unlitMaterials.d.ts.map +1 -1
- package/dist/unlitMaterials.js +4 -2
- package/dist/unlitMaterials.js.map +1 -1
- package/package.json +9 -3
- package/src/colorTransform.test.ts +66 -9
- package/src/customShaderMaterial.test.ts +20 -0
- package/src/material.test.ts +14 -38
- package/src/phongToPbr.test.ts +67 -0
- package/dist/color.d.ts +0 -23
- package/dist/color.d.ts.map +0 -1
- package/dist/color.js +0 -291
- package/dist/color.js.map +0 -1
- package/dist/colorTransformMaterial.d.ts +0 -4
- package/dist/colorTransformMaterial.d.ts.map +0 -1
- package/dist/colorTransformMaterial.js +0 -18
- package/dist/colorTransformMaterial.js.map +0 -1
- package/src/color.test.ts +0 -383
- package/src/colorTransformMaterial.test.ts +0 -26
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customShaderMaterial.d.ts","sourceRoot":"","sources":["../src/customShaderMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAU5D,wBAAgB,0BAA0B,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,GAAG,oBAAoB,CAM/G"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CustomShaderMaterialKind } from '@flighthq/types';
|
|
2
|
+
import { createSurfaceMaterial } from './surfaceMaterial';
|
|
3
|
+
// User-authored shader material. `shaderKey` references a vertex+fragment pair registered on
|
|
4
|
+
// the render state (registerGlCustomMaterialShader); `uniforms` carries flat scalar/vector
|
|
5
|
+
// values; `textures` carries named texture bindings. All default to their sentinel (empty key,
|
|
6
|
+
// null bags) so a bare createCustomShaderMaterial() is structurally valid for tests and
|
|
7
|
+
// serialization even before a shader key is assigned.
|
|
8
|
+
export function createCustomShaderMaterial(opts) {
|
|
9
|
+
const material = createSurfaceMaterial(CustomShaderMaterialKind);
|
|
10
|
+
material.shaderKey = opts?.shaderKey ?? '';
|
|
11
|
+
material.textures = opts?.textures ?? null;
|
|
12
|
+
material.uniforms = opts?.uniforms ?? null;
|
|
13
|
+
return material;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=customShaderMaterial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customShaderMaterial.js","sourceRoot":"","sources":["../src/customShaderMaterial.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,6FAA6F;AAC7F,2FAA2F;AAC3F,+FAA+F;AAC/F,wFAAwF;AACxF,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,IAA8C;IACvF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,wBAAwB,CAAyB,CAAC;IACzF,QAAQ,CAAC,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC3C,QAAQ,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC3C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * from './classicMaterials';
|
|
2
|
-
export * from './color';
|
|
3
2
|
export * from './colorTransform';
|
|
4
|
-
export * from './
|
|
3
|
+
export * from './customShaderMaterial';
|
|
5
4
|
export * from './material';
|
|
6
5
|
export * from './materialPresets';
|
|
7
6
|
export * from './materialValidation';
|
|
8
7
|
export * from './pbrExtensionMaterials';
|
|
9
8
|
export * from './pbrMaterials';
|
|
9
|
+
export * from './phongToPbr';
|
|
10
10
|
export * from './surfaceMaterial';
|
|
11
11
|
export * from './unlitMaterials';
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * from './classicMaterials';
|
|
2
|
-
export * from './color';
|
|
3
2
|
export * from './colorTransform';
|
|
4
|
-
export * from './
|
|
3
|
+
export * from './customShaderMaterial';
|
|
5
4
|
export * from './material';
|
|
6
5
|
export * from './materialPresets';
|
|
7
6
|
export * from './materialValidation';
|
|
8
7
|
export * from './pbrExtensionMaterials';
|
|
9
8
|
export * from './pbrMaterials';
|
|
9
|
+
export * from './phongToPbr';
|
|
10
10
|
export * from './surfaceMaterial';
|
|
11
11
|
export * from './unlitMaterials';
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/dist/material.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../src/material.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../src/material.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAItD,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAIlE;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,CAG5E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAInD;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAUpF"}
|
package/dist/material.js
CHANGED
|
@@ -1,40 +1,31 @@
|
|
|
1
1
|
import { createEntity } from '@flighthq/entity';
|
|
2
|
-
import { UniformColorTransformMaterialKind } from '@flighthq/types';
|
|
3
|
-
import { cloneColorTransform, equalsColorTransform } from './colorTransform';
|
|
4
2
|
// Structural shallow clone of any material entity. Scalar fields and kind are copied by
|
|
5
3
|
// value; Texture/map handle references are shared (they are not owned by the material).
|
|
6
|
-
// The sub-entity `colorTransform` of UniformColorTransformMaterial is deep-cloned so the
|
|
7
|
-
// two materials do not share mutable transform state.
|
|
8
4
|
export function cloneMaterial(source) {
|
|
9
5
|
const clone = createEntity({ kind: source.kind });
|
|
10
6
|
copyMaterialFields(clone, source, source.kind);
|
|
11
7
|
return clone;
|
|
12
8
|
}
|
|
13
9
|
// Structural copy for pooling and reuse. Writes all own enumerable fields from `source`
|
|
14
|
-
// onto `out`. Map handles are shared by reference
|
|
15
|
-
// UniformColorTransformMaterial is deep-copied. Alias-safe: reads all inputs before
|
|
16
|
-
// writing (each field is independent, but `colorTransform` is copied first to avoid a
|
|
17
|
-
// partial write if `out === source`).
|
|
10
|
+
// onto `out`. Map handles are shared by reference. Alias-safe: each field is independent.
|
|
18
11
|
export function copyMaterial(out, source) {
|
|
19
12
|
if (out === source)
|
|
20
13
|
return;
|
|
21
14
|
copyMaterialFields(out, source, source.kind);
|
|
22
15
|
}
|
|
23
16
|
export function createMaterial(kind) {
|
|
24
|
-
|
|
17
|
+
const material = createEntity({ kind });
|
|
18
|
+
material.name = null;
|
|
19
|
+
return material;
|
|
25
20
|
}
|
|
26
21
|
// Structural equality for dedup, pooling, and serialization round-trips — NOT the batch
|
|
27
22
|
// flush path (batching keys on material by reference). Compares own enumerable data fields
|
|
28
23
|
// by value for scalars and kind strings, and by reference for Texture/map handles.
|
|
29
|
-
// UniformColorTransformMaterial gets deep equality on its colorTransform sub-entity.
|
|
30
24
|
export function equalsMaterial(a, b) {
|
|
31
25
|
if (a === b)
|
|
32
26
|
return true;
|
|
33
27
|
if (a.kind !== b.kind)
|
|
34
28
|
return false;
|
|
35
|
-
if (a.kind === UniformColorTransformMaterialKind) {
|
|
36
|
-
return equalsColorTransform(a.colorTransform, b.colorTransform);
|
|
37
|
-
}
|
|
38
29
|
const aFields = a;
|
|
39
30
|
const bFields = b;
|
|
40
31
|
for (const key of Object.keys(aFields)) {
|
|
@@ -47,7 +38,7 @@ export function equalsMaterial(a, b) {
|
|
|
47
38
|
}
|
|
48
39
|
// Internal helper — writes all own enumerable data fields from `src` onto `dst`. Skips
|
|
49
40
|
// the `kind` field (already set on `dst` at construction). Handles the `standard` sub-block
|
|
50
|
-
//
|
|
41
|
+
// by shallow-field copy; all other values are assigned.
|
|
51
42
|
function copyMaterialFields(dst, src, kind) {
|
|
52
43
|
const dstFields = dst;
|
|
53
44
|
const srcFields = src;
|
|
@@ -55,11 +46,7 @@ function copyMaterialFields(dst, src, kind) {
|
|
|
55
46
|
if (key === 'kind')
|
|
56
47
|
continue;
|
|
57
48
|
const value = srcFields[key];
|
|
58
|
-
if (key === '
|
|
59
|
-
// Deep-copy the ColorTransform sub-entity so the clone is independent.
|
|
60
|
-
dstFields[key] = cloneColorTransform(value);
|
|
61
|
-
}
|
|
62
|
-
else if (key === 'standard' && value != null && typeof value === 'object') {
|
|
49
|
+
if (key === 'standard' && value != null && typeof value === 'object') {
|
|
63
50
|
// Shallow-copy the StandardPbrMaterialProperties block into an existing or new object.
|
|
64
51
|
dstFields[key] = { ...value };
|
|
65
52
|
}
|
package/dist/material.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.js","sourceRoot":"","sources":["../src/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"material.js","sourceRoot":"","sources":["../src/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,wFAAwF;AACxF,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,MAA0B;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAa,CAAC;IAC9D,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wFAAwF;AACxF,0FAA0F;AAC1F,MAAM,UAAU,YAAY,CAAC,GAAa,EAAE,MAA0B;IACpE,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO;IAC3B,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAU;IACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,CAAa,CAAC;IACpD,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,wFAAwF;AACxF,2FAA2F;AAC3F,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,CAAqB,EAAE,CAAqB;IACzE,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,OAAO,GAAG,CAAuC,CAAC;IACxD,MAAM,OAAO,GAAG,CAAuC,CAAC;IACxD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,IAAI,GAAG,KAAK,MAAM;YAAE,SAAS;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uFAAuF;AACvF,4FAA4F;AAC5F,wDAAwD;AACxD,SAAS,kBAAkB,CAAC,GAAa,EAAE,GAAuB,EAAE,IAAU;IAC5E,MAAM,SAAS,GAAG,GAAyC,CAAC;IAC5D,MAAM,SAAS,GAAG,GAAyC,CAAC;IAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,IAAI,GAAG,KAAK,MAAM;YAAE,SAAS;QAC7B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,GAAG,KAAK,UAAU,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrE,uFAAuF;YACvF,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAI,KAAgB,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IACD,iFAAiF;IACjF,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbrMaterials.d.ts","sourceRoot":"","sources":["../src/pbrMaterials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pbrMaterials.d.ts","sourceRoot":"","sources":["../src/pbrMaterials.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,6BAA6B,EAC7B,mBAAmB,EACnB,6BAA6B,EAC9B,MAAM,iBAAiB,CAAC;AAiBzB,wBAAgB,sCAAsC,CACpD,GAAG,EAAE,6BAA6B,EAClC,MAAM,EAAE,QAAQ,CAAC,6BAA6B,CAAC,GAC9C,IAAI,CAmDN;AAKD,wBAAgB,mCAAmC,CACjD,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACtD,6BAA6B,CAe/B;AAKD,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG,mBAAmB,CAI5G;AAKD,wBAAgB,mCAAmC,CACjD,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACtD,6BAA6B,CAI/B"}
|
package/dist/pbrMaterials.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { unpackColorToLinear } from '@flighthq/color';
|
|
1
2
|
import { SpecularGlossinessPbrMaterialKind, StandardPbrMaterialKind } from '@flighthq/types';
|
|
2
|
-
import { unpackColorToLinear } from './color';
|
|
3
3
|
import { createSurfaceMaterial } from './surfaceMaterial';
|
|
4
4
|
// Converts a legacy specular-glossiness material to a metallic-roughness property block.
|
|
5
5
|
// Writes `out` with the computed base-color, metallic, and roughness values. The conversion
|
package/dist/pbrMaterials.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbrMaterials.js","sourceRoot":"","sources":["../src/pbrMaterials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pbrMaterials.js","sourceRoot":"","sources":["../src/pbrMaterials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PhongMaterial, StandardPbrMaterial, StandardPbrMaterialProperties } from '@flighthq/types';
|
|
2
|
+
export declare function convertPhongToStandardPbrMaterial(phong: Readonly<PhongMaterial>, opts?: Readonly<Partial<StandardPbrMaterialProperties>>): StandardPbrMaterial;
|
|
3
|
+
export declare function getPbrMetallicFromPhongSpecular(specular: number, diffuse: number): number;
|
|
4
|
+
export declare function getPbrRoughnessFromPhongShininess(shininess: number): number;
|
|
5
|
+
export declare function getPhongToPbrLightExposure(): number;
|
|
6
|
+
//# sourceMappingURL=phongToPbr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phongToPbr.d.ts","sourceRoot":"","sources":["../src/phongToPbr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAezG,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC9B,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACtD,mBAAmB,CAUrB;AAMD,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzF;AAKD,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3E;AAcD,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getColorLuminance } from '@flighthq/color';
|
|
2
|
+
import { createStandardPbrMaterial } from './pbrMaterials';
|
|
3
|
+
// Migrates a classic `PhongMaterial` to a metallic-roughness `StandardPbrMaterial` whose surface
|
|
4
|
+
// reads equivalently. A reference (not exact) mapping: the Phong reflection-vector lobe and the
|
|
5
|
+
// GGX microfacet lobe cannot match at every angle, so this preserves overall appearance —
|
|
6
|
+
// base color, gloss, and brightness — rather than per-highlight shape. `opts` overrides any mapped
|
|
7
|
+
// field (e.g. to force `metallic`). Diffuse and baseColor share the packed sRgb-albedo encoding,
|
|
8
|
+
// so the color transfers unchanged; the renderer decodes both identically.
|
|
9
|
+
//
|
|
10
|
+
// IMPORTANT — brightness: the metallic-roughness diffuse term divides albedo by π that classic
|
|
11
|
+
// Phong does not (see `getPhongToPbrLightExposure`). The material alone cannot compensate a
|
|
12
|
+
// per-light normalization, so scale the scene's light intensity by that exposure or a migrated
|
|
13
|
+
// scene renders ~π× (≈3.2×) too dark.
|
|
14
|
+
export function convertPhongToStandardPbrMaterial(phong, opts) {
|
|
15
|
+
return createStandardPbrMaterial({
|
|
16
|
+
baseColor: phong.diffuse,
|
|
17
|
+
baseColorMap: phong.diffuseMap,
|
|
18
|
+
metallic: getPbrMetallicFromPhongSpecular(phong.specular, phong.diffuse),
|
|
19
|
+
normalMap: phong.normalMap,
|
|
20
|
+
normalScale: phong.normalScale,
|
|
21
|
+
roughness: getPbrRoughnessFromPhongShininess(phong.shininess),
|
|
22
|
+
...opts,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Reference metallic guess from a Phong specular/diffuse pair. Phong does not encode metalness, so
|
|
26
|
+
// this is conservative: dielectric (0) unless a strong specular sits over a near-black diffuse — the
|
|
27
|
+
// only Phong configuration that reads unambiguously metallic. Callers that know the material is
|
|
28
|
+
// metal should pass `metallic` through `convertPhongToStandardPbrMaterial`'s `opts` instead.
|
|
29
|
+
export function getPbrMetallicFromPhongSpecular(specular, diffuse) {
|
|
30
|
+
return getColorLuminance(specular) > 0.5 && getColorLuminance(diffuse) < 0.04 ? 1 : 0;
|
|
31
|
+
}
|
|
32
|
+
// Maps a Blinn-Phong specular exponent to a GGX roughness via `sqrt(2 / (shininess + 2))`, clamped
|
|
33
|
+
// to [0, 1]. Monotonic: higher shininess (sharper highlight) → lower roughness (smoother surface).
|
|
34
|
+
// The Phong default shininess of 32 maps to roughness ≈ 0.243.
|
|
35
|
+
export function getPbrRoughnessFromPhongShininess(shininess) {
|
|
36
|
+
return Math.min(1, Math.max(0, Math.sqrt(2 / (Math.max(0, shininess) + 2))));
|
|
37
|
+
}
|
|
38
|
+
// The exposure (in EV) to apply to a scene's lights when migrating classic-Phong materials to
|
|
39
|
+
// metallic-roughness PBR, so brightness is preserved under the same lights. The PBR diffuse BRDF
|
|
40
|
+
// divides albedo by π for energy conservation while classic Phong does not, so PBR diffuse is ~1/π
|
|
41
|
+
// as bright for equal light radiance. This returns `log2(π)` (≈ 1.651 EV) — i.e. a ×π scale —
|
|
42
|
+
// applied via `applyLightExposure(intensity, getPhongToPbrLightExposure())` from `@flighthq/lighting`.
|
|
43
|
+
// Skipping it is the classic "ported scene is far too dark" failure.
|
|
44
|
+
//
|
|
45
|
+
// Assumed input, so it is applied exactly ONCE: light intensities already in Flight's LINEAR-radiance
|
|
46
|
+
// Phong convention. This is the single Phong→PBR energy step; it is NOT a general "engine porting"
|
|
47
|
+
// scale. Porting from a foreign engine whose lights are in a different space (e.g. a gamma-space LDR
|
|
48
|
+
// source) is a separate, earlier conversion into Flight's linear Phong convention that belongs in the
|
|
49
|
+
// importer, not here — do not fold that engine's own boost into this π, and do not apply this twice.
|
|
50
|
+
export function getPhongToPbrLightExposure() {
|
|
51
|
+
return Math.log2(Math.PI);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=phongToPbr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phongToPbr.js","sourceRoot":"","sources":["../src/phongToPbr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iGAAiG;AACjG,gGAAgG;AAChG,0FAA0F;AAC1F,mGAAmG;AACnG,iGAAiG;AACjG,2EAA2E;AAC3E,EAAE;AACF,+FAA+F;AAC/F,4FAA4F;AAC5F,+FAA+F;AAC/F,sCAAsC;AACtC,MAAM,UAAU,iCAAiC,CAC/C,KAA8B,EAC9B,IAAuD;IAEvD,OAAO,yBAAyB,CAAC;QAC/B,SAAS,EAAE,KAAK,CAAC,OAAO;QACxB,YAAY,EAAE,KAAK,CAAC,UAAU;QAC9B,QAAQ,EAAE,+BAA+B,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;QACxE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,iCAAiC,CAAC,KAAK,CAAC,SAAS,CAAC;QAC7D,GAAG,IAAI;KACR,CAAC,CAAC;AACL,CAAC;AAED,mGAAmG;AACnG,qGAAqG;AACrG,gGAAgG;AAChG,6FAA6F;AAC7F,MAAM,UAAU,+BAA+B,CAAC,QAAgB,EAAE,OAAe;IAC/E,OAAO,iBAAiB,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,mGAAmG;AACnG,mGAAmG;AACnG,+DAA+D;AAC/D,MAAM,UAAU,iCAAiC,CAAC,SAAiB;IACjE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,8FAA8F;AAC9F,iGAAiG;AACjG,mGAAmG;AACnG,8FAA8F;AAC9F,uGAAuG;AACvG,qEAAqE;AACrE,EAAE;AACF,sGAAsG;AACtG,mGAAmG;AACnG,qGAAqG;AACrG,sGAAsG;AACtG,qGAAqG;AACrG,MAAM,UAAU,0BAA0B;IACxC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlitMaterials.d.ts","sourceRoot":"","sources":["../src/unlitMaterials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAgBzB,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,aAAa,CAK1F;AAID,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,gBAAgB,CAMnG;AAID,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAK7F;AAGD,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAK7F;AAID,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,YAAY,CAOvF;
|
|
1
|
+
{"version":3,"file":"unlitMaterials.d.ts","sourceRoot":"","sources":["../src/unlitMaterials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAgBzB,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,aAAa,CAK1F;AAID,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,gBAAgB,CAMnG;AAID,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAK7F;AAGD,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAK7F;AAID,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,YAAY,CAOvF;AAKD,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,aAAa,CAM1F;AAGD,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG,mBAAmB,CAI5G;AAGD,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,GAAG,iBAAiB,CAKtG"}
|
package/dist/unlitMaterials.js
CHANGED
|
@@ -42,12 +42,14 @@ export function createToonMaterial(opts) {
|
|
|
42
42
|
material.steps = opts?.steps ?? 3;
|
|
43
43
|
return material;
|
|
44
44
|
}
|
|
45
|
-
// Lighting-independent flat-color material. `baseColor` defaults to white, `baseColorMap`
|
|
46
|
-
// null. Full fidelity on every backend including Canvas2D
|
|
45
|
+
// Lighting-independent flat-color material. `baseColor` defaults to white, `baseColorMap` and
|
|
46
|
+
// `baseColorVideoMap` to null. Full fidelity on every backend including Canvas2D; a bound
|
|
47
|
+
// `baseColorVideoMap` (live video stream) is sampled only on the GL backend today.
|
|
47
48
|
export function createUnlitMaterial(opts) {
|
|
48
49
|
const material = createSurfaceMaterial(UnlitMaterialKind);
|
|
49
50
|
material.baseColor = opts?.baseColor ?? 0xffffffff;
|
|
50
51
|
material.baseColorMap = opts?.baseColorMap ?? null;
|
|
52
|
+
material.baseColorVideoMap = opts?.baseColorVideoMap ?? null;
|
|
51
53
|
return material;
|
|
52
54
|
}
|
|
53
55
|
// Uses the mesh's `color0` vertex attribute as unlit surface color. `tint` defaults to white.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlitMaterials.js","sourceRoot":"","sources":["../src/unlitMaterials.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,6FAA6F;AAC7F,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,IAAuC;IACzE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,iBAAiB,CAAkB,CAAC;IAC3E,QAAQ,CAAC,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9B,QAAQ,CAAC,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC;IAChC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kFAAkF;AAClF,+EAA+E;AAC/E,MAAM,UAAU,sBAAsB,CAAC,IAA0C;IAC/E,MAAM,QAAQ,GAAG,qBAAqB,CAAC,oBAAoB,CAAqB,CAAC;IACjF,QAAQ,CAAC,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,UAAU,CAAC;IACjD,QAAQ,CAAC,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;IACjD,QAAQ,CAAC,gBAAgB,GAAG,IAAI,EAAE,gBAAgB,IAAI,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8FAA8F;AAC9F,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAAC,IAAwC;IAC3E,MAAM,QAAQ,GAAG,qBAAqB,CAAC,kBAAkB,CAAmB,CAAC;IAC7E,QAAQ,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC;IACvC,QAAQ,CAAC,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,UAAU,CAAC;IACzC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,oBAAoB,CAAC,IAAwC;IAC3E,MAAM,QAAQ,GAAG,qBAAqB,CAAC,kBAAkB,CAAmB,CAAC;IAC7E,QAAQ,CAAC,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,QAAQ,CAAC,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,CAAC,CAAC;IAC9C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,+FAA+F;AAC/F,6FAA6F;AAC7F,MAAM,UAAU,kBAAkB,CAAC,IAAsC;IACvE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,gBAAgB,CAAiB,CAAC;IACzE,QAAQ,CAAC,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,UAAU,CAAC;IACnD,QAAQ,CAAC,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,IAAI,CAAC;IACnD,QAAQ,CAAC,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;IAClC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"unlitMaterials.js","sourceRoot":"","sources":["../src/unlitMaterials.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/materials",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.2.1-next.410.a23f189",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/flighthq/flight.git",
|
|
7
|
+
"directory": "packages/materials"
|
|
8
|
+
},
|
|
4
9
|
"type": "module",
|
|
5
10
|
"main": "dist/index.js",
|
|
6
11
|
"types": "dist/index.d.ts",
|
|
@@ -27,8 +32,9 @@
|
|
|
27
32
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
28
33
|
},
|
|
29
34
|
"dependencies": {
|
|
30
|
-
"@flighthq/
|
|
31
|
-
"@flighthq/
|
|
35
|
+
"@flighthq/color": "0.2.1-next.410.a23f189",
|
|
36
|
+
"@flighthq/entity": "0.2.1-next.410.a23f189",
|
|
37
|
+
"@flighthq/types": "0.2.1-next.410.a23f189"
|
|
32
38
|
},
|
|
33
39
|
"devDependencies": {
|
|
34
40
|
"typescript": "^5.3.0"
|
|
@@ -67,15 +67,72 @@ describe('concatColorTransform', () => {
|
|
|
67
67
|
expect(out.redOffset).toBe(2 * 5 + 10);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
it('
|
|
71
|
-
const a = createColorTransform({
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
it('produces correct result when out aliases source', () => {
|
|
71
|
+
const a = createColorTransform({
|
|
72
|
+
redMultiplier: 2,
|
|
73
|
+
greenMultiplier: 0.5,
|
|
74
|
+
blueMultiplier: 3,
|
|
75
|
+
alphaMultiplier: 0.25,
|
|
76
|
+
redOffset: 10,
|
|
77
|
+
greenOffset: 20,
|
|
78
|
+
blueOffset: 30,
|
|
79
|
+
alphaOffset: 40,
|
|
80
|
+
});
|
|
81
|
+
const b = createColorTransform({
|
|
82
|
+
redMultiplier: 3,
|
|
83
|
+
greenMultiplier: 4,
|
|
84
|
+
blueMultiplier: 0.5,
|
|
85
|
+
alphaMultiplier: 2,
|
|
86
|
+
redOffset: 5,
|
|
87
|
+
greenOffset: 15,
|
|
88
|
+
blueOffset: 25,
|
|
89
|
+
alphaOffset: 35,
|
|
90
|
+
});
|
|
91
|
+
const ref = createColorTransform();
|
|
92
|
+
concatColorTransform(ref, a, b);
|
|
93
|
+
concatColorTransform(a, a, b);
|
|
94
|
+
expect(a.redMultiplier).toBe(ref.redMultiplier);
|
|
95
|
+
expect(a.greenMultiplier).toBe(ref.greenMultiplier);
|
|
96
|
+
expect(a.blueMultiplier).toBe(ref.blueMultiplier);
|
|
97
|
+
expect(a.alphaMultiplier).toBe(ref.alphaMultiplier);
|
|
98
|
+
expect(a.redOffset).toBe(ref.redOffset);
|
|
99
|
+
expect(a.greenOffset).toBe(ref.greenOffset);
|
|
100
|
+
expect(a.blueOffset).toBe(ref.blueOffset);
|
|
101
|
+
expect(a.alphaOffset).toBe(ref.alphaOffset);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('produces correct result when out aliases other', () => {
|
|
105
|
+
const a = createColorTransform({
|
|
106
|
+
redMultiplier: 2,
|
|
107
|
+
greenMultiplier: 0.5,
|
|
108
|
+
blueMultiplier: 3,
|
|
109
|
+
alphaMultiplier: 0.25,
|
|
110
|
+
redOffset: 10,
|
|
111
|
+
greenOffset: 20,
|
|
112
|
+
blueOffset: 30,
|
|
113
|
+
alphaOffset: 40,
|
|
114
|
+
});
|
|
115
|
+
const b = createColorTransform({
|
|
116
|
+
redMultiplier: 3,
|
|
117
|
+
greenMultiplier: 4,
|
|
118
|
+
blueMultiplier: 0.5,
|
|
119
|
+
alphaMultiplier: 2,
|
|
120
|
+
redOffset: 5,
|
|
121
|
+
greenOffset: 15,
|
|
122
|
+
blueOffset: 25,
|
|
123
|
+
alphaOffset: 35,
|
|
124
|
+
});
|
|
125
|
+
const ref = createColorTransform();
|
|
126
|
+
concatColorTransform(ref, a, b);
|
|
127
|
+
concatColorTransform(b, a, b);
|
|
128
|
+
expect(b.redMultiplier).toBe(ref.redMultiplier);
|
|
129
|
+
expect(b.greenMultiplier).toBe(ref.greenMultiplier);
|
|
130
|
+
expect(b.blueMultiplier).toBe(ref.blueMultiplier);
|
|
131
|
+
expect(b.alphaMultiplier).toBe(ref.alphaMultiplier);
|
|
132
|
+
expect(b.redOffset).toBe(ref.redOffset);
|
|
133
|
+
expect(b.greenOffset).toBe(ref.greenOffset);
|
|
134
|
+
expect(b.blueOffset).toBe(ref.blueOffset);
|
|
135
|
+
expect(b.alphaOffset).toBe(ref.alphaOffset);
|
|
79
136
|
});
|
|
80
137
|
});
|
|
81
138
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CustomShaderMaterialKind } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { createCustomShaderMaterial } from './customShaderMaterial';
|
|
4
|
+
|
|
5
|
+
describe('createCustomShaderMaterial', () => {
|
|
6
|
+
it('creates a custom shader material with default sentinel values', () => {
|
|
7
|
+
const material = createCustomShaderMaterial();
|
|
8
|
+
expect(material.kind).toBe(CustomShaderMaterialKind);
|
|
9
|
+
expect(material.shaderKey).toBe('');
|
|
10
|
+
expect(material.uniforms).toBeNull();
|
|
11
|
+
expect(material.textures).toBeNull();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('applies overrides', () => {
|
|
15
|
+
const uniforms = { u_time: 1.5, u_scale: [2, 3] };
|
|
16
|
+
const material = createCustomShaderMaterial({ shaderKey: 'myShader', uniforms });
|
|
17
|
+
expect(material.shaderKey).toBe('myShader');
|
|
18
|
+
expect(material.uniforms).toBe(uniforms);
|
|
19
|
+
});
|
|
20
|
+
});
|
package/src/material.test.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import type { StandardPbrMaterial
|
|
2
|
-
import {
|
|
3
|
-
ColorTransformMaterialKind,
|
|
4
|
-
StandardPbrMaterialKind,
|
|
5
|
-
UniformColorTransformMaterialKind,
|
|
6
|
-
} from '@flighthq/types';
|
|
1
|
+
import type { StandardPbrMaterial } from '@flighthq/types';
|
|
2
|
+
import { StandardPbrMaterialKind } from '@flighthq/types';
|
|
7
3
|
|
|
8
|
-
import { createColorTransform } from './colorTransform';
|
|
9
|
-
import { createColorTransformMaterial, createUniformColorTransformMaterial } from './colorTransformMaterial';
|
|
10
4
|
import { cloneMaterial, copyMaterial, createMaterial, equalsMaterial } from './material';
|
|
11
5
|
import { createStandardPbrMaterial } from './pbrMaterials';
|
|
12
6
|
|
|
13
7
|
const TestMaterialKind = 'TestMaterial';
|
|
8
|
+
const OtherMaterialKind = 'OtherMaterial';
|
|
14
9
|
|
|
15
10
|
describe('cloneMaterial', () => {
|
|
16
11
|
it('returns a new object with the same kind', () => {
|
|
@@ -27,21 +22,16 @@ describe('cloneMaterial', () => {
|
|
|
27
22
|
expect(clonePbr.roughness).toBe(0.25);
|
|
28
23
|
expect(clone.kind).toBe(StandardPbrMaterialKind);
|
|
29
24
|
});
|
|
30
|
-
it('deep-clones the colorTransform of a UniformColorTransformMaterial', () => {
|
|
31
|
-
const ct = createColorTransform({ redMultiplier: 0.5 });
|
|
32
|
-
const original = createUniformColorTransformMaterial(ct);
|
|
33
|
-
const clone = cloneMaterial(original) as UniformColorTransformMaterial;
|
|
34
|
-
expect(clone.colorTransform).not.toBe(original.colorTransform);
|
|
35
|
-
expect(clone.colorTransform.redMultiplier).toBe(0.5);
|
|
36
|
-
// Mutating the clone does not affect the original.
|
|
37
|
-
clone.colorTransform.redMultiplier = 1;
|
|
38
|
-
expect(original.colorTransform.redMultiplier).toBe(0.5);
|
|
39
|
-
});
|
|
40
25
|
it('produces a clone that is structurally equal to the original', () => {
|
|
41
26
|
const original = createStandardPbrMaterial({ metallic: 0.7 });
|
|
42
27
|
const clone = cloneMaterial(original);
|
|
43
28
|
expect(equalsMaterial(original, clone)).toBe(true);
|
|
44
29
|
});
|
|
30
|
+
it('carries the authored name onto the clone', () => {
|
|
31
|
+
const original = createMaterial(TestMaterialKind);
|
|
32
|
+
original.name = 'canopy';
|
|
33
|
+
expect(cloneMaterial(original).name).toBe('canopy');
|
|
34
|
+
});
|
|
45
35
|
});
|
|
46
36
|
|
|
47
37
|
describe('copyMaterial', () => {
|
|
@@ -58,14 +48,6 @@ describe('copyMaterial', () => {
|
|
|
58
48
|
copyMaterial(material, material);
|
|
59
49
|
expect(material.metallic).toBe(0.5);
|
|
60
50
|
});
|
|
61
|
-
it('deep-copies the colorTransform sub-entity', () => {
|
|
62
|
-
const ct = createColorTransform({ redMultiplier: 0.4 });
|
|
63
|
-
const source = createUniformColorTransformMaterial(ct);
|
|
64
|
-
const out = createUniformColorTransformMaterial();
|
|
65
|
-
copyMaterial(out, source);
|
|
66
|
-
expect(out.colorTransform).not.toBe(source.colorTransform);
|
|
67
|
-
expect(out.colorTransform.redMultiplier).toBe(0.4);
|
|
68
|
-
});
|
|
69
51
|
});
|
|
70
52
|
|
|
71
53
|
describe('createMaterial', () => {
|
|
@@ -73,6 +55,10 @@ describe('createMaterial', () => {
|
|
|
73
55
|
const material = createMaterial(TestMaterialKind);
|
|
74
56
|
expect(material.kind).toBe(TestMaterialKind);
|
|
75
57
|
});
|
|
58
|
+
|
|
59
|
+
it('defaults the authored name to null', () => {
|
|
60
|
+
expect(createMaterial(TestMaterialKind).name).toBeNull();
|
|
61
|
+
});
|
|
76
62
|
});
|
|
77
63
|
|
|
78
64
|
describe('equalsMaterial', () => {
|
|
@@ -82,16 +68,7 @@ describe('equalsMaterial', () => {
|
|
|
82
68
|
});
|
|
83
69
|
|
|
84
70
|
it('is false for different kinds', () => {
|
|
85
|
-
expect(equalsMaterial(
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('compares the color transform of uniform color transform materials', () => {
|
|
89
|
-
const a = createUniformColorTransformMaterial(createColorTransform({ redMultiplier: 0.5 }));
|
|
90
|
-
const b = createUniformColorTransformMaterial(createColorTransform({ redMultiplier: 0.5 }));
|
|
91
|
-
const c = createUniformColorTransformMaterial(createColorTransform({ redMultiplier: 0.25 }));
|
|
92
|
-
expect(a.kind).toBe(UniformColorTransformMaterialKind);
|
|
93
|
-
expect(equalsMaterial(a, b)).toBe(true);
|
|
94
|
-
expect(equalsMaterial(a, c)).toBe(false);
|
|
71
|
+
expect(equalsMaterial(createMaterial(TestMaterialKind), createMaterial(OtherMaterialKind))).toBe(false);
|
|
95
72
|
});
|
|
96
73
|
|
|
97
74
|
it('compares scalar fields of standard PBR materials structurally', () => {
|
|
@@ -104,7 +81,6 @@ describe('equalsMaterial', () => {
|
|
|
104
81
|
});
|
|
105
82
|
|
|
106
83
|
it('treats same-kind materials without comparable fields as equal', () => {
|
|
107
|
-
expect(equalsMaterial(
|
|
108
|
-
expect(createColorTransformMaterial().kind).toBe(ColorTransformMaterialKind);
|
|
84
|
+
expect(equalsMaterial(createMaterial(TestMaterialKind), createMaterial(TestMaterialKind))).toBe(true);
|
|
109
85
|
});
|
|
110
86
|
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { StandardPbrMaterialKind } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { createPhongMaterial } from './classicMaterials';
|
|
4
|
+
import {
|
|
5
|
+
convertPhongToStandardPbrMaterial,
|
|
6
|
+
getPbrMetallicFromPhongSpecular,
|
|
7
|
+
getPbrRoughnessFromPhongShininess,
|
|
8
|
+
getPhongToPbrLightExposure,
|
|
9
|
+
} from './phongToPbr';
|
|
10
|
+
|
|
11
|
+
describe('convertPhongToStandardPbrMaterial', () => {
|
|
12
|
+
it('maps a neutral Phong material to a plausible PBR material', () => {
|
|
13
|
+
const phong = createPhongMaterial();
|
|
14
|
+
const pbr = convertPhongToStandardPbrMaterial(phong);
|
|
15
|
+
expect(pbr.kind).toBe(StandardPbrMaterialKind);
|
|
16
|
+
// Diffuse and baseColor share the packed sRgb-albedo encoding — color transfers unchanged.
|
|
17
|
+
expect(pbr.baseColor).toBe(phong.diffuse);
|
|
18
|
+
expect(pbr.roughness).toBeGreaterThan(0);
|
|
19
|
+
expect(pbr.roughness).toBeLessThan(1);
|
|
20
|
+
// A white specular over a white diffuse is a dielectric, not a metal.
|
|
21
|
+
expect(pbr.metallic).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
it('preserves the normal map and scale', () => {
|
|
24
|
+
const phong = createPhongMaterial({ normalScale: 0.5 });
|
|
25
|
+
const pbr = convertPhongToStandardPbrMaterial(phong);
|
|
26
|
+
expect(pbr.normalScale).toBe(0.5);
|
|
27
|
+
expect(pbr.normalMap).toBe(phong.normalMap);
|
|
28
|
+
});
|
|
29
|
+
it('lets opts override a mapped field', () => {
|
|
30
|
+
const phong = createPhongMaterial();
|
|
31
|
+
const pbr = convertPhongToStandardPbrMaterial(phong, { metallic: 1, roughness: 0.2 });
|
|
32
|
+
expect(pbr.metallic).toBe(1);
|
|
33
|
+
expect(pbr.roughness).toBe(0.2);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('getPbrMetallicFromPhongSpecular', () => {
|
|
38
|
+
it('reads a bright specular over a near-black diffuse as metallic', () => {
|
|
39
|
+
expect(getPbrMetallicFromPhongSpecular(0xffffffff, 0x000000ff)).toBe(1);
|
|
40
|
+
});
|
|
41
|
+
it('reads a white specular over a lit diffuse as dielectric', () => {
|
|
42
|
+
expect(getPbrMetallicFromPhongSpecular(0xffffffff, 0xffffffff)).toBe(0);
|
|
43
|
+
expect(getPbrMetallicFromPhongSpecular(0x808080ff, 0x333333ff)).toBe(0);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('getPbrRoughnessFromPhongShininess', () => {
|
|
48
|
+
it('maps the Phong default shininess of 32 to roughness ≈ 0.243', () => {
|
|
49
|
+
expect(getPbrRoughnessFromPhongShininess(32)).toBeCloseTo(0.2425, 3);
|
|
50
|
+
});
|
|
51
|
+
it('is monotonic decreasing in shininess', () => {
|
|
52
|
+
expect(getPbrRoughnessFromPhongShininess(2)).toBeGreaterThan(getPbrRoughnessFromPhongShininess(200));
|
|
53
|
+
});
|
|
54
|
+
it('clamps to [0, 1] and handles the degenerate shininess of 0', () => {
|
|
55
|
+
const r = getPbrRoughnessFromPhongShininess(0);
|
|
56
|
+
expect(r).toBeLessThanOrEqual(1);
|
|
57
|
+
expect(r).toBeGreaterThanOrEqual(0);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('getPhongToPbrLightExposure', () => {
|
|
62
|
+
it('returns log2(π) — a ×π light scale that offsets the Lambert 1/π diffuse normalization', () => {
|
|
63
|
+
expect(getPhongToPbrLightExposure()).toBeCloseTo(Math.log2(Math.PI), 10);
|
|
64
|
+
// Applying the exposure multiplies intensity by ≈π (≈3.14) — the anti-too-dark factor.
|
|
65
|
+
expect(2 ** getPhongToPbrLightExposure()).toBeCloseTo(Math.PI, 10);
|
|
66
|
+
});
|
|
67
|
+
});
|