Skip to content

Commit 48b9e4d

Browse files
MiiBondMike Bond
authored andcommitted
WIP glTFLoader dynamic material load
1 parent e3bfa80 commit 48b9e4d

8 files changed

+270
-139
lines changed

packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Nullable } from "core/types";
2-
import { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
2+
import type { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
3+
import type { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
34
import type { Material } from "core/Materials/material";
45

56
import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces";
@@ -21,6 +22,8 @@ declare module "../../glTFFileLoader" {
2122
}
2223
}
2324

25+
let PBRMaterialClass: typeof PBRMaterial | typeof OpenPBRMaterial;
26+
2427
/**
2528
* [Specification](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_anisotropy)
2629
*/
@@ -60,8 +63,15 @@ export class KHR_materials_anisotropy implements IGLTFLoaderExtension {
6063
* @internal
6164
*/
6265
// eslint-disable-next-line no-restricted-syntax
63-
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
66+
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, useOpenPBR: boolean = false): Nullable<Promise<void>> {
6467
return GLTFLoader.LoadExtensionAsync<IKHRMaterialsAnisotropy>(context, material, this.name, async (extensionContext, extension) => {
68+
if (useOpenPBR) {
69+
const mod = await import("core/Materials/PBR/openPbrMaterial");
70+
PBRMaterialClass = mod.OpenPBRMaterial;
71+
} else {
72+
const mod = await import("core/Materials/PBR/pbrMaterial");
73+
PBRMaterialClass = mod.PBRMaterial;
74+
}
6575
const promises = new Array<Promise<any>>();
6676
promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial));
6777
promises.push(this._loadIridescencePropertiesAsync(extensionContext, extension, babylonMaterial));
@@ -70,23 +80,23 @@ export class KHR_materials_anisotropy implements IGLTFLoaderExtension {
7080
}
7181

7282
private async _loadIridescencePropertiesAsync(context: string, properties: IKHRMaterialsAnisotropy, babylonMaterial: Material): Promise<void> {
73-
if (!(babylonMaterial instanceof PBRMaterial)) {
83+
if (!(babylonMaterial instanceof PBRMaterialClass)) {
7484
throw new Error(`${context}: Material type not supported`);
7585
}
7686

7787
const promises = new Array<Promise<any>>();
7888

79-
babylonMaterial.anisotropy.isEnabled = true;
89+
(babylonMaterial as PBRMaterial).anisotropy.isEnabled = true;
8090

81-
babylonMaterial.anisotropy.intensity = properties.anisotropyStrength ?? 0;
82-
babylonMaterial.anisotropy.angle = properties.anisotropyRotation ?? 0;
91+
(babylonMaterial as PBRMaterial).anisotropy.intensity = properties.anisotropyStrength ?? 0;
92+
(babylonMaterial as PBRMaterial).anisotropy.angle = properties.anisotropyRotation ?? 0;
8393

8494
if (properties.anisotropyTexture) {
8595
(properties.anisotropyTexture as ITextureInfo).nonColorData = true;
8696
promises.push(
8797
this._loader.loadTextureInfoAsync(`${context}/anisotropyTexture`, properties.anisotropyTexture, (texture) => {
8898
texture.name = `${babylonMaterial.name} (Anisotropy Intensity)`;
89-
babylonMaterial.anisotropy.texture = texture;
99+
(babylonMaterial as PBRMaterial).anisotropy.texture = texture;
90100
})
91101
);
92102
}

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

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { Nullable } from "core/types";
2-
import { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
2+
import type { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
3+
import type { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
34
import type { Material } from "core/Materials/material";
5+
import type { BaseTexture } from "core/Materials/Textures/baseTexture";
46

57
import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces";
68
import type { IGLTFLoaderExtension } from "../glTFLoaderExtension";
@@ -21,6 +23,8 @@ declare module "../../glTFFileLoader" {
2123
}
2224
}
2325

26+
let PBRMaterialClass: typeof PBRMaterial | typeof OpenPBRMaterial;
27+
2428
/**
2529
* [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md)
2630
* [Playground Sample](https://www.babylonjs-playground.com/frame.html#7F7PN6#8)
@@ -61,54 +65,66 @@ export class KHR_materials_clearcoat implements IGLTFLoaderExtension {
6165
* @internal
6266
*/
6367
// eslint-disable-next-line no-restricted-syntax
64-
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
68+
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, useOpenPBR: boolean = false): Nullable<Promise<void>> {
6569
return GLTFLoader.LoadExtensionAsync<IKHRMaterialsClearcoat>(context, material, this.name, async (extensionContext, extension) => {
70+
if (useOpenPBR) {
71+
const mod = await import("core/Materials/PBR/openPbrMaterial");
72+
PBRMaterialClass = mod.OpenPBRMaterial;
73+
} else {
74+
const mod = await import("core/Materials/PBR/pbrMaterial");
75+
PBRMaterialClass = mod.PBRMaterial;
76+
}
77+
if (!(babylonMaterial instanceof PBRMaterialClass)) {
78+
throw new Error(`${context}: Material type not supported`);
79+
}
6680
const promises = new Array<Promise<any>>();
6781
promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial));
68-
promises.push(this._loadClearCoatPropertiesAsync(extensionContext, extension, babylonMaterial));
82+
promises.push(this._loadClearCoatPropertiesAsync(extensionContext, extension, babylonMaterial, useOpenPBR));
6983
await Promise.all(promises);
7084
});
7185
}
7286

7387
// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
74-
private _loadClearCoatPropertiesAsync(context: string, properties: IKHRMaterialsClearcoat, babylonMaterial: Material): Promise<void> {
75-
if (!(babylonMaterial instanceof PBRMaterial)) {
88+
private _loadClearCoatPropertiesAsync(context: string, properties: IKHRMaterialsClearcoat, babylonMaterial: Material, useOpenPBR: boolean = false): Promise<void> {
89+
if (!(babylonMaterial instanceof PBRMaterialClass)) {
7690
throw new Error(`${context}: Material type not supported`);
7791
}
7892

7993
const promises = new Array<Promise<any>>();
80-
81-
babylonMaterial.clearCoat.isEnabled = true;
82-
babylonMaterial.clearCoat.useRoughnessFromMainTexture = false;
83-
babylonMaterial.clearCoat.remapF0OnInterfaceChange = false;
94+
let coatRoughness = 0;
95+
let coatWeight = 0;
96+
let coatWeightTexture: Nullable<BaseTexture> = null;
97+
let coatRoughnessTexture: Nullable<BaseTexture> = null;
98+
let coatNormalTexture: Nullable<BaseTexture> = null;
99+
let coatNormalTextureScale = 1;
84100

85101
if (properties.clearcoatFactor != undefined) {
86-
babylonMaterial.clearCoat.intensity = properties.clearcoatFactor;
102+
coatWeight = properties.clearcoatFactor;
87103
} else {
88-
babylonMaterial.clearCoat.intensity = 0;
104+
coatWeight = 0;
89105
}
90106

91107
if (properties.clearcoatTexture) {
92108
promises.push(
93109
this._loader.loadTextureInfoAsync(`${context}/clearcoatTexture`, properties.clearcoatTexture, (texture) => {
94110
texture.name = `${babylonMaterial.name} (ClearCoat)`;
95-
babylonMaterial.clearCoat.texture = texture;
111+
coatWeightTexture = texture;
96112
})
97113
);
98114
}
99115

100116
if (properties.clearcoatRoughnessFactor != undefined) {
101-
babylonMaterial.clearCoat.roughness = properties.clearcoatRoughnessFactor;
117+
coatRoughness = properties.clearcoatRoughnessFactor;
102118
} else {
103-
babylonMaterial.clearCoat.roughness = 0;
119+
coatRoughness = 0;
104120
}
105121

106122
if (properties.clearcoatRoughnessTexture) {
107123
(properties.clearcoatRoughnessTexture as ITextureInfo).nonColorData = true;
108124
promises.push(
109125
this._loader.loadTextureInfoAsync(`${context}/clearcoatRoughnessTexture`, properties.clearcoatRoughnessTexture, (texture) => {
110126
texture.name = `${babylonMaterial.name} (ClearCoat Roughness)`;
111-
babylonMaterial.clearCoat.textureRoughness = texture;
127+
coatRoughnessTexture = texture;
112128
})
113129
);
114130
}
@@ -118,19 +134,37 @@ export class KHR_materials_clearcoat implements IGLTFLoaderExtension {
118134
promises.push(
119135
this._loader.loadTextureInfoAsync(`${context}/clearcoatNormalTexture`, properties.clearcoatNormalTexture, (texture) => {
120136
texture.name = `${babylonMaterial.name} (ClearCoat Normal)`;
121-
babylonMaterial.clearCoat.bumpTexture = texture;
137+
coatNormalTexture = texture;
122138
})
123139
);
124140

125141
babylonMaterial.invertNormalMapX = !babylonMaterial.getScene().useRightHandedSystem;
126142
babylonMaterial.invertNormalMapY = babylonMaterial.getScene().useRightHandedSystem;
127143
if (properties.clearcoatNormalTexture.scale != undefined) {
128-
babylonMaterial.clearCoat.bumpTexture!.level = properties.clearcoatNormalTexture.scale;
144+
coatNormalTextureScale = properties.clearcoatNormalTexture.scale;
129145
}
130146
}
131147

132148
// eslint-disable-next-line github/no-then
133-
return Promise.all(promises).then(() => {});
149+
return Promise.all(promises).then(() => {
150+
if (useOpenPBR) {
151+
// eslint-disable-next-line github/no-then
152+
return;
153+
}
154+
const material = babylonMaterial as PBRMaterial;
155+
material.clearCoat.isEnabled = true;
156+
material.clearCoat.useRoughnessFromMainTexture = false;
157+
material.clearCoat.remapF0OnInterfaceChange = false;
158+
material.clearCoat.intensity = coatWeight;
159+
material.clearCoat.texture = coatWeightTexture;
160+
material.clearCoat.roughness = coatRoughness;
161+
material.clearCoat.textureRoughness = coatRoughnessTexture;
162+
163+
material.clearCoat.bumpTexture = coatNormalTexture;
164+
if (coatNormalTexture) {
165+
material.clearCoat.bumpTexture!.level = coatNormalTextureScale;
166+
}
167+
});
134168
}
135169
}
136170

packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable github/no-then */
22
import type { Nullable } from "core/types";
3-
import { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
3+
import type { PBRMaterial } from "core/Materials/PBR/pbrMaterial";
4+
import type { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
45
import type { Material } from "core/Materials/material";
56
import type { BaseTexture } from "core/Materials/Textures/baseTexture";
67
import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces";
@@ -23,6 +24,8 @@ declare module "../../glTFFileLoader" {
2324
}
2425
}
2526

27+
let PBRMaterialClass: typeof PBRMaterial | typeof OpenPBRMaterial;
28+
2629
/**
2730
* [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)
2831
* !!! Experimental Extension Subject to Changes !!!
@@ -66,8 +69,15 @@ export class KHR_materials_diffuse_transmission implements IGLTFLoaderExtension
6669
* @internal
6770
*/
6871
// eslint-disable-next-line no-restricted-syntax
69-
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
72+
public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, useOpenPBR: boolean = false): Nullable<Promise<void>> {
7073
return GLTFLoader.LoadExtensionAsync<IKHRMaterialsDiffuseTransmission>(context, material, this.name, async (extensionContext, extension) => {
74+
if (useOpenPBR) {
75+
const mod = await import("core/Materials/PBR/openPbrMaterial");
76+
PBRMaterialClass = mod.OpenPBRMaterial;
77+
} else {
78+
const mod = await import("core/Materials/PBR/pbrMaterial");
79+
PBRMaterialClass = mod.PBRMaterial;
80+
}
7181
const promises = new Array<Promise<any>>();
7282
promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial));
7383
promises.push(this._loadTranslucentPropertiesAsync(extensionContext, material, babylonMaterial, extension));
@@ -77,62 +87,71 @@ export class KHR_materials_diffuse_transmission implements IGLTFLoaderExtension
7787

7888
// eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async
7989
private _loadTranslucentPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IKHRMaterialsDiffuseTransmission): Promise<void> {
80-
if (!(babylonMaterial instanceof PBRMaterial)) {
90+
if (!(babylonMaterial instanceof PBRMaterialClass)) {
8191
throw new Error(`${context}: Material type not supported`);
8292
}
8393

84-
const pbrMaterial = babylonMaterial;
85-
86-
// Enables "translucency" texture which represents diffusely-transmitted light.
87-
pbrMaterial.subSurface.isTranslucencyEnabled = true;
88-
89-
// Since this extension models thin-surface transmission only, we must make the
90-
// internal IOR == 1.0 and set the thickness to 0.
91-
pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0;
92-
pbrMaterial.subSurface.minimumThickness = 0.0;
93-
pbrMaterial.subSurface.maximumThickness = 0.0;
94-
95-
// Tint color will be used for transmission.
96-
pbrMaterial.subSurface.useAlbedoToTintTranslucency = false;
94+
let translucencyWeight = 0.0;
95+
let translucencyWeightTexture: Nullable<BaseTexture>;
96+
let translucencyColor = Color3.White();
97+
let translucencyColorTexture: Nullable<BaseTexture>;
9798

9899
if (extension.diffuseTransmissionFactor !== undefined) {
99-
pbrMaterial.subSurface.translucencyIntensity = extension.diffuseTransmissionFactor;
100-
} else {
101-
pbrMaterial.subSurface.translucencyIntensity = 0.0;
102-
pbrMaterial.subSurface.isTranslucencyEnabled = false;
103-
return Promise.resolve();
100+
translucencyWeight = extension.diffuseTransmissionFactor;
104101
}
105102

106103
const promises = new Array<Promise<any>>();
107104

108-
pbrMaterial.subSurface.useGltfStyleTextures = true;
109-
110105
if (extension.diffuseTransmissionTexture) {
111106
(extension.diffuseTransmissionTexture as ITextureInfo).nonColorData = true;
112107
promises.push(
113108
this._loader.loadTextureInfoAsync(`${context}/diffuseTransmissionTexture`, extension.diffuseTransmissionTexture).then((texture: BaseTexture) => {
114109
texture.name = `${babylonMaterial.name} (Diffuse Transmission)`;
115-
pbrMaterial.subSurface.translucencyIntensityTexture = texture;
110+
translucencyWeightTexture = texture;
116111
})
117112
);
118113
}
119114

120115
if (extension.diffuseTransmissionColorFactor !== undefined) {
121-
pbrMaterial.subSurface.translucencyColor = Color3.FromArray(extension.diffuseTransmissionColorFactor);
122-
} else {
123-
pbrMaterial.subSurface.translucencyColor = Color3.White();
116+
translucencyColor = Color3.FromArray(extension.diffuseTransmissionColorFactor);
124117
}
125118

126119
if (extension.diffuseTransmissionColorTexture) {
127120
promises.push(
128121
this._loader.loadTextureInfoAsync(`${context}/diffuseTransmissionColorTexture`, extension.diffuseTransmissionColorTexture).then((texture: BaseTexture) => {
129122
texture.name = `${babylonMaterial.name} (Diffuse Transmission Color)`;
130-
pbrMaterial.subSurface.translucencyColorTexture = texture;
123+
translucencyColorTexture = texture;
131124
})
132125
);
133126
}
134127

135-
return Promise.all(promises).then(() => {});
128+
return Promise.all(promises).then(() => {
129+
const pbrMaterial = babylonMaterial as PBRMaterial;
130+
131+
// Enables "translucency" texture which represents diffusely-transmitted light.
132+
pbrMaterial.subSurface.isTranslucencyEnabled = true;
133+
134+
// Since this extension models thin-surface transmission only, we must make the
135+
// internal IOR == 1.0 and set the thickness to 0.
136+
pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0;
137+
pbrMaterial.subSurface.minimumThickness = 0.0;
138+
pbrMaterial.subSurface.maximumThickness = 0.0;
139+
140+
// Tint color will be used for transmission.
141+
pbrMaterial.subSurface.useAlbedoToTintTranslucency = false;
142+
143+
pbrMaterial.subSurface.translucencyIntensity = translucencyWeight;
144+
if (translucencyWeight === 0.0) {
145+
pbrMaterial.subSurface.isTranslucencyEnabled = false;
146+
return;
147+
}
148+
149+
pbrMaterial.subSurface.useGltfStyleTextures = true;
150+
pbrMaterial.subSurface.translucencyIntensityTexture = translucencyWeightTexture;
151+
152+
pbrMaterial.subSurface.translucencyColor = translucencyColor;
153+
pbrMaterial.subSurface.translucencyColorTexture = translucencyColorTexture;
154+
});
136155
}
137156
}
138157

0 commit comments

Comments
 (0)