UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

1,009 lines (1,008 loc) 43.9 kB
import { __decorate } from "../../tslib.es6.js"; /* eslint-disable @typescript-eslint/naming-convention */ import { serialize, serializeAsColor3, expandToProperty, serializeAsTexture, serializeAsVector3 } from "../../Misc/decorators.js"; import { SmartArray } from "../../Misc/smartArray.js"; import { Logger } from "../../Misc/logger.js"; import { TmpVectors, Vector3, Vector4 } from "../../Maths/math.vector.js"; import { VertexBuffer } from "../../Buffers/buffer.js"; import { MaterialDefines } from "../../Materials/materialDefines.js"; import { PushMaterial } from "../../Materials/pushMaterial.js"; import { ImageProcessingDefinesMixin } from "../../Materials/imageProcessingConfiguration.defines.js"; import { ImageProcessingConfiguration } from "../../Materials/imageProcessingConfiguration.js"; import { RegisterClass } from "../../Misc/typeStore.js"; import { MaterialFlags } from "../materialFlags.js"; import { Color3 } from "../../Maths/math.color.js"; import { EffectFallbacks } from "../effectFallbacks.js"; import { AddClipPlaneUniforms, BindClipPlane } from "../clipPlaneMaterialHelper.js"; import { BindBonesParameters, BindFogParameters, BindLights, BindLogDepth, BindTextureMatrix, BindIBLParameters, BindIBLSamplers, HandleFallbacksForShadows, PrepareAttributesForBones, PrepareAttributesForInstances, PrepareDefinesForAttributes, PrepareDefinesForFrameBoundValues, PrepareDefinesForLights, PrepareDefinesForIBL, PrepareDefinesForMergedUV, PrepareDefinesForMisc, PrepareDefinesForMultiview, PrepareUniformsAndSamplersList, PrepareUniformsAndSamplersForIBL, PrepareUniformLayoutForIBL, } from "../materialHelper.functions.js"; import { SerializationHelper } from "../../Misc/decorators.serialization.js"; import { ImageProcessingMixin } from "../imageProcessing.js"; class BackgroundMaterialDefinesBase extends MaterialDefines { } /** * Background material defines definition. * @internal Mainly internal Use */ class BackgroundMaterialDefines extends ImageProcessingDefinesMixin(BackgroundMaterialDefinesBase) { /** * Constructor of the defines. */ constructor() { super(); /** * True if the diffuse texture is in use. */ this.DIFFUSE = false; /** * The direct UV channel to use. */ this.DIFFUSEDIRECTUV = 0; /** * True if the diffuse texture is in gamma space. */ this.GAMMADIFFUSE = false; /** * True if the diffuse texture has opacity in the alpha channel. */ this.DIFFUSEHASALPHA = false; /** * True if you want the material to fade to transparent at grazing angle. */ this.OPACITYFRESNEL = false; /** * True if an extra blur needs to be added in the reflection. */ this.REFLECTIONBLUR = false; /** * True if you want the material to fade to reflection at grazing angle. */ this.REFLECTIONFRESNEL = false; /** * True if you want the material to falloff as far as you move away from the scene center. */ this.REFLECTIONFALLOFF = false; /** * False if the current Webgl implementation does not support the texture lod extension. */ this.TEXTURELODSUPPORT = false; /** * True to ensure the data are premultiplied. */ this.PREMULTIPLYALPHA = false; /** * True if the texture contains cooked RGB values and not gray scaled multipliers. */ this.USERGBCOLOR = false; /** * True if highlight and shadow levels have been specified. It can help ensuring the main perceived color * stays aligned with the desired configuration. */ this.USEHIGHLIGHTANDSHADOWCOLORS = false; /** * True if only shadows must be rendered */ this.BACKMAT_SHADOWONLY = false; /** * True to add noise in order to reduce the banding effect. */ this.NOISE = false; /** * is the reflection texture in BGR color scheme? * Mainly used to solve a bug in ios10 video tag */ this.REFLECTIONBGR = false; /** * True if ground projection has been enabled. */ this.PROJECTED_GROUND = false; /** Defines whether reflection is enabled */ this.REFLECTION = false; /** Defines whether the reflection map is 3D */ this.REFLECTIONMAP_3D = false; /** Defines whether the reflection map is spherical */ this.REFLECTIONMAP_SPHERICAL = false; /** Defines whether the reflection map is planar */ this.REFLECTIONMAP_PLANAR = false; /** Defines whether the reflection map is cubic */ this.REFLECTIONMAP_CUBIC = false; /** Defines whether the reflection map is in projection mode */ this.REFLECTIONMAP_PROJECTION = false; /** Defines whether the reflection map is a skybox */ this.REFLECTIONMAP_SKYBOX = false; /** Defines whether the reflection map is explicit */ this.REFLECTIONMAP_EXPLICIT = false; /** Defines whether the reflection map is equirectangular */ this.REFLECTIONMAP_EQUIRECTANGULAR = false; /** Defines whether the reflection map is fixed equirectangular */ this.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false; /** Defines whether the reflection map is mirrored fixed equirectangular */ this.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false; /** Defines whether the cubic map should be inverted */ this.INVERTCUBICMAP = false; /** Defines whether the reflection map uses opposite Z */ this.REFLECTIONMAP_OPPOSITEZ = false; /** Defines whether LOD is stored in the reflection alpha channel */ this.LODINREFLECTIONALPHA = false; /** Defines whether the reflection uses gamma space */ this.GAMMAREFLECTION = false; /** Defines whether the reflection is in RGBD format */ this.RGBDREFLECTION = false; /** Defines whether the equirectangular reflection uses a custom field of view */ this.EQUIRECTANGULAR_RELFECTION_FOV = false; /** Defines whether main UV1 channel is used */ this.MAINUV1 = false; /** Defines whether main UV2 channel is used */ this.MAINUV2 = false; /** Defines whether UV1 is used */ this.UV1 = false; /** Defines whether UV2 is used */ this.UV2 = false; /** Defines whether clip plane 1 is enabled */ this.CLIPPLANE = false; /** Defines whether clip plane 2 is enabled */ this.CLIPPLANE2 = false; /** Defines whether clip plane 3 is enabled */ this.CLIPPLANE3 = false; /** Defines whether clip plane 4 is enabled */ this.CLIPPLANE4 = false; /** Defines whether clip plane 5 is enabled */ this.CLIPPLANE5 = false; /** Defines whether clip plane 6 is enabled */ this.CLIPPLANE6 = false; /** Defines whether point size is used */ this.POINTSIZE = false; /** Defines whether fog is enabled */ this.FOG = false; /** Defines whether normals are available */ this.NORMAL = false; /** Defines the number of bone influencers */ this.NUM_BONE_INFLUENCERS = 0; /** Defines the number of bones per mesh */ this.BonesPerMesh = 0; /** Defines whether instances are used */ this.INSTANCES = false; /** Defines whether shadow uses float textures */ this.SHADOWFLOAT = false; /** Defines whether logarithmic depth is enabled */ this.LOGARITHMICDEPTH = false; /** Defines whether non-uniform scaling is applied */ this.NONUNIFORMSCALING = false; /** Defines whether alpha testing is enabled */ this.ALPHATEST = false; this.rebuild(); } } class BackgroundMaterialBase extends ImageProcessingMixin(PushMaterial) { } /** * Background material used to create an efficient environment around your scene. * #157MGZ: simple test */ export class BackgroundMaterial extends BackgroundMaterialBase { /** * Experimental Internal Use Only. * * Key light Color in "perceptual value" meaning the color you would like to see on screen. * This acts as a helper to set the primary color to a more "human friendly" value. * Conversion to linear space as well as exposure and tone mapping correction will be applied to keep the * output color as close as possible from the chosen value. * (This does not account for contrast color grading and color curves as they are considered post effect and not directly * part of lighting setup.) */ get _perceptualColor() { return this.__perceptualColor; } set _perceptualColor(value) { this.__perceptualColor = value; this._computePrimaryColorFromPerceptualColor(); this._markAllSubMeshesAsLightsDirty(); } /** * Defines the level of the shadows (dark area of the reflection map) in order to help scaling the colors. * The color opposite to the primary color is used at the level chosen to define what the black area would look. */ get primaryColorShadowLevel() { return this._primaryColorShadowLevel; } set primaryColorShadowLevel(value) { this._primaryColorShadowLevel = value; this._computePrimaryColors(); this._markAllSubMeshesAsLightsDirty(); } /** * Defines the level of the highlights (highlight area of the reflection map) in order to help scaling the colors. * The primary color is used at the level chosen to define what the white area would look. */ get primaryColorHighlightLevel() { return this._primaryColorHighlightLevel; } set primaryColorHighlightLevel(value) { this._primaryColorHighlightLevel = value; this._computePrimaryColors(); this._markAllSubMeshesAsLightsDirty(); } /** * Sets the reflection reflectance fresnel values according to the default standard * empirically know to work well :-) */ set reflectionStandardFresnelWeight(value) { let reflectionWeight = value; if (reflectionWeight < 0.5) { reflectionWeight = reflectionWeight * 2.0; this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 * reflectionWeight; this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 * reflectionWeight; } else { reflectionWeight = reflectionWeight * 2.0 - 1.0; this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 + (1.0 - BackgroundMaterial.StandardReflectance0) * reflectionWeight; this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 + (1.0 - BackgroundMaterial.StandardReflectance90) * reflectionWeight; } } /** * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out". * Best used when trying to implement visual zoom effects like fish-eye or binoculars while not adjusting camera fov. * Recommended to be keep at 1.0 except for special cases. */ get fovMultiplier() { return this._fovMultiplier; } set fovMultiplier(value) { if (isNaN(value)) { value = 1.0; } this._fovMultiplier = Math.max(0.0, Math.min(2.0, value)); } /** * Instantiates a Background Material in the given scene * @param name The friendly name of the material * @param scene The scene to add the material to * @param forceGLSL Use the GLSL code generation for the shader (even on WebGPU). Default is false */ constructor(name, scene, forceGLSL = false) { super(name, scene, undefined, forceGLSL); /** * Key light Color (multiply against the environment texture) */ this.primaryColor = Color3.White(); this._primaryColorShadowLevel = 0; this._primaryColorHighlightLevel = 0; /** * Reflection Texture used in the material. * Should be author in a specific way for the best result (refer to the documentation). */ this.reflectionTexture = null; /** * Reflection Texture level of blur. * * Can be use to reuse an existing HDR Texture and target a specific LOD to prevent authoring the * texture twice. */ this.reflectionBlur = 0; /** * Diffuse Texture used in the material. * Should be author in a specific way for the best result (refer to the documentation). */ this.diffuseTexture = null; this._shadowLights = null; /** * Specify the list of lights casting shadow on the material. * All scene shadow lights will be included if null. */ this.shadowLights = null; /** * Helps adjusting the shadow to a softer level if required. * 0 means black shadows and 1 means no shadows. */ this.shadowLevel = 0; /** * In case of opacity Fresnel or reflection falloff, this is use as a scene center. * It is usually zero but might be interesting to modify according to your setup. */ this.sceneCenter = Vector3.Zero(); /** * This helps specifying that the material is falling off to the sky box at grazing angle. * This helps ensuring a nice transition when the camera goes under the ground. */ this.opacityFresnel = true; /** * This helps specifying that the material is falling off from diffuse to the reflection texture at grazing angle. * This helps adding a mirror texture on the ground. */ this.reflectionFresnel = false; /** * This helps specifying the falloff radius off the reflection texture from the sceneCenter. * This helps adding a nice falloff effect to the reflection if used as a mirror for instance. */ this.reflectionFalloffDistance = 0.0; /** * This specifies the weight of the reflection against the background in case of reflection Fresnel. */ this.reflectionAmount = 1.0; /** * This specifies the weight of the reflection at grazing angle. */ this.reflectionReflectance0 = 0.05; /** * This specifies the weight of the reflection at a perpendicular point of view. */ this.reflectionReflectance90 = 0.5; /** * Helps to directly use the maps channels instead of their level. */ this.useRGBColor = true; /** * This helps reducing the banding effect that could occur on the background. */ this.enableNoise = false; this._fovMultiplier = 1.0; /** * Enable the FOV adjustment feature controlled by fovMultiplier. */ this.useEquirectangularFOV = false; this._maxSimultaneousLights = 4; /** * Number of Simultaneous lights allowed on the material. */ this.maxSimultaneousLights = 4; this._shadowOnly = false; /** * Make the material only render shadows */ this.shadowOnly = false; /** * Due to a bug in iOS10, video tags (which are using the background material) are in BGR and not RGB. * Setting this flag to true (not done automatically!) will convert it back to RGB. */ this.switchToBGR = false; this._enableGroundProjection = false; /** * Enables the ground projection mode on the material. * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection */ this.enableGroundProjection = false; /** * Defines the radius of the projected ground if enableGroundProjection is true. * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection */ this.projectedGroundRadius = 1000; /** * Defines the height of the projected ground if enableGroundProjection is true. * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/skybox#ground-projection */ this.projectedGroundHeight = 10; // Temp values kept as cache in the material. this._renderTargets = new SmartArray(16); this._reflectionControls = Vector4.Zero(); this._white = Color3.White(); this._primaryShadowColor = Color3.Black(); this._primaryHighlightColor = Color3.Black(); this._shadersLoaded = false; // Setup the default processing configuration to the scene. this._attachImageProcessingConfiguration(null); this.getRenderTargetTextures = () => { this._renderTargets.reset(); if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) { this._renderTargets.push(this._diffuseTexture); } if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) { this._renderTargets.push(this._reflectionTexture); } return this._renderTargets; }; } /** * Gets a boolean indicating that current material needs to register RTT */ get hasRenderTargetTextures() { if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) { return true; } if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) { return true; } return false; } /** * The entire material has been created in order to prevent overdraw. * @returns false */ needAlphaTesting() { return true; } /** * The entire material has been created in order to prevent overdraw. * @returns true if blending is enable */ needAlphaBlending() { return this.alpha < 1 || (this._diffuseTexture != null && this._diffuseTexture.hasAlpha) || this._shadowOnly; } /** * Checks whether the material is ready to be rendered for a given mesh. * @param mesh The mesh to render * @param subMesh The submesh to check against * @param useInstances Specify wether or not the material is used with instances * @returns true if all the dependencies are ready (Textures, Effects...) */ isReadyForSubMesh(mesh, subMesh, useInstances = false) { const drawWrapper = subMesh._drawWrapper; if (drawWrapper.effect && this.isFrozen) { if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) { return true; } } if (!subMesh.materialDefines) { subMesh.materialDefines = new BackgroundMaterialDefines(); } const scene = this.getScene(); const defines = subMesh.materialDefines; if (this._isReadyForSubMesh(subMesh)) { return true; } const engine = scene.getEngine(); // Lights PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights); defines._needNormals = true; // Multiview PrepareDefinesForMultiview(scene, defines); // Textures if (defines._areTexturesDirty) { defines._needUVs = false; if (scene.texturesEnabled) { if (scene.getEngine().getCaps().textureLOD) { defines.TEXTURELODSUPPORT = true; } if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) { if (!this._diffuseTexture.isReadyOrNotBlocking()) { return false; } PrepareDefinesForMergedUV(this._diffuseTexture, defines, "DIFFUSE"); defines.DIFFUSEHASALPHA = this._diffuseTexture.hasAlpha; defines.GAMMADIFFUSE = this._diffuseTexture.gammaSpace; defines.OPACITYFRESNEL = this._opacityFresnel; } else { defines.DIFFUSE = false; defines.DIFFUSEDIRECTUV = 0; defines.DIFFUSEHASALPHA = false; defines.GAMMADIFFUSE = false; defines.OPACITYFRESNEL = false; } const reflectionTexture = this._reflectionTexture; PrepareDefinesForIBL(scene, reflectionTexture, defines); if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) { if (!reflectionTexture.isReadyOrNotBlocking()) { return false; } defines.EQUIRECTANGULAR_RELFECTION_FOV = this.useEquirectangularFOV; defines.REFLECTIONBGR = this.switchToBGR; defines.REFLECTIONBLUR = this._reflectionBlur > 0; if (this.reflectionFresnel) { defines.REFLECTIONFRESNEL = true; defines.REFLECTIONFALLOFF = this.reflectionFalloffDistance > 0; this._reflectionControls.x = this.reflectionAmount; this._reflectionControls.y = this.reflectionReflectance0; this._reflectionControls.z = this.reflectionReflectance90; this._reflectionControls.w = 1 / this.reflectionFalloffDistance; } else { defines.REFLECTIONFRESNEL = false; defines.REFLECTIONFALLOFF = false; } } else { defines.REFLECTIONFRESNEL = false; defines.REFLECTIONFALLOFF = false; defines.REFLECTIONBLUR = false; } } defines.PREMULTIPLYALPHA = this.alphaMode === 7 || this.alphaMode === 8; defines.USERGBCOLOR = this._useRGBColor; defines.NOISE = this._enableNoise; } if (defines._areLightsDirty) { defines.USEHIGHLIGHTANDSHADOWCOLORS = !this._useRGBColor && (this._primaryColorShadowLevel !== 0 || this._primaryColorHighlightLevel !== 0); defines.BACKMAT_SHADOWONLY = this._shadowOnly; } if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) { if (!this._imageProcessingConfiguration.isReady()) { return false; } this._imageProcessingConfiguration.prepareDefines(defines); } if (defines._areMiscDirty) { if (defines.REFLECTIONMAP_3D && this._enableGroundProjection) { defines.PROJECTED_GROUND = true; defines.REFLECTIONMAP_SKYBOX = true; } else { defines.PROJECTED_GROUND = false; } } // Misc. PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines, undefined, undefined, undefined, this._isVertexOutputInvariant); // Values that need to be evaluated on every frame PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, subMesh.getRenderingMesh().hasThinInstances); // Attribs if (PrepareDefinesForAttributes(mesh, defines, false, true, false)) { if (mesh) { if (!scene.getEngine().getCaps().standardDerivatives && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) { mesh.createNormals(true); Logger.Warn("BackgroundMaterial: Normals have been created for the mesh: " + mesh.name); } } } // Get correct effect if (defines.isDirty) { defines.markAsProcessed(); scene.resetCachedMaterial(); // Fallbacks const fallbacks = new EffectFallbacks(); if (defines.FOG) { fallbacks.addFallback(0, "FOG"); } if (defines.POINTSIZE) { fallbacks.addFallback(1, "POINTSIZE"); } if (defines.MULTIVIEW) { fallbacks.addFallback(0, "MULTIVIEW"); } HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights); //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); } PrepareAttributesForBones(attribs, mesh, defines, fallbacks); PrepareAttributesForInstances(attribs, defines); const uniforms = [ "world", "view", "viewProjection", "vEyePosition", "vLightsType", "vFogInfos", "vFogColor", "pointSize", "mBones", "vPrimaryColor", "vPrimaryColorShadow", "fFovMultiplier", "shadowLevel", "alpha", "vBackgroundCenter", "vReflectionControl", "vDiffuseInfos", "diffuseMatrix", "projectedGroundInfos", "logarithmicDepthConstant", ]; AddClipPlaneUniforms(uniforms); const samplers = ["diffuseSampler"]; PrepareUniformsAndSamplersForIBL(uniforms, samplers, false); const uniformBuffers = ["Material", "Scene"]; if (ImageProcessingConfiguration) { ImageProcessingConfiguration.PrepareUniforms(uniforms, defines); ImageProcessingConfiguration.PrepareSamplers(samplers, defines); } PrepareUniformsAndSamplersList({ uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: defines, maxSimultaneousLights: this._maxSimultaneousLights, }); const join = defines.toString(); const effect = scene.getEngine().createEffect("background", { attributes: attribs, uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: join, fallbacks: fallbacks, onCompiled: this.onCompiled, onError: this.onError, indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }, shaderLanguage: this._shaderLanguage, extraInitializationsAsync: this._shadersLoaded ? undefined : async () => { if (this.shaderLanguage === 1 /* ShaderLanguage.WGSL */) { await Promise.all([import("../../ShadersWGSL/background.vertex.js"), import("../../ShadersWGSL/background.fragment.js")]); } else { await Promise.all([import("../../Shaders/background.vertex.js"), import("../../Shaders/background.fragment.js")]); } this._shadersLoaded = true; }, }, engine); subMesh.setEffect(effect, defines, this._materialContext); this.buildUniformLayout(); } if (!subMesh.effect || !subMesh.effect.isReady()) { return false; } defines._renderId = scene.getRenderId(); drawWrapper._wasPreviouslyReady = true; drawWrapper._wasPreviouslyUsingInstances = useInstances; this._checkScenePerformancePriority(); return true; } /** * Compute the primary color according to the chosen perceptual color. */ _computePrimaryColorFromPerceptualColor() { if (!this.__perceptualColor) { return; } this._primaryColor.copyFrom(this.__perceptualColor); // Revert gamma space. this._primaryColor.toLinearSpaceToRef(this._primaryColor, this.getScene().getEngine().useExactSrgbConversions); // Revert image processing configuration. if (this._imageProcessingConfiguration) { // Revert Exposure. this._primaryColor.scaleToRef(1 / this._imageProcessingConfiguration.exposure, this._primaryColor); } this._computePrimaryColors(); } /** * Compute the highlights and shadow colors according to their chosen levels. */ _computePrimaryColors() { if (this._primaryColorShadowLevel === 0 && this._primaryColorHighlightLevel === 0) { return; } // Find the highlight color based on the configuration. this._primaryColor.scaleToRef(this._primaryColorShadowLevel, this._primaryShadowColor); this._primaryColor.subtractToRef(this._primaryShadowColor, this._primaryShadowColor); // Find the shadow color based on the configuration. this._white.subtractToRef(this._primaryColor, this._primaryHighlightColor); this._primaryHighlightColor.scaleToRef(this._primaryColorHighlightLevel, this._primaryHighlightColor); this._primaryColor.addToRef(this._primaryHighlightColor, this._primaryHighlightColor); } /** * Build the uniform buffer used in the material. */ buildUniformLayout() { // Order is important ! this._uniformBuffer.addUniform("vPrimaryColor", 4); this._uniformBuffer.addUniform("vPrimaryColorShadow", 4); this._uniformBuffer.addUniform("vDiffuseInfos", 2); this._uniformBuffer.addUniform("diffuseMatrix", 16); this._uniformBuffer.addUniform("fFovMultiplier", 1); this._uniformBuffer.addUniform("pointSize", 1); this._uniformBuffer.addUniform("shadowLevel", 1); this._uniformBuffer.addUniform("alpha", 1); this._uniformBuffer.addUniform("vBackgroundCenter", 3); this._uniformBuffer.addUniform("vReflectionControl", 4); this._uniformBuffer.addUniform("projectedGroundInfos", 2); PrepareUniformLayoutForIBL(this._uniformBuffer, true, false, false); this._uniformBuffer.create(); } /** * Unbind the material. */ unbind() { if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) { this._uniformBuffer.setTexture("diffuseSampler", null); } if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) { this._uniformBuffer.setTexture("reflectionSampler", null); } super.unbind(); } /** * Bind only the world matrix to the material. * @param world The world matrix to bind. */ bindOnlyWorldMatrix(world) { this._activeEffect.setMatrix("world", world); } /** * Bind the material for a dedicated submesh (every used meshes will be considered opaque). * @param world The world matrix to bind. * @param mesh the mesh to bind for. * @param subMesh The submesh to bind for. */ bindForSubMesh(world, mesh, subMesh) { const scene = this.getScene(); const defines = subMesh.materialDefines; if (!defines) { return; } const effect = subMesh.effect; if (!effect) { return; } this._activeEffect = effect; // Matrices this.bindOnlyWorldMatrix(world); // Bones BindBonesParameters(mesh, this._activeEffect); const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility); if (mustRebind) { this._uniformBuffer.bindToEffect(effect, "Material"); this.bindViewProjection(effect); const reflectionTexture = this._reflectionTexture; if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync || subMesh._drawWrapper._forceRebindOnNextCall) { // Texture uniforms if (scene.texturesEnabled) { if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) { this._uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level); BindTextureMatrix(this._diffuseTexture, this._uniformBuffer, "diffuse"); } BindIBLParameters(scene, defines, this._uniformBuffer, Color3.White(), reflectionTexture, false, true, false, false, false, false, this._reflectionBlur); } if (this.shadowLevel > 0) { this._uniformBuffer.updateFloat("shadowLevel", this.shadowLevel); } this._uniformBuffer.updateFloat("alpha", this.alpha); // Point size if (this.pointsCloud) { this._uniformBuffer.updateFloat("pointSize", this.pointSize); } if (defines.USEHIGHLIGHTANDSHADOWCOLORS) { this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryHighlightColor, 1.0); this._uniformBuffer.updateColor4("vPrimaryColorShadow", this._primaryShadowColor, 1.0); } else { this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, 1.0); } } this._uniformBuffer.updateFloat("fFovMultiplier", this._fovMultiplier); // Fresnel if (defines.REFLECTIONFRESNEL) { this._uniformBuffer.updateFloat4("vReflectionControl", this._reflectionControls.x, this._reflectionControls.y, this._reflectionControls.z, this._reflectionControls.w); } if ((defines.REFLECTIONFRESNEL && defines.REFLECTIONFALLOFF) || defines.OPACITYFRESNEL) { const center = TmpVectors.Vector3[0].copyFrom(this.sceneCenter).subtractInPlace(scene.floatingOriginOffset); this._uniformBuffer.updateFloat3("vBackgroundCenter", center.x, center.y, center.z); } // Textures if (scene.texturesEnabled) { if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) { this._uniformBuffer.setTexture("diffuseSampler", this._diffuseTexture); } if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) { BindIBLSamplers(scene, defines, this._uniformBuffer, reflectionTexture); } if (defines.PROJECTED_GROUND) { this._uniformBuffer.updateFloat2("projectedGroundInfos", this.projectedGroundRadius, this.projectedGroundHeight); } } // Clip plane BindClipPlane(this._activeEffect, this, scene); scene.bindEyePosition(effect); } else if (scene.getEngine()._features.needToAlwaysBindUniformBuffers) { this._uniformBuffer.bindToEffect(effect, "Material"); this._needToBindSceneUbo = true; } if (mustRebind || !this.isFrozen) { if (scene.lightsEnabled) { BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights); } // View this.bindView(effect); // Fog BindFogParameters(scene, mesh, this._activeEffect, true); // Log. depth if (this._useLogarithmicDepth) { BindLogDepth(defines, effect, scene); } // image processing if (this._imageProcessingConfiguration) { this._imageProcessingConfiguration.bind(this._activeEffect); } } this._afterBind(mesh, this._activeEffect, subMesh); this._uniformBuffer.update(); } /** * Checks to see if a texture is used in the material. * @param texture - Base texture to use. * @returns - Boolean specifying if a texture is used in the material. */ hasTexture(texture) { if (super.hasTexture(texture)) { return true; } if (this._reflectionTexture === texture) { return true; } if (this._diffuseTexture === texture) { return true; } return false; } /** * Dispose the material. * @param forceDisposeEffect Force disposal of the associated effect. * @param forceDisposeTextures Force disposal of the associated textures. */ dispose(forceDisposeEffect = false, forceDisposeTextures = false) { if (forceDisposeTextures) { if (this.diffuseTexture) { this.diffuseTexture.dispose(); } if (this.reflectionTexture) { this.reflectionTexture.dispose(); } } this._renderTargets.dispose(); if (this._imageProcessingConfiguration && this._imageProcessingObserver) { this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver); } super.dispose(forceDisposeEffect); } /** * Clones the material. * @param name The cloned name. * @returns The cloned material. */ clone(name) { return SerializationHelper.Clone(() => new BackgroundMaterial(name, this.getScene()), this); } /** * Serializes the current material to its JSON representation. * @returns The JSON representation. */ serialize() { const serializationObject = super.serialize(); serializationObject.customType = "BABYLON.BackgroundMaterial"; return serializationObject; } /** * Gets the class name of the material * @returns "BackgroundMaterial" */ getClassName() { return "BackgroundMaterial"; } /** * Parse a JSON input to create back a background material. * @param source The JSON data to parse * @param scene The scene to create the parsed material in * @param rootUrl The root url of the assets the material depends upon * @returns the instantiated BackgroundMaterial. */ static Parse(source, scene, rootUrl) { return SerializationHelper.Parse(() => new BackgroundMaterial(source.name, scene), source, scene, rootUrl); } } /** * Standard reflectance value at parallel view angle. */ BackgroundMaterial.StandardReflectance0 = 0.05; /** * Standard reflectance value at grazing angle. */ BackgroundMaterial.StandardReflectance90 = 0.5; __decorate([ serializeAsColor3() ], BackgroundMaterial.prototype, "_primaryColor", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsLightsDirty") ], BackgroundMaterial.prototype, "primaryColor", void 0); __decorate([ serializeAsColor3() ], BackgroundMaterial.prototype, "__perceptualColor", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_primaryColorShadowLevel", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_primaryColorHighlightLevel", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsLightsDirty") ], BackgroundMaterial.prototype, "primaryColorHighlightLevel", null); __decorate([ serializeAsTexture() ], BackgroundMaterial.prototype, "_reflectionTexture", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionTexture", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionBlur", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionBlur", void 0); __decorate([ serializeAsTexture() ], BackgroundMaterial.prototype, "_diffuseTexture", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "diffuseTexture", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "shadowLights", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_shadowLevel", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "shadowLevel", void 0); __decorate([ serializeAsVector3() ], BackgroundMaterial.prototype, "_sceneCenter", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "sceneCenter", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_opacityFresnel", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "opacityFresnel", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionFresnel", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionFresnel", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionFalloffDistance", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionFalloffDistance", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionAmount", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionAmount", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionReflectance0", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionReflectance0", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_reflectionReflectance90", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "reflectionReflectance90", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_useRGBColor", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "useRGBColor", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_enableNoise", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "enableNoise", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_maxSimultaneousLights", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsTexturesDirty") ], BackgroundMaterial.prototype, "maxSimultaneousLights", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "_shadowOnly", void 0); __decorate([ expandToProperty("_markAllSubMeshesAsLightsDirty") ], BackgroundMaterial.prototype, "shadowOnly", void 0); __decorate([ serialize(), expandToProperty("_markAllSubMeshesAsMiscDirty") ], BackgroundMaterial.prototype, "enableGroundProjection", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "projectedGroundRadius", void 0); __decorate([ serialize() ], BackgroundMaterial.prototype, "projectedGroundHeight", void 0); RegisterClass("BABYLON.BackgroundMaterial", BackgroundMaterial); //# sourceMappingURL=backgroundMaterial.js.map