diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts index 49f1cb165dd..1758a7b93c2 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts @@ -5,8 +5,8 @@ import { VertexBuffer } from "core/Buffers/buffer"; import { Geometry } from "core/Meshes/geometry"; import type { Mesh } from "core/Meshes/mesh"; -import type { IKHRDracoMeshCompression } from "babylonjs-gltf2interface"; import { MeshPrimitiveMode, AccessorComponentType } from "babylonjs-gltf2interface"; +import type { IKHRDracoMeshCompression } from "babylonjs-gltf2interface"; import type { IMeshPrimitive, IBufferView } from "../glTFLoaderInterfaces"; import type { IGLTFLoaderExtension } from "../glTFLoaderExtension"; import { GLTFLoader, ArrayItem } from "../glTFLoader"; diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts index f6ba9732ef9..e49e9667876 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts @@ -9,7 +9,7 @@ import { Light } from "core/Lights/light"; import type { TransformNode } from "core/Meshes/transformNode"; import type { IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from "babylonjs-gltf2interface"; -import { IKHRLightsPunctual_LightType } from "babylonjs-gltf2interface"; +import { KHRLightsPunctual_LightType } from "babylonjs-gltf2interface"; import type { INode } from "../glTFLoaderInterfaces"; import type { IGLTFLoaderExtension } from "../glTFLoaderExtension"; import { GLTFLoader, ArrayItem } from "../glTFLoader"; @@ -74,15 +74,15 @@ export class KHR_lights implements IGLTFLoaderExtension { this._loader.babylonScene._blockEntityCollection = !!this._loader._assetContainer; switch (light.type) { - case IKHRLightsPunctual_LightType.DIRECTIONAL: { + case KHRLightsPunctual_LightType.DIRECTIONAL: { babylonLight = new DirectionalLight(name, Vector3.Backward(), this._loader.babylonScene); break; } - case IKHRLightsPunctual_LightType.POINT: { + case KHRLightsPunctual_LightType.POINT: { babylonLight = new PointLight(name, Vector3.Zero(), this._loader.babylonScene); break; } - case IKHRLightsPunctual_LightType.SPOT: { + case KHRLightsPunctual_LightType.SPOT: { const babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 1, this._loader.babylonScene); babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2; babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2; diff --git a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts index ee8ce15ec00..356a39ef299 100644 --- a/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts +++ b/packages/dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts @@ -6,16 +6,10 @@ import type { BaseTexture } from "core/Materials/Textures/baseTexture"; import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces"; import type { IGLTFLoaderExtension } from "../glTFLoaderExtension"; import { GLTFLoader } from "../glTFLoader"; +import type { IKHRMaterialsVolume } from "babylonjs-gltf2interface"; const NAME = "KHR_materials_volume"; -interface IMaterialsTransmission { - attenuationColor?: number[]; - attenuationDistance?: number; - thicknessTexture?: ITextureInfo; - thicknessFactor?: number; -} - /** * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume) * @since 5.0.0 @@ -66,7 +60,7 @@ export class KHR_materials_volume implements IGLTFLoaderExtension { * @hidden */ public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable> { - return GLTFLoader.LoadExtensionAsync(context, material, this.name, (extensionContext, extension) => { + return GLTFLoader.LoadExtensionAsync(context, material, this.name, (extensionContext, extension) => { const promises = new Array>(); promises.push(this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); @@ -75,7 +69,7 @@ export class KHR_materials_volume implements IGLTFLoaderExtension { }); } - private _loadVolumePropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IMaterialsTransmission): Promise { + private _loadVolumePropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material, extension: IKHRMaterialsVolume): Promise { if (!(babylonMaterial instanceof PBRMaterial)) { throw new Error(`${context}: Material type not supported`); } diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts index 9390598db0e..2f24db6604e 100644 --- a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts @@ -7,7 +7,7 @@ import { DirectionalLight } from "core/Lights/directionalLight"; import type { Node } from "core/node"; import { ShadowLight } from "core/Lights/shadowLight"; import type { INode, IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from "babylonjs-gltf2interface"; -import { IKHRLightsPunctual_LightType } from "babylonjs-gltf2interface"; +import { KHRLightsPunctual_LightType } from "babylonjs-gltf2interface"; import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension"; import { _Exporter } from "../glTFExporter"; import { Logger } from "core/Misc/logger"; @@ -72,11 +72,11 @@ export class KHR_lights_punctual implements IGLTFExporterExtensionV2 { const lightType = babylonLight.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT - ? IKHRLightsPunctual_LightType.POINT + ? KHRLightsPunctual_LightType.POINT : babylonLight.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT - ? IKHRLightsPunctual_LightType.DIRECTIONAL + ? KHRLightsPunctual_LightType.DIRECTIONAL : babylonLight.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT - ? IKHRLightsPunctual_LightType.SPOT + ? KHRLightsPunctual_LightType.SPOT : null; if (lightType == null) { Logger.Warn(`${context}: Light ${babylonLight.name} is not supported in ${NAME}`); @@ -89,7 +89,7 @@ export class KHR_lights_punctual implements IGLTFExporterExtensionV2 { } node.translation = lightPosition.asArray(); } - if (lightType !== IKHRLightsPunctual_LightType.POINT) { + if (lightType !== KHRLightsPunctual_LightType.POINT) { const localAxis = babylonLight.direction; const yaw = -Math.atan2(localAxis.z * (this._exporter._babylonScene.useRightHandedSystem ? -1 : 1), localAxis.x) + Math.PI / 2; const len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z); @@ -119,7 +119,7 @@ export class KHR_lights_punctual implements IGLTFExporterExtensionV2 { light.range = babylonLight.range; } - if (lightType === IKHRLightsPunctual_LightType.SPOT) { + if (lightType === KHRLightsPunctual_LightType.SPOT) { const babylonSpotLight = babylonLight as SpotLight; if (babylonSpotLight.angle !== Math.PI / 2.0) { if (light.spot == null) { diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts new file mode 100644 index 00000000000..4dc76291f4d --- /dev/null +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts @@ -0,0 +1,59 @@ +import type { IMaterial, IKHRMaterialsIor } from "babylonjs-gltf2interface"; +import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension"; +import { _Exporter } from "../glTFExporter"; +import type { Material } from "core/Materials/material"; +import { PBRMaterial } from "core/Materials/PBR/pbrMaterial"; + +const NAME = "KHR_materials_ior"; + +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export class KHR_materials_ior implements IGLTFExporterExtensionV2 { + /** Name of this extension */ + public readonly name = NAME; + + /** Defines whether this extension is enabled */ + public enabled = true; + + /** Defines whether this extension is required */ + public required = false; + + private _wasUsed = false; + + constructor() {} + + public dispose() {} + + /** @hidden */ + public get wasUsed() { + return this._wasUsed; + } + + private _isExtensionEnabled(mat: PBRMaterial): boolean { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value. + } + + public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise { + return new Promise((resolve) => { + if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) { + this._wasUsed = true; + + const iorInfo: IKHRMaterialsIor = { + ior: babylonMaterial.indexOfRefraction, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = iorInfo; + } + resolve(node); + }); + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior()); diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts index 43d85edaeb5..4e87437d4e9 100644 --- a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts @@ -55,6 +55,10 @@ export class KHR_materials_specular implements IGLTFExporterExtensionV2 { } private _isExtensionEnabled(mat: PBRMaterial): boolean { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } return ( (mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) || (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) || diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts new file mode 100644 index 00000000000..6143f3b0998 --- /dev/null +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts @@ -0,0 +1,92 @@ +import type { IMaterial, IKHRMaterialsTransmission } from "babylonjs-gltf2interface"; +import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension"; +import { _Exporter } from "../glTFExporter"; +import type { Material } from "core/Materials/material"; +import { PBRMaterial } from "core/Materials/PBR/pbrMaterial"; +import type { BaseTexture } from "core/Materials/Textures/baseTexture"; + +const NAME = "KHR_materials_transmission"; + +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export class KHR_materials_transmission implements IGLTFExporterExtensionV2 { + /** Name of this extension */ + public readonly name = NAME; + + /** Defines whether this extension is enabled */ + public enabled = true; + + /** Defines whether this extension is required */ + public required = false; + + private _exporter: _Exporter; + + private _wasUsed = false; + + constructor(exporter: _Exporter) { + this._exporter = exporter; + } + + public dispose() {} + + /** @hidden */ + public get wasUsed() { + return this._wasUsed; + } + + public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] { + const additionalTextures: BaseTexture[] = []; + + if (babylonMaterial instanceof PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + + return additionalTextures; + } + + private _isExtensionEnabled(mat: PBRMaterial): boolean { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + const subs = mat.subSurface; + return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat); + } + + private _hasTexturesExtension(mat: PBRMaterial): boolean { + return mat.subSurface.refractionIntensityTexture != null; + } + + public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise { + return new Promise((resolve) => { + if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) { + this._wasUsed = true; + + const subs = babylonMaterial.subSurface; + const transmissionFactor = subs.refractionIntensity === 0 ? undefined : subs.refractionIntensity; + + const transmissionTexture = this._exporter._glTFMaterialExporter._getTextureInfo(subs.refractionIntensityTexture) ?? undefined; + + const volumeInfo: IKHRMaterialsTransmission = { + transmissionFactor: transmissionFactor, + transmissionTexture: transmissionTexture, + hasTextures: () => { + return this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = volumeInfo; + } + resolve(node); + }); + } +} + +_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter)); diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts new file mode 100644 index 00000000000..51e55def129 --- /dev/null +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts @@ -0,0 +1,105 @@ +import type { IMaterial, IKHRMaterialsVolume } from "babylonjs-gltf2interface"; +import type { IGLTFExporterExtensionV2 } from "../glTFExporterExtension"; +import { _Exporter } from "../glTFExporter"; +import type { Material } from "core/Materials/material"; +import { PBRMaterial } from "core/Materials/PBR/pbrMaterial"; +import type { BaseTexture } from "core/Materials/Textures/baseTexture"; +import { Color3 } from "core/Maths/math.color"; + +const NAME = "KHR_materials_volume"; + +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export class KHR_materials_volume implements IGLTFExporterExtensionV2 { + /** Name of this extension */ + public readonly name = NAME; + + /** Defines whether this extension is enabled */ + public enabled = true; + + /** Defines whether this extension is required */ + public required = false; + + private _exporter: _Exporter; + + private _wasUsed = false; + + constructor(exporter: _Exporter) { + this._exporter = exporter; + } + + public dispose() {} + + /** @hidden */ + public get wasUsed() { + return this._wasUsed; + } + + public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] { + const additionalTextures: BaseTexture[] = []; + + if (babylonMaterial instanceof PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + + return additionalTextures; + } + + private _isExtensionEnabled(mat: PBRMaterial): boolean { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + const subs = mat.subSurface; + // this extension requires either the KHR_materials_transmission or KHR_materials_translucency extensions. + if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) { + return false; + } + return ( + (subs.maximumThickness != undefined && subs.maximumThickness != 0) || + (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) || + (subs.tintColor != undefined && subs.tintColor != Color3.White()) || + this._hasTexturesExtension(mat) + ); + } + + private _hasTexturesExtension(mat: PBRMaterial): boolean { + return mat.subSurface.thicknessTexture != null; + } + + public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise { + return new Promise((resolve) => { + if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) { + this._wasUsed = true; + + const subs = babylonMaterial.subSurface; + const thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness; + const thicknessTexture = this._exporter._glTFMaterialExporter._getTextureInfo(subs.thicknessTexture) ?? undefined; + const attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance; + const attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray(); + + const volumeInfo: IKHRMaterialsVolume = { + thicknessFactor: thicknessFactor, + thicknessTexture: thicknessTexture, + attenuationDistance: attenuationDistance, + attenuationColor: attenuationColor, + hasTextures: () => { + return this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = volumeInfo; + } + resolve(node); + }); + } +} + +_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter)); diff --git a/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts b/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts index 389a331b868..3c14dbdaa44 100644 --- a/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts +++ b/packages/dev/serializers/src/glTF/2.0/Extensions/index.ts @@ -4,4 +4,7 @@ export * from "./KHR_materials_clearcoat"; export * from "./KHR_materials_iridescence"; export * from "./KHR_materials_sheen"; export * from "./KHR_materials_unlit"; +export * from "./KHR_materials_ior"; export * from "./KHR_materials_specular"; +export * from "./KHR_materials_volume"; +export * from "./KHR_materials_transmission"; diff --git a/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts b/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts index b3a1f15f1dc..4e4b53c8b1e 100644 --- a/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts +++ b/packages/public/glTF2Interface/babylon.glTF2Interface.d.ts @@ -1,6 +1,9 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/no-unused-vars */ declare module "babylonjs-gltf2interface" { export = BABYLON.GLTF2; } + /** * Module for glTF 2.0 Interface */ @@ -903,7 +906,7 @@ declare module BABYLON.GLTF2 { hasSkins: boolean; hasTextures: boolean; maxAttributesUsed: number; - primitivesCount: number + primitivesCount: number; }; issues: { messages: Array; @@ -911,7 +914,7 @@ declare module BABYLON.GLTF2 { numHints: number; numInfos: number; numWarnings: number; - truncated: boolean + truncated: boolean; }; mimeType: string; uri: string; @@ -995,10 +998,10 @@ declare module BABYLON.GLTF2 { */ /** @hidden */ - const enum IKHRLightsPunctual_LightType { + const enum KHRLightsPunctual_LightType { DIRECTIONAL = "directional", POINT = "point", - SPOT = "spot" + SPOT = "spot", } /** @hidden */ @@ -1008,7 +1011,7 @@ declare module BABYLON.GLTF2 { /** @hidden */ interface IKHRLightsPunctual_Light extends IChildRootProperty { - type: IKHRLightsPunctual_LightType; + type: KHRLightsPunctual_LightType; color?: number[]; intensity?: number; range?: number; @@ -1025,7 +1028,7 @@ declare module BABYLON.GLTF2 { /** @hidden */ interface IMaterialExtension { - hasTextures?() : boolean; + hasTextures?(): boolean; } /** @hidden */ @@ -1049,12 +1052,45 @@ declare module BABYLON.GLTF2 { /** * Interfaces from the KHR_materials_ior extension - * !!! Experimental Extension Subject to Changes !!! */ /** @hidden */ interface IKHRMaterialsIor extends IMaterialExtension { - ior: number; + ior?: number; + } + + /** + * Interfaces from the KHR_materials_volume extension + */ + + /** @hidden */ + interface IKHRMaterialsVolume extends IMaterialExtension { + thicknessFactor?: number; + thicknessTexture?: ITextureInfo; + attenuationDistance?: number; + attenuationColor?: number[]; + } + + /** + * Interfaces from the KHR_materials_specular extension + */ + + /** @hidden */ + interface IKHRMaterialsSpecular extends IMaterialExtension { + specularFactor?: number; + specularColorFactor?: number[]; + specularTexture?: ITextureInfo; + specularColorTexture?: ITextureInfo; + } + + /** + * Interfaces from the KHR_materials_transmission extension + */ + + /** @hidden */ + interface IKHRMaterialsTransmission extends IMaterialExtension { + transmissionFactor?: number; + transmissionTexture?: ITextureInfo; } /** @@ -1082,7 +1118,6 @@ declare module BABYLON.GLTF2 { /** * Interfaces from the KHR_materials_sheen extension - * !!! Experimental Extension Subject to Changes !!! */ /** @hidden */ @@ -1093,30 +1128,6 @@ declare module BABYLON.GLTF2 { sheenRoughnessTexture?: ITextureInfo; } - /** - * Interfaces from the KHR_materials_specular extension - * !!! Experimental Extension Subject to Changes !!! - */ - - /** @hidden */ - interface IKHRMaterialsSpecular extends IMaterialExtension { - specularFactor?: number; - specularColorFactor?: number[]; - specularTexture?: ITextureInfo; - specularColorTexture?: ITextureInfo; - } - - /** - * Interfaces from the KHR_materials_transmission extension - * !!! Experimental Extension Subject to Changes !!! - */ - - /** @hidden */ - interface IKHRMaterialsTransmission extends IMaterialExtension { - transmissionFactor?: number; - transmissionTexture?: ITextureInfo; - } - /** * Interfaces from the KHR_materials_translucency extension * !!! Experimental Extension Subject to Changes !!!