@babylonjs/core 7.3.2 → 7.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Compute/computeEffect.js +4 -4
- package/Compute/computeEffect.js.map +1 -1
- package/Engines/IPipelineContext.d.ts +3 -0
- package/Engines/IPipelineContext.js.map +1 -1
- package/Engines/Native/nativePipelineContext.d.ts +2 -0
- package/Engines/Native/nativePipelineContext.js +3 -0
- package/Engines/Native/nativePipelineContext.js.map +1 -1
- package/Engines/Processors/iShaderProcessor.d.ts +3 -2
- package/Engines/Processors/iShaderProcessor.js.map +1 -1
- package/Engines/Processors/shaderProcessor.d.ts +15 -23
- package/Engines/Processors/shaderProcessor.js +332 -320
- package/Engines/Processors/shaderProcessor.js.map +1 -1
- package/Engines/WebGL/webGLPipelineContext.d.ts +2 -0
- package/Engines/WebGL/webGLPipelineContext.js +3 -0
- package/Engines/WebGL/webGLPipelineContext.js.map +1 -1
- package/Engines/WebGL/webGLShaderProcessors.d.ts +3 -2
- package/Engines/WebGL/webGLShaderProcessors.js +2 -2
- package/Engines/WebGL/webGLShaderProcessors.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.computeShader.js +1 -1
- package/Engines/WebGPU/Extensions/engine.computeShader.js.map +1 -1
- package/Engines/WebGPU/webgpuPipelineContext.d.ts +2 -0
- package/Engines/WebGPU/webgpuPipelineContext.js +3 -0
- package/Engines/WebGPU/webgpuPipelineContext.js.map +1 -1
- package/Engines/WebGPU/webgpuShaderProcessorsGLSL.d.ts +3 -2
- package/Engines/WebGPU/webgpuShaderProcessorsGLSL.js +2 -4
- package/Engines/WebGPU/webgpuShaderProcessorsGLSL.js.map +1 -1
- package/Engines/abstractEngine.d.ts +10 -5
- package/Engines/abstractEngine.functions.d.ts +38 -0
- package/Engines/abstractEngine.functions.js +75 -0
- package/Engines/abstractEngine.functions.js.map +1 -0
- package/Engines/abstractEngine.js +22 -14
- package/Engines/abstractEngine.js.map +1 -1
- package/Engines/constants.d.ts +2 -0
- package/Engines/constants.js +2 -0
- package/Engines/constants.js.map +1 -1
- package/Engines/thinEngine.d.ts +11 -6
- package/Engines/thinEngine.functions.d.ts +96 -0
- package/Engines/thinEngine.functions.js +249 -0
- package/Engines/thinEngine.functions.js.map +1 -0
- package/Engines/thinEngine.js +50 -129
- package/Engines/thinEngine.js.map +1 -1
- package/Engines/webgpuEngine.js +5 -1
- package/Engines/webgpuEngine.js.map +1 -1
- package/Materials/Node/Blocks/Dual/textureBlock.js +3 -3
- package/Materials/Node/Blocks/Dual/textureBlock.js.map +1 -1
- package/Materials/Textures/Procedurals/proceduralTexture.d.ts +9 -1
- package/Materials/Textures/Procedurals/proceduralTexture.js +16 -0
- package/Materials/Textures/Procedurals/proceduralTexture.js.map +1 -1
- package/Materials/effect.d.ts +11 -6
- package/Materials/effect.functions.d.ts +86 -0
- package/Materials/effect.functions.js +185 -0
- package/Materials/effect.functions.js.map +1 -0
- package/Materials/effect.js +94 -153
- package/Materials/effect.js.map +1 -1
- package/Materials/effect.webgl.functions.d.ts +13 -0
- package/Materials/effect.webgl.functions.js +83 -0
- package/Materials/effect.webgl.functions.js.map +1 -0
- package/Materials/materialPluginManager.js +2 -2
- package/Materials/materialPluginManager.js.map +1 -1
- package/Meshes/Compression/dracoCompression.js.map +1 -1
- package/Meshes/Compression/dracoCompressionWorker.d.ts +1 -1
- package/Meshes/Compression/dracoCompressionWorker.js +21 -10
- package/Meshes/Compression/dracoCompressionWorker.js.map +1 -1
- package/Meshes/Node/nodeGeometryBlock.js +1 -0
- package/Meshes/Node/nodeGeometryBlock.js.map +1 -1
- package/Misc/fileTools.js +4 -3
- package/Misc/fileTools.js.map +1 -1
- package/package.json +1 -1
package/Materials/effect.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Observable } from "../Misc/observable.js";
|
|
2
2
|
|
|
3
|
-
import { GetDOMTextContent, IsWindowObjectExist } from "../Misc/domManagement.js";
|
|
4
3
|
import { Logger } from "../Misc/logger.js";
|
|
5
|
-
import { ShaderProcessor } from "../Engines/Processors/shaderProcessor.js";
|
|
6
4
|
import { ShaderStore as EngineShaderStore } from "../Engines/shaderStore.js";
|
|
7
5
|
import { ShaderLanguage } from "./shaderLanguage.js";
|
|
6
|
+
import { _processShaderCode, getCachedPipeline, createAndPreparePipelineContext, resetCachedPipeline } from "./effect.functions.js";
|
|
8
7
|
/**
|
|
9
8
|
* Effect containing vertex and fragment shader that can be executed on an object.
|
|
10
9
|
*/
|
|
@@ -123,6 +122,8 @@ export class Effect {
|
|
|
123
122
|
this._processFinalCode = null;
|
|
124
123
|
this.name = baseName;
|
|
125
124
|
this._key = key;
|
|
125
|
+
const pipelineName = this._key.replace(/\r/g, "").replace(/\n/g, "|");
|
|
126
|
+
let cachedPipeline = undefined;
|
|
126
127
|
if (attributesNamesOrOptions.attributes) {
|
|
127
128
|
const options = attributesNamesOrOptions;
|
|
128
129
|
this._engine = uniformsNamesOrEngine;
|
|
@@ -145,6 +146,7 @@ export class Effect {
|
|
|
145
146
|
}
|
|
146
147
|
this._processFinalCode = options.processFinalCode ?? null;
|
|
147
148
|
this._processCodeAfterIncludes = options.processCodeAfterIncludes ?? undefined;
|
|
149
|
+
cachedPipeline = options.existingPipelineContext;
|
|
148
150
|
}
|
|
149
151
|
else {
|
|
150
152
|
this._engine = engine;
|
|
@@ -159,42 +161,29 @@ export class Effect {
|
|
|
159
161
|
this._indexParameters = indexParameters;
|
|
160
162
|
this._fallbacks = fallbacks;
|
|
161
163
|
}
|
|
164
|
+
// Use the cache if we can. For now, WebGL2 only.
|
|
165
|
+
if (this._engine.shaderPlatformName === "WEBGL2") {
|
|
166
|
+
cachedPipeline = getCachedPipeline(pipelineName, this._engine._gl) ?? cachedPipeline;
|
|
167
|
+
}
|
|
162
168
|
this._attributeLocationByName = {};
|
|
163
169
|
this.uniqueId = Effect._UniqueIdSeed++;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
/** @internal */
|
|
167
|
-
_processShaderCode(shaderProcessor = null, keepExistingPipelineContext = false) {
|
|
168
|
-
let vertexSource;
|
|
169
|
-
let fragmentSource;
|
|
170
|
-
const baseName = this.name;
|
|
171
|
-
const hostDocument = IsWindowObjectExist() ? this._engine.getHostDocument() : null;
|
|
172
|
-
if (typeof baseName === "string") {
|
|
173
|
-
vertexSource = baseName;
|
|
174
|
-
}
|
|
175
|
-
else if (baseName.vertexSource) {
|
|
176
|
-
vertexSource = "source:" + baseName.vertexSource;
|
|
177
|
-
}
|
|
178
|
-
else if (baseName.vertexElement) {
|
|
179
|
-
vertexSource = hostDocument?.getElementById(baseName.vertexElement) || baseName.vertexElement;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
vertexSource = baseName.vertex || baseName;
|
|
183
|
-
}
|
|
184
|
-
if (typeof baseName === "string") {
|
|
185
|
-
fragmentSource = baseName;
|
|
186
|
-
}
|
|
187
|
-
else if (baseName.fragmentSource) {
|
|
188
|
-
fragmentSource = "source:" + baseName.fragmentSource;
|
|
189
|
-
}
|
|
190
|
-
else if (baseName.fragmentElement) {
|
|
191
|
-
fragmentSource = hostDocument?.getElementById(baseName.fragmentElement) || baseName.fragmentElement;
|
|
170
|
+
if (!cachedPipeline) {
|
|
171
|
+
this._processShaderCode();
|
|
192
172
|
}
|
|
193
173
|
else {
|
|
194
|
-
|
|
174
|
+
this._pipelineContext = cachedPipeline;
|
|
175
|
+
this._pipelineContext.setEngine(this._engine);
|
|
176
|
+
this._onRenderingStateCompiled(this._pipelineContext);
|
|
177
|
+
// rebuildRebind for spector
|
|
178
|
+
if (this._pipelineContext.program) {
|
|
179
|
+
this._pipelineContext.program.__SPECTOR_rebuildProgram = this._rebuildProgram.bind(this);
|
|
180
|
+
}
|
|
195
181
|
}
|
|
182
|
+
}
|
|
183
|
+
/** @internal */
|
|
184
|
+
_processShaderCode(shaderProcessor = null, keepExistingPipelineContext = false) {
|
|
196
185
|
this._processingContext = this._engine._getShaderProcessingContext(this._shaderLanguage);
|
|
197
|
-
|
|
186
|
+
const processorOptions = {
|
|
198
187
|
defines: this.defines.split("\n"),
|
|
199
188
|
indexParameters: this._indexParameters,
|
|
200
189
|
isFragment: false,
|
|
@@ -210,52 +199,11 @@ export class Effect {
|
|
|
210
199
|
useReverseDepthBuffer: this._engine.useReverseDepthBuffer,
|
|
211
200
|
processCodeAfterIncludes: this._processCodeAfterIncludes,
|
|
212
201
|
};
|
|
213
|
-
|
|
214
|
-
const shadersLoaded = () => {
|
|
215
|
-
if (shaderCodes[0] && shaderCodes[1]) {
|
|
216
|
-
processorOptions.isFragment = true;
|
|
217
|
-
const [migratedVertexCode, fragmentCode] = shaderCodes;
|
|
218
|
-
ShaderProcessor.Process(fragmentCode, processorOptions, (migratedFragmentCode, codeBeforeMigration) => {
|
|
219
|
-
this._fragmentSourceCodeBeforeMigration = codeBeforeMigration;
|
|
220
|
-
if (this._processFinalCode) {
|
|
221
|
-
migratedFragmentCode = this._processFinalCode("fragment", migratedFragmentCode);
|
|
222
|
-
}
|
|
223
|
-
const finalShaders = ShaderProcessor.Finalize(migratedVertexCode, migratedFragmentCode, processorOptions);
|
|
224
|
-
processorOptions = null;
|
|
225
|
-
this._useFinalCode(finalShaders.vertexCode, finalShaders.fragmentCode, baseName, keepExistingPipelineContext);
|
|
226
|
-
}, this._engine);
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
this._loadShader(vertexSource, "Vertex", "", (vertexCode) => {
|
|
230
|
-
ShaderProcessor.Initialize(processorOptions);
|
|
231
|
-
ShaderProcessor.Process(vertexCode, processorOptions, (migratedVertexCode, codeBeforeMigration) => {
|
|
232
|
-
this._rawVertexSourceCode = vertexCode;
|
|
233
|
-
this._vertexSourceCodeBeforeMigration = codeBeforeMigration;
|
|
234
|
-
if (this._processFinalCode) {
|
|
235
|
-
migratedVertexCode = this._processFinalCode("vertex", migratedVertexCode);
|
|
236
|
-
}
|
|
237
|
-
shaderCodes[0] = migratedVertexCode;
|
|
238
|
-
shadersLoaded();
|
|
239
|
-
}, this._engine);
|
|
240
|
-
});
|
|
241
|
-
this._loadShader(fragmentSource, "Fragment", "Pixel", (fragmentCode) => {
|
|
242
|
-
this._rawFragmentSourceCode = fragmentCode;
|
|
243
|
-
shaderCodes[1] = fragmentCode;
|
|
244
|
-
shadersLoaded();
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
_useFinalCode(migratedVertexCode, migratedFragmentCode, baseName, keepExistingPipelineContext = false) {
|
|
248
|
-
if (baseName) {
|
|
249
|
-
const vertex = baseName.vertexElement || baseName.vertex || baseName.spectorName || baseName;
|
|
250
|
-
const fragment = baseName.fragmentElement || baseName.fragment || baseName.spectorName || baseName;
|
|
251
|
-
this._vertexSourceCode = (this._shaderLanguage === ShaderLanguage.WGSL ? "//" : "") + "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
|
|
252
|
-
this._fragmentSourceCode = (this._shaderLanguage === ShaderLanguage.WGSL ? "//" : "") + "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
202
|
+
_processShaderCode(processorOptions, this.name, this._processFinalCode, (migratedVertexCode, migratedFragmentCode) => {
|
|
255
203
|
this._vertexSourceCode = migratedVertexCode;
|
|
256
204
|
this._fragmentSourceCode = migratedFragmentCode;
|
|
257
|
-
|
|
258
|
-
this.
|
|
205
|
+
this._prepareEffect(keepExistingPipelineContext);
|
|
206
|
+
}, this._shaderLanguage, this._engine, this);
|
|
259
207
|
}
|
|
260
208
|
/**
|
|
261
209
|
* Unique key for this effect
|
|
@@ -421,46 +369,6 @@ export class Effect {
|
|
|
421
369
|
this._checkIsReady(previousPipelineContext);
|
|
422
370
|
}, 16);
|
|
423
371
|
}
|
|
424
|
-
_loadShader(shader, key, optionalKey, callback) {
|
|
425
|
-
if (typeof HTMLElement !== "undefined") {
|
|
426
|
-
// DOM element ?
|
|
427
|
-
if (shader instanceof HTMLElement) {
|
|
428
|
-
const shaderCode = GetDOMTextContent(shader);
|
|
429
|
-
callback(shaderCode);
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
// Direct source ?
|
|
434
|
-
if (shader.substr(0, 7) === "source:") {
|
|
435
|
-
callback(shader.substr(7));
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
// Base64 encoded ?
|
|
439
|
-
if (shader.substr(0, 7) === "base64:") {
|
|
440
|
-
const shaderBinary = window.atob(shader.substr(7));
|
|
441
|
-
callback(shaderBinary);
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
const shaderStore = EngineShaderStore.GetShadersStore(this._shaderLanguage);
|
|
445
|
-
// Is in local store ?
|
|
446
|
-
if (shaderStore[shader + key + "Shader"]) {
|
|
447
|
-
callback(shaderStore[shader + key + "Shader"]);
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
if (optionalKey && shaderStore[shader + optionalKey + "Shader"]) {
|
|
451
|
-
callback(shaderStore[shader + optionalKey + "Shader"]);
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
let shaderUrl;
|
|
455
|
-
if (shader[0] === "." || shader[0] === "/" || shader.indexOf("http") > -1) {
|
|
456
|
-
shaderUrl = shader;
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
shaderUrl = EngineShaderStore.GetShadersRepository(this._shaderLanguage) + shader;
|
|
460
|
-
}
|
|
461
|
-
// Vertex shader
|
|
462
|
-
this._engine._loadFile(shaderUrl + "." + key.toLowerCase() + ".fx", callback);
|
|
463
|
-
}
|
|
464
372
|
/**
|
|
465
373
|
* Gets the vertex shader source code of this effect
|
|
466
374
|
* This is the final source code that will be compiled, after all the processing has been done (pre-processing applied, code injection/replacement, etc)
|
|
@@ -507,6 +415,26 @@ export class Effect {
|
|
|
507
415
|
get rawFragmentSourceCode() {
|
|
508
416
|
return this._rawFragmentSourceCode;
|
|
509
417
|
}
|
|
418
|
+
getPipelineGenerationOptions() {
|
|
419
|
+
return {
|
|
420
|
+
platformName: this._engine.shaderPlatformName,
|
|
421
|
+
shaderLanguage: this._shaderLanguage,
|
|
422
|
+
shaderNameOrContent: this.name,
|
|
423
|
+
key: this._key,
|
|
424
|
+
defines: this.defines.split("\n"),
|
|
425
|
+
addGlobalDefines: false,
|
|
426
|
+
extendedProcessingOptions: {
|
|
427
|
+
indexParameters: this._indexParameters,
|
|
428
|
+
isNDCHalfZRange: this._engine.isNDCHalfZRange,
|
|
429
|
+
useReverseDepthBuffer: this._engine.useReverseDepthBuffer,
|
|
430
|
+
supportsUniformBuffers: this._engine.supportsUniformBuffers,
|
|
431
|
+
},
|
|
432
|
+
extendedCreatePipelineOptions: {
|
|
433
|
+
transformFeedbackVaryings: this._transformFeedbackVaryings,
|
|
434
|
+
createAsRaw: !!(this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride),
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
}
|
|
510
438
|
/**
|
|
511
439
|
* Recompiles the webGL program
|
|
512
440
|
* @param vertexSourceCode The source code for the vertex shader.
|
|
@@ -536,52 +464,65 @@ export class Effect {
|
|
|
536
464
|
this._fallbacks = null;
|
|
537
465
|
this._prepareEffect();
|
|
538
466
|
}
|
|
467
|
+
_onRenderingStateCompiled(pipelineContext) {
|
|
468
|
+
this._pipelineContext = pipelineContext;
|
|
469
|
+
this._pipelineContext.setEngine(this._engine);
|
|
470
|
+
this._attributes = [];
|
|
471
|
+
this._pipelineContext._fillEffectInformation(this, this._uniformBuffersNames, this._uniformsNames, this._uniforms, this._samplerList, this._samplers, this._attributesNames, this._attributes);
|
|
472
|
+
// Caches attribute locations.
|
|
473
|
+
if (this._attributesNames) {
|
|
474
|
+
for (let i = 0; i < this._attributesNames.length; i++) {
|
|
475
|
+
const name = this._attributesNames[i];
|
|
476
|
+
this._attributeLocationByName[name] = this._attributes[i];
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
this._engine.bindSamplers(this);
|
|
480
|
+
this._compilationError = "";
|
|
481
|
+
this._isReady = true;
|
|
482
|
+
if (this.onCompiled) {
|
|
483
|
+
this.onCompiled(this);
|
|
484
|
+
}
|
|
485
|
+
this.onCompileObservable.notifyObservers(this);
|
|
486
|
+
this.onCompileObservable.clear();
|
|
487
|
+
// Unbind mesh reference in fallbacks
|
|
488
|
+
if (this._fallbacks) {
|
|
489
|
+
this._fallbacks.unBindMesh();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
539
492
|
/**
|
|
540
493
|
* Prepares the effect
|
|
541
494
|
* @internal
|
|
542
495
|
*/
|
|
543
496
|
_prepareEffect(keepExistingPipelineContext = false) {
|
|
544
|
-
const attributesNames = this._attributesNames;
|
|
545
|
-
const defines = this.defines;
|
|
546
497
|
const previousPipelineContext = this._pipelineContext;
|
|
547
498
|
this._isReady = false;
|
|
548
499
|
try {
|
|
500
|
+
const overrides = !!(this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride);
|
|
501
|
+
const defines = overrides ? null : this.defines;
|
|
502
|
+
const vertex = overrides ? this._vertexSourceCodeOverride : this._vertexSourceCode;
|
|
503
|
+
const fragment = overrides ? this._fragmentSourceCodeOverride : this._fragmentSourceCode;
|
|
549
504
|
const engine = this._engine;
|
|
550
|
-
this._pipelineContext = (
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
engine.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const name = attributesNames[i];
|
|
566
|
-
this._attributeLocationByName[name] = this._attributes[i];
|
|
505
|
+
this._pipelineContext = createAndPreparePipelineContext({
|
|
506
|
+
existingPipelineContext: keepExistingPipelineContext ? previousPipelineContext : null,
|
|
507
|
+
vertex,
|
|
508
|
+
fragment,
|
|
509
|
+
context: engine.shaderPlatformName === "WEBGL2" ? engine._gl : undefined,
|
|
510
|
+
rebuildRebind: (vertexSourceCode, fragmentSourceCode, onCompiled, onError) => this._rebuildProgram(vertexSourceCode, fragmentSourceCode, onCompiled, onError),
|
|
511
|
+
defines,
|
|
512
|
+
transformFeedbackVaryings: this._transformFeedbackVaryings,
|
|
513
|
+
name: this._key.replace(/\r/g, "").replace(/\n/g, "|"),
|
|
514
|
+
createAsRaw: overrides,
|
|
515
|
+
parallelShaderCompile: engine._caps.parallelShaderCompile,
|
|
516
|
+
shaderProcessingContext: this._processingContext,
|
|
517
|
+
onRenderingStateCompiled: (pipelineContext) => {
|
|
518
|
+
if (previousPipelineContext && !keepExistingPipelineContext) {
|
|
519
|
+
this._engine._deletePipelineContext(previousPipelineContext);
|
|
567
520
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
this.onCompiled(this);
|
|
574
|
-
}
|
|
575
|
-
this.onCompileObservable.notifyObservers(this);
|
|
576
|
-
this.onCompileObservable.clear();
|
|
577
|
-
// Unbind mesh reference in fallbacks
|
|
578
|
-
if (this._fallbacks) {
|
|
579
|
-
this._fallbacks.unBindMesh();
|
|
580
|
-
}
|
|
581
|
-
if (previousPipelineContext && !keepExistingPipelineContext) {
|
|
582
|
-
this.getEngine()._deletePipelineContext(previousPipelineContext);
|
|
583
|
-
}
|
|
584
|
-
});
|
|
521
|
+
if (pipelineContext) {
|
|
522
|
+
this._onRenderingStateCompiled(pipelineContext);
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
}, this._engine.createPipelineContext.bind(this._engine), this._engine._preparePipelineContext.bind(this._engine));
|
|
585
526
|
if (this._pipelineContext.isAsync) {
|
|
586
527
|
this._checkIsReady(previousPipelineContext);
|
|
587
528
|
}
|
|
@@ -1201,7 +1142,7 @@ export class Effect {
|
|
|
1201
1142
|
**/
|
|
1202
1143
|
dispose() {
|
|
1203
1144
|
if (this._pipelineContext) {
|
|
1204
|
-
this._pipelineContext
|
|
1145
|
+
resetCachedPipeline(this._pipelineContext);
|
|
1205
1146
|
}
|
|
1206
1147
|
this._engine._releaseEffect(this);
|
|
1207
1148
|
this._isDisposed = true;
|