import { Nullable } from "babylonjs/types"; import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial"; import { Material } from "babylonjs/Materials/material"; import { IMaterial } from "../glTFLoaderInterfaces"; import { IGLTFLoaderExtension } from "../glTFLoaderExtension"; import { GLTFLoader } from "../glTFLoader"; import { Color3 } from 'babylonjs/Maths/math.color'; import { IKHRMaterialsSheen } from 'babylonjs-gltf2interface'; const NAME = "KHR_materials_sheen"; /** * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1688) * [Playground Sample](https://www.babylonjs-playground.com/frame.html#BNIZX6#4) * !!! Experimental Extension Subject to Changes !!! */ export class KHR_materials_sheen implements IGLTFLoaderExtension { /** * The name of this extension. */ public readonly name = NAME; /** * Defines whether this extension is enabled. */ public enabled: boolean; /** * Defines a number that determines the order the extensions are applied. */ public order = 190; private _loader: GLTFLoader; /** @hidden */ constructor(loader: GLTFLoader) { this._loader = loader; this.enabled = this._loader.isExtensionUsed(NAME); } /** @hidden */ public dispose() { (this._loader as any) = null; } /** @hidden */ public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable> { return GLTFLoader.LoadExtensionAsync(context, material, this.name, (extensionContext, extension) => { const promises = new Array>(); promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); promises.push(this._loadSheenPropertiesAsync(extensionContext, extension, babylonMaterial)); return Promise.all(promises).then(() => { }); }); } private _loadSheenPropertiesAsync(context: string, properties: IKHRMaterialsSheen, babylonMaterial: Material): Promise { if (!(babylonMaterial instanceof PBRMaterial)) { throw new Error(`${context}: Material type not supported`); } const promises = new Array>(); babylonMaterial.sheen.isEnabled = true; babylonMaterial.sheen.intensity = 1; if (properties.sheenColorFactor != undefined) { babylonMaterial.sheen.color = Color3.FromArray(properties.sheenColorFactor); } else { babylonMaterial.sheen.color = Color3.Black(); } if (properties.sheenColorTexture) { promises.push(this._loader.loadTextureInfoAsync(`${context}/sheenColorTexture`, properties.sheenColorTexture, (texture) => { texture.name = `${babylonMaterial.name} (Sheen Color)`; babylonMaterial.sheen.texture = texture; })); } if (properties.sheenRoughnessFactor !== undefined) { babylonMaterial.sheen.roughness = properties.sheenRoughnessFactor; } else { babylonMaterial.sheen.roughness = 0; } if (properties.sheenRoughnessTexture) { promises.push(this._loader.loadTextureInfoAsync(`${context}/sheenRoughnessTexture`, properties.sheenRoughnessTexture, (texture) => { texture.name = `${babylonMaterial.name} (Sheen Roughness)`; babylonMaterial.sheen.textureRoughness = texture; })); } babylonMaterial.sheen.albedoScaling = true; babylonMaterial.sheen.useRoughnessFromMainTexture = false; return Promise.all(promises).then(() => { }); } } GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_sheen(loader));