@babylonjs/gui
Version:
For usage documentation please visit the [GUI documentation](https://doc.babylonjs.com/features/featuresDeepDive/gui/).
469 lines • 19.6 kB
JavaScript
import { __decorate } from "@babylonjs/core/tslib.es6.js";
import { serialize, serializeAsVector3 } from "@babylonjs/core/Misc/decorators.js";
import { SerializationHelper } from "@babylonjs/core/Misc/decorators.serialization.js";
import { Vector3, Vector4 } from "@babylonjs/core/Maths/math.vector.js";
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
import { MaterialDefines } from "@babylonjs/core/Materials/materialDefines.js";
import { PushMaterial } from "@babylonjs/core/Materials/pushMaterial.js";
import { VertexBuffer } from "@babylonjs/core/Buffers/buffer.js";
import { RegisterClass } from "@babylonjs/core/Misc/typeStore.js";
import { Color4 } from "@babylonjs/core/Maths/math.color.js";
import { EffectFallbacks } from "@babylonjs/core/Materials/effectFallbacks.js";
import { Constants } from "@babylonjs/core/Engines/constants.js";
import "./shaders/fluentBackplate.fragment.js";
import "./shaders/fluentBackplate.vertex.js";
import { HandleFallbacksForShadows, PrepareAttributesForInstances, PrepareDefinesForAttributes, PrepareUniformsAndSamplersList } from "@babylonjs/core/Materials/materialHelper.functions.js";
import { Tools } from "@babylonjs/core/Misc/tools.js";
/** @internal */
class FluentBackplateMaterialDefines extends MaterialDefines {
constructor() {
super();
this.BLOB_ENABLE = true;
this.BLOB_ENABLE_2 = true;
this.SMOOTH_EDGES = true;
this.IRIDESCENT_MAP_ENABLE = true;
this._needNormals = true;
this.rebuild();
}
}
/**
* Class used to render square buttons with fluent design
*/
export class FluentBackplateMaterial extends PushMaterial {
constructor(name, scene) {
super(name, scene);
/**
* Gets or sets the corner radius on the backplate. Best to keep this value between 0.01 and 0.5. Default is 0.03.
*/
this.radius = 0.03;
/**
* Gets or sets the line width of the backplate.
*/
this.lineWidth = 0.01;
/**
* Gets or sets whether to use absolute sizes when calculating effects on the backplate.
* Since desktop and VR/AR have different relative sizes, it's usually best to keep this false.
*/
this.absoluteSizes = false;
/** @internal */
this._filterWidth = 1;
/**
* Gets or sets the base color of the backplate.
*/
this.baseColor = new Color4(0.0392157, 0.0666667, 0.207843, 1);
/**
* Gets or sets the line color of the backplate.
*/
this.lineColor = new Color4(0.14902, 0.133333, 0.384314, 1);
/**
* Gets or sets the intensity of the fluent hover glow effect.
*/
this.blobIntensity = 0.98;
/**
* Gets or sets the far size of the fluent hover glow effect.
*/
this.blobFarSize = 0.04;
/**
* Gets or sets the distance considered "near" to the backplate, which controls the size of the fluent hover glow effect (see blobNearSize).
*/
this.blobNearDistance = 0;
/**
* Gets or sets the distance considered "far" from the backplate, which controls the size of the fluent hover glow effect (see blobFarSize).
*/
this.blobFarDistance = 0.08;
/**
* Gets or sets the length of the fluent hover glow effect fade.
*/
this.blobFadeLength = 0.08;
/**
* Gets or sets the size of the fluent hover glow effect when the left pointer is considered "near" to the backplate (see blobNearDistance).
*/
this.blobNearSize = 0.22;
/**
* Gets or sets the progress of the fluent hover glow effect selection animation corresponding to the left pointer (0.0 - 1.0).
*/
this.blobPulse = 0;
/**
* Gets or sets the opacity of the fluent hover glow effect corresponding to the left pointer (0.0 - 1.0). Default is 0.
*/
this.blobFade = 0;
/**
* Gets or sets the size of the fluent hover glow effect when the right pointer is considered "near" to the backplate (see blobNearDistance).
*/
this.blobNearSize2 = 0.22;
/**
* Gets or sets the progress of the fluent hover glow effect selection animation corresponding to the right pointer (0.0 - 1.0).
*/
this.blobPulse2 = 0;
/**
* Gets or sets the opacity of the fluent hover glow effect corresponding to the right pointer (0.0 - 1.0). Default is 0.
*/
this.blobFade2 = 0;
/** @internal */
this._rate = 0.135;
/**
* Gets or sets the color of the highlights on the backplate line.
*/
this.highlightColor = new Color4(0.98, 0.98, 0.98, 1);
/**
* Gets or sets the width of the highlights on the backplate line.
*/
this.highlightWidth = 0.25;
/** @internal */
this._highlightTransform = new Vector4(1, 1, 0, 0);
/** @internal */
this._highlight = 1;
/**
* Gets or sets the intensity of the iridescence effect.
*/
this.iridescenceIntensity = 0;
/**
* Gets or sets the intensity of the iridescence effect on the backplate edges.
*/
this.iridescenceEdgeIntensity = 1;
/** @internal */
this._angle = -45;
/**
* Gets or sets the opacity of the backplate (0.0 - 1.0).
*/
this.fadeOut = 1;
/** @internal */
this._reflected = true;
/** @internal */
this._frequency = 1;
/** @internal */
this._verticalOffset = 0;
/**
* Gets or sets the world-space position of the tip of the left index finger.
*/
this.globalLeftIndexTipPosition = Vector3.Zero();
this._globalLeftIndexTipPosition4 = Vector4.Zero();
/**
* Gets or sets the world-space position of the tip of the right index finger.
*/
this.globalRightIndexTipPosition = Vector3.Zero();
this._globalRightIndexTipPosition4 = Vector4.Zero();
this.alphaMode = Constants.ALPHA_DISABLE;
this.backFaceCulling = false;
const blobTextureUrl = Tools.GetAssetUrl(FluentBackplateMaterial.BLOB_TEXTURE_URL);
const iridescentMapUrl = Tools.GetAssetUrl(FluentBackplateMaterial.IM_TEXTURE_URL);
this._blobTexture = new Texture(blobTextureUrl, this.getScene(), true, false, Texture.NEAREST_SAMPLINGMODE);
this._iridescentMap = new Texture(iridescentMapUrl, this.getScene(), true, false, Texture.NEAREST_SAMPLINGMODE);
}
needAlphaBlending() {
return false;
}
needAlphaTesting() {
return false;
}
getAlphaTestTexture() {
return null;
}
isReadyForSubMesh(mesh, subMesh) {
const drawWrapper = subMesh._drawWrapper;
if (this.isFrozen) {
if (drawWrapper.effect && drawWrapper._wasPreviouslyReady) {
return true;
}
}
if (!this._blobTexture.isReady() || !this._iridescentMap.isReady()) {
return false;
}
if (!subMesh.materialDefines) {
subMesh.materialDefines = new FluentBackplateMaterialDefines();
}
const defines = subMesh.materialDefines;
const scene = this.getScene();
if (this._isReadyForSubMesh(subMesh)) {
return true;
}
const engine = scene.getEngine();
// Attribs
PrepareDefinesForAttributes(mesh, defines, false, false);
// Get correct effect
if (defines.isDirty) {
defines.markAsProcessed();
scene.resetCachedMaterial();
// Fallbacks
const fallbacks = new EffectFallbacks();
if (defines.FOG) {
fallbacks.addFallback(1, "FOG");
}
HandleFallbacksForShadows(defines, fallbacks);
defines.IMAGEPROCESSINGPOSTPROCESS = scene.imageProcessingConfiguration.applyByPostProcess;
//Attributes
const attribs = [VertexBuffer.PositionKind];
if (defines.NORMAL) {
attribs.push(VertexBuffer.NormalKind);
}
if (defines.UV1) {
attribs.push(VertexBuffer.UVKind);
}
if (defines.UV2) {
attribs.push(VertexBuffer.UV2Kind);
}
if (defines.VERTEXCOLOR) {
attribs.push(VertexBuffer.ColorKind);
}
if (defines.TANGENT) {
attribs.push(VertexBuffer.TangentKind);
}
PrepareAttributesForInstances(attribs, defines);
// Legacy browser patch
const shaderName = "fluentBackplate";
const join = defines.toString();
const uniforms = [
"world",
"viewProjection",
"cameraPosition",
"_Radius_",
"_Line_Width_",
"_Absolute_Sizes_",
"_Filter_Width_",
"_Base_Color_",
"_Line_Color_",
"_Radius_Top_Left_",
"_Radius_Top_Right_",
"_Radius_Bottom_Left_",
"_Radius_Bottom_Right_",
"_Blob_Position_",
"_Blob_Intensity_",
"_Blob_Near_Size_",
"_Blob_Far_Size_",
"_Blob_Near_Distance_",
"_Blob_Far_Distance_",
"_Blob_Fade_Length_",
"_Blob_Pulse_",
"_Blob_Fade_",
"_Blob_Texture_",
"_Blob_Position_2_",
"_Blob_Near_Size_2_",
"_Blob_Pulse_2_",
"_Blob_Fade_2_",
"_Rate_",
"_Highlight_Color_",
"_Highlight_Width_",
"_Highlight_Transform_",
"_Highlight_",
"_Iridescence_Intensity_",
"_Iridescence_Edge_Intensity_",
"_Angle_",
"_Fade_Out_",
"_Reflected_",
"_Frequency_",
"_Vertical_Offset_",
"_Iridescent_Map_",
"_Use_Global_Left_Index_",
"_Use_Global_Right_Index_",
"Global_Left_Index_Tip_Position",
"Global_Right_Index_Tip_Position",
];
const samplers = ["_Blob_Texture_", "_Iridescent_Map_"];
const uniformBuffers = [];
PrepareUniformsAndSamplersList({
uniformsNames: uniforms,
uniformBuffersNames: uniformBuffers,
samplers: samplers,
defines: defines,
maxSimultaneousLights: 4,
});
subMesh.setEffect(scene.getEngine().createEffect(shaderName, {
attributes: attribs,
uniformsNames: uniforms,
uniformBuffersNames: uniformBuffers,
samplers: samplers,
defines: join,
fallbacks: fallbacks,
onCompiled: this.onCompiled,
onError: this.onError,
indexParameters: { maxSimultaneousLights: 4 },
}, engine), defines, this._materialContext);
}
if (!subMesh.effect || !subMesh.effect.isReady()) {
return false;
}
defines._renderId = scene.getRenderId();
drawWrapper._wasPreviouslyReady = true;
return true;
}
bindForSubMesh(world, mesh, subMesh) {
const defines = subMesh.materialDefines;
if (!defines) {
return;
}
const effect = subMesh.effect;
if (!effect) {
return;
}
this._activeEffect = effect;
// Matrices
this.bindOnlyWorldMatrix(world);
this._activeEffect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
this._activeEffect.setVector3("cameraPosition", this.getScene().activeCamera?.position ?? Vector3.ZeroReadOnly);
// "Round Rect"
this._activeEffect.setFloat("_Radius_", this.radius);
this._activeEffect.setFloat("_Line_Width_", this.lineWidth);
this._activeEffect.setFloat("_Absolute_Sizes_", this.absoluteSizes ? 1.0 : 0.0);
this._activeEffect.setFloat("_Filter_Width_", this._filterWidth);
this._activeEffect.setDirectColor4("_Base_Color_", this.baseColor);
this._activeEffect.setDirectColor4("_Line_Color_", this.lineColor);
// "Radii Multipliers"
this._activeEffect.setFloat("_Radius_Top_Left_", 1);
this._activeEffect.setFloat("_Radius_Top_Right_", 1.0);
this._activeEffect.setFloat("_Radius_Bottom_Left_", 1.0);
this._activeEffect.setFloat("_Radius_Bottom_Right_", 1.0);
// "Blob"
//define BLOB_ENABLE true;
this._activeEffect.setFloat("_Blob_Intensity_", this.blobIntensity);
this._activeEffect.setFloat("_Blob_Near_Size_", this.blobNearSize);
this._activeEffect.setFloat("_Blob_Far_Size_", this.blobFarSize);
this._activeEffect.setFloat("_Blob_Near_Distance_", this.blobNearDistance);
this._activeEffect.setFloat("_Blob_Far_Distance_", this.blobFarDistance);
this._activeEffect.setFloat("_Blob_Fade_Length_", this.blobFadeLength);
this._activeEffect.setFloat("_Blob_Pulse_", this.blobPulse);
this._activeEffect.setFloat("_Blob_Fade_", this.blobFade);
// "Blob Texture"
this._activeEffect.setTexture("_Blob_Texture_", this._blobTexture);
// "Blob 2"
//define BLOB_ENABLE_2 true;
this._activeEffect.setFloat("_Blob_Near_Size_2_", this.blobNearSize2);
this._activeEffect.setFloat("_Blob_Pulse_2_", this.blobPulse2);
this._activeEffect.setFloat("_Blob_Fade_2_", this.blobFade2);
// "Line Highlight"
this._activeEffect.setFloat("_Rate_", this._rate);
this._activeEffect.setDirectColor4("_Highlight_Color_", this.highlightColor);
this._activeEffect.setFloat("_Highlight_Width_", this.highlightWidth);
this._activeEffect.setVector4("_Highlight_Transform_", this._highlightTransform);
this._activeEffect.setFloat("_Highlight_", this._highlight);
// "Iridescence"
this._activeEffect.setFloat("_Iridescence_Intensity_", this.iridescenceIntensity);
this._activeEffect.setFloat("_Iridescence_Edge_Intensity_", this.iridescenceEdgeIntensity);
this._activeEffect.setFloat("_Angle_", this._angle);
// "Fade"
this._activeEffect.setFloat("_Fade_Out_", this.fadeOut);
// "Antialiasing"
//define SMOOTH_EDGES true;
// "ChooseAngle"
this._activeEffect.setFloat("_Reflected_", this._reflected ? 1.0 : 0.0);
// "Multiply"
this._activeEffect.setFloat("_Frequency_", this._frequency);
this._activeEffect.setFloat("_Vertical_Offset_", this._verticalOffset);
// "Color Texture"
//define IRIDESCENT_MAP_ENABLE true;
this._activeEffect.setTexture("_Iridescent_Map_", this._iridescentMap);
// "Global"
this._activeEffect.setFloat("_Use_Global_Left_Index_", 1.0);
this._activeEffect.setFloat("_Use_Global_Right_Index_", 1.0);
this._globalLeftIndexTipPosition4.set(this.globalLeftIndexTipPosition.x, this.globalLeftIndexTipPosition.y, this.globalLeftIndexTipPosition.z, 1.0);
this._activeEffect.setVector4("Global_Left_Index_Tip_Position", this._globalLeftIndexTipPosition4);
this._globalRightIndexTipPosition4.set(this.globalRightIndexTipPosition.x, this.globalRightIndexTipPosition.y, this.globalRightIndexTipPosition.z, 1.0);
this._activeEffect.setVector4("Global_Right_Index_Tip_Position", this._globalRightIndexTipPosition4);
this._afterBind(mesh, this._activeEffect, subMesh);
}
/**
* Get the list of animatables in the material.
* @returns the list of animatables object used in the material
*/
getAnimatables() {
return [];
}
dispose(forceDisposeEffect) {
super.dispose(forceDisposeEffect);
this._blobTexture.dispose();
this._iridescentMap.dispose();
}
clone(name) {
return SerializationHelper.Clone(() => new FluentBackplateMaterial(name, this.getScene()), this);
}
serialize() {
const serializationObject = super.serialize();
serializationObject.customType = "BABYLON.FluentBackplateMaterial";
return serializationObject;
}
getClassName() {
return "FluentBackplateMaterial";
}
// Statics
static Parse(source, scene, rootUrl) {
return SerializationHelper.Parse(() => new FluentBackplateMaterial(source.name, scene), source, scene, rootUrl);
}
}
/**
* URL pointing to the texture used to define the coloring for the fluent blob effect.
*/
FluentBackplateMaterial.BLOB_TEXTURE_URL = "https://assets.babylonjs.com/core/MRTK/mrtk-fluent-backplate-blob.png";
/**
* URL pointing to the texture used to define iridescent map.
*/
FluentBackplateMaterial.IM_TEXTURE_URL = "https://assets.babylonjs.com/core/MRTK/mrtk-fluent-backplate-iridescence.png";
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "radius", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "lineWidth", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "absoluteSizes", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "baseColor", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "lineColor", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobIntensity", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobFarSize", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobNearDistance", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobFarDistance", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobFadeLength", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobNearSize", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobPulse", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobFade", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobNearSize2", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobPulse2", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "blobFade2", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "highlightColor", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "highlightWidth", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "iridescenceIntensity", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "iridescenceEdgeIntensity", void 0);
__decorate([
serialize()
], FluentBackplateMaterial.prototype, "fadeOut", void 0);
__decorate([
serializeAsVector3()
], FluentBackplateMaterial.prototype, "globalLeftIndexTipPosition", void 0);
__decorate([
serializeAsVector3()
], FluentBackplateMaterial.prototype, "globalRightIndexTipPosition", void 0);
RegisterClass("BABYLON.GUI.FluentBackplateMaterial", FluentBackplateMaterial);
//# sourceMappingURL=fluentBackplateMaterial.js.map