@babylonjs/serializers 8.33.3 → 8.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/glTF/2.0/Extensions/EXT_lights_area.d.ts +39 -0
- package/glTF/2.0/Extensions/EXT_lights_area.js +133 -0
- package/glTF/2.0/Extensions/EXT_lights_area.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +21 -100
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat_anisotropy.js +21 -100
- package/glTF/2.0/Extensions/KHR_materials_clearcoat_anisotropy.js.map +1 -1
- package/glTF/2.0/Extensions/index.d.ts +1 -0
- package/glTF/2.0/Extensions/index.js +1 -0
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/glTFAnimation.js +2 -2
- package/glTF/2.0/glTFAnimation.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.d.ts +2 -2
- package/glTF/2.0/glTFMaterialExporter.js +85 -14
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/glTF/2.0/glTFUtilities.d.ts +2 -1
- package/glTF/2.0/glTFUtilities.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Nullable } from "@babylonjs/core/types.js";
|
|
2
|
+
import type { Node } from "@babylonjs/core/node.js";
|
|
3
|
+
import type { INode } from "babylonjs-gltf2interface";
|
|
4
|
+
import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension.js";
|
|
5
|
+
import { GLTFExporter } from "../glTFExporter.js";
|
|
6
|
+
/**
|
|
7
|
+
* [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/EXT_lights_area/README.md)
|
|
8
|
+
*/
|
|
9
|
+
export declare class EXT_lights_area implements IGLTFExporterExtensionV2 {
|
|
10
|
+
/** The name of this extension. */
|
|
11
|
+
readonly name = "EXT_lights_area";
|
|
12
|
+
/** Defines whether this extension is enabled. */
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
/** Defines whether this extension is required */
|
|
15
|
+
required: boolean;
|
|
16
|
+
/** Reference to the glTF exporter */
|
|
17
|
+
private _exporter;
|
|
18
|
+
private _lights;
|
|
19
|
+
/**
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
constructor(exporter: GLTFExporter);
|
|
23
|
+
/** @internal */
|
|
24
|
+
dispose(): void;
|
|
25
|
+
/** @internal */
|
|
26
|
+
get wasUsed(): boolean;
|
|
27
|
+
/** @internal */
|
|
28
|
+
onExporting(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Define this method to modify the default behavior when exporting a node
|
|
31
|
+
* @param context The context when exporting the node
|
|
32
|
+
* @param node glTF node
|
|
33
|
+
* @param babylonNode BabylonJS node
|
|
34
|
+
* @param nodeMap Node mapping of babylon node to glTF node index
|
|
35
|
+
* @param convertToRightHanded Flag to convert the values to right-handed
|
|
36
|
+
* @returns nullable INode promise
|
|
37
|
+
*/
|
|
38
|
+
postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Vector3, Quaternion, TmpVectors } from "@babylonjs/core/Maths/math.vector.js";
|
|
2
|
+
import { Light } from "@babylonjs/core/Lights/light.js";
|
|
3
|
+
import { GLTFExporter } from "../glTFExporter.js";
|
|
4
|
+
import { Logger } from "@babylonjs/core/Misc/logger.js";
|
|
5
|
+
import { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from "../glTFUtilities.js";
|
|
6
|
+
const NAME = "EXT_lights_area";
|
|
7
|
+
const DEFAULTS = {
|
|
8
|
+
name: "",
|
|
9
|
+
color: [1, 1, 1],
|
|
10
|
+
intensity: 1,
|
|
11
|
+
size: 1,
|
|
12
|
+
};
|
|
13
|
+
const RECTDEFAULTS = {
|
|
14
|
+
aspect: 1,
|
|
15
|
+
};
|
|
16
|
+
const LIGHTDIRECTION = Vector3.Backward();
|
|
17
|
+
/**
|
|
18
|
+
* [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/EXT_lights_area/README.md)
|
|
19
|
+
*/
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
21
|
+
export class EXT_lights_area {
|
|
22
|
+
/**
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
constructor(exporter) {
|
|
26
|
+
/** The name of this extension. */
|
|
27
|
+
this.name = NAME;
|
|
28
|
+
/** Defines whether this extension is enabled. */
|
|
29
|
+
this.enabled = true;
|
|
30
|
+
/** Defines whether this extension is required */
|
|
31
|
+
this.required = false;
|
|
32
|
+
this._exporter = exporter;
|
|
33
|
+
}
|
|
34
|
+
/** @internal */
|
|
35
|
+
dispose() {
|
|
36
|
+
this._lights = null;
|
|
37
|
+
}
|
|
38
|
+
/** @internal */
|
|
39
|
+
get wasUsed() {
|
|
40
|
+
return !!this._lights;
|
|
41
|
+
}
|
|
42
|
+
/** @internal */
|
|
43
|
+
onExporting() {
|
|
44
|
+
this._exporter._glTF.extensions[NAME] = this._lights;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Define this method to modify the default behavior when exporting a node
|
|
48
|
+
* @param context The context when exporting the node
|
|
49
|
+
* @param node glTF node
|
|
50
|
+
* @param babylonNode BabylonJS node
|
|
51
|
+
* @param nodeMap Node mapping of babylon node to glTF node index
|
|
52
|
+
* @param convertToRightHanded Flag to convert the values to right-handed
|
|
53
|
+
* @returns nullable INode promise
|
|
54
|
+
*/
|
|
55
|
+
async postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded) {
|
|
56
|
+
return await new Promise((resolve) => {
|
|
57
|
+
if (!(babylonNode instanceof Light)) {
|
|
58
|
+
resolve(node);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const lightType = babylonNode.getTypeID() == Light.LIGHTTYPEID_RECT_AREALIGHT ? "rect" /* EXTLightsArea_LightType.RECT */ : null;
|
|
62
|
+
if (!lightType) {
|
|
63
|
+
Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);
|
|
64
|
+
resolve(node);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const areaLight = babylonNode;
|
|
68
|
+
if (areaLight.falloffType !== Light.FALLOFF_GLTF) {
|
|
69
|
+
Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);
|
|
70
|
+
}
|
|
71
|
+
// Set the node's translation and rotation here, since lights are not handled in exportNodeAsync
|
|
72
|
+
if (!areaLight.position.equalsToFloats(0, 0, 0)) {
|
|
73
|
+
const translation = TmpVectors.Vector3[0].copyFrom(areaLight.position);
|
|
74
|
+
if (convertToRightHanded) {
|
|
75
|
+
ConvertToRightHandedPosition(translation);
|
|
76
|
+
}
|
|
77
|
+
node.translation = translation.asArray();
|
|
78
|
+
}
|
|
79
|
+
// Represent the Babylon light's direction as a quaternion
|
|
80
|
+
// relative to glTF lights' forward direction, (0, 0, -1).
|
|
81
|
+
const direction = Vector3.Forward();
|
|
82
|
+
if (convertToRightHanded) {
|
|
83
|
+
ConvertToRightHandedPosition(direction);
|
|
84
|
+
}
|
|
85
|
+
const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);
|
|
86
|
+
if (!Quaternion.IsIdentity(lightRotationQuaternion)) {
|
|
87
|
+
node.rotation = lightRotationQuaternion.asArray();
|
|
88
|
+
}
|
|
89
|
+
const light = {
|
|
90
|
+
type: lightType,
|
|
91
|
+
name: areaLight.name,
|
|
92
|
+
color: areaLight.diffuse.asArray(),
|
|
93
|
+
intensity: areaLight.intensity,
|
|
94
|
+
size: areaLight.height,
|
|
95
|
+
rect: {
|
|
96
|
+
aspect: areaLight.width / areaLight.height,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
OmitDefaultValues(light, DEFAULTS);
|
|
100
|
+
if (light.rect) {
|
|
101
|
+
OmitDefaultValues(light.rect, RECTDEFAULTS);
|
|
102
|
+
}
|
|
103
|
+
this._lights || (this._lights = {
|
|
104
|
+
lights: [],
|
|
105
|
+
});
|
|
106
|
+
this._lights.lights.push(light);
|
|
107
|
+
const lightReference = {
|
|
108
|
+
light: this._lights.lights.length - 1,
|
|
109
|
+
};
|
|
110
|
+
// Assign the light to its parent node, if possible, to condense the glTF
|
|
111
|
+
// Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export
|
|
112
|
+
const parentBabylonNode = babylonNode.parent;
|
|
113
|
+
if (parentBabylonNode && IsChildCollapsible(areaLight, parentBabylonNode)) {
|
|
114
|
+
const parentNodeIndex = nodeMap.get(parentBabylonNode);
|
|
115
|
+
if (parentNodeIndex) {
|
|
116
|
+
// Combine the light's transformation with the parent's
|
|
117
|
+
const parentNode = this._exporter._nodes[parentNodeIndex];
|
|
118
|
+
CollapseChildIntoParent(node, parentNode);
|
|
119
|
+
parentNode.extensions || (parentNode.extensions = {});
|
|
120
|
+
parentNode.extensions[NAME] = lightReference;
|
|
121
|
+
// Do not export the original node
|
|
122
|
+
resolve(null);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
node.extensions || (node.extensions = {});
|
|
127
|
+
node.extensions[NAME] = lightReference;
|
|
128
|
+
resolve(node);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
GLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_lights_area(exporter));
|
|
133
|
+
//# sourceMappingURL=EXT_lights_area.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EXT_lights_area.js","sourceRoot":"","sources":["../../../../../../dev/serializers/src/glTF/2.0/Extensions/EXT_lights_area.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport type { INode, IEXTLightsArea_LightReference, IEXTLightsArea_Light, IEXTLightsArea } from \"babylonjs-gltf2interface\";\r\nimport { EXTLightsArea_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from \"../glTFUtilities\";\r\nimport type { RectAreaLight } from \"core/Lights/rectAreaLight\";\r\n\r\nconst NAME = \"EXT_lights_area\";\r\nconst DEFAULTS: Omit<IEXTLightsArea_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n size: 1,\r\n};\r\nconst RECTDEFAULTS: NonNullable<IEXTLightsArea_Light[\"rect\"]> = {\r\n aspect: 1,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/EXT_lights_area/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_lights_area implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IEXTLightsArea;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof Light)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType = babylonNode.getTypeID() == Light.LIGHTTYPEID_RECT_AREALIGHT ? EXTLightsArea_LightType.RECT : null;\r\n if (!lightType) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const areaLight = babylonNode as RectAreaLight;\r\n\r\n if (areaLight.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!areaLight.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(areaLight.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Represent the Babylon light's direction as a quaternion\r\n // relative to glTF lights' forward direction, (0, 0, -1).\r\n const direction = Vector3.Forward();\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n\r\n const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n\r\n const light: IEXTLightsArea_Light = {\r\n type: lightType,\r\n name: areaLight.name,\r\n color: areaLight.diffuse.asArray(),\r\n intensity: areaLight.intensity,\r\n size: areaLight.height,\r\n rect: {\r\n aspect: areaLight.width / areaLight.height,\r\n },\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n if (light.rect) {\r\n OmitDefaultValues(light.rect, RECTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IEXTLightsArea_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsChildCollapsible(areaLight, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_lights_area(exporter));\r\n"]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { GLTFExporter } from "../glTFExporter.js";
|
|
2
2
|
import { PBRBaseMaterial } from "@babylonjs/core/Materials/PBR/pbrBaseMaterial.js";
|
|
3
3
|
import { OpenPBRMaterial } from "@babylonjs/core/Materials/PBR/openpbrMaterial.js";
|
|
4
|
-
import {
|
|
5
|
-
import { Effect } from "@babylonjs/core/Materials/effect.js";
|
|
6
|
-
import { ProceduralTexture } from "@babylonjs/core/Materials/Textures/Procedurals/proceduralTexture.js";
|
|
4
|
+
import { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from "@babylonjs/core/Materials/Textures/textureMerger.js";
|
|
7
5
|
const NAME = "KHR_materials_anisotropy";
|
|
8
6
|
// Convert OpenPBR anisotropy values to glTF-compatible values
|
|
9
7
|
function OpenpbrAnisotropyStrengthToGltf(baseRoughness, anisotropy) {
|
|
@@ -14,109 +12,26 @@ function OpenpbrAnisotropyStrengthToGltf(baseRoughness, anisotropy) {
|
|
|
14
12
|
const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);
|
|
15
13
|
return { newBaseRoughness, newAnisotropyStrength };
|
|
16
14
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
destination.vAng = source.vAng;
|
|
24
|
-
destination.wAng = source.wAng;
|
|
25
|
-
destination.uRotationCenter = source.uRotationCenter;
|
|
26
|
-
destination.vRotationCenter = source.vRotationCenter;
|
|
15
|
+
function GetAnisoTextureId(babylonMaterial) {
|
|
16
|
+
const anisoStrengthTexture = babylonMaterial.specularRoughnessAnisotropyTexture;
|
|
17
|
+
const tangentTexture = babylonMaterial.geometryTangentTexture;
|
|
18
|
+
const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture.getInternalTexture().uniqueId : "NoStrength";
|
|
19
|
+
const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture.getInternalTexture().uniqueId : "NoTangent";
|
|
20
|
+
return `${strengthId}_${tangentId}`;
|
|
27
21
|
}
|
|
28
|
-
// Custom shader for merging anisotropy into tangent texture
|
|
29
|
-
const AnisotropyMergeFragment = `
|
|
30
|
-
precision highp float;
|
|
31
|
-
#ifdef HAS_TANGENT_TEXTURE
|
|
32
|
-
uniform sampler2D tangentTexture;
|
|
33
|
-
#endif
|
|
34
|
-
#ifdef HAS_ANISOTROPY_TEXTURE
|
|
35
|
-
uniform sampler2D anisotropyTexture;
|
|
36
|
-
#endif
|
|
37
|
-
uniform int useRoughnessFromMetallicGreen;
|
|
38
|
-
uniform int useAnisotropyFromTangentBlue;
|
|
39
|
-
|
|
40
|
-
varying vec2 vUV;
|
|
41
|
-
|
|
42
|
-
void main() {
|
|
43
|
-
vec2 tangent = vec2(1.0, 0.0);
|
|
44
|
-
float anisotropy = 1.0;
|
|
45
|
-
#ifdef HAS_TANGENT_TEXTURE
|
|
46
|
-
// Tangent texture is present
|
|
47
|
-
vec4 tangentSample = texture2D(tangentTexture, vUV);
|
|
48
|
-
tangent = tangentSample.rg;
|
|
49
|
-
|
|
50
|
-
if (useAnisotropyFromTangentBlue > 0) {
|
|
51
|
-
anisotropy = tangentSample.b;
|
|
52
|
-
}
|
|
53
|
-
#endif
|
|
54
|
-
#ifdef HAS_ANISOTROPY_TEXTURE
|
|
55
|
-
// Anisotropy texture is present
|
|
56
|
-
vec4 anisotropySample = texture2D(anisotropyTexture, vUV);
|
|
57
|
-
anisotropy = anisotropySample.r;
|
|
58
|
-
#endif
|
|
59
|
-
|
|
60
|
-
// Output: RG = tangent XY, B = anisotropy strength
|
|
61
|
-
vec4 anisotropyData = vec4(tangent.x, tangent.y, anisotropy, 1.0);
|
|
62
|
-
gl_FragColor = anisotropyData;
|
|
63
|
-
}
|
|
64
|
-
`;
|
|
65
22
|
// In your postExportMaterialAsync method:
|
|
66
23
|
async function CreateMergedAnisotropyTexture(babylonMaterial) {
|
|
67
24
|
const scene = babylonMaterial.getScene();
|
|
68
|
-
// Register the custom shader if not already done
|
|
69
|
-
if (!Effect.ShadersStore["anisotropyMergeFragmentShader"]) {
|
|
70
|
-
Effect.ShadersStore["anisotropyMergeFragmentShader"] = AnisotropyMergeFragment;
|
|
71
|
-
}
|
|
72
25
|
const anisoStrengthTexture = babylonMaterial.specularRoughnessAnisotropyTexture;
|
|
73
26
|
const tangentTexture = babylonMaterial.geometryTangentTexture;
|
|
74
27
|
// If we don't have any textures, we don't need to generate anything.
|
|
75
28
|
if (!(anisoStrengthTexture || tangentTexture)) {
|
|
76
29
|
return null;
|
|
77
30
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
format: Constants.TEXTUREFORMAT_RGBA,
|
|
83
|
-
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
|
|
84
|
-
generateDepthBuffer: false,
|
|
85
|
-
generateStencilBuffer: false,
|
|
86
|
-
generateMipMaps: false,
|
|
87
|
-
};
|
|
88
|
-
const rtTexture = new ProceduralTexture(babylonMaterial.name + "_anisotropy", {
|
|
89
|
-
width,
|
|
90
|
-
height,
|
|
91
|
-
}, "anisotropyMerge", scene, textureOptions);
|
|
92
|
-
rtTexture.refreshRate = -1;
|
|
93
|
-
// Set uniforms and defines
|
|
94
|
-
let defines = "";
|
|
95
|
-
if (tangentTexture) {
|
|
96
|
-
defines += "#define HAS_TANGENT_TEXTURE\n";
|
|
97
|
-
rtTexture.setTexture("tangentTexture", tangentTexture);
|
|
98
|
-
CopyTextureTransform(tangentTexture, rtTexture);
|
|
99
|
-
}
|
|
100
|
-
rtTexture.setVector2("tangentVector", babylonMaterial.geometryTangent);
|
|
101
|
-
if (anisoStrengthTexture) {
|
|
102
|
-
defines += "#define HAS_ANISOTROPY_TEXTURE\n";
|
|
103
|
-
rtTexture.setTexture("anisotropyTexture", anisoStrengthTexture);
|
|
104
|
-
CopyTextureTransform(anisoStrengthTexture, rtTexture);
|
|
105
|
-
}
|
|
106
|
-
rtTexture.setInt("useAnisotropyFromTangentBlue", babylonMaterial._useSpecularRoughnessAnisotropyFromTangentTexture ? 1 : 0);
|
|
107
|
-
rtTexture.defines = defines;
|
|
108
|
-
return await new Promise((resolve, reject) => {
|
|
109
|
-
// Compile and render
|
|
110
|
-
rtTexture.executeWhenReady(() => {
|
|
111
|
-
try {
|
|
112
|
-
rtTexture.render();
|
|
113
|
-
resolve(rtTexture);
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
});
|
|
31
|
+
return await MergeTexturesAsync("AnisotropyTexture", CreateRGBAConfiguration(tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel
|
|
32
|
+
tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel
|
|
33
|
+
anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel
|
|
34
|
+
), scene);
|
|
120
35
|
}
|
|
121
36
|
/**
|
|
122
37
|
* @internal
|
|
@@ -158,10 +73,16 @@ export class KHR_materials_anisotropy {
|
|
|
158
73
|
}
|
|
159
74
|
else if (babylonMaterial instanceof OpenPBRMaterial) {
|
|
160
75
|
if (babylonMaterial.specularRoughnessAnisotropy > 0) {
|
|
161
|
-
const
|
|
162
|
-
if (
|
|
163
|
-
additionalTextures.push(
|
|
164
|
-
|
|
76
|
+
const texId = GetAnisoTextureId(babylonMaterial);
|
|
77
|
+
if (this._anisoTexturesMap[texId]) {
|
|
78
|
+
additionalTextures.push(this._anisoTexturesMap[texId]);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);
|
|
82
|
+
if (anisoTexture) {
|
|
83
|
+
additionalTextures.push(anisoTexture);
|
|
84
|
+
this._anisoTexturesMap[texId] = anisoTexture;
|
|
85
|
+
}
|
|
165
86
|
}
|
|
166
87
|
return additionalTextures;
|
|
167
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KHR_materials_anisotropy.js","sourceRoot":"","sources":["../../../../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Effect } from \"core/Materials/effect\";\r\nimport { ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport type { IProceduralTextureCreationOptions } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\nfunction CopyTextureTransform(source: Texture, destination: Texture) {\r\n destination.uOffset = source.uOffset;\r\n destination.vOffset = source.vOffset;\r\n destination.uScale = source.uScale;\r\n destination.vScale = source.vScale;\r\n destination.uAng = source.uAng;\r\n destination.vAng = source.vAng;\r\n destination.wAng = source.wAng;\r\n destination.uRotationCenter = source.uRotationCenter;\r\n destination.vRotationCenter = source.vRotationCenter;\r\n}\r\n\r\n// Custom shader for merging anisotropy into tangent texture\r\nconst AnisotropyMergeFragment = `\r\n precision highp float;\r\n#ifdef HAS_TANGENT_TEXTURE\r\n uniform sampler2D tangentTexture;\r\n#endif\r\n#ifdef HAS_ANISOTROPY_TEXTURE\r\n uniform sampler2D anisotropyTexture;\r\n#endif\r\n uniform int useRoughnessFromMetallicGreen;\r\n uniform int useAnisotropyFromTangentBlue;\r\n\r\n varying vec2 vUV;\r\n\r\n void main() {\r\n vec2 tangent = vec2(1.0, 0.0);\r\n float anisotropy = 1.0;\r\n #ifdef HAS_TANGENT_TEXTURE\r\n // Tangent texture is present\r\n vec4 tangentSample = texture2D(tangentTexture, vUV);\r\n tangent = tangentSample.rg;\r\n\r\n if (useAnisotropyFromTangentBlue > 0) {\r\n anisotropy = tangentSample.b;\r\n }\r\n #endif\r\n #ifdef HAS_ANISOTROPY_TEXTURE\r\n // Anisotropy texture is present\r\n vec4 anisotropySample = texture2D(anisotropyTexture, vUV);\r\n anisotropy = anisotropySample.r;\r\n #endif\r\n \r\n // Output: RG = tangent XY, B = anisotropy strength\r\n vec4 anisotropyData = vec4(tangent.x, tangent.y, anisotropy, 1.0);\r\n gl_FragColor = anisotropyData;\r\n }\r\n`;\r\n\r\n// In your postExportMaterialAsync method:\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<ProceduralTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n // Register the custom shader if not already done\r\n if (!Effect.ShadersStore[\"anisotropyMergeFragmentShader\"]) {\r\n Effect.ShadersStore[\"anisotropyMergeFragmentShader\"] = AnisotropyMergeFragment;\r\n }\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n const width = Math.max(anisoStrengthTexture ? anisoStrengthTexture.getSize().width : 1, tangentTexture ? tangentTexture.getSize().width : 1);\r\n const height = Math.max(anisoStrengthTexture ? anisoStrengthTexture.getSize().height : 1, tangentTexture ? tangentTexture.getSize().height : 1);\r\n const textureOptions: IProceduralTextureCreationOptions = {\r\n type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n format: Constants.TEXTUREFORMAT_RGBA,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n generateStencilBuffer: false,\r\n generateMipMaps: false,\r\n };\r\n const rtTexture = new ProceduralTexture(\r\n babylonMaterial.name + \"_anisotropy\",\r\n {\r\n width,\r\n height,\r\n },\r\n \"anisotropyMerge\",\r\n scene,\r\n textureOptions\r\n );\r\n rtTexture.refreshRate = -1;\r\n\r\n // Set uniforms and defines\r\n let defines = \"\";\r\n if (tangentTexture) {\r\n defines += \"#define HAS_TANGENT_TEXTURE\\n\";\r\n rtTexture.setTexture(\"tangentTexture\", tangentTexture);\r\n CopyTextureTransform(tangentTexture as Texture, rtTexture);\r\n }\r\n rtTexture.setVector2(\"tangentVector\", babylonMaterial.geometryTangent);\r\n if (anisoStrengthTexture) {\r\n defines += \"#define HAS_ANISOTROPY_TEXTURE\\n\";\r\n rtTexture.setTexture(\"anisotropyTexture\", anisoStrengthTexture);\r\n CopyTextureTransform(anisoStrengthTexture as Texture, rtTexture);\r\n }\r\n rtTexture.setInt(\"useAnisotropyFromTangentBlue\", babylonMaterial._useSpecularRoughnessAnisotropyFromTangentTexture ? 1 : 0);\r\n rtTexture.defines = defines;\r\n\r\n return await new Promise<ProceduralTexture>((resolve, reject) => {\r\n // Compile and render\r\n rtTexture.executeWhenReady(() => {\r\n try {\r\n rtTexture.render();\r\n resolve(rtTexture);\r\n } catch (error) {\r\n reject(error instanceof Error ? error : new Error(String(error)));\r\n }\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n private _anisoTexturesMap: Record<string, ProceduralTexture> = {};\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._anisoTexturesMap[babylonMaterial.id] = anisoTexture;\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n let roughnessTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessTexture;\r\n if (babylonMaterial._useRoughnessFromMetallicTextureGreen) {\r\n roughnessTexture = babylonMaterial.baseMetalnessTexture;\r\n }\r\n const mergedAnisoTexture = this._anisoTexturesMap[babylonMaterial.id];\r\n\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.specularRoughness;\r\n let newAnisotropyStrength = babylonMaterial.specularRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.specularRoughness, babylonMaterial.specularRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: newAnisotropyStrength,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle + Math.PI * 0.5,\r\n anisotropyTexture: undefined,\r\n };\r\n node.extensions[NAME] = anisotropyInfo;\r\n return resolve(node);\r\n }\r\n\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.specularRoughnessAnisotropy,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle,\r\n anisotropyTexture: mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined,\r\n extensions: {},\r\n };\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n anisotropyInfo.extensions![\"EXT_materials_anisotropy_openpbr\"] = {\r\n openPbrAnisotropyEnabled: true,\r\n };\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"EXT_materials_anisotropy_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"EXT_materials_anisotropy_openpbr\");\r\n }\r\n }\r\n\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n"]}
|
|
1
|
+
{"version":3,"file":"KHR_materials_anisotropy.js","sourceRoot":"","sources":["../../../../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\nfunction GetAnisoTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture!.getInternalTexture()!.uniqueId : \"NoStrength\";\r\n const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture!.getInternalTexture()!.uniqueId : \"NoTangent\";\r\n return `${strengthId}_${tangentId}`;\r\n}\r\n\r\n// In your postExportMaterialAsync method:\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<ProceduralTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n return await MergeTexturesAsync(\r\n \"AnisotropyTexture\",\r\n CreateRGBAConfiguration(\r\n tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel\r\n tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel\r\n anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel\r\n ),\r\n scene\r\n );\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n private _anisoTexturesMap: Record<string, ProceduralTexture> = {};\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n if (this._anisoTexturesMap[texId]) {\r\n additionalTextures.push(this._anisoTexturesMap[texId]);\r\n } else {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._anisoTexturesMap[texId] = anisoTexture;\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n let roughnessTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessTexture;\r\n if (babylonMaterial._useRoughnessFromMetallicTextureGreen) {\r\n roughnessTexture = babylonMaterial.baseMetalnessTexture;\r\n }\r\n const mergedAnisoTexture = this._anisoTexturesMap[babylonMaterial.id];\r\n\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.specularRoughness;\r\n let newAnisotropyStrength = babylonMaterial.specularRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.specularRoughness, babylonMaterial.specularRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: newAnisotropyStrength,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle + Math.PI * 0.5,\r\n anisotropyTexture: undefined,\r\n };\r\n node.extensions[NAME] = anisotropyInfo;\r\n return resolve(node);\r\n }\r\n\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.specularRoughnessAnisotropy,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle,\r\n anisotropyTexture: mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined,\r\n extensions: {},\r\n };\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n anisotropyInfo.extensions![\"EXT_materials_anisotropy_openpbr\"] = {\r\n openPbrAnisotropyEnabled: true,\r\n };\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"EXT_materials_anisotropy_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"EXT_materials_anisotropy_openpbr\");\r\n }\r\n }\r\n\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n"]}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { GLTFExporter } from "../glTFExporter.js";
|
|
2
2
|
import { OpenPBRMaterial } from "@babylonjs/core/Materials/PBR/openpbrMaterial.js";
|
|
3
|
-
import {
|
|
4
|
-
import { Effect } from "@babylonjs/core/Materials/effect.js";
|
|
5
|
-
import { ProceduralTexture } from "@babylonjs/core/Materials/Textures/Procedurals/proceduralTexture.js";
|
|
3
|
+
import { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from "@babylonjs/core/Materials/Textures/textureMerger.js";
|
|
6
4
|
const NAME = "KHR_materials_clearcoat_anisotropy";
|
|
7
5
|
// Convert OpenPBR anisotropy values to glTF-compatible values
|
|
8
6
|
function OpenpbrAnisotropyStrengthToGltf(baseRoughness, anisotropy) {
|
|
@@ -13,109 +11,26 @@ function OpenpbrAnisotropyStrengthToGltf(baseRoughness, anisotropy) {
|
|
|
13
11
|
const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);
|
|
14
12
|
return { newBaseRoughness, newAnisotropyStrength };
|
|
15
13
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
destination.vAng = source.vAng;
|
|
23
|
-
destination.wAng = source.wAng;
|
|
24
|
-
destination.uRotationCenter = source.uRotationCenter;
|
|
25
|
-
destination.vRotationCenter = source.vRotationCenter;
|
|
14
|
+
function GetAnisoTextureId(babylonMaterial) {
|
|
15
|
+
const anisoStrengthTexture = babylonMaterial.coatRoughnessAnisotropyTexture;
|
|
16
|
+
const tangentTexture = babylonMaterial.geometryCoatTangentTexture;
|
|
17
|
+
const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture.getInternalTexture().uniqueId : "NoStrength";
|
|
18
|
+
const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture.getInternalTexture().uniqueId : "NoTangent";
|
|
19
|
+
return `${strengthId}_${tangentId}`;
|
|
26
20
|
}
|
|
27
|
-
// Custom shader for merging anisotropy into tangent texture
|
|
28
|
-
const AnisotropyMergeFragment = `
|
|
29
|
-
precision highp float;
|
|
30
|
-
#ifdef HAS_TANGENT_TEXTURE
|
|
31
|
-
uniform sampler2D tangentTexture;
|
|
32
|
-
#endif
|
|
33
|
-
#ifdef HAS_ANISOTROPY_TEXTURE
|
|
34
|
-
uniform sampler2D anisotropyTexture;
|
|
35
|
-
#endif
|
|
36
|
-
uniform int useRoughnessFromMetallicGreen;
|
|
37
|
-
uniform int useAnisotropyFromTangentBlue;
|
|
38
|
-
|
|
39
|
-
varying vec2 vUV;
|
|
40
|
-
|
|
41
|
-
void main() {
|
|
42
|
-
vec2 tangent = vec2(1.0, 0.0);
|
|
43
|
-
float anisotropy = 1.0;
|
|
44
|
-
#ifdef HAS_TANGENT_TEXTURE
|
|
45
|
-
// Tangent texture is present
|
|
46
|
-
vec4 tangentSample = texture2D(tangentTexture, vUV);
|
|
47
|
-
tangent = tangentSample.rg;
|
|
48
|
-
|
|
49
|
-
if (useAnisotropyFromTangentBlue > 0) {
|
|
50
|
-
anisotropy = tangentSample.b;
|
|
51
|
-
}
|
|
52
|
-
#endif
|
|
53
|
-
#ifdef HAS_ANISOTROPY_TEXTURE
|
|
54
|
-
// Anisotropy texture is present
|
|
55
|
-
vec4 anisotropySample = texture2D(anisotropyTexture, vUV);
|
|
56
|
-
anisotropy = anisotropySample.r;
|
|
57
|
-
#endif
|
|
58
|
-
|
|
59
|
-
// Output: RG = tangent XY, B = anisotropy strength
|
|
60
|
-
vec4 anisotropyData = vec4(tangent.x, tangent.y, anisotropy, 1.0);
|
|
61
|
-
gl_FragColor = anisotropyData;
|
|
62
|
-
}
|
|
63
|
-
`;
|
|
64
21
|
// In your postExportMaterialAsync method:
|
|
65
22
|
async function CreateMergedAnisotropyTexture(babylonMaterial) {
|
|
66
23
|
const scene = babylonMaterial.getScene();
|
|
67
|
-
// Register the custom shader if not already done
|
|
68
|
-
if (!Effect.ShadersStore["anisotropyMergeFragmentShader"]) {
|
|
69
|
-
Effect.ShadersStore["anisotropyMergeFragmentShader"] = AnisotropyMergeFragment;
|
|
70
|
-
}
|
|
71
24
|
const anisoStrengthTexture = babylonMaterial.coatRoughnessAnisotropyTexture;
|
|
72
25
|
const tangentTexture = babylonMaterial.geometryCoatTangentTexture;
|
|
73
26
|
// If we don't have any textures, we don't need to generate anything.
|
|
74
27
|
if (!(anisoStrengthTexture || tangentTexture)) {
|
|
75
28
|
return null;
|
|
76
29
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
format: Constants.TEXTUREFORMAT_RGBA,
|
|
82
|
-
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
|
|
83
|
-
generateDepthBuffer: false,
|
|
84
|
-
generateStencilBuffer: false,
|
|
85
|
-
generateMipMaps: false,
|
|
86
|
-
};
|
|
87
|
-
const rtTexture = new ProceduralTexture(babylonMaterial.name + "_anisotropy", {
|
|
88
|
-
width,
|
|
89
|
-
height,
|
|
90
|
-
}, "anisotropyMerge", scene, textureOptions);
|
|
91
|
-
rtTexture.refreshRate = -1;
|
|
92
|
-
// Set uniforms and defines
|
|
93
|
-
let defines = "";
|
|
94
|
-
if (tangentTexture) {
|
|
95
|
-
defines += "#define HAS_TANGENT_TEXTURE\n";
|
|
96
|
-
rtTexture.setTexture("tangentTexture", tangentTexture);
|
|
97
|
-
CopyTextureTransform(tangentTexture, rtTexture);
|
|
98
|
-
}
|
|
99
|
-
rtTexture.setVector2("tangentVector", babylonMaterial.geometryTangent);
|
|
100
|
-
if (anisoStrengthTexture) {
|
|
101
|
-
defines += "#define HAS_ANISOTROPY_TEXTURE\n";
|
|
102
|
-
rtTexture.setTexture("anisotropyTexture", anisoStrengthTexture);
|
|
103
|
-
CopyTextureTransform(anisoStrengthTexture, rtTexture);
|
|
104
|
-
}
|
|
105
|
-
rtTexture.setInt("useAnisotropyFromTangentBlue", babylonMaterial._useCoatRoughnessAnisotropyFromTangentTexture ? 1 : 0);
|
|
106
|
-
rtTexture.defines = defines;
|
|
107
|
-
return await new Promise((resolve, reject) => {
|
|
108
|
-
// Compile and render
|
|
109
|
-
rtTexture.executeWhenReady(() => {
|
|
110
|
-
try {
|
|
111
|
-
rtTexture.render();
|
|
112
|
-
resolve(rtTexture);
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
30
|
+
return await MergeTexturesAsync("AnisotropyTexture", CreateRGBAConfiguration(tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel
|
|
31
|
+
tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel
|
|
32
|
+
anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel
|
|
33
|
+
), scene);
|
|
119
34
|
}
|
|
120
35
|
/**
|
|
121
36
|
* @internal
|
|
@@ -149,10 +64,16 @@ export class KHR_materials_clearcoat_anisotropy {
|
|
|
149
64
|
const additionalTextures = [];
|
|
150
65
|
if (babylonMaterial instanceof OpenPBRMaterial) {
|
|
151
66
|
if (babylonMaterial.coatRoughnessAnisotropy > 0) {
|
|
152
|
-
const
|
|
153
|
-
if (
|
|
154
|
-
additionalTextures.push(
|
|
155
|
-
|
|
67
|
+
const texId = GetAnisoTextureId(babylonMaterial);
|
|
68
|
+
if (this._anisoTexturesMap[texId]) {
|
|
69
|
+
additionalTextures.push(this._anisoTexturesMap[texId]);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);
|
|
73
|
+
if (anisoTexture) {
|
|
74
|
+
additionalTextures.push(anisoTexture);
|
|
75
|
+
this._anisoTexturesMap[texId] = anisoTexture;
|
|
76
|
+
}
|
|
156
77
|
}
|
|
157
78
|
return additionalTextures;
|
|
158
79
|
}
|