浏览代码

Merge pull request #8092 from sebavan/master

Store thinengine in basetexture.
sebavan 5 年之前
父节点
当前提交
9e524d724f

+ 52 - 0
src/Engines/Extensions/engine.readTexture.ts

@@ -0,0 +1,52 @@
+import { ThinEngine } from "../../Engines/thinEngine";
+import { InternalTexture } from '../../Materials/Textures/internalTexture';
+import { Nullable } from '../../types';
+
+declare module "../../Engines/thinEngine" {
+    export interface ThinEngine {
+        /** @hidden */
+        _readTexturePixels(texture: InternalTexture, width: number, height: number, faceIndex?: number, level?: number, buffer?: Nullable<ArrayBufferView>): ArrayBufferView;
+    }
+}
+
+ThinEngine.prototype._readTexturePixels = function(texture: InternalTexture, width: number, height: number, faceIndex = -1, level = 0, buffer: Nullable<ArrayBufferView> = null): ArrayBufferView {
+    let gl = this._gl;
+    if (!this._dummyFramebuffer) {
+        let dummy = gl.createFramebuffer();
+
+        if (!dummy) {
+            throw new Error("Unable to create dummy framebuffer");
+        }
+
+        this._dummyFramebuffer = dummy;
+    }
+    gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);
+
+    if (faceIndex > -1) {
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._webGLTexture, level);
+    } else {
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, level);
+    }
+
+    let readType = (texture.type !== undefined) ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;
+
+    switch (readType) {
+        case gl.UNSIGNED_BYTE:
+            if (!buffer) {
+                buffer = new Uint8Array(4 * width * height);
+            }
+            readType = gl.UNSIGNED_BYTE;
+            break;
+        default:
+            if (!buffer) {
+                buffer = new Float32Array(4 * width * height);
+            }
+            readType = gl.FLOAT;
+            break;
+    }
+
+    gl.readPixels(0, 0, width, height, gl.RGBA, readType, <DataView>buffer);
+    gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);
+
+    return buffer;
+};

+ 1 - 0
src/Engines/Extensions/index.ts

@@ -12,6 +12,7 @@ export * from "./engine.renderTargetCube";
 export * from "./engine.webVR";
 export * from "./engine.uniformBuffer";
 export * from "./engine.views";
+export * from "./engine.readTexture";
 
 // must import first since nothing references the exports
 import "./engine.textureSelector";

+ 1 - 48
src/Engines/engine.ts

@@ -22,6 +22,7 @@ import { WebGLDataBuffer } from '../Meshes/WebGL/webGLDataBuffer';
 import { Logger } from '../Misc/logger';
 
 import "./Extensions/engine.alpha";
+import "./Extensions/engine.readTexture";
 
 declare type Material = import("../Materials/material").Material;
 declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
@@ -417,7 +418,6 @@ export class Engine extends ThinEngine {
 
     private _loadingScreen: ILoadingScreen;
     private _pointerLockRequested: boolean;
-    private _dummyFramebuffer: WebGLFramebuffer;
     private _rescalePostProcess: PostProcess;
 
     // Deterministic lockstepMaxSteps
@@ -1776,49 +1776,6 @@ export class Engine extends ThinEngine {
         });
     }
 
-    /** @hidden */
-    public _readTexturePixels(texture: InternalTexture, width: number, height: number, faceIndex = -1, level = 0, buffer: Nullable<ArrayBufferView> = null): ArrayBufferView {
-        let gl = this._gl;
-        if (!this._dummyFramebuffer) {
-            let dummy = gl.createFramebuffer();
-
-            if (!dummy) {
-                throw new Error("Unable to create dummy framebuffer");
-            }
-
-            this._dummyFramebuffer = dummy;
-        }
-        gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);
-
-        if (faceIndex > -1) {
-            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._webGLTexture, level);
-        } else {
-            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, level);
-        }
-
-        let readType = (texture.type !== undefined) ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;
-
-        switch (readType) {
-            case gl.UNSIGNED_BYTE:
-                if (!buffer) {
-                    buffer = new Uint8Array(4 * width * height);
-                }
-                readType = gl.UNSIGNED_BYTE;
-                break;
-            default:
-                if (!buffer) {
-                    buffer = new Float32Array(4 * width * height);
-                }
-                readType = gl.FLOAT;
-                break;
-        }
-
-        gl.readPixels(0, 0, width, height, gl.RGBA, readType, <DataView>buffer);
-        gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);
-
-        return buffer;
-    }
-
     public dispose(): void {
         this.hideLoadingUI();
 
@@ -1844,10 +1801,6 @@ export class Engine extends ThinEngine {
             Engine.audioEngine.dispose();
         }
 
-        if (this._dummyFramebuffer) {
-            this._gl.deleteFramebuffer(this._dummyFramebuffer);
-        }
-
         //WebVR
         this.disableVR();
 

+ 9 - 2
src/Engines/thinEngine.ts

@@ -350,7 +350,9 @@ export class ThinEngine {
     private _uintIndicesCurrentlySet = false;
     protected _currentBoundBuffer = new Array<Nullable<WebGLBuffer>>();
     /** @hidden */
-    protected _currentFramebuffer: Nullable<WebGLFramebuffer> = null;
+    public _currentFramebuffer: Nullable<WebGLFramebuffer> = null;
+    /** @hidden */
+    public _dummyFramebuffer: Nullable<WebGLFramebuffer> = null;
     private _currentBufferPointers = new Array<BufferPointer>();
     private _currentInstanceLocations = new Array<number>();
     private _currentInstanceBuffers = new Array<DataBuffer>();
@@ -3471,7 +3473,8 @@ export class ThinEngine {
         }
 
         this._activeChannel = channel;
-        this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
+        const target = texture ? this._getTextureTarget(texture) : this._gl.TEXTURE_2D;
+        this._bindTextureDirectly(target, texture);
     }
 
     /**
@@ -3735,6 +3738,10 @@ export class ThinEngine {
             this._emptyCubeTexture = null;
         }
 
+        if (this._dummyFramebuffer) {
+            this._gl.deleteFramebuffer(this._dummyFramebuffer);
+        }
+
         // Release effects
         this.releaseEffects();
 

+ 1 - 1
src/Materials/Textures/MultiviewRenderTarget.ts

@@ -19,7 +19,7 @@ export class MultiviewRenderTarget extends RenderTargetTexture {
         internalTexture.isMultiview = true;
         internalTexture.format = Constants.TEXTUREFORMAT_RGBA;
         this._texture = internalTexture;
-        this.samples = this._engine.getCaps().maxSamples || this.samples;
+        this.samples = this._getEngine()!.getCaps().maxSamples || this.samples;
     }
 
     /**

+ 10 - 10
src/Materials/Textures/Procedurals/proceduralTexture.ts

@@ -81,7 +81,7 @@ export class ProceduralTexture extends Texture {
     private _matrices: { [key: string]: Matrix } = {};
 
     private _fallbackTextureUsed = false;
-    private _engine: Engine;
+    private _fullEngine: Engine;
 
     private _cachedDefines = "";
 
@@ -112,7 +112,7 @@ export class ProceduralTexture extends Texture {
         }
         scene.proceduralTextures.push(this);
 
-        this._engine = scene.getEngine();
+        this._fullEngine = scene.getEngine();
 
         this.name = name;
         this.isRenderTarget = true;
@@ -124,11 +124,11 @@ export class ProceduralTexture extends Texture {
         this._fallbackTexture = fallbackTexture;
 
         if (isCube) {
-            this._texture = this._engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
+            this._texture = this._fullEngine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
             this.setFloat("face", 0);
         }
         else {
-            this._texture = this._engine.createRenderTargetTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
+            this._texture = this._fullEngine.createRenderTargetTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
         }
 
         // VBO
@@ -138,7 +138,7 @@ export class ProceduralTexture extends Texture {
         vertices.push(-1, -1);
         vertices.push(1, -1);
 
-        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._engine, vertices, VertexBuffer.PositionKind, false, false, 2);
+        this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._fullEngine, vertices, VertexBuffer.PositionKind, false, false, 2);
 
         this._createIndexBuffer();
     }
@@ -167,7 +167,7 @@ export class ProceduralTexture extends Texture {
     }
 
     private _createIndexBuffer(): void {
-        var engine = this._engine;
+        var engine = this._fullEngine;
 
         // Indices
         var indices = [];
@@ -217,7 +217,7 @@ export class ProceduralTexture extends Texture {
      * @returns true if ready, otherwise, false.
      */
     public isReady(): boolean {
-        var engine = this._engine;
+        var engine = this._fullEngine;
         var shaders;
 
         if (!this._fragment) {
@@ -341,7 +341,7 @@ export class ProceduralTexture extends Texture {
         }
 
         this.releaseInternalTexture();
-        this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
+        this._texture = this._fullEngine.createRenderTargetTexture(size, generateMipMaps);
 
         // Update properties
         this._size = size;
@@ -484,7 +484,7 @@ export class ProceduralTexture extends Texture {
             return;
         }
 
-        var engine = this._engine;
+        var engine = this._fullEngine;
 
         // Render
         engine.enableEffect(this._effect);
@@ -627,7 +627,7 @@ export class ProceduralTexture extends Texture {
             this._vertexBuffers[VertexBuffer.PositionKind] = null;
         }
 
-        if (this._indexBuffer && this._engine._releaseBuffer(this._indexBuffer)) {
+        if (this._indexBuffer && this._fullEngine._releaseBuffer(this._indexBuffer)) {
             this._indexBuffer = null;
         }
 

+ 1 - 0
src/Materials/Textures/baseTexture.polynomial.ts

@@ -24,6 +24,7 @@ Object.defineProperty(BaseTexture.prototype, "sphericalPolynomial", {
             if (this._texture.isReady) {
                 this._texture._sphericalPolynomial =
                     CubeMapToSphericalPolynomialTools.ConvertCubeMapTextureToSphericalPolynomial(this);
+                return this._texture._sphericalPolynomial;
             }
         }
 

+ 60 - 44
src/Materials/Textures/baseTexture.ts

@@ -11,6 +11,7 @@ import { GUID } from '../../Misc/guid';
 import { ISize, Size } from '../../Maths/math.size';
 
 import "../../Misc/fileTools";
+import { ThinEngine } from '../../Engines/thinEngine';
 
 declare type Animation = import("../../Animations/animation").Animation;
 
@@ -372,6 +373,7 @@ export class BaseTexture implements IAnimatable {
     public delayLoadState = Constants.DELAYLOADSTATE_NONE;
 
     private _scene: Nullable<Scene> = null;
+    private _engine: Nullable<ThinEngine> = null;
 
     /** @hidden */
     public _texture: Nullable<InternalTexture> = null;
@@ -390,24 +392,28 @@ export class BaseTexture implements IAnimatable {
      * Base class of all the textures in babylon.
      * It groups all the common properties the materials, post process, lights... might need
      * in order to make a correct use of the texture.
-     * @param scene Define the scene the texture blongs to
+     * @param sceneOrEngine Define the scene or engine the texture blongs to
      */
-    constructor(scene: Nullable<Scene>) {
-        this._setScene(scene);
-        this._uid = null;
-    }
-
-    /** @hidden */
-    public _setScene(scene: Nullable<Scene>): void {
-        if (this._scene) {
-            this._scene.removeTexture(this);
+    constructor(sceneOrEngine: Nullable<Scene | ThinEngine>) {
+        if (sceneOrEngine) {
+            if (BaseTexture._isScene(sceneOrEngine)) {
+                this._scene = sceneOrEngine;
+            }
+            else {
+                this._engine = sceneOrEngine;
+            }
+        }
+        else {
+            this._scene = EngineStore.LastCreatedScene;
         }
 
-        this._scene = scene || EngineStore.LastCreatedScene;
         if (this._scene) {
             this.uniqueId = this._scene.getUniqueId();
             this._scene.addTexture(this);
+            this._engine = this._scene.getEngine();
         }
+
+        this._uid = null;
     }
 
     /**
@@ -418,6 +424,11 @@ export class BaseTexture implements IAnimatable {
         return this._scene;
     }
 
+    /** @hidden */
+    protected _getEngine(): Nullable<ThinEngine> {
+        return this._engine;
+    }
+
     /**
      * Get the texture transform matrix used to offset tile the texture for istance.
      * @returns the transformation matrix
@@ -508,41 +519,40 @@ export class BaseTexture implements IAnimatable {
     }
 
     /**
-           * Update the sampling mode of the texture.
-           * Default is Trilinear mode.
-           *
-           * | Value | Type               | Description |
-           * | ----- | ------------------ | ----------- |
-           * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |
-           * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |
-           * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |
-           * | 4     | NEAREST_NEAREST_MIPNEAREST |             |
-           * | 5    | NEAREST_LINEAR_MIPNEAREST |             |
-           * | 6    | NEAREST_LINEAR_MIPLINEAR |             |
-           * | 7    | NEAREST_LINEAR |             |
-           * | 8    | NEAREST_NEAREST |             |
-           * | 9   | LINEAR_NEAREST_MIPNEAREST |             |
-           * | 10   | LINEAR_NEAREST_MIPLINEAR |             |
-           * | 11   | LINEAR_LINEAR |             |
-           * | 12   | LINEAR_NEAREST |             |
-           *
-           *    > _mag_: magnification filter (close to the viewer)
-           *    > _min_: minification filter (far from the viewer)
-           *    > _mip_: filter used between mip map levels
-           *@param samplingMode Define the new sampling mode of the texture
-           */
+     * Update the sampling mode of the texture.
+     * Default is Trilinear mode.
+     *
+     * | Value | Type               | Description |
+     * | ----- | ------------------ | ----------- |
+     * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |
+     * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |
+     * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |
+     * | 4     | NEAREST_NEAREST_MIPNEAREST |             |
+     * | 5    | NEAREST_LINEAR_MIPNEAREST |             |
+     * | 6    | NEAREST_LINEAR_MIPLINEAR |             |
+     * | 7    | NEAREST_LINEAR |             |
+     * | 8    | NEAREST_NEAREST |             |
+     * | 9   | LINEAR_NEAREST_MIPNEAREST |             |
+     * | 10   | LINEAR_NEAREST_MIPLINEAR |             |
+     * | 11   | LINEAR_LINEAR |             |
+     * | 12   | LINEAR_NEAREST |             |
+     *
+     *    > _mag_: magnification filter (close to the viewer)
+     *    > _min_: minification filter (far from the viewer)
+     *    > _mip_: filter used between mip map levels
+     *@param samplingMode Define the new sampling mode of the texture
+     */
     public updateSamplingMode(samplingMode: number): void {
         if (!this._texture) {
             return;
         }
 
-        let scene = this.getScene();
-
-        if (!scene) {
+        const engine = this._getEngine();
+        if (!engine) {
             return;
         }
 
-        scene.getEngine().updateTextureSamplingMode(samplingMode, this._texture);
+        engine.updateTextureSamplingMode(samplingMode, this._texture);
     }
 
     /**
@@ -561,11 +571,12 @@ export class BaseTexture implements IAnimatable {
 
     /** @hidden */
     public _getFromCache(url: Nullable<string>, noMipmap: boolean, sampling?: number, invertY?: boolean): Nullable<InternalTexture> {
-        if (!this._scene) {
+        const engine = this._getEngine();
+        if (!engine) {
             return null;
         }
 
-        var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+        var texturesCache = engine.getLoadedTexturesCache();
         for (var index = 0; index < texturesCache.length; index++) {
             var texturesCacheEntry = texturesCache[index];
 
@@ -653,14 +664,12 @@ export class BaseTexture implements IAnimatable {
         var size = this.getSize();
         var width = size.width;
         var height = size.height;
-        let scene = this.getScene();
 
-        if (!scene) {
+        const engine = this._getEngine();
+        if (!engine) {
             return null;
         }
 
-        var engine = scene.getEngine();
-
         if (level != 0) {
             width = width / Math.pow(2, level);
             height = height / Math.pow(2, level);
@@ -728,6 +737,7 @@ export class BaseTexture implements IAnimatable {
                 this._scene.textures.splice(index, 1);
             }
             this._scene.onTextureRemovedObservable.notifyObservers(this);
+            this._scene = null;
         }
 
         if (this._texture === undefined) {
@@ -740,6 +750,8 @@ export class BaseTexture implements IAnimatable {
         // Callback
         this.onDisposeObservable.notifyObservers(this);
         this.onDisposeObservable.clear();
+
+        this._engine = null;
     }
 
     /**
@@ -795,4 +807,8 @@ export class BaseTexture implements IAnimatable {
             }
         }
     }
+
+    private static _isScene(sceneOrEngine: Scene | ThinEngine): sceneOrEngine is Scene {
+        return sceneOrEngine.getClassName() === "Scene";
+    }
 }

+ 8 - 21
src/Materials/Textures/colorGradingTexture.ts

@@ -30,7 +30,6 @@ export class ColorGradingTexture extends BaseTexture {
     private static _noneEmptyLineRegex = /\S+/;
 
     private _textureMatrix: Matrix;
-    private _engine: ThinEngine;
     private _onLoad: Nullable<() => void>;
 
     /**
@@ -41,8 +40,7 @@ export class ColorGradingTexture extends BaseTexture {
      * @param onLoad defines a callback triggered when the texture has been loaded
      */
     constructor(url: string, sceneOrEngine: Scene | ThinEngine, onLoad: Nullable<() => void> = null) {
-        const isScene = ColorGradingTexture._isScene(sceneOrEngine);
-        super(isScene ? (sceneOrEngine as Scene) : null);
+        super(sceneOrEngine);
 
         if (!url) {
             return;
@@ -56,22 +54,19 @@ export class ColorGradingTexture extends BaseTexture {
         this._texture = this._getFromCache(url, true);
 
         if (!this._texture) {
-            if (ColorGradingTexture._isScene(sceneOrEngine)) {
-                this._engine = sceneOrEngine.getEngine();
-
-                if (!sceneOrEngine.useDelayedTextureLoading) {
+            const scene = this.getScene();
+            if (scene) {
+                if (!scene.useDelayedTextureLoading) {
                     this.loadTexture();
                 } else {
                     this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;
                 }
             }
             else {
-                this._engine = sceneOrEngine;
                 this.loadTexture();
             }
         }
         else {
-            this._engine = this._texture.getEngine();
             this._triggerOnLoad();
         }
     }
@@ -97,7 +92,7 @@ export class ColorGradingTexture extends BaseTexture {
      * Occurs when the file being loaded is a .3dl LUT file.
      */
     private load3dlTexture() {
-        var engine = this._engine as ThinEngine;
+        var engine = this._getEngine()!;
         var texture: InternalTexture;
         if (engine.webGLVersion === 1) {
             texture = engine.createRawTexture(null, 1, 1, Constants.TEXTUREFORMAT_RGBA, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, null, Constants.TEXTURETYPE_UNSIGNED_INT);
@@ -110,7 +105,7 @@ export class ColorGradingTexture extends BaseTexture {
         this._texture.isReady = false;
 
         this.isCube = false;
-        this.is3D = this._engine.webGLVersion > 1;
+        this.is3D = engine.webGLVersion > 1;
         this.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
         this.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
         this.wrapR = Constants.TEXTURE_CLAMP_ADDRESSMODE;
@@ -220,7 +215,7 @@ export class ColorGradingTexture extends BaseTexture {
             scene._loadFile(this.url, callback);
         }
         else {
-            this._engine._loadFile(this.url, callback);
+            engine._loadFile(this.url, callback);
         }
 
         return this._texture;
@@ -239,7 +234,7 @@ export class ColorGradingTexture extends BaseTexture {
      * Clones the color gradind texture.
      */
     public clone(): ColorGradingTexture {
-        var newTexture = new ColorGradingTexture(this.url, <Scene>this.getScene());
+        var newTexture = new ColorGradingTexture(this.url, this.getScene() || this._getEngine()!);
 
         // Base texture
         newTexture.level = this.level;
@@ -295,14 +290,6 @@ export class ColorGradingTexture extends BaseTexture {
 
         return serializationObject;
     }
-
-    /**
-     * Returns true if the passed parameter is a scene object (can be use for typings)
-     * @param sceneOrEngine The object to test.
-     */
-    private static _isScene(sceneOrEngine: Scene | ThinEngine): sceneOrEngine is Scene {
-        return sceneOrEngine.getClassName() === "Scene";
-    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.ColorGradingTexture"] = ColorGradingTexture;

+ 7 - 20
src/Materials/Textures/cubeTexture.ts

@@ -103,7 +103,6 @@ export class CubeTexture extends BaseTexture {
 
     private _format: number;
     private _createPolynomials: boolean;
-    private _engine: ThinEngine;
 
     /** @hidden */
     public _prefiltered: boolean = false;
@@ -146,7 +145,7 @@ export class CubeTexture extends BaseTexture {
      * Creates a cube texture to use with reflection for instance. It can be based upon dds or six images as well
      * as prefiltered data.
      * @param rootUrl defines the url of the texture or the root name of the six images
-     * @param scene defines the scene the texture is attached to
+     * @param null defines the scene or engine the texture is attached to
      * @param extensions defines the suffixes add to the picture name in case six images are in use like _px.jpg...
      * @param noMipmap defines if mipmaps should be created or not
      * @param files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz
@@ -164,15 +163,7 @@ export class CubeTexture extends BaseTexture {
         onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format: number = Constants.TEXTUREFORMAT_RGBA, prefiltered = false,
         forcedExtension: any = null, createPolynomials: boolean = false,
         lodScale: number = 0.8, lodOffset: number = 0) {
-        super(null);
-        if (CubeTexture._isScene(sceneOrEngine)) {
-            this._setScene(sceneOrEngine);
-            this._engine = sceneOrEngine.getEngine();
-        }
-        else {
-            this._setScene(null);
-            this._engine = sceneOrEngine;
-        }
+        super(sceneOrEngine);
 
         this.name = rootUrl;
         this.url = rootUrl;
@@ -240,10 +231,10 @@ export class CubeTexture extends BaseTexture {
             const scene = this.getScene();
             if (!scene?.useDelayedTextureLoading) {
                 if (prefiltered) {
-                    this._texture = this._engine.createPrefilteredCubeTexture(rootUrl, scene, lodScale, lodOffset, onLoad, onError, format, forcedExtension, this._createPolynomials);
+                    this._texture = this._getEngine()!.createPrefilteredCubeTexture(rootUrl, scene, lodScale, lodOffset, onLoad, onError, format, forcedExtension, this._createPolynomials);
                 }
                 else {
-                    this._texture = this._engine.createCubeTexture(rootUrl, scene, files, noMipmap, onLoad, onError, this._format, forcedExtension, false, lodScale, lodOffset);
+                    this._texture = this._getEngine()!.createCubeTexture(rootUrl, scene, files, noMipmap, onLoad, onError, this._format, forcedExtension, false, lodScale, lodOffset);
                 }
                 this._texture?.onLoadedObservable.add(() => this.onLoadObservable.notifyObservers(this));
 
@@ -321,10 +312,10 @@ export class CubeTexture extends BaseTexture {
         if (!this._texture) {
             const scene = this.getScene();
             if (this._prefiltered) {
-                this._texture = this._engine.createPrefilteredCubeTexture(this.url, scene, 0.8, 0, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
+                this._texture = this._getEngine()!.createPrefilteredCubeTexture(this.url, scene, 0.8, 0, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
             }
             else {
-                this._texture = this._engine.createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, null, this._format, forcedExtension);
+                this._texture = this._getEngine()!.createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, null, this._format, forcedExtension);
             }
 
             this._texture?.onLoadedObservable.add(() => this.onLoadObservable.notifyObservers(this));
@@ -401,7 +392,7 @@ export class CubeTexture extends BaseTexture {
         let uniqueId = 0;
 
         let newCubeTexture = SerializationHelper.Clone(() => {
-            const cubeTexture = new CubeTexture(this.url, this.getScene() || this._engine, this._extensions, this._noMipmap, this._files);
+            const cubeTexture = new CubeTexture(this.url, this.getScene() || this._getEngine()!, this._extensions, this._noMipmap, this._files);
             uniqueId = cubeTexture.uniqueId;
 
             return cubeTexture;
@@ -411,10 +402,6 @@ export class CubeTexture extends BaseTexture {
 
         return newCubeTexture;
     }
-
-    private static _isScene(sceneOrEngine: Scene | ThinEngine): sceneOrEngine is Scene {
-        return sceneOrEngine.getClassName() === "Scene";
-    }
 }
 
 Texture._CubeTextureParser = CubeTexture.Parse;

+ 10 - 8
src/Materials/Textures/dynamicTexture.ts

@@ -2,7 +2,6 @@ import { Logger } from "../../Misc/logger";
 import { Nullable } from "../../types";
 import { Scene } from "../../scene";
 import { ISize } from "../../Maths/math.size";
-import { Engine } from "../../Engines/engine";
 import { Texture } from "../../Materials/Textures/texture";
 import { Constants } from "../../Engines/constants";
 import "../../Engines/Extensions/engine.dynamicTexture";
@@ -16,7 +15,6 @@ export class DynamicTexture extends Texture {
     private _generateMipMaps: boolean;
     private _canvas: HTMLCanvasElement | OffscreenCanvas;
     private _context: CanvasRenderingContext2D;
-    private _engine: Engine;
 
     /**
      * Creates a DynamicTexture
@@ -32,22 +30,26 @@ export class DynamicTexture extends Texture {
         super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format);
 
         this.name = name;
-        this._engine = (<Scene>this.getScene()).getEngine();
         this.wrapU = Texture.CLAMP_ADDRESSMODE;
         this.wrapV = Texture.CLAMP_ADDRESSMODE;
 
         this._generateMipMaps = generateMipMaps;
 
+        const engine = this._getEngine();
+        if (!engine) {
+            return;
+        }
+
         if (options.getContext) {
             this._canvas = options;
-            this._texture = this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+            this._texture = engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
         } else {
             this._canvas = CanvasGenerator.CreateCanvas(1, 1);
 
             if (options.width || options.width === 0) {
-                this._texture = this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+                this._texture = engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
             } else {
-                this._texture = this._engine.createDynamicTexture(options, options, generateMipMaps, samplingMode);
+                this._texture = engine.createDynamicTexture(options, options, generateMipMaps, samplingMode);
             }
         }
 
@@ -79,7 +81,7 @@ export class DynamicTexture extends Texture {
 
         this.releaseInternalTexture();
 
-        this._texture = this._engine.createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this.samplingMode);
+        this._texture = this._getEngine()!.createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this.samplingMode);
     }
 
     /**
@@ -131,7 +133,7 @@ export class DynamicTexture extends Texture {
      * @param premulAlpha defines if alpha is stored as premultiplied (default is false)
      */
     public update(invertY?: boolean, premulAlpha = false): void {
-        this._engine.updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY, premulAlpha, this._format || undefined);
+        this._getEngine()!.updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY, premulAlpha, this._format || undefined);
     }
 
     /**

+ 7 - 19
src/Materials/Textures/hdrCubeTexture.ts

@@ -37,7 +37,6 @@ export class HDRCubeTexture extends BaseTexture {
     private _size: number;
     private _onLoad: Nullable<() => void> = null;
     private _onError: Nullable<() => void> = null;
-    private _engine: ThinEngine;
 
     /**
      * The texture URL.
@@ -110,7 +109,7 @@ export class HDRCubeTexture extends BaseTexture {
      * Instantiates an HDRTexture from the following parameters.
      *
      * @param url The location of the HDR raw data (Panorama stored in RGBE format)
-     * @param scene The scene the texture will be used in
+     * @param sceneOrEngine The scene or engine the texture will be used in
      * @param size The cubemap desired size (the more it increases the longer the generation will be)
      * @param noMipmap Forces to not generate the mipmap if true
      * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process
@@ -118,15 +117,7 @@ export class HDRCubeTexture extends BaseTexture {
      * @param reserved Reserved flag for internal use.
      */
     constructor(url: string, sceneOrEngine: Scene | ThinEngine, size: number, noMipmap = false, generateHarmonics = true, gammaSpace = false, reserved = false, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
-        super(null);
-        if (HDRCubeTexture._isScene(sceneOrEngine)) {
-            this._setScene(sceneOrEngine);
-            this._engine = sceneOrEngine.getEngine();
-        }
-        else {
-            this._setScene(null);
-            this._engine = sceneOrEngine;
-        }
+        super(sceneOrEngine);
 
         if (!url) {
             return;
@@ -174,6 +165,7 @@ export class HDRCubeTexture extends BaseTexture {
      * Occurs when the file is raw .hdr file.
      */
     private loadTexture() {
+        const engine = this._getEngine()!;
         var callback = (buffer: ArrayBuffer): Nullable<ArrayBufferView[]> => {
 
             this.lodGenerationOffset = 0.0;
@@ -195,7 +187,7 @@ export class HDRCubeTexture extends BaseTexture {
             for (var j = 0; j < 6; j++) {
 
                 // Create uintarray fallback.
-                if (!this._engine.getCaps().textureFloat) {
+                if (!engine.getCaps().textureFloat) {
                     // 3 channels of 1 bytes per pixel in bytes.
                     var byteBuffer = new ArrayBuffer(this._size * this._size * 3);
                     byteArray = new Uint8Array(byteBuffer);
@@ -246,16 +238,16 @@ export class HDRCubeTexture extends BaseTexture {
             return results;
         };
 
-        this._texture = this._engine.createRawCubeTextureFromUrl(this.url, this.getScene(), this._size,
+        this._texture = engine.createRawCubeTextureFromUrl(this.url, this.getScene(), this._size,
             Constants.TEXTUREFORMAT_RGB,
-            this._engine.getCaps().textureFloat ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_INT,
+            engine.getCaps().textureFloat ? Constants.TEXTURETYPE_FLOAT : Constants.TEXTURETYPE_UNSIGNED_INT,
             this._noMipmap,
             callback,
             null, this._onLoad, this._onError);
     }
 
     public clone(): HDRCubeTexture {
-        var newTexture = new HDRCubeTexture(this.url, this.getScene() || this._engine, this._size, this._noMipmap, this._generateHarmonics,
+        var newTexture = new HDRCubeTexture(this.url, this.getScene() || this._getEngine()!, this._size, this._noMipmap, this._generateHarmonics,
             this.gammaSpace);
 
         // Base texture
@@ -359,10 +351,6 @@ export class HDRCubeTexture extends BaseTexture {
 
         return serializationObject;
     }
-
-    private static _isScene(sceneOrEngine: Scene | ThinEngine): sceneOrEngine is Scene {
-        return sceneOrEngine.getClassName() === "Scene";
-    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.HDRCubeTexture"] = HDRCubeTexture;

+ 14 - 12
src/Materials/Textures/htmlElementTexture.ts

@@ -54,7 +54,6 @@ export class HtmlElementTexture extends BaseTexture {
     };
 
     private _textureMatrix: Matrix;
-    private _engine: ThinEngine;
     private _isVideo: boolean;
     private _generateMipMaps: boolean;
     private _samplingMode: number;
@@ -67,7 +66,7 @@ export class HtmlElementTexture extends BaseTexture {
      * @param options Defines the other none mandatory texture creation options
      */
     constructor(name: string, element: HTMLVideoElement | HTMLCanvasElement, options: IHtmlElementTextureOptions) {
-        super(options.scene);
+        super(options.scene || options.engine);
 
         if (!element || (!options.engine && !options.scene)) {
             return;
@@ -78,7 +77,6 @@ export class HtmlElementTexture extends BaseTexture {
             ...options
         };
 
-        this._engine = options.engine || options.scene!.getEngine();
         this._generateMipMaps = options.generateMipMaps!;
         this._samplingMode = options.samplingMode!;
         this._textureMatrix = Matrix.Identity();
@@ -104,12 +102,15 @@ export class HtmlElementTexture extends BaseTexture {
             height = this.element.height;
         }
 
-        this._texture = this._engine.createDynamicTexture(
-            width,
-            height,
-            this._generateMipMaps,
-            this._samplingMode
-        );
+        const engine = this._getEngine();
+        if (engine) {
+            this._texture = engine.createDynamicTexture(
+                width,
+                height,
+                this._generateMipMaps,
+                this._samplingMode
+            );
+        }
 
         this.update();
     }
@@ -126,7 +127,8 @@ export class HtmlElementTexture extends BaseTexture {
      * @param invertY Defines wether the texture should be inverted on Y (false by default on video and true on canvas)
      */
     public update(invertY: Nullable<boolean> = null): void {
-        if (this._texture == null) {
+        const engine = this._getEngine();
+        if (this._texture == null || engine == null) {
             return;
         }
 
@@ -136,13 +138,13 @@ export class HtmlElementTexture extends BaseTexture {
                 return;
             }
 
-            this._engine.updateVideoTexture(this._texture,
+            engine.updateVideoTexture(this._texture,
                 videoElement,
                 invertY === null ? true : invertY);
         }
         else {
             const canvasElement = this.element as HTMLCanvasElement;
-            this._engine.updateDynamicTexture(this._texture,
+            engine.updateDynamicTexture(this._texture,
                 canvasElement,
                 invertY === null ? true : invertY,
                 false);

+ 3 - 5
src/Materials/Textures/multiRenderTarget.ts

@@ -65,7 +65,7 @@ export class MultiRenderTarget extends RenderTargetTexture {
      * Get if draw buffers are currently supported by the used hardware and browser.
      */
     public get isSupported(): boolean {
-        return this._engine.webGLVersion > 1 || this._engine.getCaps().drawBuffersExtension;
+        return this._getEngine()!.webGLVersion > 1 || this._getEngine()!.getCaps().drawBuffersExtension;
     }
 
     /**
@@ -125,8 +125,6 @@ export class MultiRenderTarget extends RenderTargetTexture {
 
         super(name, size, scene, generateMipMaps, doNotChangeAspectRatio);
 
-        this._engine = scene.getEngine();
-
         if (!this.isSupported) {
             this.dispose();
             return;
@@ -182,7 +180,7 @@ export class MultiRenderTarget extends RenderTargetTexture {
     }
 
     private _createInternalTextures(): void {
-        this._internalTextures = this._engine.createMultipleRenderTarget(this._size, this._multiRenderTargetOptions);
+        this._internalTextures = this._getEngine()!.createMultipleRenderTarget(this._size, this._multiRenderTargetOptions);
     }
 
     private _createTextures(): void {
@@ -209,7 +207,7 @@ export class MultiRenderTarget extends RenderTargetTexture {
             return;
         }
 
-        this._samples = this._engine.updateMultipleRenderTargetTextureSampleCount(this._internalTextures, value);
+        this._samples = this._getEngine()!.updateMultipleRenderTargetTextureSampleCount(this._internalTextures, value);
     }
 
     /**

+ 2 - 5
src/Materials/Textures/rawTexture.ts

@@ -1,5 +1,4 @@
 import { Scene } from "../../scene";
-import { Engine } from "../../Engines/engine";
 import { Texture } from "./texture";
 import { Constants } from "../../Engines/constants";
 import "../../Engines/Extensions/engine.rawTexture";
@@ -10,8 +9,6 @@ import "../../Engines/Extensions/engine.rawTexture";
  * if you wish to create your texture pixel by pixel.
  */
 export class RawTexture extends Texture {
-    private _engine: Engine;
-
     /**
      * Instantiates a new RawTexture.
      * Raw texture can help creating a texture directly from an array of data.
@@ -34,7 +31,7 @@ export class RawTexture extends Texture {
         public format: number,
         scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, type: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(null, scene, !generateMipMaps, invertY);
-        this._engine = scene.getEngine();
+
         this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode, null, type);
 
         this.wrapU = Texture.CLAMP_ADDRESSMODE;
@@ -46,7 +43,7 @@ export class RawTexture extends Texture {
      * @param data Define the new data of the texture
      */
     public update(data: ArrayBufferView): void {
-        this._engine.updateRawTexture(this._texture, data, this._texture!.format, this._texture!.invertY, null, this._texture!.type);
+        this._getEngine()!.updateRawTexture(this._texture, data, this._texture!.format, this._texture!.invertY, null, this._texture!.type);
     }
 
     /**

+ 1 - 5
src/Materials/Textures/rawTexture2DArray.ts

@@ -1,5 +1,4 @@
 import { Scene } from "../../scene";
-import { Engine } from "../../Engines/engine";
 import { Texture } from "./texture";
 import { Constants } from "../../Engines/constants";
 import "../../Engines/Extensions/engine.rawTexture";
@@ -7,8 +6,6 @@ import "../../Engines/Extensions/engine.rawTexture";
  * Class used to store 2D array textures containing user data
  */
 export class RawTexture2DArray extends Texture {
-    private _engine: Engine;
-
     /**
      * Create a new RawTexture2DArray
      * @param data defines the data of the texture
@@ -30,7 +27,6 @@ export class RawTexture2DArray extends Texture {
         samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,
         textureType = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(null, scene, !generateMipMaps, invertY);
-        this._engine = scene.getEngine();
 
         this._texture = scene.getEngine().createRawTexture2DArray(
             data,
@@ -56,6 +52,6 @@ export class RawTexture2DArray extends Texture {
         if (!this._texture) {
             return;
         }
-        this._engine.updateRawTexture2DArray(this._texture, data, this._texture.format, this._texture!.invertY, null, this._texture.type);
+        this._getEngine()!.updateRawTexture2DArray(this._texture, data, this._texture.format, this._texture!.invertY, null, this._texture.type);
     }
 }

+ 1 - 5
src/Materials/Textures/rawTexture3D.ts

@@ -1,5 +1,4 @@
 import { Scene } from "../../scene";
-import { Engine } from "../../Engines/engine";
 import { Texture } from "./texture";
 import { Constants } from "../../Engines/constants";
 import "../../Engines/Extensions/engine.rawTexture";
@@ -7,8 +6,6 @@ import "../../Engines/Extensions/engine.rawTexture";
  * Class used to store 3D textures containing user data
  */
 export class RawTexture3D extends Texture {
-    private _engine: Engine;
-
     /**
      * Create a new RawTexture3D
      * @param data defines the data of the texture
@@ -30,7 +27,6 @@ export class RawTexture3D extends Texture {
         samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,
         textureType = Constants.TEXTURETYPE_UNSIGNED_INT) {
         super(null, scene, !generateMipMaps, invertY);
-        this._engine = scene.getEngine();
 
         this._texture = scene.getEngine().createRawTexture3D(
             data,
@@ -56,6 +52,6 @@ export class RawTexture3D extends Texture {
         if (!this._texture) {
             return;
         }
-        this._engine.updateRawTexture3D(this._texture, data, this._texture.format, this._texture!.invertY, null, this._texture.type);
+        this._getEngine()!.updateRawTexture3D(this._texture, data, this._texture.format, this._texture!.invertY, null, this._texture.type);
     }
 }

+ 3 - 6
src/Materials/Textures/renderTargetTexture.ts

@@ -244,8 +244,6 @@ export class RenderTargetTexture extends Texture {
         return this._renderTargetOptions;
     }
 
-    protected _engine: Engine;
-
     protected _onRatioRescale(): void {
         if (this._sizeRatio) {
             this.resize(this._initialSizeParameter);
@@ -309,13 +307,11 @@ export class RenderTargetTexture extends Texture {
     constructor(name: string, size: number | { width: number, height: number, layers?: number } | { ratio: number }, scene: Nullable<Scene>, generateMipMaps?: boolean, doNotChangeAspectRatio: boolean = true, type: number = Constants.TEXTURETYPE_UNSIGNED_INT, public isCube = false, samplingMode = Texture.TRILINEAR_SAMPLINGMODE, generateDepthBuffer = true, generateStencilBuffer = false, isMulti = false, format = Constants.TEXTUREFORMAT_RGBA, delayAllocation = false) {
         super(null, scene, !generateMipMaps);
         scene = this.getScene();
-
         if (!scene) {
             return;
         }
 
         this.renderList = new Array<AbstractMesh>();
-        this._engine = scene.getEngine();
         this.name = name;
         this.isRenderTarget = true;
         this._initialSizeParameter = size;
@@ -386,9 +382,10 @@ export class RenderTargetTexture extends Texture {
     private _processSizeParameter(size: number | { width: number, height: number } | { ratio: number }): void {
         if ((<{ ratio: number }>size).ratio) {
             this._sizeRatio = (<{ ratio: number }>size).ratio;
+            const engine = this._getEngine()!;
             this._size = {
-                width: this._bestReflectionRenderTargetDimension(this._engine.getRenderWidth(), this._sizeRatio),
-                height: this._bestReflectionRenderTargetDimension(this._engine.getRenderHeight(), this._sizeRatio)
+                width: this._bestReflectionRenderTargetDimension(engine.getRenderWidth(), this._sizeRatio),
+                height: this._bestReflectionRenderTargetDimension(engine.getRenderHeight(), this._sizeRatio)
             };
         } else {
             this._size = <number | { width: number, height: number, layers?: number }>size;

+ 3 - 5
src/Materials/Textures/texture.ts

@@ -266,7 +266,7 @@ export class Texture extends BaseTexture {
      * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.
      * @see http://doc.babylonjs.com/babylon101/materials#texture
      * @param url defines the url of the picture to load as a texture
-     * @param scene defines the scene or engine the texture will belong to
+     * @param sceneOrEngine defines the scene or engine the texture will belong to
      * @param noMipmap defines if the texture will require mip maps or not
      * @param invertY defines if the texture needs to be inverted on the y axis during loading
      * @param samplingMode defines the sampling mode we want for the texture while fectching from it (Texture.NEAREST_SAMPLINGMODE...)
@@ -278,7 +278,7 @@ export class Texture extends BaseTexture {
      * @param mimeType defines an optional mime type information
      */
     constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | ThinEngine>, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, deleteBuffer: boolean = false, format?: number, mimeType?: string) {
-        super((sceneOrEngine && sceneOrEngine.getClassName() === "Scene") ? (sceneOrEngine as Scene) : null);
+        super(sceneOrEngine);
 
         this.name = url || "";
         this.url = url;
@@ -293,8 +293,7 @@ export class Texture extends BaseTexture {
         }
 
         var scene = this.getScene();
-        var engine = (sceneOrEngine && (sceneOrEngine as ThinEngine).getCaps) ? (sceneOrEngine as ThinEngine) : (scene ? scene.getEngine() : null);
-
+        var engine = this._getEngine();
         if (!engine) {
             return;
         }
@@ -399,7 +398,6 @@ export class Texture extends BaseTexture {
         }
 
         let scene = this.getScene();
-
         if (!scene) {
             return;
         }

+ 4 - 7
src/Materials/Textures/videoTexture.ts

@@ -3,7 +3,6 @@ import { Tools } from "../../Misc/tools";
 import { Logger } from "../../Misc/logger";
 import { Nullable } from "../../types";
 import { Scene } from "../../scene";
-import { Engine } from "../../Engines/engine";
 import { Texture } from "../../Materials/Textures/texture";
 
 import "../../Engines/Extensions/engine.videoTexture";
@@ -64,7 +63,6 @@ export class VideoTexture extends Texture {
     }
 
     private _generateMipMaps: boolean;
-    private _engine: Engine;
     private _stillImageCaptured = false;
     private _displayingPosterTexture = false;
     private _settings: VideoTextureSettings;
@@ -100,7 +98,6 @@ export class VideoTexture extends Texture {
     ) {
         super(null, scene, !generateMipMaps, invertY);
 
-        this._engine = this.getScene()!.getEngine();
         this._generateMipMaps = generateMipMaps;
         this._initialSamplingMode = samplingMode;
         this.autoUpdateTexture = settings.autoUpdateTexture;
@@ -132,7 +129,7 @@ export class VideoTexture extends Texture {
         const videoHasEnoughData = (this.video.readyState >= this.video.HAVE_CURRENT_DATA);
         if (settings.poster &&
             (!settings.autoPlay || !videoHasEnoughData)) {
-            this._texture = this._engine.createTexture(settings.poster!, false, !this.invertY, scene);
+            this._texture = this._getEngine()!.createTexture(settings.poster!, false, !this.invertY, scene);
             this._displayingPosterTexture = true;
         }
         else if (videoHasEnoughData) {
@@ -183,7 +180,7 @@ export class VideoTexture extends Texture {
             }
         }
 
-        if (!this._engine.needPOTTextures ||
+        if (!this._getEngine()!.needPOTTextures ||
             (Tools.IsExponentOfTwo(this.video.videoWidth) && Tools.IsExponentOfTwo(this.video.videoHeight))) {
             this.wrapU = Texture.WRAP_ADDRESSMODE;
             this.wrapV = Texture.WRAP_ADDRESSMODE;
@@ -193,7 +190,7 @@ export class VideoTexture extends Texture {
             this._generateMipMaps = false;
         }
 
-        this._texture = this._engine.createDynamicTexture(
+        this._texture = this._getEngine()!.createDynamicTexture(
             this.video.videoWidth,
             this.video.videoHeight,
             this._generateMipMaps,
@@ -311,7 +308,7 @@ export class VideoTexture extends Texture {
 
         this._frameId = frameId;
 
-        this._engine.updateVideoTexture(this._texture, this.video, this._invertY);
+        this._getEngine()!.updateVideoTexture(this._texture, this.video, this._invertY);
     }
 
     /**

+ 3 - 7
src/Misc/environmentTextureTools.ts

@@ -5,13 +5,13 @@ import { Scalar } from "../Maths/math.scalar";
 import { SphericalPolynomial } from "../Maths/sphericalPolynomial";
 import { InternalTexture, InternalTextureSource } from "../Materials/Textures/internalTexture";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
-import { CubeTexture } from "../Materials/Textures/cubeTexture";
 import { Constants } from "../Engines/constants";
 import { Scene } from "../scene";
 import { PostProcess } from "../PostProcesses/postProcess";
 import { Logger } from "../Misc/logger";
 
 import "../Engines/Extensions/engine.renderTargetCube";
+import "../Engines/Extensions/engine.readTexture";
 import "../Materials/Textures/baseTexture.polynomial";
 
 import "../Shaders/rgbdEncode.fragment";
@@ -145,16 +145,12 @@ export class EnvironmentTextureTools {
      * @param texture defines the cube texture to convert in env file
      * @return a promise containing the environment data if succesfull.
      */
-    public static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer> {
+    public static CreateEnvTextureAsync(texture: BaseTexture): Promise<ArrayBuffer> {
         let internalTexture = texture.getInternalTexture();
         if (!internalTexture) {
             return Promise.reject("The cube texture is invalid.");
         }
 
-        if (!texture._prefiltered) {
-            return Promise.reject("The cube texture is invalid (not prefiltered).");
-        }
-
         let engine = internalTexture.getEngine() as Engine;
         if (engine && engine.premultipliedAlpha) {
             return Promise.reject("Env texture can only be created when the engine is created with the premultipliedAlpha option set to false.");
@@ -303,7 +299,7 @@ export class EnvironmentTextureTools {
      * @param texture defines the texture containing the polynomials
      * @return the JSON representation of the spherical info
      */
-    private static _CreateEnvTextureIrradiance(texture: CubeTexture): Nullable<EnvironmentTextureIrradianceInfoV1> {
+    private static _CreateEnvTextureIrradiance(texture: BaseTexture): Nullable<EnvironmentTextureIrradianceInfoV1> {
         let polynmials = texture.sphericalPolynomial;
         if (polynmials == null) {
             return null;