Skip to content

Commit bff96da

Browse files
author
Mike Bond
committed
Adding support to export GLB with OpenPBR
1 parent 9bf4077 commit bff96da

File tree

3 files changed

+121
-16
lines changed

3 files changed

+121
-16
lines changed

packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { PBRBaseMaterial } from "core/Materials/PBR/pbrBaseMaterial";
66
import type { BaseTexture } from "core/Materials/Textures/baseTexture";
77

88
import { Tools } from "core/Misc/tools";
9+
import { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
910

1011
const NAME = "KHR_materials_clearcoat";
1112

@@ -53,6 +54,19 @@ export class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {
5354
}
5455
return additionalTextures;
5556
}
57+
} else if (babylonMaterial instanceof OpenPBRMaterial) {
58+
if (babylonMaterial.coatWeight > 0) {
59+
if (babylonMaterial.coatWeightTexture) {
60+
additionalTextures.push(babylonMaterial.coatWeightTexture);
61+
}
62+
if (babylonMaterial.geometryCoatNormalTexture) {
63+
additionalTextures.push(babylonMaterial.geometryCoatNormalTexture);
64+
}
65+
if (babylonMaterial.coatRoughnessTexture) {
66+
additionalTextures.push(babylonMaterial.coatRoughnessTexture);
67+
}
68+
return additionalTextures;
69+
}
5670
}
5771

5872
return [];
@@ -101,6 +115,43 @@ export class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {
101115
this._exporter._materialNeedsUVsSet.add(babylonMaterial);
102116
}
103117

118+
node.extensions[NAME] = clearCoatInfo;
119+
} else if (babylonMaterial instanceof OpenPBRMaterial) {
120+
if (babylonMaterial.coatWeight == 0.0) {
121+
resolve(node);
122+
return;
123+
}
124+
125+
this._wasUsed = true;
126+
127+
node.extensions = node.extensions || {};
128+
129+
const clearCoatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.coatWeightTexture);
130+
let clearCoatTextureRoughnessInfo;
131+
if (babylonMaterial.useCoatRoughnessFromWeightTexture) {
132+
clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.coatWeightTexture);
133+
} else {
134+
clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.coatRoughnessTexture);
135+
}
136+
137+
if (babylonMaterial.coatColorTexture) {
138+
Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);
139+
}
140+
141+
const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.geometryCoatNormalTexture);
142+
143+
const clearCoatInfo: IKHRMaterialsClearcoat = {
144+
clearcoatFactor: babylonMaterial.coatWeight,
145+
clearcoatTexture: clearCoatTextureInfo ?? undefined,
146+
clearcoatRoughnessFactor: babylonMaterial.coatRoughness,
147+
clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo ?? undefined,
148+
clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,
149+
};
150+
151+
if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {
152+
this._exporter._materialNeedsUVsSet.add(babylonMaterial);
153+
}
154+
104155
node.extensions[NAME] = clearCoatInfo;
105156
}
106157
resolve(node);

packages/dev/serializers/src/glTF/2.0/glTFExporter.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import { Color3, Color4 } from "core/Maths/math.color";
8080
import { TargetCamera } from "core/Cameras/targetCamera";
8181
import { Epsilon } from "core/Maths/math.constants";
8282
import { DataWriter } from "./dataWriter";
83+
import { OpenPBRMaterial } from "core/Materials";
8384

8485
class ExporterState {
8586
// Babylon indices array, start, count, offset, flip -> glTF accessor index
@@ -1411,6 +1412,8 @@ export class GLTFExporter {
14111412
materialIndex = await this._materialExporter.exportPBRMaterialAsync(babylonMaterial, hasUVs);
14121413
} else if (babylonMaterial instanceof StandardMaterial) {
14131414
materialIndex = await this._materialExporter.exportStandardMaterialAsync(babylonMaterial, hasUVs);
1415+
} else if (babylonMaterial instanceof OpenPBRMaterial) {
1416+
materialIndex = await this._materialExporter.exportOpenPBRMaterialAsync(babylonMaterial, hasUVs);
14141417
} else {
14151418
Logger.Warn(`Unsupported material '${babylonMaterial.name}' with type ${babylonMaterial.getClassName()}`);
14161419
return;

packages/dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ import { DumpTools } from "core/Misc/dumpTools";
2222

2323
import type { Material } from "core/Materials/material";
2424
import type { StandardMaterial } from "core/Materials/standardMaterial";
25-
import type { PBRBaseMaterial } from "core/Materials/PBR/pbrBaseMaterial";
25+
import { PBRBaseMaterial } from "core/Materials/PBR/pbrBaseMaterial";
2626
import { SpecularPowerToRoughness } from "core/Helpers/materialConversionHelper";
27+
import type { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
2728

2829
const Epsilon = 1e-6;
2930
const DielectricSpecular = new Color3(0.04, 0.04, 0.04);
@@ -524,26 +525,35 @@ export class GLTFMaterialExporter {
524525

525526
/**
526527
* Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors
528+
* @param baseColor Base color of the material
529+
* @param metallic Metallic factor of the material
530+
* @param roughness Roughness factor of the material
531+
* @param albedoTexture Albedo texture of the material
532+
* @param metallicRoughnessTexture Metallic roughness texture of the material
527533
* @param babylonPBRMaterial BJS PBR Metallic Roughness Material
528534
* @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface
529535
* @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
530536
* @returns glTF PBR Metallic Roughness factors
531537
*/
532538
private async _convertMetalRoughFactorsToMetallicRoughnessAsync(
533-
babylonPBRMaterial: PBRBaseMaterial,
539+
baseColor: Color3,
540+
metallic: Nullable<number>,
541+
roughness: Nullable<number>,
542+
albedoTexture: Nullable<BaseTexture>,
543+
metallicRoughnessTexture: Nullable<BaseTexture>,
544+
babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,
534545
glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,
535546
hasUVs: boolean
536547
): Promise<IPBRMetallicRoughness> {
537548
const promises: Promise<void>[] = [];
538549

539550
const metallicRoughness: IPBRMetallicRoughness = {
540-
baseColor: babylonPBRMaterial._albedoColor,
541-
metallic: babylonPBRMaterial._metallic,
542-
roughness: babylonPBRMaterial._roughness,
551+
baseColor: baseColor,
552+
metallic: metallic,
553+
roughness: roughness,
543554
};
544555

545556
if (hasUVs) {
546-
const albedoTexture = babylonPBRMaterial._albedoTexture;
547557
if (albedoTexture) {
548558
promises.push(
549559
this.exportTextureAsync(albedoTexture).then((glTFTexture) => {
@@ -553,10 +563,9 @@ export class GLTFMaterialExporter {
553563
})
554564
);
555565
}
556-
const metallicTexture = babylonPBRMaterial._metallicTexture;
557-
if (metallicTexture) {
566+
if (metallicRoughnessTexture) {
558567
promises.push(
559-
this.exportTextureAsync(metallicTexture).then((glTFTexture) => {
568+
this.exportTextureAsync(metallicRoughnessTexture).then((glTFTexture) => {
560569
if (glTFTexture) {
561570
glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
562571
}
@@ -741,7 +750,16 @@ export class GLTFMaterialExporter {
741750
}
742751

743752
const metallicRoughness = useMetallicRoughness
744-
? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs)
753+
? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(
754+
babylonPBRMaterial._albedoColor,
755+
babylonPBRMaterial._metallic,
756+
babylonPBRMaterial._roughness,
757+
babylonPBRMaterial._albedoTexture,
758+
babylonPBRMaterial._metallicTexture,
759+
babylonPBRMaterial,
760+
glTFPbrMetallicRoughness,
761+
hasUVs
762+
)
745763
: await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs);
746764

747765
await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);
@@ -754,7 +772,7 @@ export class GLTFMaterialExporter {
754772

755773
private async _setMetallicRoughnessPbrMaterialAsync(
756774
metallicRoughness: IPBRMetallicRoughness,
757-
babylonPBRMaterial: PBRBaseMaterial,
775+
babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,
758776
glTFMaterial: IMaterial,
759777
glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,
760778
hasUVs: boolean
@@ -782,7 +800,7 @@ export class GLTFMaterialExporter {
782800
if (hasUVs) {
783801
const promises: Promise<void>[] = [];
784802

785-
const bumpTexture = babylonPBRMaterial._bumpTexture;
803+
const bumpTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._bumpTexture : babylonPBRMaterial.geometryNormalTexture;
786804
if (bumpTexture) {
787805
promises.push(
788806
this.exportTextureAsync(bumpTexture).then((glTFTexture) => {
@@ -796,7 +814,7 @@ export class GLTFMaterialExporter {
796814
);
797815
}
798816

799-
const ambientTexture = babylonPBRMaterial._ambientTexture;
817+
const ambientTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._ambientTexture : babylonPBRMaterial.ambientOcclusionTexture;
800818
if (ambientTexture) {
801819
promises.push(
802820
this.exportTextureAsync(ambientTexture).then((glTFTexture) => {
@@ -808,7 +826,8 @@ export class GLTFMaterialExporter {
808826
};
809827

810828
glTFMaterial.occlusionTexture = occlusionTexture;
811-
const ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength;
829+
const ambientTextureStrength =
830+
babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._ambientTextureStrength : babylonPBRMaterial.ambientOcclusionTexture.level;
812831
if (ambientTextureStrength) {
813832
occlusionTexture.strength = ambientTextureStrength;
814833
}
@@ -817,7 +836,7 @@ export class GLTFMaterialExporter {
817836
);
818837
}
819838

820-
const emissiveTexture = babylonPBRMaterial._emissiveTexture;
839+
const emissiveTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveTexture : babylonPBRMaterial.emissionColorTexture;
821840
if (emissiveTexture) {
822841
promises.push(
823842
this.exportTextureAsync(emissiveTexture).then((glTFTexture) => {
@@ -834,14 +853,46 @@ export class GLTFMaterialExporter {
834853
}
835854
}
836855

837-
const emissiveColor = babylonPBRMaterial._emissiveColor;
856+
const emissiveColor = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveColor : babylonPBRMaterial.emissionColor;
838857
if (!emissiveColor.equalsWithEpsilon(Black, Epsilon)) {
839858
glTFMaterial.emissiveFactor = emissiveColor.asArray();
840859
}
841860

842861
glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
843862
}
844863

864+
public async exportOpenPBRMaterialAsync(babylonOpenPBRMaterial: OpenPBRMaterial, hasUVs: boolean): Promise<number> {
865+
const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};
866+
867+
const glTFMaterial: IMaterial = {
868+
name: babylonOpenPBRMaterial.name,
869+
};
870+
871+
const albedoColor = babylonOpenPBRMaterial.baseColor;
872+
const alpha = babylonOpenPBRMaterial.geometryOpacity;
873+
if (albedoColor) {
874+
glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];
875+
}
876+
877+
const metallicRoughness = await this._convertMetalRoughFactorsToMetallicRoughnessAsync(
878+
babylonOpenPBRMaterial.baseColor,
879+
babylonOpenPBRMaterial.baseMetalness,
880+
babylonOpenPBRMaterial.specularRoughness,
881+
babylonOpenPBRMaterial.baseColorTexture,
882+
babylonOpenPBRMaterial.baseMetalRoughTexture,
883+
babylonOpenPBRMaterial,
884+
glTFPbrMetallicRoughness,
885+
hasUVs
886+
);
887+
888+
await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonOpenPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);
889+
await this._finishMaterialAsync(glTFMaterial, babylonOpenPBRMaterial);
890+
891+
const materials = this._exporter._materials;
892+
materials.push(glTFMaterial);
893+
return materials.length - 1;
894+
}
895+
845896
public async exportTextureAsync(babylonTexture: BaseTexture): Promise<Nullable<ITextureInfo>> {
846897
let textureInfo = this._textureMap.get(babylonTexture);
847898
if (textureInfo) {

0 commit comments

Comments
 (0)