@babylonjs/serializers 7.37.1 → 7.37.2
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_mesh_gpu_instancing.d.ts +6 -7
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +18 -12
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +5 -6
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +99 -109
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +6 -6
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +9 -9
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +7 -7
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js +2 -2
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +2 -2
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_ior.js +2 -2
- package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js +7 -7
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_sheen.js +8 -8
- package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_specular.js +7 -7
- package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +6 -6
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_unlit.js +2 -2
- package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_materials_volume.js +6 -6
- package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_transform.js +2 -2
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/Extensions/index.d.ts +9 -9
- package/glTF/2.0/Extensions/index.js +9 -9
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/dataWriter.d.ts +18 -0
- package/glTF/2.0/dataWriter.js +65 -0
- package/glTF/2.0/dataWriter.js.map +1 -0
- package/glTF/2.0/glTFAnimation.d.ts +4 -10
- package/glTF/2.0/glTFAnimation.js +87 -19
- package/glTF/2.0/glTFAnimation.js.map +1 -1
- package/glTF/2.0/glTFData.d.ts +5 -3
- package/glTF/2.0/glTFData.js +35 -36
- package/glTF/2.0/glTFData.js.map +1 -1
- package/glTF/2.0/glTFExporter.d.ts +62 -363
- package/glTF/2.0/glTFExporter.js +867 -1579
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFExporterExtension.d.ts +8 -9
- package/glTF/2.0/glTFExporterExtension.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.d.ts +26 -126
- package/glTF/2.0/glTFMaterialExporter.js +276 -438
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/glTF/2.0/glTFMorphTargetsUtilities.d.ts +14 -0
- package/glTF/2.0/glTFMorphTargetsUtilities.js +105 -0
- package/glTF/2.0/glTFMorphTargetsUtilities.js.map +1 -0
- package/glTF/2.0/glTFSerializer.d.ts +10 -13
- package/glTF/2.0/glTFSerializer.js +25 -44
- package/glTF/2.0/glTFSerializer.js.map +1 -1
- package/glTF/2.0/glTFUtilities.d.ts +75 -43
- package/glTF/2.0/glTFUtilities.js +350 -103
- package/glTF/2.0/glTFUtilities.js.map +1 -1
- package/package.json +3 -3
@@ -1,3 +1,4 @@
|
|
1
|
+
/* eslint-disable babylonjs/available */
|
1
2
|
import { Vector2 } from "@babylonjs/core/Maths/math.vector.js";
|
2
3
|
import { Color3 } from "@babylonjs/core/Maths/math.color.js";
|
3
4
|
import { Scalar } from "@babylonjs/core/Maths/math.scalar.js";
|
@@ -7,7 +8,12 @@ import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
|
|
7
8
|
import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
|
8
9
|
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
9
10
|
import { DumpTools } from "@babylonjs/core/Misc/dumpTools.js";
|
10
|
-
|
11
|
+
const epsilon = 1e-6;
|
12
|
+
const dielectricSpecular = new Color3(0.04, 0.04, 0.04);
|
13
|
+
const maxSpecularPower = 1024;
|
14
|
+
const white = Color3.White();
|
15
|
+
const black = Color3.Black();
|
16
|
+
function GetFileExtensionFromMimeType(mimeType) {
|
11
17
|
switch (mimeType) {
|
12
18
|
case "image/jpeg" /* ImageMimeType.JPEG */:
|
13
19
|
return ".jpg";
|
@@ -20,202 +26,78 @@ function getFileExtensionFromMimeType(mimeType) {
|
|
20
26
|
}
|
21
27
|
}
|
22
28
|
/**
|
23
|
-
*
|
29
|
+
* Computes the metallic factor.
|
30
|
+
* @param diffuse diffused value
|
31
|
+
* @param specular specular value
|
32
|
+
* @param oneMinusSpecularStrength one minus the specular strength
|
33
|
+
* @returns metallic value
|
24
34
|
* @internal
|
25
35
|
*/
|
26
|
-
export
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
*/
|
31
|
-
this._textureMap = {};
|
32
|
-
// Mapping of internal textures to images to avoid exporting duplicate images.
|
33
|
-
this._internalTextureToImage = {};
|
34
|
-
this._textureMap = {};
|
35
|
-
this._exporter = exporter;
|
36
|
+
export function _SolveMetallic(diffuse, specular, oneMinusSpecularStrength) {
|
37
|
+
if (specular < dielectricSpecular.r) {
|
38
|
+
dielectricSpecular;
|
39
|
+
return 0;
|
36
40
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
const a = dielectricSpecular.r;
|
42
|
+
const b = (diffuse * oneMinusSpecularStrength) / (1.0 - dielectricSpecular.r) + specular - 2.0 * dielectricSpecular.r;
|
43
|
+
const c = dielectricSpecular.r - specular;
|
44
|
+
const d = b * b - 4.0 * a * c;
|
45
|
+
return Scalar.Clamp((-b + Math.sqrt(d)) / (2.0 * a), 0, 1);
|
46
|
+
}
|
47
|
+
/**
|
48
|
+
* Sets the glTF alpha mode to a glTF material from the Babylon Material
|
49
|
+
* @param glTFMaterial glTF material
|
50
|
+
* @param babylonMaterial Babylon material
|
51
|
+
*/
|
52
|
+
function SetAlphaMode(glTFMaterial, babylonMaterial) {
|
53
|
+
if (babylonMaterial.needAlphaBlending()) {
|
54
|
+
glTFMaterial.alphaMode = "BLEND" /* MaterialAlphaMode.BLEND */;
|
46
55
|
}
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
* @param mimeType texture mime type
|
51
|
-
* @param hasTextureCoords specifies if texture coordinates are present on the material
|
52
|
-
* @returns promise that resolves after all materials have been converted
|
53
|
-
*/
|
54
|
-
_convertMaterialsToGLTFAsync(exportMaterials, mimeType, hasTextureCoords) {
|
55
|
-
const promises = [];
|
56
|
-
exportMaterials.forEach((material) => {
|
57
|
-
if (material.getClassName() === "StandardMaterial") {
|
58
|
-
promises.push(this._convertStandardMaterialAsync(material, mimeType, hasTextureCoords));
|
59
|
-
}
|
60
|
-
else if (material.getClassName().indexOf("PBR") !== -1) {
|
61
|
-
promises.push(this._convertPBRMaterialAsync(material, mimeType, hasTextureCoords));
|
62
|
-
}
|
63
|
-
else {
|
64
|
-
Tools.Warn(`Unsupported material type: ${material.name}`);
|
65
|
-
}
|
66
|
-
});
|
67
|
-
return Promise.all(promises).then(() => {
|
68
|
-
/* do nothing */
|
69
|
-
});
|
56
|
+
else if (babylonMaterial.needAlphaTesting()) {
|
57
|
+
glTFMaterial.alphaMode = "MASK" /* MaterialAlphaMode.MASK */;
|
58
|
+
glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;
|
70
59
|
}
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
_stripTexturesFromMaterial(originalMaterial) {
|
77
|
-
const newMaterial = {};
|
78
|
-
if (originalMaterial) {
|
79
|
-
newMaterial.name = originalMaterial.name;
|
80
|
-
newMaterial.doubleSided = originalMaterial.doubleSided;
|
81
|
-
newMaterial.alphaMode = originalMaterial.alphaMode;
|
82
|
-
newMaterial.alphaCutoff = originalMaterial.alphaCutoff;
|
83
|
-
newMaterial.emissiveFactor = originalMaterial.emissiveFactor;
|
84
|
-
const originalPBRMetallicRoughness = originalMaterial.pbrMetallicRoughness;
|
85
|
-
if (originalPBRMetallicRoughness) {
|
86
|
-
newMaterial.pbrMetallicRoughness = {};
|
87
|
-
newMaterial.pbrMetallicRoughness.baseColorFactor = originalPBRMetallicRoughness.baseColorFactor;
|
88
|
-
newMaterial.pbrMetallicRoughness.metallicFactor = originalPBRMetallicRoughness.metallicFactor;
|
89
|
-
newMaterial.pbrMetallicRoughness.roughnessFactor = originalPBRMetallicRoughness.roughnessFactor;
|
90
|
-
}
|
91
|
-
}
|
92
|
-
return newMaterial;
|
60
|
+
}
|
61
|
+
function CreateWhiteTexture(width, height, scene) {
|
62
|
+
const data = new Uint8Array(width * height * 4);
|
63
|
+
for (let i = 0; i < data.length; i = i + 4) {
|
64
|
+
data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;
|
93
65
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
const pbrMat = material.pbrMetallicRoughness;
|
104
|
-
if (pbrMat) {
|
105
|
-
if (pbrMat.baseColorTexture || pbrMat.metallicRoughnessTexture) {
|
106
|
-
return true;
|
107
|
-
}
|
108
|
-
}
|
109
|
-
if (material.extensions) {
|
110
|
-
for (const extension in material.extensions) {
|
111
|
-
const extensionObject = material.extensions[extension];
|
112
|
-
if (extensionObject) {
|
113
|
-
return extensionObject.hasTextures?.();
|
114
|
-
}
|
115
|
-
}
|
66
|
+
const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);
|
67
|
+
return rawTexture;
|
68
|
+
}
|
69
|
+
function ConvertPixelArrayToFloat32(pixels) {
|
70
|
+
if (pixels instanceof Uint8Array) {
|
71
|
+
const length = pixels.length;
|
72
|
+
const buffer = new Float32Array(pixels.length);
|
73
|
+
for (let i = 0; i < length; ++i) {
|
74
|
+
buffer[i] = pixels[i] / 255;
|
116
75
|
}
|
117
|
-
return
|
76
|
+
return buffer;
|
118
77
|
}
|
119
|
-
|
120
|
-
|
121
|
-
const textureUid = babylonTexture.uid;
|
122
|
-
if (textureUid in this._textureMap) {
|
123
|
-
return this._textureMap[textureUid];
|
124
|
-
}
|
125
|
-
}
|
126
|
-
return null;
|
78
|
+
else if (pixels instanceof Float32Array) {
|
79
|
+
return pixels;
|
127
80
|
}
|
128
|
-
|
129
|
-
|
130
|
-
* @param babylonStandardMaterial
|
131
|
-
* @returns glTF Metallic Roughness Material representation
|
132
|
-
*/
|
133
|
-
_convertToGLTFPBRMetallicRoughness(babylonStandardMaterial) {
|
134
|
-
// Defines a cubic bezier curve where x is specular power and y is roughness
|
135
|
-
const P0 = new Vector2(0, 1);
|
136
|
-
const P1 = new Vector2(0, 0.1);
|
137
|
-
const P2 = new Vector2(0, 0.1);
|
138
|
-
const P3 = new Vector2(1300, 0.1);
|
139
|
-
/**
|
140
|
-
* Given the control points, solve for x based on a given t for a cubic bezier curve
|
141
|
-
* @param t a value between 0 and 1
|
142
|
-
* @param p0 first control point
|
143
|
-
* @param p1 second control point
|
144
|
-
* @param p2 third control point
|
145
|
-
* @param p3 fourth control point
|
146
|
-
* @returns number result of cubic bezier curve at the specified t
|
147
|
-
*/
|
148
|
-
function cubicBezierCurve(t, p0, p1, p2, p3) {
|
149
|
-
return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3;
|
150
|
-
}
|
151
|
-
/**
|
152
|
-
* Evaluates a specified specular power value to determine the appropriate roughness value,
|
153
|
-
* based on a pre-defined cubic bezier curve with specular on the abscissa axis (x-axis)
|
154
|
-
* and roughness on the ordinant axis (y-axis)
|
155
|
-
* @param specularPower specular power of standard material
|
156
|
-
* @returns Number representing the roughness value
|
157
|
-
*/
|
158
|
-
function solveForRoughness(specularPower) {
|
159
|
-
// Given P0.x = 0, P1.x = 0, P2.x = 0
|
160
|
-
// x = t * t * t * P3.x
|
161
|
-
// t = (x / P3.x)^(1/3)
|
162
|
-
const t = Math.pow(specularPower / P3.x, 0.333333);
|
163
|
-
return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
|
164
|
-
}
|
165
|
-
const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);
|
166
|
-
const opacity = babylonStandardMaterial.alpha;
|
167
|
-
const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, _GLTFMaterialExporter._MaxSpecularPower);
|
168
|
-
const roughness = solveForRoughness(specularPower);
|
169
|
-
const glTFPbrMetallicRoughness = {
|
170
|
-
baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],
|
171
|
-
metallicFactor: 0,
|
172
|
-
roughnessFactor: roughness,
|
173
|
-
};
|
174
|
-
return glTFPbrMetallicRoughness;
|
81
|
+
else {
|
82
|
+
throw new Error("Unsupported pixel format!");
|
175
83
|
}
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
}
|
188
|
-
const a = this._DielectricSpecular.r;
|
189
|
-
const b = (diffuse * oneMinusSpecularStrength) / (1.0 - this._DielectricSpecular.r) + specular - 2.0 * this._DielectricSpecular.r;
|
190
|
-
const c = this._DielectricSpecular.r - specular;
|
191
|
-
const D = b * b - 4.0 * a * c;
|
192
|
-
return Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
|
84
|
+
}
|
85
|
+
/**
|
86
|
+
* Utility methods for working with glTF material conversion properties.
|
87
|
+
* @internal
|
88
|
+
*/
|
89
|
+
export class GLTFMaterialExporter {
|
90
|
+
constructor(_exporter) {
|
91
|
+
this._exporter = _exporter;
|
92
|
+
// Mapping to store textures
|
93
|
+
this._textureMap = new Map();
|
94
|
+
// Mapping of internal textures to images to avoid exporting duplicate images
|
95
|
+
this._internalTextureToImage = {};
|
193
96
|
}
|
194
|
-
|
195
|
-
|
196
|
-
* @param glTFMaterial glTF material
|
197
|
-
* @param babylonMaterial Babylon material
|
198
|
-
*/
|
199
|
-
static _SetAlphaMode(glTFMaterial, babylonMaterial) {
|
200
|
-
if (babylonMaterial.needAlphaBlending()) {
|
201
|
-
glTFMaterial.alphaMode = "BLEND" /* MaterialAlphaMode.BLEND */;
|
202
|
-
}
|
203
|
-
else if (babylonMaterial.needAlphaTesting()) {
|
204
|
-
glTFMaterial.alphaMode = "MASK" /* MaterialAlphaMode.MASK */;
|
205
|
-
glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;
|
206
|
-
}
|
97
|
+
getTextureInfo(babylonTexture) {
|
98
|
+
return babylonTexture ? (this._textureMap.get(babylonTexture) ?? null) : null;
|
207
99
|
}
|
208
|
-
|
209
|
-
* Converts a Babylon Standard Material to a glTF Material
|
210
|
-
* @param babylonStandardMaterial BJS Standard Material
|
211
|
-
* @param mimeType mime type to use for the textures
|
212
|
-
* @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
213
|
-
* @returns promise, resolved with the material
|
214
|
-
*/
|
215
|
-
_convertStandardMaterialAsync(babylonStandardMaterial, mimeType, hasTextureCoords) {
|
216
|
-
const materialMap = this._exporter._materialMap;
|
217
|
-
const materials = this._exporter._materials;
|
218
|
-
const promises = [];
|
100
|
+
async exportStandardMaterialAsync(babylonStandardMaterial, mimeType, hasUVs) {
|
219
101
|
const pbrMetallicRoughness = this._convertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
|
220
102
|
const material = { name: babylonStandardMaterial.name };
|
221
103
|
if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
|
@@ -224,9 +106,11 @@ export class _GLTFMaterialExporter {
|
|
224
106
|
}
|
225
107
|
material.doubleSided = true;
|
226
108
|
}
|
227
|
-
if (
|
228
|
-
|
229
|
-
|
109
|
+
if (hasUVs) {
|
110
|
+
const promises = [];
|
111
|
+
const diffuseTexture = babylonStandardMaterial.diffuseTexture;
|
112
|
+
if (diffuseTexture) {
|
113
|
+
promises.push(this.exportTextureAsync(diffuseTexture, mimeType).then((textureInfo) => {
|
230
114
|
if (textureInfo) {
|
231
115
|
pbrMetallicRoughness.baseColorTexture = textureInfo;
|
232
116
|
}
|
@@ -234,7 +118,7 @@ export class _GLTFMaterialExporter {
|
|
234
118
|
}
|
235
119
|
const bumpTexture = babylonStandardMaterial.bumpTexture;
|
236
120
|
if (bumpTexture) {
|
237
|
-
promises.push(this.
|
121
|
+
promises.push(this.exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {
|
238
122
|
if (textureInfo) {
|
239
123
|
material.normalTexture = textureInfo;
|
240
124
|
if (bumpTexture.level !== 1) {
|
@@ -243,16 +127,18 @@ export class _GLTFMaterialExporter {
|
|
243
127
|
}
|
244
128
|
}));
|
245
129
|
}
|
246
|
-
|
130
|
+
const emissiveTexture = babylonStandardMaterial.emissiveTexture;
|
131
|
+
if (emissiveTexture) {
|
247
132
|
material.emissiveFactor = [1.0, 1.0, 1.0];
|
248
|
-
promises.push(this.
|
133
|
+
promises.push(this.exportTextureAsync(emissiveTexture, mimeType).then((textureInfo) => {
|
249
134
|
if (textureInfo) {
|
250
135
|
material.emissiveTexture = textureInfo;
|
251
136
|
}
|
252
137
|
}));
|
253
138
|
}
|
254
|
-
|
255
|
-
|
139
|
+
const ambientTexture = babylonStandardMaterial.ambientTexture;
|
140
|
+
if (ambientTexture) {
|
141
|
+
promises.push(this.exportTextureAsync(ambientTexture, mimeType).then((textureInfo) => {
|
256
142
|
if (textureInfo) {
|
257
143
|
const occlusionTexture = {
|
258
144
|
index: textureInfo.index,
|
@@ -261,6 +147,10 @@ export class _GLTFMaterialExporter {
|
|
261
147
|
}
|
262
148
|
}));
|
263
149
|
}
|
150
|
+
if (promises.length > 0) {
|
151
|
+
this._exporter._materialNeedsUVsSet.add(babylonStandardMaterial);
|
152
|
+
await Promise.all(promises);
|
153
|
+
}
|
264
154
|
}
|
265
155
|
if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
|
266
156
|
if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {
|
@@ -270,45 +160,68 @@ export class _GLTFMaterialExporter {
|
|
270
160
|
Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
|
271
161
|
}
|
272
162
|
}
|
273
|
-
if (babylonStandardMaterial.emissiveColor && !
|
163
|
+
if (babylonStandardMaterial.emissiveColor && !babylonStandardMaterial.emissiveColor.equalsWithEpsilon(black, epsilon)) {
|
274
164
|
material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
|
275
165
|
}
|
276
166
|
material.pbrMetallicRoughness = pbrMetallicRoughness;
|
277
|
-
|
167
|
+
SetAlphaMode(material, babylonStandardMaterial);
|
168
|
+
await this._finishMaterialAsync(material, babylonStandardMaterial, mimeType);
|
169
|
+
const materials = this._exporter._materials;
|
278
170
|
materials.push(material);
|
279
|
-
|
280
|
-
return this._finishMaterial(promises, material, babylonStandardMaterial, mimeType);
|
171
|
+
return materials.length - 1;
|
281
172
|
}
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
173
|
+
_convertToGLTFPBRMetallicRoughness(babylonStandardMaterial) {
|
174
|
+
// Defines a cubic bezier curve where x is specular power and y is roughness
|
175
|
+
const P0 = new Vector2(0, 1);
|
176
|
+
const P1 = new Vector2(0, 0.1);
|
177
|
+
const P2 = new Vector2(0, 0.1);
|
178
|
+
const P3 = new Vector2(1300, 0.1);
|
179
|
+
/**
|
180
|
+
* Given the control points, solve for x based on a given t for a cubic bezier curve
|
181
|
+
* @param t a value between 0 and 1
|
182
|
+
* @param p0 first control point
|
183
|
+
* @param p1 second control point
|
184
|
+
* @param p2 third control point
|
185
|
+
* @param p3 fourth control point
|
186
|
+
* @returns number result of cubic bezier curve at the specified t
|
187
|
+
*/
|
188
|
+
function cubicBezierCurve(t, p0, p1, p2, p3) {
|
189
|
+
return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3;
|
190
|
+
}
|
191
|
+
/**
|
192
|
+
* Evaluates a specified specular power value to determine the appropriate roughness value,
|
193
|
+
* based on a pre-defined cubic bezier curve with specular on the abscissa axis (x-axis)
|
194
|
+
* and roughness on the ordinant axis (y-axis)
|
195
|
+
* @param specularPower specular power of standard material
|
196
|
+
* @returns Number representing the roughness value
|
197
|
+
*/
|
198
|
+
function solveForRoughness(specularPower) {
|
199
|
+
// Given P0.x = 0, P1.x = 0, P2.x = 0
|
200
|
+
// x = t * t * t * P3.x
|
201
|
+
// t = (x / P3.x)^(1/3)
|
202
|
+
const t = Math.pow(specularPower / P3.x, 0.333333);
|
203
|
+
return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
|
204
|
+
}
|
205
|
+
const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);
|
206
|
+
const opacity = babylonStandardMaterial.alpha;
|
207
|
+
const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, maxSpecularPower);
|
208
|
+
const roughness = solveForRoughness(specularPower);
|
209
|
+
const glTFPbrMetallicRoughness = {
|
210
|
+
baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],
|
211
|
+
metallicFactor: 0,
|
212
|
+
roughnessFactor: roughness,
|
213
|
+
};
|
214
|
+
return glTFPbrMetallicRoughness;
|
215
|
+
}
|
216
|
+
async _finishMaterialAsync(glTFMaterial, babylonMaterial, mimeType) {
|
217
|
+
const textures = this._exporter._extensionsPostExportMaterialAdditionalTextures("exportMaterial", glTFMaterial, babylonMaterial);
|
218
|
+
const promises = [];
|
219
|
+
for (const texture of textures) {
|
220
|
+
promises.push(this.exportTextureAsync(texture, mimeType));
|
221
|
+
}
|
222
|
+
await Promise.all(promises);
|
223
|
+
await this._exporter._extensionsPostExportMaterialAsync("exportMaterial", glTFMaterial, babylonMaterial);
|
303
224
|
}
|
304
|
-
/**
|
305
|
-
* Converts an image typed array buffer to a base64 image
|
306
|
-
* @param buffer typed array buffer
|
307
|
-
* @param width width of the image
|
308
|
-
* @param height height of the image
|
309
|
-
* @param mimeType mimetype of the image
|
310
|
-
* @returns base64 image string
|
311
|
-
*/
|
312
225
|
async _getImageDataAsync(buffer, width, height, mimeType) {
|
313
226
|
const textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;
|
314
227
|
const hostingScene = this._exporter._babylonScene;
|
@@ -319,21 +232,6 @@ export class _GLTFMaterialExporter {
|
|
319
232
|
const data = await engine._readTexturePixels(tempTexture, width, height);
|
320
233
|
return (await DumpTools.DumpDataAsync(width, height, data, mimeType, undefined, true, true));
|
321
234
|
}
|
322
|
-
/**
|
323
|
-
* Generates a white texture based on the specified width and height
|
324
|
-
* @param width width of the texture in pixels
|
325
|
-
* @param height height of the texture in pixels
|
326
|
-
* @param scene babylonjs scene
|
327
|
-
* @returns white texture
|
328
|
-
*/
|
329
|
-
_createWhiteTexture(width, height, scene) {
|
330
|
-
const data = new Uint8Array(width * height * 4);
|
331
|
-
for (let i = 0; i < data.length; i = i + 4) {
|
332
|
-
data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;
|
333
|
-
}
|
334
|
-
const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);
|
335
|
-
return rawTexture;
|
336
|
-
}
|
337
235
|
/**
|
338
236
|
* Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null
|
339
237
|
* @param texture1 first texture to resize
|
@@ -351,7 +249,7 @@ export class _GLTFMaterialExporter {
|
|
351
249
|
resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
|
352
250
|
}
|
353
251
|
else {
|
354
|
-
resizedTexture1 =
|
252
|
+
resizedTexture1 = CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);
|
355
253
|
}
|
356
254
|
resizedTexture2 = texture2;
|
357
255
|
}
|
@@ -360,7 +258,7 @@ export class _GLTFMaterialExporter {
|
|
360
258
|
resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
|
361
259
|
}
|
362
260
|
else {
|
363
|
-
resizedTexture2 =
|
261
|
+
resizedTexture2 = CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);
|
364
262
|
}
|
365
263
|
resizedTexture1 = texture1;
|
366
264
|
}
|
@@ -373,32 +271,10 @@ export class _GLTFMaterialExporter {
|
|
373
271
|
texture2: resizedTexture2,
|
374
272
|
};
|
375
273
|
}
|
376
|
-
/**
|
377
|
-
* Converts an array of pixels to a Float32Array
|
378
|
-
* Throws an error if the pixel format is not supported
|
379
|
-
* @param pixels - array buffer containing pixel values
|
380
|
-
* @returns Float32 of pixels
|
381
|
-
*/
|
382
|
-
_convertPixelArrayToFloat32(pixels) {
|
383
|
-
if (pixels instanceof Uint8Array) {
|
384
|
-
const length = pixels.length;
|
385
|
-
const buffer = new Float32Array(pixels.length);
|
386
|
-
for (let i = 0; i < length; ++i) {
|
387
|
-
buffer[i] = pixels[i] / 255;
|
388
|
-
}
|
389
|
-
return buffer;
|
390
|
-
}
|
391
|
-
else if (pixels instanceof Float32Array) {
|
392
|
-
return pixels;
|
393
|
-
}
|
394
|
-
else {
|
395
|
-
throw new Error("Unsupported pixel format!");
|
396
|
-
}
|
397
|
-
}
|
398
274
|
/**
|
399
275
|
* Convert Specular Glossiness Textures to Metallic Roughness
|
400
276
|
* See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
|
401
|
-
* @
|
277
|
+
* @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-.js/babylon.pbrUtilities.js
|
402
278
|
* @param diffuseTexture texture used to store diffuse information
|
403
279
|
* @param specularGlossinessTexture texture used to store specular and glossiness information
|
404
280
|
* @param factors specular glossiness material factors
|
@@ -408,7 +284,7 @@ export class _GLTFMaterialExporter {
|
|
408
284
|
async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(diffuseTexture, specularGlossinessTexture, factors, mimeType) {
|
409
285
|
const promises = new Array();
|
410
286
|
if (!(diffuseTexture || specularGlossinessTexture)) {
|
411
|
-
return Promise.reject("
|
287
|
+
return Promise.reject("diffuse and specular glossiness textures are not defined!");
|
412
288
|
}
|
413
289
|
const scene = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null;
|
414
290
|
if (scene) {
|
@@ -421,13 +297,13 @@ export class _GLTFMaterialExporter {
|
|
421
297
|
const diffusePixels = await resizedTextures.texture1.readPixels();
|
422
298
|
const specularPixels = await resizedTextures.texture2.readPixels();
|
423
299
|
if (diffusePixels) {
|
424
|
-
diffuseBuffer =
|
300
|
+
diffuseBuffer = ConvertPixelArrayToFloat32(diffusePixels);
|
425
301
|
}
|
426
302
|
else {
|
427
303
|
return Promise.reject("Failed to retrieve pixels from diffuse texture!");
|
428
304
|
}
|
429
305
|
if (specularPixels) {
|
430
|
-
specularGlossinessBuffer =
|
306
|
+
specularGlossinessBuffer = ConvertPixelArrayToFloat32(specularPixels);
|
431
307
|
}
|
432
308
|
else {
|
433
309
|
return Promise.reject("Failed to retrieve pixels from specular glossiness texture!");
|
@@ -436,7 +312,7 @@ export class _GLTFMaterialExporter {
|
|
436
312
|
const metallicRoughnessBuffer = new Uint8Array(byteLength);
|
437
313
|
const baseColorBuffer = new Uint8Array(byteLength);
|
438
314
|
const strideSize = 4;
|
439
|
-
const maxBaseColor =
|
315
|
+
const maxBaseColor = black;
|
440
316
|
let maxMetallic = 0;
|
441
317
|
let maxRoughness = 0;
|
442
318
|
for (let h = 0; h < height; ++h) {
|
@@ -481,22 +357,21 @@ export class _GLTFMaterialExporter {
|
|
481
357
|
for (let h = 0; h < height; ++h) {
|
482
358
|
for (let w = 0; w < width; ++w) {
|
483
359
|
const destinationOffset = (width * h + w) * strideSize;
|
484
|
-
baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r >
|
485
|
-
baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g >
|
486
|
-
baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b >
|
360
|
+
baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > epsilon ? metallicRoughnessFactors.baseColor.r : 1;
|
361
|
+
baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > epsilon ? metallicRoughnessFactors.baseColor.g : 1;
|
362
|
+
baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > epsilon ? metallicRoughnessFactors.baseColor.b : 1;
|
487
363
|
const linearBaseColorPixel = Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
|
488
364
|
const sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions);
|
489
365
|
baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;
|
490
366
|
baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;
|
491
367
|
baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;
|
492
|
-
if (!
|
368
|
+
if (!sRGBBaseColorPixel.equalsWithEpsilon(white, epsilon)) {
|
493
369
|
writeOutBaseColorTexture = true;
|
494
370
|
}
|
495
|
-
metallicRoughnessBuffer[destinationOffset + 1] /=
|
496
|
-
|
497
|
-
metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors.metallic : 1;
|
371
|
+
metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness > epsilon ? metallicRoughnessFactors.roughness : 1;
|
372
|
+
metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic > epsilon ? metallicRoughnessFactors.metallic : 1;
|
498
373
|
const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
|
499
|
-
if (!
|
374
|
+
if (!metallicRoughnessPixel.equalsWithEpsilon(white, epsilon)) {
|
500
375
|
writeOutMetallicRoughnessTexture = true;
|
501
376
|
}
|
502
377
|
}
|
@@ -528,11 +403,9 @@ export class _GLTFMaterialExporter {
|
|
528
403
|
const diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor);
|
529
404
|
const specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor);
|
530
405
|
const oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor);
|
531
|
-
const metallic =
|
532
|
-
const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 -
|
533
|
-
const baseColorFromSpecular = specularGlossiness.specularColor
|
534
|
-
.subtract(_GLTFMaterialExporter._DielectricSpecular.scale(1 - metallic))
|
535
|
-
.scale(1 / Math.max(metallic, _GLTFMaterialExporter._Epsilon));
|
406
|
+
const metallic = _SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
|
407
|
+
const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - dielectricSpecular.r) / Math.max(1 - metallic));
|
408
|
+
const baseColorFromSpecular = specularGlossiness.specularColor.subtract(dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic));
|
536
409
|
let baseColor = Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
|
537
410
|
baseColor = baseColor.clampToRef(0, 1, baseColor);
|
538
411
|
const metallicRoughness = {
|
@@ -569,23 +442,20 @@ export class _GLTFMaterialExporter {
|
|
569
442
|
* @param babylonPBRMaterial BJS PBR Metallic Roughness Material
|
570
443
|
* @param mimeType mime type to use for the textures
|
571
444
|
* @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface
|
572
|
-
* @param
|
445
|
+
* @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
573
446
|
* @returns glTF PBR Metallic Roughness factors
|
574
447
|
*/
|
575
|
-
_convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness,
|
448
|
+
async _convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs) {
|
576
449
|
const promises = [];
|
577
|
-
const baseColor = babylonPBRMaterial._albedoColor;
|
578
|
-
const metallic = babylonPBRMaterial._metallic;
|
579
|
-
const roughness = babylonPBRMaterial._roughness;
|
580
450
|
const metallicRoughness = {
|
581
|
-
baseColor:
|
582
|
-
metallic:
|
583
|
-
roughness:
|
451
|
+
baseColor: babylonPBRMaterial._albedoColor,
|
452
|
+
metallic: babylonPBRMaterial._metallic,
|
453
|
+
roughness: babylonPBRMaterial._roughness,
|
584
454
|
};
|
585
|
-
if (
|
455
|
+
if (hasUVs) {
|
586
456
|
const albedoTexture = babylonPBRMaterial._albedoTexture;
|
587
457
|
if (albedoTexture) {
|
588
|
-
promises.push(this.
|
458
|
+
promises.push(this.exportTextureAsync(babylonPBRMaterial._albedoTexture, mimeType).then((glTFTexture) => {
|
589
459
|
if (glTFTexture) {
|
590
460
|
glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
591
461
|
}
|
@@ -593,16 +463,18 @@ export class _GLTFMaterialExporter {
|
|
593
463
|
}
|
594
464
|
const metallicTexture = babylonPBRMaterial._metallicTexture;
|
595
465
|
if (metallicTexture) {
|
596
|
-
promises.push(this.
|
466
|
+
promises.push(this.exportTextureAsync(metallicTexture, mimeType).then((glTFTexture) => {
|
597
467
|
if (glTFTexture) {
|
598
468
|
glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
|
599
469
|
}
|
600
470
|
}));
|
601
471
|
}
|
602
472
|
}
|
603
|
-
|
604
|
-
|
605
|
-
|
473
|
+
if (promises.length > 0) {
|
474
|
+
this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);
|
475
|
+
await Promise.all(promises);
|
476
|
+
}
|
477
|
+
return metallicRoughness;
|
606
478
|
}
|
607
479
|
_getTextureSampler(texture) {
|
608
480
|
const sampler = {};
|
@@ -703,50 +575,41 @@ export class _GLTFMaterialExporter {
|
|
703
575
|
* @param babylonPBRMaterial BJS PBR Metallic Roughness Material
|
704
576
|
* @param mimeType mime type to use for the textures
|
705
577
|
* @param pbrMetallicRoughness glTF PBR Metallic Roughness interface
|
706
|
-
* @param
|
578
|
+
* @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
707
579
|
* @returns glTF PBR Metallic Roughness factors
|
708
580
|
*/
|
709
|
-
_convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, pbrMetallicRoughness,
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
}
|
740
|
-
});
|
581
|
+
async _convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, pbrMetallicRoughness, hasUVs) {
|
582
|
+
const specGloss = {
|
583
|
+
diffuseColor: babylonPBRMaterial._albedoColor,
|
584
|
+
specularColor: babylonPBRMaterial._reflectivityColor,
|
585
|
+
glossiness: babylonPBRMaterial._microSurface,
|
586
|
+
};
|
587
|
+
const albedoTexture = babylonPBRMaterial._albedoTexture;
|
588
|
+
const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;
|
589
|
+
const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;
|
590
|
+
if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {
|
591
|
+
return Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported");
|
592
|
+
}
|
593
|
+
if ((albedoTexture || reflectivityTexture) && hasUVs) {
|
594
|
+
this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);
|
595
|
+
const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);
|
596
|
+
const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType);
|
597
|
+
const textures = this._exporter._textures;
|
598
|
+
if (metallicRoughnessFactors.baseColorTextureData) {
|
599
|
+
const imageIndex = this._exportImage(`baseColor${textures.length}`, mimeType, metallicRoughnessFactors.baseColorTextureData);
|
600
|
+
pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);
|
601
|
+
}
|
602
|
+
if (metallicRoughnessFactors.metallicRoughnessTextureData) {
|
603
|
+
const imageIndex = this._exportImage(`metallicRoughness${textures.length}`, mimeType, metallicRoughnessFactors.metallicRoughnessTextureData);
|
604
|
+
pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);
|
605
|
+
}
|
606
|
+
return metallicRoughnessFactors;
|
607
|
+
}
|
608
|
+
else {
|
609
|
+
return this._convertSpecularGlossinessToMetallicRoughness(specGloss);
|
610
|
+
}
|
741
611
|
}
|
742
|
-
|
743
|
-
* Converts a Babylon PBR Base Material to a glTF Material
|
744
|
-
* @param babylonPBRMaterial BJS PBR Base Material
|
745
|
-
* @param mimeType mime type to use for the textures
|
746
|
-
* @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
747
|
-
* @returns async glTF Material representation
|
748
|
-
*/
|
749
|
-
_convertPBRMaterialAsync(babylonPBRMaterial, mimeType, hasTextureCoords) {
|
612
|
+
async exportPBRMaterialAsync(babylonPBRMaterial, mimeType, hasUVs) {
|
750
613
|
const glTFPbrMetallicRoughness = {};
|
751
614
|
const glTFMaterial = {
|
752
615
|
name: babylonPBRMaterial.name,
|
@@ -758,88 +621,81 @@ export class _GLTFMaterialExporter {
|
|
758
621
|
if (albedoColor) {
|
759
622
|
glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];
|
760
623
|
}
|
761
|
-
return this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then((metallicRoughness) => {
|
762
|
-
return this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords);
|
763
|
-
});
|
764
|
-
}
|
765
|
-
else {
|
766
|
-
return this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then((metallicRoughness) => {
|
767
|
-
return this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords);
|
768
|
-
});
|
769
624
|
}
|
770
|
-
|
771
|
-
|
772
|
-
|
625
|
+
const metallicRoughness = useMetallicRoughness
|
626
|
+
? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs)
|
627
|
+
: await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs);
|
628
|
+
await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs);
|
629
|
+
await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial, mimeType);
|
773
630
|
const materials = this._exporter._materials;
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
631
|
+
materials.push(glTFMaterial);
|
632
|
+
return materials.length - 1;
|
633
|
+
}
|
634
|
+
async _setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs) {
|
635
|
+
SetAlphaMode(glTFMaterial, babylonPBRMaterial);
|
636
|
+
if (!metallicRoughness.baseColor.equalsWithEpsilon(white, epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, epsilon)) {
|
637
|
+
glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];
|
638
|
+
}
|
639
|
+
if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {
|
640
|
+
glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;
|
641
|
+
}
|
642
|
+
if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {
|
643
|
+
glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;
|
644
|
+
}
|
645
|
+
if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {
|
646
|
+
if (!babylonPBRMaterial._twoSidedLighting) {
|
647
|
+
Tools.Warn(babylonPBRMaterial.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.");
|
786
648
|
}
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
glTFMaterial.normalTexture = glTFTexture;
|
799
|
-
if (bumpTexture.level !== 1) {
|
800
|
-
glTFMaterial.normalTexture.scale = bumpTexture.level;
|
801
|
-
}
|
802
|
-
}
|
803
|
-
});
|
804
|
-
promises.push(promise);
|
805
|
-
}
|
806
|
-
const ambientTexture = babylonPBRMaterial._ambientTexture;
|
807
|
-
if (ambientTexture) {
|
808
|
-
const promise = this._exportTextureAsync(ambientTexture, mimeType).then((glTFTexture) => {
|
809
|
-
if (glTFTexture) {
|
810
|
-
const occlusionTexture = {
|
811
|
-
index: glTFTexture.index,
|
812
|
-
texCoord: glTFTexture.texCoord,
|
813
|
-
extensions: glTFTexture.extensions,
|
814
|
-
};
|
815
|
-
glTFMaterial.occlusionTexture = occlusionTexture;
|
816
|
-
const ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength;
|
817
|
-
if (ambientTextureStrength) {
|
818
|
-
occlusionTexture.strength = ambientTextureStrength;
|
819
|
-
}
|
649
|
+
glTFMaterial.doubleSided = true;
|
650
|
+
}
|
651
|
+
if (hasUVs) {
|
652
|
+
const promises = [];
|
653
|
+
const bumpTexture = babylonPBRMaterial._bumpTexture;
|
654
|
+
if (bumpTexture) {
|
655
|
+
promises.push(this.exportTextureAsync(bumpTexture, mimeType).then((glTFTexture) => {
|
656
|
+
if (glTFTexture) {
|
657
|
+
glTFMaterial.normalTexture = glTFTexture;
|
658
|
+
if (bumpTexture.level !== 1) {
|
659
|
+
glTFMaterial.normalTexture.scale = bumpTexture.level;
|
820
660
|
}
|
821
|
-
}
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
661
|
+
}
|
662
|
+
}));
|
663
|
+
}
|
664
|
+
const ambientTexture = babylonPBRMaterial._ambientTexture;
|
665
|
+
if (ambientTexture) {
|
666
|
+
promises.push(this.exportTextureAsync(ambientTexture, mimeType).then((glTFTexture) => {
|
667
|
+
if (glTFTexture) {
|
668
|
+
const occlusionTexture = {
|
669
|
+
index: glTFTexture.index,
|
670
|
+
texCoord: glTFTexture.texCoord,
|
671
|
+
extensions: glTFTexture.extensions,
|
672
|
+
};
|
673
|
+
glTFMaterial.occlusionTexture = occlusionTexture;
|
674
|
+
const ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength;
|
675
|
+
if (ambientTextureStrength) {
|
676
|
+
occlusionTexture.strength = ambientTextureStrength;
|
829
677
|
}
|
830
|
-
}
|
831
|
-
|
832
|
-
}
|
678
|
+
}
|
679
|
+
}));
|
833
680
|
}
|
834
|
-
const
|
835
|
-
if (
|
836
|
-
|
681
|
+
const emissiveTexture = babylonPBRMaterial._emissiveTexture;
|
682
|
+
if (emissiveTexture) {
|
683
|
+
promises.push(this.exportTextureAsync(emissiveTexture, mimeType).then((glTFTexture) => {
|
684
|
+
if (glTFTexture) {
|
685
|
+
glTFMaterial.emissiveTexture = glTFTexture;
|
686
|
+
}
|
687
|
+
}));
|
837
688
|
}
|
838
|
-
|
839
|
-
|
840
|
-
|
689
|
+
if (promises.length > 0) {
|
690
|
+
this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);
|
691
|
+
await Promise.all(promises);
|
692
|
+
}
|
693
|
+
}
|
694
|
+
const emissiveColor = babylonPBRMaterial._emissiveColor;
|
695
|
+
if (!emissiveColor.equalsWithEpsilon(black, epsilon)) {
|
696
|
+
glTFMaterial.emissiveFactor = emissiveColor.asArray();
|
841
697
|
}
|
842
|
-
|
698
|
+
glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
|
843
699
|
}
|
844
700
|
_getPixelsFromTexture(babylonTexture) {
|
845
701
|
const pixels = babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_BYTE
|
@@ -847,13 +703,7 @@ export class _GLTFMaterialExporter {
|
|
847
703
|
: babylonTexture.readPixels();
|
848
704
|
return pixels;
|
849
705
|
}
|
850
|
-
|
851
|
-
* Extracts a texture from a Babylon texture into file data and glTF data
|
852
|
-
* @param babylonTexture Babylon texture to extract
|
853
|
-
* @param mimeType Mime Type of the babylonTexture
|
854
|
-
* @returns glTF texture info, or null if the texture format is not supported
|
855
|
-
*/
|
856
|
-
_exportTextureAsync(babylonTexture, mimeType) {
|
706
|
+
async exportTextureAsync(babylonTexture, mimeType) {
|
857
707
|
const extensionPromise = this._exporter._extensionsPreExportTextureAsync("exporter", babylonTexture, mimeType);
|
858
708
|
if (!extensionPromise) {
|
859
709
|
return this._exportTextureInfoAsync(babylonTexture, mimeType);
|
@@ -866,8 +716,8 @@ export class _GLTFMaterialExporter {
|
|
866
716
|
});
|
867
717
|
}
|
868
718
|
async _exportTextureInfoAsync(babylonTexture, mimeType) {
|
869
|
-
|
870
|
-
if (!
|
719
|
+
let textureInfo = this._textureMap.get(babylonTexture);
|
720
|
+
if (!textureInfo) {
|
871
721
|
const pixels = await this._getPixelsFromTexture(babylonTexture);
|
872
722
|
if (!pixels) {
|
873
723
|
return null;
|
@@ -899,16 +749,16 @@ export class _GLTFMaterialExporter {
|
|
899
749
|
})();
|
900
750
|
internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndexPromise;
|
901
751
|
}
|
902
|
-
|
903
|
-
this._textureMap
|
904
|
-
this._exporter._extensionsPostExportTextures("exporter",
|
752
|
+
textureInfo = this._exportTextureInfo(await imageIndexPromise, samplerIndex, babylonTexture.coordinatesIndex);
|
753
|
+
this._textureMap.set(babylonTexture, textureInfo);
|
754
|
+
this._exporter._extensionsPostExportTextures("exporter", textureInfo, babylonTexture);
|
905
755
|
}
|
906
|
-
return
|
756
|
+
return textureInfo;
|
907
757
|
}
|
908
758
|
_exportImage(name, mimeType, data) {
|
909
759
|
const imageData = this._exporter._imageData;
|
910
760
|
const baseName = name.replace(/\.\/|\/|\.\\|\\/g, "_");
|
911
|
-
const extension =
|
761
|
+
const extension = GetFileExtensionFromMimeType(mimeType);
|
912
762
|
let fileName = baseName + extension;
|
913
763
|
if (fileName in imageData) {
|
914
764
|
fileName = `${baseName}_${Tools.RandomId()}${extension}`;
|
@@ -952,16 +802,4 @@ export class _GLTFMaterialExporter {
|
|
952
802
|
return samplers.length - 1;
|
953
803
|
}
|
954
804
|
}
|
955
|
-
/**
|
956
|
-
* Represents the dielectric specular values for R, G and B
|
957
|
-
*/
|
958
|
-
_GLTFMaterialExporter._DielectricSpecular = new Color3(0.04, 0.04, 0.04);
|
959
|
-
/**
|
960
|
-
* Allows the maximum specular power to be defined for material calculations
|
961
|
-
*/
|
962
|
-
_GLTFMaterialExporter._MaxSpecularPower = 1024;
|
963
|
-
/**
|
964
|
-
* Numeric tolerance value
|
965
|
-
*/
|
966
|
-
_GLTFMaterialExporter._Epsilon = 1e-6;
|
967
805
|
//# sourceMappingURL=glTFMaterialExporter.js.map
|