123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554 |
- import { __decorate } from "../tslib.es6.js";
- import { serialize } from "../Misc/decorators.js";
- import { Tools } from "../Misc/tools.js";
- import { Observable } from "../Misc/observable.js";
- import { EngineStore } from "../Engines/engineStore.js";
- import { SubMesh } from "../Meshes/subMesh.js";
- import { UniformBuffer } from "./uniformBuffer.js";
- import { Logger } from "../Misc/logger.js";
- import { Plane } from "../Maths/math.plane.js";
- import { DrawWrapper } from "./drawWrapper.js";
- import { MaterialStencilState } from "./materialStencilState.js";
- import { ScenePerformancePriority } from "../scene.js";
- import { MaterialPluginEvent } from "./materialPluginEvent.js";
- import { BindSceneUniformBuffer } from "./materialHelper.functions.js";
- import { SerializationHelper } from "../Misc/decorators.serialization.js";
- /**
- * Base class for the main features of a material in Babylon.js
- */
- export class Material {
- /**
- * If the material can be rendered to several textures with MRT extension
- */
- get canRenderToMRT() {
- // By default, shaders are not compatible with MRTs
- // Base classes should override that if their shader supports MRT
- return false;
- }
- /**
- * Sets the alpha value of the material
- */
- set alpha(value) {
- if (this._alpha === value) {
- return;
- }
- const oldValue = this._alpha;
- this._alpha = value;
- // Only call dirty when there is a state change (no alpha / alpha)
- if (oldValue === 1 || value === 1) {
- this.markAsDirty(Material.MiscDirtyFlag + Material.PrePassDirtyFlag);
- }
- }
- /**
- * Gets the alpha value of the material
- */
- get alpha() {
- return this._alpha;
- }
- /**
- * Sets the culling state (true to enable culling, false to disable)
- */
- set backFaceCulling(value) {
- if (this._backFaceCulling === value) {
- return;
- }
- this._backFaceCulling = value;
- this.markAsDirty(Material.TextureDirtyFlag);
- }
- /**
- * Gets the culling state
- */
- get backFaceCulling() {
- return this._backFaceCulling;
- }
- /**
- * Sets the type of faces that should be culled (true for back faces, false for front faces)
- */
- set cullBackFaces(value) {
- if (this._cullBackFaces === value) {
- return;
- }
- this._cullBackFaces = value;
- this.markAsDirty(Material.TextureDirtyFlag);
- }
- /**
- * Gets the type of faces that should be culled
- */
- get cullBackFaces() {
- return this._cullBackFaces;
- }
- /**
- * Block the dirty-mechanism for this specific material
- * When set to false after being true the material will be marked as dirty.
- */
- get blockDirtyMechanism() {
- return this._blockDirtyMechanism;
- }
- set blockDirtyMechanism(value) {
- if (this._blockDirtyMechanism === value) {
- return;
- }
- this._blockDirtyMechanism = value;
- if (!value) {
- this.markDirty();
- }
- }
- /**
- * This allows you to modify the material without marking it as dirty after every change.
- * This function should be used if you need to make more than one dirty-enabling change to the material - adding a texture, setting a new fill mode and so on.
- * The callback will pass the material as an argument, so you can make your changes to it.
- * @param callback the callback to be executed that will update the material
- */
- atomicMaterialsUpdate(callback) {
- this.blockDirtyMechanism = true;
- try {
- callback(this);
- }
- finally {
- this.blockDirtyMechanism = false;
- }
- }
- /**
- * Gets a boolean indicating that current material needs to register RTT
- */
- get hasRenderTargetTextures() {
- this._eventInfo.hasRenderTargetTextures = false;
- this._callbackPluginEventHasRenderTargetTextures(this._eventInfo);
- return this._eventInfo.hasRenderTargetTextures;
- }
- /**
- * Called during a dispose event
- */
- set onDispose(callback) {
- if (this._onDisposeObserver) {
- this.onDisposeObservable.remove(this._onDisposeObserver);
- }
- this._onDisposeObserver = this.onDisposeObservable.add(callback);
- }
- /**
- * An event triggered when the material is bound
- */
- get onBindObservable() {
- if (!this._onBindObservable) {
- this._onBindObservable = new Observable();
- }
- return this._onBindObservable;
- }
- /**
- * Called during a bind event
- */
- set onBind(callback) {
- if (this._onBindObserver) {
- this.onBindObservable.remove(this._onBindObserver);
- }
- this._onBindObserver = this.onBindObservable.add(callback);
- }
- /**
- * An event triggered when the material is unbound
- */
- get onUnBindObservable() {
- if (!this._onUnBindObservable) {
- this._onUnBindObservable = new Observable();
- }
- return this._onUnBindObservable;
- }
- /**
- * An event triggered when the effect is (re)created
- */
- get onEffectCreatedObservable() {
- if (!this._onEffectCreatedObservable) {
- this._onEffectCreatedObservable = new Observable();
- }
- return this._onEffectCreatedObservable;
- }
- /**
- * Sets the value of the alpha mode.
- *
- * | Value | Type | Description |
- * | --- | --- | --- |
- * | 0 | ALPHA_DISABLE | |
- * | 1 | ALPHA_ADD | |
- * | 2 | ALPHA_COMBINE | |
- * | 3 | ALPHA_SUBTRACT | |
- * | 4 | ALPHA_MULTIPLY | |
- * | 5 | ALPHA_MAXIMIZED | |
- * | 6 | ALPHA_ONEONE | |
- * | 7 | ALPHA_PREMULTIPLIED | |
- * | 8 | ALPHA_PREMULTIPLIED_PORTERDUFF | |
- * | 9 | ALPHA_INTERPOLATE | |
- * | 10 | ALPHA_SCREENMODE | |
- *
- */
- set alphaMode(value) {
- if (this._alphaMode === value) {
- return;
- }
- this._alphaMode = value;
- this.markAsDirty(Material.TextureDirtyFlag);
- }
- /**
- * Gets the value of the alpha mode
- */
- get alphaMode() {
- return this._alphaMode;
- }
- /**
- * Sets the need depth pre-pass value
- */
- set needDepthPrePass(value) {
- if (this._needDepthPrePass === value) {
- return;
- }
- this._needDepthPrePass = value;
- if (this._needDepthPrePass) {
- this.checkReadyOnEveryCall = true;
- }
- }
- /**
- * Gets the depth pre-pass value
- */
- get needDepthPrePass() {
- return this._needDepthPrePass;
- }
- /**
- * Can this material render to prepass
- */
- get isPrePassCapable() {
- return false;
- }
- /**
- * Sets the state for enabling fog
- */
- set fogEnabled(value) {
- if (this._fogEnabled === value) {
- return;
- }
- this._fogEnabled = value;
- this.markAsDirty(Material.MiscDirtyFlag);
- }
- /**
- * Gets the value of the fog enabled state
- */
- get fogEnabled() {
- return this._fogEnabled;
- }
- get wireframe() {
- switch (this._fillMode) {
- case Material.WireFrameFillMode:
- case Material.LineListDrawMode:
- case Material.LineLoopDrawMode:
- case Material.LineStripDrawMode:
- return true;
- }
- return this._scene.forceWireframe;
- }
- /**
- * Sets the state of wireframe mode
- */
- set wireframe(value) {
- this.fillMode = value ? Material.WireFrameFillMode : Material.TriangleFillMode;
- }
- /**
- * Gets the value specifying if point clouds are enabled
- */
- get pointsCloud() {
- switch (this._fillMode) {
- case Material.PointFillMode:
- case Material.PointListDrawMode:
- return true;
- }
- return this._scene.forcePointsCloud;
- }
- /**
- * Sets the state of point cloud mode
- */
- set pointsCloud(value) {
- this.fillMode = value ? Material.PointFillMode : Material.TriangleFillMode;
- }
- /**
- * Gets the material fill mode
- */
- get fillMode() {
- return this._fillMode;
- }
- /**
- * Sets the material fill mode
- */
- set fillMode(value) {
- if (this._fillMode === value) {
- return;
- }
- this._fillMode = value;
- this.markAsDirty(Material.MiscDirtyFlag);
- }
- /**
- * In case the depth buffer does not allow enough depth precision for your scene (might be the case in large scenes)
- * You can try switching to logarithmic depth.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/logarithmicDepthBuffer
- */
- get useLogarithmicDepth() {
- return this._useLogarithmicDepth;
- }
- set useLogarithmicDepth(value) {
- const fragmentDepthSupported = this.getScene().getEngine().getCaps().fragmentDepthSupported;
- if (value && !fragmentDepthSupported) {
- Logger.Warn("Logarithmic depth has been requested for a material on a device that doesn't support it.");
- }
- this._useLogarithmicDepth = value && fragmentDepthSupported;
- this._markAllSubMeshesAsMiscDirty();
- }
- /** @internal */
- _getDrawWrapper() {
- return this._drawWrapper;
- }
- /**
- * @internal
- */
- _setDrawWrapper(drawWrapper) {
- this._drawWrapper = drawWrapper;
- }
- /**
- * Creates a material instance
- * @param name defines the name of the material
- * @param scene defines the scene to reference
- * @param doNotAdd specifies if the material should be added to the scene
- */
- constructor(name, scene, doNotAdd) {
- /**
- * Custom shadow depth material to use for shadow rendering instead of the in-built one
- */
- this.shadowDepthWrapper = null;
- /**
- * Gets or sets a boolean indicating that the material is allowed (if supported) to do shader hot swapping.
- * This means that the material can keep using a previous shader while a new one is being compiled.
- * This is mostly used when shader parallel compilation is supported (true by default)
- */
- this.allowShaderHotSwapping = true;
- /**
- * Gets or sets user defined metadata
- */
- this.metadata = null;
- /**
- * For internal use only. Please do not use.
- */
- this.reservedDataStore = null;
- /**
- * Specifies if the ready state should be checked on each call
- */
- this.checkReadyOnEveryCall = false;
- /**
- * Specifies if the ready state should be checked once
- */
- this.checkReadyOnlyOnce = false;
- /**
- * The state of the material
- */
- this.state = "";
- /**
- * The alpha value of the material
- */
- this._alpha = 1.0;
- /**
- * Specifies if back face culling is enabled
- */
- this._backFaceCulling = true;
- /**
- * Specifies if back or front faces should be culled (when culling is enabled)
- */
- this._cullBackFaces = true;
- this._blockDirtyMechanism = false;
- /**
- * Callback triggered when the material is compiled
- */
- this.onCompiled = null;
- /**
- * Callback triggered when an error occurs
- */
- this.onError = null;
- /**
- * Callback triggered to get the render target textures
- */
- this.getRenderTargetTextures = null;
- /**
- * Specifies if the material should be serialized
- */
- this.doNotSerialize = false;
- /**
- * @internal
- */
- this._storeEffectOnSubMeshes = false;
- /**
- * Stores the animations for the material
- */
- this.animations = null;
- /**
- * An event triggered when the material is disposed
- */
- this.onDisposeObservable = new Observable();
- /**
- * An observer which watches for dispose events
- */
- this._onDisposeObserver = null;
- this._onUnBindObservable = null;
- /**
- * An observer which watches for bind events
- */
- this._onBindObserver = null;
- /**
- * Stores the value of the alpha mode
- */
- this._alphaMode = 2;
- /**
- * Stores the state of the need depth pre-pass value
- */
- this._needDepthPrePass = false;
- /**
- * Specifies if depth writing should be disabled
- */
- this.disableDepthWrite = false;
- /**
- * Specifies if color writing should be disabled
- */
- this.disableColorWrite = false;
- /**
- * Specifies if depth writing should be forced
- */
- this.forceDepthWrite = false;
- /**
- * Specifies the depth function that should be used. 0 means the default engine function
- */
- this.depthFunction = 0;
- /**
- * Specifies if there should be a separate pass for culling
- */
- this.separateCullingPass = false;
- /**
- * Stores the state specifying if fog should be enabled
- */
- this._fogEnabled = true;
- /**
- * Stores the size of points
- */
- this.pointSize = 1.0;
- /**
- * Stores the z offset Factor value
- */
- this.zOffset = 0;
- /**
- * Stores the z offset Units value
- */
- this.zOffsetUnits = 0;
- /**
- * Gives access to the stencil properties of the material
- */
- this.stencil = new MaterialStencilState();
- /**
- * Specifies if uniform buffers should be used
- */
- this._useUBO = false;
- /**
- * Stores the fill mode state
- */
- this._fillMode = Material.TriangleFillMode;
- /**
- * Specifies if the depth write state should be cached
- */
- this._cachedDepthWriteState = false;
- /**
- * Specifies if the color write state should be cached
- */
- this._cachedColorWriteState = false;
- /**
- * Specifies if the depth function state should be cached
- */
- this._cachedDepthFunctionState = 0;
- /** @internal */
- this._indexInSceneMaterialArray = -1;
- /** @internal */
- this.meshMap = null;
- /** @internal */
- this._parentContainer = null;
- /** @internal */
- this._uniformBufferLayoutBuilt = false;
- this._eventInfo = {}; // will be initialized before each event notification
- /** @internal */
- this._callbackPluginEventGeneric = () => void 0;
- /** @internal */
- this._callbackPluginEventIsReadyForSubMesh = () => void 0;
- /** @internal */
- this._callbackPluginEventPrepareDefines = () => void 0;
- /** @internal */
- this._callbackPluginEventPrepareDefinesBeforeAttributes = () => void 0;
- /** @internal */
- this._callbackPluginEventHardBindForSubMesh = () => void 0;
- /** @internal */
- this._callbackPluginEventBindForSubMesh = () => void 0;
- /** @internal */
- this._callbackPluginEventHasRenderTargetTextures = () => void 0;
- /** @internal */
- this._callbackPluginEventFillRenderTargetTextures = () => void 0;
- /**
- * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
- */
- this._forceAlphaTest = false;
- /**
- * The transparency mode of the material.
- */
- this._transparencyMode = null;
- this.name = name;
- const setScene = scene || EngineStore.LastCreatedScene;
- if (!setScene) {
- return;
- }
- this._scene = setScene;
- this._dirtyCallbacks = {};
- this._dirtyCallbacks[1] = this._markAllSubMeshesAsTexturesDirty.bind(this);
- this._dirtyCallbacks[2] = this._markAllSubMeshesAsLightsDirty.bind(this);
- this._dirtyCallbacks[4] = this._markAllSubMeshesAsFresnelDirty.bind(this);
- this._dirtyCallbacks[8] = this._markAllSubMeshesAsAttributesDirty.bind(this);
- this._dirtyCallbacks[16] = this._markAllSubMeshesAsMiscDirty.bind(this);
- this._dirtyCallbacks[32] = this._markAllSubMeshesAsPrePassDirty.bind(this);
- this._dirtyCallbacks[63] = this._markAllSubMeshesAsAllDirty.bind(this);
- this.id = name || Tools.RandomId();
- this.uniqueId = this._scene.getUniqueId();
- this._materialContext = this._scene.getEngine().createMaterialContext();
- this._drawWrapper = new DrawWrapper(this._scene.getEngine(), false);
- this._drawWrapper.materialContext = this._materialContext;
- if (this._scene.useRightHandedSystem) {
- this.sideOrientation = Material.ClockWiseSideOrientation;
- }
- else {
- this.sideOrientation = Material.CounterClockWiseSideOrientation;
- }
- this._uniformBuffer = new UniformBuffer(this._scene.getEngine(), undefined, undefined, name);
- this._useUBO = this.getScene().getEngine().supportsUniformBuffers;
- if (!doNotAdd) {
- this._scene.addMaterial(this);
- }
- if (this._scene.useMaterialMeshMap) {
- this.meshMap = {};
- }
- Material.OnEventObservable.notifyObservers(this, MaterialPluginEvent.Created);
- }
- /**
- * Returns a string representation of the current material
- * @param fullDetails defines a boolean indicating which levels of logging is desired
- * @returns a string with material information
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- toString(fullDetails) {
- const ret = "Name: " + this.name;
- return ret;
- }
- /**
- * Gets the class name of the material
- * @returns a string with the class name of the material
- */
- getClassName() {
- return "Material";
- }
- /** @internal */
- get _isMaterial() {
- return true;
- }
- /**
- * Specifies if updates for the material been locked
- */
- get isFrozen() {
- return this.checkReadyOnlyOnce;
- }
- /**
- * Locks updates for the material
- */
- freeze() {
- this.markDirty();
- this.checkReadyOnlyOnce = true;
- }
- /**
- * Unlocks updates for the material
- */
- unfreeze() {
- this.markDirty();
- this.checkReadyOnlyOnce = false;
- }
- /**
- * Specifies if the material is ready to be used
- * @param mesh defines the mesh to check
- * @param useInstances specifies if instances should be used
- * @returns a boolean indicating if the material is ready to be used
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- isReady(mesh, useInstances) {
- return true;
- }
- /**
- * Specifies that the submesh is ready to be used
- * @param mesh defines the mesh to check
- * @param subMesh defines which submesh to check
- * @param useInstances specifies that instances should be used
- * @returns a boolean indicating that the submesh is ready or not
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- isReadyForSubMesh(mesh, subMesh, useInstances) {
- const defines = subMesh.materialDefines;
- if (!defines) {
- return false;
- }
- this._eventInfo.isReadyForSubMesh = true;
- this._eventInfo.defines = defines;
- this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);
- return this._eventInfo.isReadyForSubMesh;
- }
- /**
- * Returns the material effect
- * @returns the effect associated with the material
- */
- getEffect() {
- return this._drawWrapper.effect;
- }
- /**
- * Returns the current scene
- * @returns a Scene
- */
- getScene() {
- return this._scene;
- }
- /**
- * Gets the current transparency mode.
- */
- get transparencyMode() {
- return this._transparencyMode;
- }
- /**
- * Sets the transparency mode of the material.
- *
- * | Value | Type | Description |
- * | ----- | ----------------------------------- | ----------- |
- * | 0 | OPAQUE | |
- * | 1 | ALPHATEST | |
- * | 2 | ALPHABLEND | |
- * | 3 | ALPHATESTANDBLEND | |
- *
- */
- set transparencyMode(value) {
- if (this._transparencyMode === value) {
- return;
- }
- this._transparencyMode = value;
- this._forceAlphaTest = value === Material.MATERIAL_ALPHATESTANDBLEND;
- this._markAllSubMeshesAsTexturesAndMiscDirty();
- }
- /**
- * Returns true if alpha blending should be disabled.
- */
- get _disableAlphaBlending() {
- return this._transparencyMode === Material.MATERIAL_OPAQUE || this._transparencyMode === Material.MATERIAL_ALPHATEST;
- }
- /**
- * Specifies whether or not this material should be rendered in alpha blend mode.
- * @returns a boolean specifying if alpha blending is needed
- */
- needAlphaBlending() {
- if (this._disableAlphaBlending) {
- return false;
- }
- return this.alpha < 1.0;
- }
- /**
- * Specifies if the mesh will require alpha blending
- * @param mesh defines the mesh to check
- * @returns a boolean specifying if alpha blending is needed for the mesh
- */
- needAlphaBlendingForMesh(mesh) {
- if (mesh.visibility < 1.0) {
- return true;
- }
- if (this._disableAlphaBlending) {
- return false;
- }
- return mesh.hasVertexAlpha || this.needAlphaBlending();
- }
- /**
- * Specifies whether or not this material should be rendered in alpha test mode.
- * @returns a boolean specifying if an alpha test is needed.
- */
- needAlphaTesting() {
- if (this._forceAlphaTest) {
- return true;
- }
- return false;
- }
- /**
- * Specifies if material alpha testing should be turned on for the mesh
- * @param mesh defines the mesh to check
- * @returns a boolean specifying if alpha testing should be turned on for the mesh
- */
- _shouldTurnAlphaTestOn(mesh) {
- return !this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting();
- }
- /**
- * Gets the texture used for the alpha test
- * @returns the texture to use for alpha testing
- */
- getAlphaTestTexture() {
- return null;
- }
- /**
- * Marks the material to indicate that it needs to be re-calculated
- * @param forceMaterialDirty - Forces the material to be marked as dirty for all components (same as this.markAsDirty(Material.AllDirtyFlag)). You should use this flag if the material is frozen and you want to force a recompilation.
- */
- markDirty(forceMaterialDirty = false) {
- const meshes = this.getScene().meshes;
- for (const mesh of meshes) {
- if (!mesh.subMeshes) {
- continue;
- }
- for (const subMesh of mesh.subMeshes) {
- if (subMesh.getMaterial() !== this) {
- continue;
- }
- for (const drawWrapper of subMesh._drawWrappers) {
- if (!drawWrapper) {
- continue;
- }
- if (this._materialContext === drawWrapper.materialContext) {
- drawWrapper._wasPreviouslyReady = false;
- drawWrapper._wasPreviouslyUsingInstances = null;
- drawWrapper._forceRebindOnNextCall = forceMaterialDirty;
- }
- }
- }
- }
- if (forceMaterialDirty) {
- this.markAsDirty(Material.AllDirtyFlag);
- }
- }
- /**
- * @internal
- */
- _preBind(effect, overrideOrientation = null) {
- const engine = this._scene.getEngine();
- const orientation = overrideOrientation == null ? this.sideOrientation : overrideOrientation;
- const reverse = orientation === Material.ClockWiseSideOrientation;
- engine.enableEffect(effect ? effect : this._getDrawWrapper());
- engine.setState(this.backFaceCulling, this.zOffset, false, reverse, this._scene._mirroredCameraPosition ? !this.cullBackFaces : this.cullBackFaces, this.stencil, this.zOffsetUnits);
- return reverse;
- }
- /**
- * Binds the material to the mesh
- * @param world defines the world transformation matrix
- * @param mesh defines the mesh to bind the material to
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- bind(world, mesh) { }
- /**
- * Initializes the uniform buffer layout for the shader.
- */
- buildUniformLayout() {
- const ubo = this._uniformBuffer;
- this._eventInfo.ubo = ubo;
- this._callbackPluginEventGeneric(MaterialPluginEvent.PrepareUniformBuffer, this._eventInfo);
- ubo.create();
- this._uniformBufferLayoutBuilt = true;
- }
- /**
- * Binds the submesh to the material
- * @param world defines the world transformation matrix
- * @param mesh defines the mesh containing the submesh
- * @param subMesh defines the submesh to bind the material to
- */
- bindForSubMesh(world, mesh, subMesh) {
- const drawWrapper = subMesh._drawWrapper;
- this._eventInfo.subMesh = subMesh;
- this._callbackPluginEventBindForSubMesh(this._eventInfo);
- drawWrapper._forceRebindOnNextCall = false;
- }
- /**
- * Binds the world matrix to the material
- * @param world defines the world transformation matrix
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- bindOnlyWorldMatrix(world) { }
- /**
- * Binds the view matrix to the effect
- * @param effect defines the effect to bind the view matrix to
- */
- bindView(effect) {
- if (!this._useUBO) {
- effect.setMatrix("view", this.getScene().getViewMatrix());
- }
- else {
- this._needToBindSceneUbo = true;
- }
- }
- /**
- * Binds the view projection and projection matrices to the effect
- * @param effect defines the effect to bind the view projection and projection matrices to
- */
- bindViewProjection(effect) {
- if (!this._useUBO) {
- effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
- effect.setMatrix("projection", this.getScene().getProjectionMatrix());
- }
- else {
- this._needToBindSceneUbo = true;
- }
- }
- /**
- * Binds the view matrix to the effect
- * @param effect defines the effect to bind the view matrix to
- * @param variableName name of the shader variable that will hold the eye position
- */
- bindEyePosition(effect, variableName) {
- if (!this._useUBO) {
- this._scene.bindEyePosition(effect, variableName);
- }
- else {
- this._needToBindSceneUbo = true;
- }
- }
- /**
- * Processes to execute after binding the material to a mesh
- * @param mesh defines the rendered mesh
- * @param effect defines the effect used to bind the material
- * @param _subMesh defines the subMesh that the material has been bound for
- */
- _afterBind(mesh, effect = null, _subMesh) {
- this._scene._cachedMaterial = this;
- if (this._needToBindSceneUbo) {
- if (effect) {
- this._needToBindSceneUbo = false;
- BindSceneUniformBuffer(effect, this.getScene().getSceneUniformBuffer());
- this._scene.finalizeSceneUbo();
- }
- }
- if (mesh) {
- this._scene._cachedVisibility = mesh.visibility;
- }
- else {
- this._scene._cachedVisibility = 1;
- }
- if (this._onBindObservable && mesh) {
- this._onBindObservable.notifyObservers(mesh);
- }
- if (this.disableDepthWrite) {
- const engine = this._scene.getEngine();
- this._cachedDepthWriteState = engine.getDepthWrite();
- engine.setDepthWrite(false);
- }
- if (this.disableColorWrite) {
- const engine = this._scene.getEngine();
- this._cachedColorWriteState = engine.getColorWrite();
- engine.setColorWrite(false);
- }
- if (this.depthFunction !== 0) {
- const engine = this._scene.getEngine();
- this._cachedDepthFunctionState = engine.getDepthFunction() || 0;
- engine.setDepthFunction(this.depthFunction);
- }
- }
- /**
- * Unbinds the material from the mesh
- */
- unbind() {
- if (this._onUnBindObservable) {
- this._onUnBindObservable.notifyObservers(this);
- }
- if (this.depthFunction !== 0) {
- const engine = this._scene.getEngine();
- engine.setDepthFunction(this._cachedDepthFunctionState);
- }
- if (this.disableDepthWrite) {
- const engine = this._scene.getEngine();
- engine.setDepthWrite(this._cachedDepthWriteState);
- }
- if (this.disableColorWrite) {
- const engine = this._scene.getEngine();
- engine.setColorWrite(this._cachedColorWriteState);
- }
- }
- /**
- * Returns the animatable textures.
- * @returns - Array of animatable textures.
- */
- getAnimatables() {
- this._eventInfo.animatables = [];
- this._callbackPluginEventGeneric(MaterialPluginEvent.GetAnimatables, this._eventInfo);
- return this._eventInfo.animatables;
- }
- /**
- * Gets the active textures from the material
- * @returns an array of textures
- */
- getActiveTextures() {
- this._eventInfo.activeTextures = [];
- this._callbackPluginEventGeneric(MaterialPluginEvent.GetActiveTextures, this._eventInfo);
- return this._eventInfo.activeTextures;
- }
- /**
- * Specifies if the material uses a texture
- * @param texture defines the texture to check against the material
- * @returns a boolean specifying if the material uses the texture
- */
- hasTexture(texture) {
- this._eventInfo.hasTexture = false;
- this._eventInfo.texture = texture;
- this._callbackPluginEventGeneric(MaterialPluginEvent.HasTexture, this._eventInfo);
- return this._eventInfo.hasTexture;
- }
- /**
- * Makes a duplicate of the material, and gives it a new name
- * @param name defines the new name for the duplicated material
- * @returns the cloned material
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- clone(name) {
- return null;
- }
- _clonePlugins(targetMaterial, rootUrl) {
- const serializationObject = {};
- // Create plugins in targetMaterial in case they don't exist
- this._serializePlugins(serializationObject);
- Material._ParsePlugins(serializationObject, targetMaterial, this._scene, rootUrl);
- // Copy the properties of the current plugins to the cloned material's plugins
- if (this.pluginManager) {
- for (const plugin of this.pluginManager._plugins) {
- const targetPlugin = targetMaterial.pluginManager.getPlugin(plugin.name);
- if (targetPlugin) {
- plugin.copyTo(targetPlugin);
- }
- }
- }
- }
- /**
- * Gets the meshes bound to the material
- * @returns an array of meshes bound to the material
- */
- getBindedMeshes() {
- if (this.meshMap) {
- const result = [];
- for (const meshId in this.meshMap) {
- const mesh = this.meshMap[meshId];
- if (mesh) {
- result.push(mesh);
- }
- }
- return result;
- }
- else {
- const meshes = this._scene.meshes;
- return meshes.filter((mesh) => mesh.material === this);
- }
- }
- /**
- * Force shader compilation
- * @param mesh defines the mesh associated with this material
- * @param onCompiled defines a function to execute once the material is compiled
- * @param options defines the options to configure the compilation
- * @param onError defines a function to execute if the material fails compiling
- */
- forceCompilation(mesh, onCompiled, options, onError) {
- const localOptions = {
- clipPlane: false,
- useInstances: false,
- ...options,
- };
- const scene = this.getScene();
- const currentHotSwapingState = this.allowShaderHotSwapping;
- this.allowShaderHotSwapping = false; // Turned off to let us evaluate the real compilation state
- const checkReady = () => {
- if (!this._scene || !this._scene.getEngine()) {
- return;
- }
- const clipPlaneState = scene.clipPlane;
- if (localOptions.clipPlane) {
- scene.clipPlane = new Plane(0, 0, 0, 1);
- }
- if (this._storeEffectOnSubMeshes) {
- let allDone = true, lastError = null;
- if (mesh.subMeshes) {
- const tempSubMesh = new SubMesh(0, 0, 0, 0, 0, mesh, undefined, false, false);
- if (tempSubMesh.materialDefines) {
- tempSubMesh.materialDefines._renderId = -1;
- }
- if (!this.isReadyForSubMesh(mesh, tempSubMesh, localOptions.useInstances)) {
- if (tempSubMesh.effect && tempSubMesh.effect.getCompilationError() && tempSubMesh.effect.allFallbacksProcessed()) {
- lastError = tempSubMesh.effect.getCompilationError();
- }
- else {
- allDone = false;
- setTimeout(checkReady, 16);
- }
- }
- }
- if (allDone) {
- this.allowShaderHotSwapping = currentHotSwapingState;
- if (lastError) {
- if (onError) {
- onError(lastError);
- }
- }
- if (onCompiled) {
- onCompiled(this);
- }
- }
- }
- else {
- if (this.isReady()) {
- this.allowShaderHotSwapping = currentHotSwapingState;
- if (onCompiled) {
- onCompiled(this);
- }
- }
- else {
- setTimeout(checkReady, 16);
- }
- }
- if (localOptions.clipPlane) {
- scene.clipPlane = clipPlaneState;
- }
- };
- checkReady();
- }
- /**
- * Force shader compilation
- * @param mesh defines the mesh that will use this material
- * @param options defines additional options for compiling the shaders
- * @returns a promise that resolves when the compilation completes
- */
- forceCompilationAsync(mesh, options) {
- return new Promise((resolve, reject) => {
- this.forceCompilation(mesh, () => {
- resolve();
- }, options, (reason) => {
- reject(reason);
- });
- });
- }
- /**
- * Marks a define in the material to indicate that it needs to be re-computed
- * @param flag defines a flag used to determine which parts of the material have to be marked as dirty
- */
- markAsDirty(flag) {
- if (this.getScene().blockMaterialDirtyMechanism || this._blockDirtyMechanism) {
- return;
- }
- Material._DirtyCallbackArray.length = 0;
- if (flag & Material.TextureDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._TextureDirtyCallBack);
- }
- if (flag & Material.LightDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._LightsDirtyCallBack);
- }
- if (flag & Material.FresnelDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._FresnelDirtyCallBack);
- }
- if (flag & Material.AttributesDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._AttributeDirtyCallBack);
- }
- if (flag & Material.MiscDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._MiscDirtyCallBack);
- }
- if (flag & Material.PrePassDirtyFlag) {
- Material._DirtyCallbackArray.push(Material._PrePassDirtyCallBack);
- }
- if (Material._DirtyCallbackArray.length) {
- this._markAllSubMeshesAsDirty(Material._RunDirtyCallBacks);
- }
- this.getScene().resetCachedMaterial();
- }
- /**
- * Resets the draw wrappers cache for all submeshes that are using this material
- */
- resetDrawCache() {
- const meshes = this.getScene().meshes;
- for (const mesh of meshes) {
- if (!mesh.subMeshes) {
- continue;
- }
- for (const subMesh of mesh.subMeshes) {
- if (subMesh.getMaterial() !== this) {
- continue;
- }
- subMesh.resetDrawCache();
- }
- }
- }
- /**
- * Marks all submeshes of a material to indicate that their material defines need to be re-calculated
- * @param func defines a function which checks material defines against the submeshes
- */
- _markAllSubMeshesAsDirty(func) {
- if (this.getScene().blockMaterialDirtyMechanism || this._blockDirtyMechanism) {
- return;
- }
- const meshes = this.getScene().meshes;
- for (const mesh of meshes) {
- if (!mesh.subMeshes) {
- continue;
- }
- for (const subMesh of mesh.subMeshes) {
- // We want to skip the submeshes which are not using this material or which have not yet rendered at least once
- if (subMesh.getMaterial(false) !== this) {
- continue;
- }
- for (const drawWrapper of subMesh._drawWrappers) {
- if (!drawWrapper || !drawWrapper.defines || !drawWrapper.defines.markAllAsDirty) {
- continue;
- }
- if (this._materialContext === drawWrapper.materialContext) {
- func(drawWrapper.defines);
- }
- }
- }
- }
- }
- /**
- * Indicates that the scene should check if the rendering now needs a prepass
- */
- _markScenePrePassDirty() {
- if (this.getScene().blockMaterialDirtyMechanism || this._blockDirtyMechanism) {
- return;
- }
- const prePassRenderer = this.getScene().enablePrePassRenderer();
- if (prePassRenderer) {
- prePassRenderer.markAsDirty();
- }
- }
- /**
- * Indicates that we need to re-calculated for all submeshes
- */
- _markAllSubMeshesAsAllDirty() {
- this._markAllSubMeshesAsDirty(Material._AllDirtyCallBack);
- }
- /**
- * Indicates that image processing needs to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsImageProcessingDirty() {
- this._markAllSubMeshesAsDirty(Material._ImageProcessingDirtyCallBack);
- }
- /**
- * Indicates that textures need to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsTexturesDirty() {
- this._markAllSubMeshesAsDirty(Material._TextureDirtyCallBack);
- }
- /**
- * Indicates that fresnel needs to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsFresnelDirty() {
- this._markAllSubMeshesAsDirty(Material._FresnelDirtyCallBack);
- }
- /**
- * Indicates that fresnel and misc need to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsFresnelAndMiscDirty() {
- this._markAllSubMeshesAsDirty(Material._FresnelAndMiscDirtyCallBack);
- }
- /**
- * Indicates that lights need to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsLightsDirty() {
- this._markAllSubMeshesAsDirty(Material._LightsDirtyCallBack);
- }
- /**
- * Indicates that attributes need to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsAttributesDirty() {
- this._markAllSubMeshesAsDirty(Material._AttributeDirtyCallBack);
- }
- /**
- * Indicates that misc needs to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsMiscDirty() {
- this._markAllSubMeshesAsDirty(Material._MiscDirtyCallBack);
- }
- /**
- * Indicates that prepass needs to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsPrePassDirty() {
- this._markAllSubMeshesAsDirty(Material._MiscDirtyCallBack);
- }
- /**
- * Indicates that textures and misc need to be re-calculated for all submeshes
- */
- _markAllSubMeshesAsTexturesAndMiscDirty() {
- this._markAllSubMeshesAsDirty(Material._TextureAndMiscDirtyCallBack);
- }
- _checkScenePerformancePriority() {
- if (this._scene.performancePriority !== ScenePerformancePriority.BackwardCompatible) {
- this.checkReadyOnlyOnce = true;
- // re-set the flag when the perf priority changes
- const observer = this._scene.onScenePerformancePriorityChangedObservable.addOnce(() => {
- this.checkReadyOnlyOnce = false;
- });
- // if this material is disposed before the scene is disposed, cleanup the observer
- this.onDisposeObservable.add(() => {
- this._scene.onScenePerformancePriorityChangedObservable.remove(observer);
- });
- }
- }
- /**
- * Sets the required values to the prepass renderer.
- * @param prePassRenderer defines the prepass renderer to setup.
- * @returns true if the pre pass is needed.
- */
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- setPrePassRenderer(prePassRenderer) {
- // Do Nothing by default
- return false;
- }
- /**
- * Disposes the material
- * @param forceDisposeEffect specifies if effects should be forcefully disposed
- * @param forceDisposeTextures specifies if textures should be forcefully disposed
- * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh
- */
- dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh) {
- const scene = this.getScene();
- // Animations
- scene.stopAnimation(this);
- scene.freeProcessedMaterials();
- // Remove from scene
- scene.removeMaterial(this);
- this._eventInfo.forceDisposeTextures = forceDisposeTextures;
- this._callbackPluginEventGeneric(MaterialPluginEvent.Disposed, this._eventInfo);
- if (this._parentContainer) {
- const index = this._parentContainer.materials.indexOf(this);
- if (index > -1) {
- this._parentContainer.materials.splice(index, 1);
- }
- this._parentContainer = null;
- }
- if (notBoundToMesh !== true) {
- // Remove from meshes
- if (this.meshMap) {
- for (const meshId in this.meshMap) {
- const mesh = this.meshMap[meshId];
- if (mesh) {
- mesh.material = null; // will set the entry in the map to undefined
- this.releaseVertexArrayObject(mesh, forceDisposeEffect);
- }
- }
- }
- else {
- const meshes = scene.meshes;
- for (const mesh of meshes) {
- if (mesh.material === this && !mesh.sourceMesh) {
- mesh.material = null;
- this.releaseVertexArrayObject(mesh, forceDisposeEffect);
- }
- }
- }
- }
- this._uniformBuffer.dispose();
- // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
- if (forceDisposeEffect && this._drawWrapper.effect) {
- if (!this._storeEffectOnSubMeshes) {
- this._drawWrapper.effect.dispose();
- }
- this._drawWrapper.effect = null;
- }
- this.metadata = null;
- // Callback
- this.onDisposeObservable.notifyObservers(this);
- this.onDisposeObservable.clear();
- if (this._onBindObservable) {
- this._onBindObservable.clear();
- }
- if (this._onUnBindObservable) {
- this._onUnBindObservable.clear();
- }
- if (this._onEffectCreatedObservable) {
- this._onEffectCreatedObservable.clear();
- }
- if (this._eventInfo) {
- this._eventInfo = {};
- }
- }
- /**
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- releaseVertexArrayObject(mesh, forceDisposeEffect) {
- const geometry = mesh.geometry;
- if (geometry) {
- if (this._storeEffectOnSubMeshes) {
- if (mesh.subMeshes) {
- for (const subMesh of mesh.subMeshes) {
- geometry._releaseVertexArrayObject(subMesh.effect);
- if (forceDisposeEffect && subMesh.effect) {
- subMesh.effect.dispose();
- }
- }
- }
- }
- else {
- geometry._releaseVertexArrayObject(this._drawWrapper.effect);
- }
- }
- }
- /**
- * Serializes this material
- * @returns the serialized material object
- */
- serialize() {
- const serializationObject = SerializationHelper.Serialize(this);
- serializationObject.stencil = this.stencil.serialize();
- serializationObject.uniqueId = this.uniqueId;
- this._serializePlugins(serializationObject);
- return serializationObject;
- }
- _serializePlugins(serializationObject) {
- serializationObject.plugins = {};
- if (this.pluginManager) {
- for (const plugin of this.pluginManager._plugins) {
- serializationObject.plugins[plugin.getClassName()] = plugin.serialize();
- }
- }
- }
- /**
- * Creates a material from parsed material data
- * @param parsedMaterial defines parsed material data
- * @param scene defines the hosting scene
- * @param rootUrl defines the root URL to use to load textures
- * @returns a new material
- */
- static Parse(parsedMaterial, scene, rootUrl) {
- if (!parsedMaterial.customType) {
- parsedMaterial.customType = "BABYLON.StandardMaterial";
- }
- else if (parsedMaterial.customType === "BABYLON.PBRMaterial" && parsedMaterial.overloadedAlbedo) {
- parsedMaterial.customType = "BABYLON.LegacyPBRMaterial";
- if (!BABYLON.LegacyPBRMaterial) {
- Logger.Error("Your scene is trying to load a legacy version of the PBRMaterial, please, include it from the materials library.");
- return null;
- }
- }
- const materialType = Tools.Instantiate(parsedMaterial.customType);
- const material = materialType.Parse(parsedMaterial, scene, rootUrl);
- material._loadedUniqueId = parsedMaterial.uniqueId;
- return material;
- }
- static _ParsePlugins(serializationObject, material, scene, rootUrl) {
- if (!serializationObject.plugins) {
- return;
- }
- for (const pluginClassName in serializationObject.plugins) {
- const pluginData = serializationObject.plugins[pluginClassName];
- let plugin = material.pluginManager?.getPlugin(pluginData.name);
- if (!plugin) {
- const pluginClassType = Tools.Instantiate("BABYLON." + pluginClassName);
- if (pluginClassType) {
- plugin = new pluginClassType(material);
- }
- }
- plugin?.parse(pluginData, scene, rootUrl);
- }
- }
- }
- /**
- * Returns the triangle fill mode
- */
- Material.TriangleFillMode = 0;
- /**
- * Returns the wireframe mode
- */
- Material.WireFrameFillMode = 1;
- /**
- * Returns the point fill mode
- */
- Material.PointFillMode = 2;
- /**
- * Returns the point list draw mode
- */
- Material.PointListDrawMode = 3;
- /**
- * Returns the line list draw mode
- */
- Material.LineListDrawMode = 4;
- /**
- * Returns the line loop draw mode
- */
- Material.LineLoopDrawMode = 5;
- /**
- * Returns the line strip draw mode
- */
- Material.LineStripDrawMode = 6;
- /**
- * Returns the triangle strip draw mode
- */
- Material.TriangleStripDrawMode = 7;
- /**
- * Returns the triangle fan draw mode
- */
- Material.TriangleFanDrawMode = 8;
- /**
- * Stores the clock-wise side orientation
- */
- Material.ClockWiseSideOrientation = 0;
- /**
- * Stores the counter clock-wise side orientation
- */
- Material.CounterClockWiseSideOrientation = 1;
- /**
- * The dirty texture flag value
- */
- Material.TextureDirtyFlag = 1;
- /**
- * The dirty light flag value
- */
- Material.LightDirtyFlag = 2;
- /**
- * The dirty fresnel flag value
- */
- Material.FresnelDirtyFlag = 4;
- /**
- * The dirty attribute flag value
- */
- Material.AttributesDirtyFlag = 8;
- /**
- * The dirty misc flag value
- */
- Material.MiscDirtyFlag = 16;
- /**
- * The dirty prepass flag value
- */
- Material.PrePassDirtyFlag = 32;
- /**
- * The all dirty flag value
- */
- Material.AllDirtyFlag = 63;
- /**
- * MaterialTransparencyMode: No transparency mode, Alpha channel is not use.
- */
- Material.MATERIAL_OPAQUE = 0;
- /**
- * MaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
- */
- Material.MATERIAL_ALPHATEST = 1;
- /**
- * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
- */
- Material.MATERIAL_ALPHABLEND = 2;
- /**
- * MaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
- * They are also discarded below the alpha cutoff threshold to improve performances.
- */
- Material.MATERIAL_ALPHATESTANDBLEND = 3;
- /**
- * The Whiteout method is used to blend normals.
- * Details of the algorithm can be found here: https://blog.selfshadow.com/publications/blending-in-detail/
- */
- Material.MATERIAL_NORMALBLENDMETHOD_WHITEOUT = 0;
- /**
- * The Reoriented Normal Mapping method is used to blend normals.
- * Details of the algorithm can be found here: https://blog.selfshadow.com/publications/blending-in-detail/
- */
- Material.MATERIAL_NORMALBLENDMETHOD_RNM = 1;
- /**
- * Event observable which raises global events common to all materials (like MaterialPluginEvent.Created)
- */
- Material.OnEventObservable = new Observable();
- Material._AllDirtyCallBack = (defines) => defines.markAllAsDirty();
- Material._ImageProcessingDirtyCallBack = (defines) => defines.markAsImageProcessingDirty();
- Material._TextureDirtyCallBack = (defines) => defines.markAsTexturesDirty();
- Material._FresnelDirtyCallBack = (defines) => defines.markAsFresnelDirty();
- Material._MiscDirtyCallBack = (defines) => defines.markAsMiscDirty();
- Material._PrePassDirtyCallBack = (defines) => defines.markAsPrePassDirty();
- Material._LightsDirtyCallBack = (defines) => defines.markAsLightDirty();
- Material._AttributeDirtyCallBack = (defines) => defines.markAsAttributesDirty();
- Material._FresnelAndMiscDirtyCallBack = (defines) => {
- Material._FresnelDirtyCallBack(defines);
- Material._MiscDirtyCallBack(defines);
- };
- Material._TextureAndMiscDirtyCallBack = (defines) => {
- Material._TextureDirtyCallBack(defines);
- Material._MiscDirtyCallBack(defines);
- };
- Material._DirtyCallbackArray = [];
- Material._RunDirtyCallBacks = (defines) => {
- for (const cb of Material._DirtyCallbackArray) {
- cb(defines);
- }
- };
- __decorate([
- serialize()
- ], Material.prototype, "id", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "uniqueId", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "name", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "metadata", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "checkReadyOnEveryCall", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "checkReadyOnlyOnce", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "state", void 0);
- __decorate([
- serialize("alpha")
- ], Material.prototype, "_alpha", void 0);
- __decorate([
- serialize("backFaceCulling")
- ], Material.prototype, "_backFaceCulling", void 0);
- __decorate([
- serialize("cullBackFaces")
- ], Material.prototype, "_cullBackFaces", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "sideOrientation", void 0);
- __decorate([
- serialize("alphaMode")
- ], Material.prototype, "_alphaMode", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "_needDepthPrePass", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "disableDepthWrite", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "disableColorWrite", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "forceDepthWrite", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "depthFunction", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "separateCullingPass", void 0);
- __decorate([
- serialize("fogEnabled")
- ], Material.prototype, "_fogEnabled", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "pointSize", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "zOffset", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "zOffsetUnits", void 0);
- __decorate([
- serialize()
- ], Material.prototype, "pointsCloud", null);
- __decorate([
- serialize()
- ], Material.prototype, "fillMode", null);
- __decorate([
- serialize()
- ], Material.prototype, "useLogarithmicDepth", null);
- __decorate([
- serialize()
- ], Material.prototype, "transparencyMode", null);
- //# sourceMappingURL=material.js.map
|