@babylonjs/serializers 5.32.1 → 5.33.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/KHR_texture_transform.d.ts +2 -9
- package/glTF/2.0/Extensions/KHR_texture_transform.js +5 -54
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/glTFExporter.d.ts +2 -2
- package/glTF/2.0/glTFExporter.js +3 -3
- package/glTF/2.0/glTFExporter.js.map +1 -1
- package/glTF/2.0/glTFExporterExtension.d.ts +1 -1
- package/glTF/2.0/glTFExporterExtension.js.map +1 -1
- package/glTF/2.0/glTFMaterialExporter.d.ts +6 -13
- package/glTF/2.0/glTFMaterialExporter.js +216 -262
- package/glTF/2.0/glTFMaterialExporter.js.map +1 -1
- package/package.json +3 -3
- package/glTF/2.0/shaders/textureTransform.fragment.d.ts +0 -5
- package/glTF/2.0/shaders/textureTransform.fragment.js +0 -13
- package/glTF/2.0/shaders/textureTransform.fragment.js.map +0 -1
|
@@ -6,6 +6,17 @@ import { TextureTools } from "@babylonjs/core/Misc/textureTools.js";
|
|
|
6
6
|
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
|
|
7
7
|
import { RawTexture } from "@babylonjs/core/Materials/Textures/rawTexture.js";
|
|
8
8
|
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
|
9
|
+
import { DumpTools } from "@babylonjs/core/Misc/dumpTools.js";
|
|
10
|
+
function getFileExtensionFromMimeType(mimeType) {
|
|
11
|
+
switch (mimeType) {
|
|
12
|
+
case "image/jpeg" /* JPEG */:
|
|
13
|
+
return ".jpg";
|
|
14
|
+
case "image/png" /* PNG */:
|
|
15
|
+
return ".png";
|
|
16
|
+
case "image/webp" /* WEBP */:
|
|
17
|
+
return ".webp";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
9
20
|
/**
|
|
10
21
|
* Utility methods for working with glTF material conversion properties. This class should only be used internally
|
|
11
22
|
* @internal
|
|
@@ -16,6 +27,8 @@ export class _GLTFMaterialExporter {
|
|
|
16
27
|
* Mapping to store textures
|
|
17
28
|
*/
|
|
18
29
|
this._textureMap = {};
|
|
30
|
+
// Mapping of internal textures to images to avoid exporting duplicate images.
|
|
31
|
+
this._internalTextureToImage = {};
|
|
19
32
|
this._textureMap = {};
|
|
20
33
|
this._exporter = exporter;
|
|
21
34
|
}
|
|
@@ -199,68 +212,68 @@ export class _GLTFMaterialExporter {
|
|
|
199
212
|
const materialMap = this._exporter._materialMap;
|
|
200
213
|
const materials = this._exporter._materials;
|
|
201
214
|
const promises = [];
|
|
202
|
-
const
|
|
203
|
-
const
|
|
215
|
+
const pbrMetallicRoughness = this._convertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
|
|
216
|
+
const material = { name: babylonStandardMaterial.name };
|
|
204
217
|
if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
|
|
205
218
|
if (!babylonStandardMaterial.twoSidedLighting) {
|
|
206
219
|
Tools.Warn(babylonStandardMaterial.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.");
|
|
207
220
|
}
|
|
208
|
-
|
|
221
|
+
material.doubleSided = true;
|
|
209
222
|
}
|
|
210
223
|
if (hasTextureCoords) {
|
|
211
224
|
if (babylonStandardMaterial.diffuseTexture) {
|
|
212
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then((
|
|
213
|
-
if (
|
|
214
|
-
|
|
225
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then((textureInfo) => {
|
|
226
|
+
if (textureInfo) {
|
|
227
|
+
pbrMetallicRoughness.baseColorTexture = textureInfo;
|
|
215
228
|
}
|
|
216
229
|
}));
|
|
217
230
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
231
|
+
const bumpTexture = babylonStandardMaterial.bumpTexture;
|
|
232
|
+
if (bumpTexture) {
|
|
233
|
+
promises.push(this._exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {
|
|
234
|
+
if (textureInfo) {
|
|
235
|
+
material.normalTexture = textureInfo;
|
|
236
|
+
if (bumpTexture.level !== 1) {
|
|
237
|
+
material.normalTexture.scale = bumpTexture.level;
|
|
224
238
|
}
|
|
225
239
|
}
|
|
226
240
|
}));
|
|
227
241
|
}
|
|
228
242
|
if (babylonStandardMaterial.emissiveTexture) {
|
|
229
|
-
|
|
230
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then((
|
|
231
|
-
if (
|
|
232
|
-
|
|
243
|
+
material.emissiveFactor = [1.0, 1.0, 1.0];
|
|
244
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then((textureInfo) => {
|
|
245
|
+
if (textureInfo) {
|
|
246
|
+
material.emissiveTexture = textureInfo;
|
|
233
247
|
}
|
|
234
248
|
}));
|
|
235
249
|
}
|
|
236
250
|
if (babylonStandardMaterial.ambientTexture) {
|
|
237
|
-
promises.push(this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then((
|
|
238
|
-
if (
|
|
251
|
+
promises.push(this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then((textureInfo) => {
|
|
252
|
+
if (textureInfo) {
|
|
239
253
|
const occlusionTexture = {
|
|
240
|
-
index:
|
|
254
|
+
index: textureInfo.index,
|
|
241
255
|
};
|
|
242
|
-
|
|
243
|
-
occlusionTexture.strength = 1.0;
|
|
256
|
+
material.occlusionTexture = occlusionTexture;
|
|
244
257
|
}
|
|
245
258
|
}));
|
|
246
259
|
}
|
|
247
260
|
}
|
|
248
261
|
if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
|
|
249
262
|
if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {
|
|
250
|
-
|
|
263
|
+
material.alphaMode = "BLEND" /* BLEND */;
|
|
251
264
|
}
|
|
252
265
|
else {
|
|
253
266
|
Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
|
|
254
267
|
}
|
|
255
268
|
}
|
|
256
269
|
if (babylonStandardMaterial.emissiveColor && !_GLTFMaterialExporter._FuzzyEquals(babylonStandardMaterial.emissiveColor, Color3.Black(), _GLTFMaterialExporter._Epsilon)) {
|
|
257
|
-
|
|
270
|
+
material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
|
|
258
271
|
}
|
|
259
|
-
|
|
260
|
-
_GLTFMaterialExporter._SetAlphaMode(
|
|
261
|
-
materials.push(
|
|
272
|
+
material.pbrMetallicRoughness = pbrMetallicRoughness;
|
|
273
|
+
_GLTFMaterialExporter._SetAlphaMode(material, babylonStandardMaterial);
|
|
274
|
+
materials.push(material);
|
|
262
275
|
materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1;
|
|
263
|
-
return this._finishMaterial(promises,
|
|
276
|
+
return this._finishMaterial(promises, material, babylonStandardMaterial, mimeType);
|
|
264
277
|
}
|
|
265
278
|
_finishMaterial(promises, glTFMaterial, babylonMaterial, mimeType) {
|
|
266
279
|
return Promise.all(promises).then(() => {
|
|
@@ -292,19 +305,15 @@ export class _GLTFMaterialExporter {
|
|
|
292
305
|
* @param mimeType mimetype of the image
|
|
293
306
|
* @returns base64 image string
|
|
294
307
|
*/
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const data = await engine._readTexturePixels(tempTexture, width, height);
|
|
305
|
-
const base64 = await Tools.DumpDataAsync(width, height, data, mimeType, undefined, true, false);
|
|
306
|
-
resolve(base64);
|
|
307
|
-
});
|
|
308
|
+
async _getImageDataAsync(buffer, width, height, mimeType) {
|
|
309
|
+
const textureType = Constants.TEXTURETYPE_UNSIGNED_INT;
|
|
310
|
+
const hostingScene = this._exporter._babylonScene;
|
|
311
|
+
const engine = hostingScene.getEngine();
|
|
312
|
+
// Create a temporary texture with the texture buffer data
|
|
313
|
+
const tempTexture = engine.createRawTexture(buffer, width, height, Constants.TEXTUREFORMAT_RGBA, false, true, Texture.NEAREST_SAMPLINGMODE, null, textureType);
|
|
314
|
+
await TextureTools.ApplyPostProcess("pass", tempTexture, hostingScene, textureType, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTUREFORMAT_RGBA);
|
|
315
|
+
const data = await engine._readTexturePixels(tempTexture, width, height);
|
|
316
|
+
return (await DumpTools.DumpDataAsync(width, height, data, mimeType, undefined, true, true));
|
|
308
317
|
}
|
|
309
318
|
/**
|
|
310
319
|
* Generates a white texture based on the specified width and height
|
|
@@ -394,7 +403,7 @@ export class _GLTFMaterialExporter {
|
|
|
394
403
|
*/
|
|
395
404
|
async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(diffuseTexture, specularGlossinessTexture, factors, mimeType) {
|
|
396
405
|
var _a;
|
|
397
|
-
const promises =
|
|
406
|
+
const promises = new Array();
|
|
398
407
|
if (!(diffuseTexture || specularGlossinessTexture)) {
|
|
399
408
|
return Promise.reject("_ConvertSpecularGlosinessTexturesToMetallicRoughness: diffuse and specular glossiness textures are not defined!");
|
|
400
409
|
}
|
|
@@ -488,16 +497,14 @@ export class _GLTFMaterialExporter {
|
|
|
488
497
|
}
|
|
489
498
|
}
|
|
490
499
|
if (writeOutMetallicRoughnessTexture) {
|
|
491
|
-
|
|
492
|
-
metallicRoughnessFactors.
|
|
493
|
-
});
|
|
494
|
-
promises.push(promise);
|
|
500
|
+
promises.push(this._getImageDataAsync(metallicRoughnessBuffer, width, height, mimeType).then((data) => {
|
|
501
|
+
metallicRoughnessFactors.metallicRoughnessTextureData = data;
|
|
502
|
+
}));
|
|
495
503
|
}
|
|
496
504
|
if (writeOutBaseColorTexture) {
|
|
497
|
-
|
|
498
|
-
metallicRoughnessFactors.
|
|
499
|
-
});
|
|
500
|
-
promises.push(promise);
|
|
505
|
+
promises.push(this._getImageDataAsync(baseColorBuffer, width, height, mimeType).then((data) => {
|
|
506
|
+
metallicRoughnessFactors.baseColorTextureData = data;
|
|
507
|
+
}));
|
|
501
508
|
}
|
|
502
509
|
return Promise.all(promises).then(() => {
|
|
503
510
|
return metallicRoughnessFactors;
|
|
@@ -592,71 +599,79 @@ export class _GLTFMaterialExporter {
|
|
|
592
599
|
return metallicRoughness;
|
|
593
600
|
});
|
|
594
601
|
}
|
|
595
|
-
|
|
596
|
-
const sampler =
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
602
|
+
_getTextureSampler(texture) {
|
|
603
|
+
const sampler = {};
|
|
604
|
+
if (!texture || !(texture instanceof Texture)) {
|
|
605
|
+
return sampler;
|
|
606
|
+
}
|
|
607
|
+
const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);
|
|
608
|
+
if (wrapS !== 10497 /* REPEAT */) {
|
|
609
|
+
sampler.wrapS = wrapS;
|
|
610
|
+
}
|
|
611
|
+
const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);
|
|
612
|
+
if (wrapT !== 10497 /* REPEAT */) {
|
|
613
|
+
sampler.wrapT = wrapT;
|
|
614
|
+
}
|
|
615
|
+
switch (texture.samplingMode) {
|
|
616
|
+
case Texture.LINEAR_LINEAR: {
|
|
617
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
618
|
+
sampler.minFilter = 9729 /* LINEAR */;
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
case Texture.LINEAR_NEAREST: {
|
|
622
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
623
|
+
sampler.minFilter = 9728 /* NEAREST */;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
case Texture.NEAREST_LINEAR: {
|
|
627
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
628
|
+
sampler.minFilter = 9729 /* LINEAR */;
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
case Texture.NEAREST_LINEAR_MIPLINEAR: {
|
|
632
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
633
|
+
sampler.minFilter = 9987 /* LINEAR_MIPMAP_LINEAR */;
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
636
|
+
case Texture.NEAREST_NEAREST: {
|
|
637
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
638
|
+
sampler.minFilter = 9728 /* NEAREST */;
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
case Texture.NEAREST_LINEAR_MIPNEAREST: {
|
|
642
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
643
|
+
sampler.minFilter = 9985 /* LINEAR_MIPMAP_NEAREST */;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
case Texture.LINEAR_NEAREST_MIPNEAREST: {
|
|
647
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
648
|
+
sampler.minFilter = 9984 /* NEAREST_MIPMAP_NEAREST */;
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
case Texture.LINEAR_NEAREST_MIPLINEAR: {
|
|
652
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
653
|
+
sampler.minFilter = 9986 /* NEAREST_MIPMAP_LINEAR */;
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
case Texture.NEAREST_NEAREST_MIPLINEAR: {
|
|
657
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
658
|
+
sampler.minFilter = 9986 /* NEAREST_MIPMAP_LINEAR */;
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
case Texture.LINEAR_LINEAR_MIPLINEAR: {
|
|
662
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
663
|
+
sampler.minFilter = 9987 /* LINEAR_MIPMAP_LINEAR */;
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
case Texture.LINEAR_LINEAR_MIPNEAREST: {
|
|
667
|
+
sampler.magFilter = 9729 /* LINEAR */;
|
|
668
|
+
sampler.minFilter = 9985 /* LINEAR_MIPMAP_NEAREST */;
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
case Texture.NEAREST_NEAREST_MIPNEAREST: {
|
|
672
|
+
sampler.magFilter = 9728 /* NEAREST */;
|
|
673
|
+
sampler.minFilter = 9984 /* NEAREST_MIPMAP_NEAREST */;
|
|
674
|
+
break;
|
|
660
675
|
}
|
|
661
676
|
}
|
|
662
677
|
return sampler;
|
|
@@ -678,15 +693,6 @@ export class _GLTFMaterialExporter {
|
|
|
678
693
|
}
|
|
679
694
|
}
|
|
680
695
|
}
|
|
681
|
-
_getGLTFTextureWrapModesSampler(texture) {
|
|
682
|
-
const wrapS = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapU : Texture.WRAP_ADDRESSMODE);
|
|
683
|
-
const wrapT = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapV : Texture.WRAP_ADDRESSMODE);
|
|
684
|
-
if (wrapS === 10497 /* REPEAT */ && wrapT === 10497 /* REPEAT */) {
|
|
685
|
-
// default wrapping mode in glTF, so omitting
|
|
686
|
-
return {};
|
|
687
|
-
}
|
|
688
|
-
return { wrapS: wrapS, wrapT: wrapT };
|
|
689
|
-
}
|
|
690
696
|
/**
|
|
691
697
|
* Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors
|
|
692
698
|
* @param babylonPBRMaterial BJS PBR Metallic Roughness Material
|
|
@@ -695,45 +701,30 @@ export class _GLTFMaterialExporter {
|
|
|
695
701
|
* @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied
|
|
696
702
|
* @returns glTF PBR Metallic Roughness factors
|
|
697
703
|
*/
|
|
698
|
-
_convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType,
|
|
704
|
+
_convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, pbrMetallicRoughness, hasTextureCoords) {
|
|
699
705
|
return Promise.resolve().then(() => {
|
|
700
|
-
const samplers = this._exporter._samplers;
|
|
701
|
-
const textures = this._exporter._textures;
|
|
702
|
-
const diffuseColor = babylonPBRMaterial._albedoColor;
|
|
703
|
-
const specularColor = babylonPBRMaterial._reflectivityColor;
|
|
704
|
-
const glossiness = babylonPBRMaterial._microSurface;
|
|
705
706
|
const specGloss = {
|
|
706
|
-
diffuseColor:
|
|
707
|
-
specularColor:
|
|
708
|
-
glossiness:
|
|
707
|
+
diffuseColor: babylonPBRMaterial._albedoColor,
|
|
708
|
+
specularColor: babylonPBRMaterial._reflectivityColor,
|
|
709
|
+
glossiness: babylonPBRMaterial._microSurface,
|
|
709
710
|
};
|
|
710
|
-
let samplerIndex = null;
|
|
711
711
|
const albedoTexture = babylonPBRMaterial._albedoTexture;
|
|
712
712
|
const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;
|
|
713
|
-
if (albedoTexture) {
|
|
714
|
-
const sampler = this._getGLTFTextureSampler(albedoTexture);
|
|
715
|
-
if (sampler.magFilter != null && sampler.minFilter != null && sampler.wrapS != null && sampler.wrapT != null) {
|
|
716
|
-
samplers.push(sampler);
|
|
717
|
-
samplerIndex = samplers.length - 1;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
713
|
const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;
|
|
721
714
|
if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {
|
|
722
715
|
return Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported");
|
|
723
716
|
}
|
|
724
717
|
if ((albedoTexture || reflectivityTexture) && hasTextureCoords) {
|
|
718
|
+
const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);
|
|
725
719
|
return this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType).then((metallicRoughnessFactors) => {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
720
|
+
const textures = this._exporter._textures;
|
|
721
|
+
if (metallicRoughnessFactors.baseColorTextureData) {
|
|
722
|
+
const imageIndex = this._exportImage(`baseColor${textures.length}`, mimeType, metallicRoughnessFactors.baseColorTextureData);
|
|
723
|
+
pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture === null || albedoTexture === void 0 ? void 0 : albedoTexture.coordinatesIndex);
|
|
731
724
|
}
|
|
732
|
-
if (metallicRoughnessFactors.
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;
|
|
736
|
-
}
|
|
725
|
+
if (metallicRoughnessFactors.metallicRoughnessTextureData) {
|
|
726
|
+
const imageIndex = this._exportImage(`metallicRoughness${textures.length}`, mimeType, metallicRoughnessFactors.metallicRoughnessTextureData);
|
|
727
|
+
pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture === null || reflectivityTexture === void 0 ? void 0 : reflectivityTexture.coordinatesIndex);
|
|
737
728
|
}
|
|
738
729
|
return metallicRoughnessFactors;
|
|
739
730
|
});
|
|
@@ -867,129 +858,92 @@ export class _GLTFMaterialExporter {
|
|
|
867
858
|
return this._exportTextureInfoAsync(texture, mimeType);
|
|
868
859
|
});
|
|
869
860
|
}
|
|
870
|
-
_exportTextureInfoAsync(babylonTexture, mimeType) {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
861
|
+
async _exportTextureInfoAsync(babylonTexture, mimeType) {
|
|
862
|
+
const textureUid = babylonTexture.uid;
|
|
863
|
+
if (textureUid in this._textureMap) {
|
|
864
|
+
return this._textureMap[textureUid];
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
const pixels = await this._getPixelsFromTexture(babylonTexture);
|
|
868
|
+
if (!pixels) {
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
const samplerIndex = this._exportTextureSampler(babylonTexture);
|
|
872
|
+
// Preserve texture mime type if defined
|
|
873
|
+
const textureMimeType = babylonTexture.mimeType;
|
|
874
|
+
if (textureMimeType) {
|
|
875
|
+
switch (textureMimeType) {
|
|
876
|
+
case "image/jpeg":
|
|
877
|
+
case "image/png":
|
|
878
|
+
case "image/webp":
|
|
879
|
+
mimeType = textureMimeType;
|
|
880
|
+
break;
|
|
881
|
+
default:
|
|
882
|
+
Tools.Warn("Unsupported media type: ${textureMimeType}");
|
|
890
883
|
break;
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
if (foundSamplerIndex == null) {
|
|
894
|
-
samplers.push(sampler);
|
|
895
|
-
samplerIndex = samplers.length - 1;
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
samplerIndex = foundSamplerIndex;
|
|
899
884
|
}
|
|
885
|
+
}
|
|
886
|
+
const internalTextureToImage = this._internalTextureToImage;
|
|
887
|
+
const internalTextureUniqueId = babylonTexture.getInternalTexture().uniqueId;
|
|
888
|
+
internalTextureToImage[internalTextureUniqueId] || (internalTextureToImage[internalTextureUniqueId] = {});
|
|
889
|
+
let imageIndex = internalTextureToImage[internalTextureUniqueId][mimeType];
|
|
890
|
+
if (imageIndex === undefined) {
|
|
900
891
|
const size = babylonTexture.getSize();
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
case "image/jpeg":
|
|
905
|
-
mimeType = "image/jpeg" /* JPEG */;
|
|
906
|
-
break;
|
|
907
|
-
case "image/png":
|
|
908
|
-
mimeType = "image/png" /* PNG */;
|
|
909
|
-
break;
|
|
910
|
-
case "image/webp":
|
|
911
|
-
mimeType = "image/webp" /* WEBP */;
|
|
912
|
-
break;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {
|
|
916
|
-
const textureInfo = this._getTextureInfoFromBase64(base64Data, babylonTexture.name.replace(/\.\/|\/|\.\\|\\/g, "_"), mimeType, babylonTexture.coordinatesIndex, samplerIndex);
|
|
917
|
-
if (textureInfo) {
|
|
918
|
-
this._textureMap[textureUid] = textureInfo;
|
|
919
|
-
this._exporter._extensionsPostExportTextures("linkTextureInfo", textureInfo, babylonTexture);
|
|
920
|
-
}
|
|
921
|
-
return textureInfo;
|
|
922
|
-
});
|
|
892
|
+
const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);
|
|
893
|
+
imageIndex = this._exportImage(babylonTexture.name, mimeType, data);
|
|
894
|
+
internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndex;
|
|
923
895
|
}
|
|
924
|
-
|
|
896
|
+
const textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, babylonTexture.coordinatesIndex);
|
|
897
|
+
this._textureMap[textureUid] = textureInfo;
|
|
898
|
+
return textureInfo;
|
|
899
|
+
}
|
|
925
900
|
}
|
|
926
|
-
|
|
927
|
-
* Builds a texture from base64 string
|
|
928
|
-
* @param base64Texture base64 texture string
|
|
929
|
-
* @param baseTextureName Name to use for the texture
|
|
930
|
-
* @param mimeType image mime type for the texture
|
|
931
|
-
* @param texCoordIndex
|
|
932
|
-
* @param samplerIndex
|
|
933
|
-
* @returns glTF texture info, or null if the texture format is not supported
|
|
934
|
-
*/
|
|
935
|
-
_getTextureInfoFromBase64(base64Texture, baseTextureName, mimeType, texCoordIndex, samplerIndex) {
|
|
936
|
-
const textures = this._exporter._textures;
|
|
937
|
-
const images = this._exporter._images;
|
|
901
|
+
_exportImage(name, mimeType, data) {
|
|
938
902
|
const imageData = this._exporter._imageData;
|
|
939
|
-
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
903
|
+
const baseName = name.replace(/\.\/|\/|\.\\|\\/g, "_");
|
|
904
|
+
const extension = getFileExtensionFromMimeType(mimeType);
|
|
905
|
+
let fileName = baseName + extension;
|
|
906
|
+
if (fileName in imageData) {
|
|
907
|
+
fileName = `${baseName}_${Tools.RandomId()}${extension}`;
|
|
908
|
+
}
|
|
909
|
+
imageData[fileName] = {
|
|
910
|
+
data: data,
|
|
911
|
+
mimeType: mimeType,
|
|
943
912
|
};
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
imageData[textureName] = imageValues;
|
|
961
|
-
if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */ || mimeType === "image/webp" /* WEBP */) {
|
|
962
|
-
const glTFImage = {
|
|
963
|
-
name: baseTextureName,
|
|
964
|
-
uri: textureName,
|
|
965
|
-
};
|
|
966
|
-
let foundIndex = null;
|
|
967
|
-
for (let i = 0; i < images.length; ++i) {
|
|
968
|
-
if (images[i].uri === originalTextureName) {
|
|
969
|
-
foundIndex = i;
|
|
970
|
-
break;
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
if (foundIndex == null) {
|
|
974
|
-
images.push(glTFImage);
|
|
975
|
-
glTFTexture.source = images.length - 1;
|
|
976
|
-
}
|
|
977
|
-
else {
|
|
978
|
-
glTFTexture.source = foundIndex;
|
|
979
|
-
}
|
|
980
|
-
textures.push(glTFTexture);
|
|
981
|
-
textureInfo = {
|
|
982
|
-
index: textures.length - 1,
|
|
983
|
-
};
|
|
984
|
-
if (texCoordIndex != null) {
|
|
985
|
-
textureInfo.texCoord = texCoordIndex;
|
|
986
|
-
}
|
|
913
|
+
const images = this._exporter._images;
|
|
914
|
+
images.push({
|
|
915
|
+
name: name,
|
|
916
|
+
uri: fileName,
|
|
917
|
+
});
|
|
918
|
+
return images.length - 1;
|
|
919
|
+
}
|
|
920
|
+
_exportTextureInfo(imageIndex, samplerIndex, coordinatesIndex) {
|
|
921
|
+
const textures = this._exporter._textures;
|
|
922
|
+
let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);
|
|
923
|
+
if (textureIndex === -1) {
|
|
924
|
+
textureIndex = textures.length;
|
|
925
|
+
textures.push({
|
|
926
|
+
source: imageIndex,
|
|
927
|
+
sampler: samplerIndex,
|
|
928
|
+
});
|
|
987
929
|
}
|
|
988
|
-
|
|
989
|
-
|
|
930
|
+
const textureInfo = { index: textureIndex };
|
|
931
|
+
if (coordinatesIndex) {
|
|
932
|
+
textureInfo.texCoord = coordinatesIndex;
|
|
990
933
|
}
|
|
991
934
|
return textureInfo;
|
|
992
935
|
}
|
|
936
|
+
_exportTextureSampler(texture) {
|
|
937
|
+
const sampler = this._getTextureSampler(texture);
|
|
938
|
+
// if a pre-existing sampler with identical parameters exists, then reuse the previous sampler
|
|
939
|
+
const samplers = this._exporter._samplers;
|
|
940
|
+
const samplerIndex = samplers.findIndex((s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT);
|
|
941
|
+
if (samplerIndex !== -1) {
|
|
942
|
+
return samplerIndex;
|
|
943
|
+
}
|
|
944
|
+
samplers.push(sampler);
|
|
945
|
+
return samplers.length - 1;
|
|
946
|
+
}
|
|
993
947
|
}
|
|
994
948
|
/**
|
|
995
949
|
* Represents the dielectric specular values for R, G and B
|