|
@@ -0,0 +1,97 @@
|
|
|
+import { Nullable } from "babylonjs/types";
|
|
|
+import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial";
|
|
|
+import { Material } from "babylonjs/Materials/material";
|
|
|
+import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
|
|
|
+import { IMaterial } from "../glTFLoaderInterfaces";
|
|
|
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
|
|
|
+import { GLTFLoader } from "../glTFLoader";
|
|
|
+import { IKHRMaterialsTranslucency } from 'babylonjs-gltf2interface';
|
|
|
+
|
|
|
+const NAME = "KHR_materials_translucency";
|
|
|
+
|
|
|
+/**
|
|
|
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)
|
|
|
+ * !!! Experimental Extension Subject to Changes !!!
|
|
|
+ */
|
|
|
+export class KHR_materials_translucency 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 = 175;
|
|
|
+
|
|
|
+ private _loader: GLTFLoader;
|
|
|
+
|
|
|
+ /** @hidden */
|
|
|
+ constructor(loader: GLTFLoader) {
|
|
|
+ this._loader = loader;
|
|
|
+ this.enabled = this._loader.isExtensionUsed(NAME);
|
|
|
+ if (this.enabled) {
|
|
|
+ loader.parent.transparencyAsCoverage = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @hidden */
|
|
|
+ public dispose() {
|
|
|
+ (this._loader as any) = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @hidden */
|
|
|
+ public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
|
|
|
+ return GLTFLoader.LoadExtensionAsync<IKHRMaterialsTranslucency>(context, material, this.name, (extensionContext, extension) => {
|
|
|
+ const promises = new Array<Promise<any>>();
|
|
|
+ promises.push(this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
|
|
|
+ promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial));
|
|
|
+ promises.push(this._loadTranslucentPropertiesAsync(extensionContext, material, babylonMaterial, extension));
|
|
|
+ return Promise.all(promises).then(() => { });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private _loadTranslucentPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IKHRMaterialsTranslucency): Promise<void> {
|
|
|
+ if (!(babylonMaterial instanceof PBRMaterial)) {
|
|
|
+ throw new Error(`${context}: Material type not supported`);
|
|
|
+ }
|
|
|
+ const pbrMaterial = babylonMaterial as PBRMaterial;
|
|
|
+
|
|
|
+ // Enables "translucency" texture which represents diffusely-transmitted light.
|
|
|
+ pbrMaterial.subSurface.isTranslucencyEnabled = true;
|
|
|
+
|
|
|
+ // Since this extension models thin-surface transmission only, we must make the
|
|
|
+ // internal IOR == 1.0 and set the thickness to 0.
|
|
|
+ pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0;
|
|
|
+ pbrMaterial.subSurface.minimumThickness = 0.0;
|
|
|
+ pbrMaterial.subSurface.maximumThickness = 0.0;
|
|
|
+
|
|
|
+ // Albedo colour will tint transmission.
|
|
|
+ pbrMaterial.subSurface.useAlbedoToTintRefraction = true;
|
|
|
+
|
|
|
+ if (extension.translucencyFactor !== undefined) {
|
|
|
+ pbrMaterial.subSurface.translucencyIntensity = extension.translucencyFactor;
|
|
|
+ } else {
|
|
|
+ pbrMaterial.subSurface.translucencyIntensity = 0.0;
|
|
|
+ pbrMaterial.subSurface.isTranslucencyEnabled = false;
|
|
|
+ return Promise.resolve();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (extension.translucencyTexture) {
|
|
|
+ return this._loader.loadTextureInfoAsync(`${context}/translucencyTexture`, extension.translucencyTexture)
|
|
|
+ .then((texture: BaseTexture) => {
|
|
|
+ pbrMaterial.subSurface.thicknessTexture = texture;
|
|
|
+ pbrMaterial.subSurface.useMaskFromThicknessTextureGltf = true;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ return Promise.resolve();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_translucency(loader));
|