浏览代码

Merge Master

sebastien 6 年之前
父节点
当前提交
d8245c1fe1

文件差异内容过多而无法显示
+ 7370 - 7340
Playground/babylon.d.txt


文件差异内容过多而无法显示
+ 7379 - 7349
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.js


+ 88 - 23
dist/preview release/babylon.max.js

@@ -25402,6 +25402,7 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
@@ -25409,6 +25410,7 @@ var BABYLON;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
         SceneComponentConstants.STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -26180,6 +26182,11 @@ var BABYLON;
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a render target is drawing.
+             */
+            _this._beforeRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -26205,6 +26212,11 @@ var BABYLON;
             _this._afterCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just after a render target has been drawn.
+             */
+            _this._afterRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after rendering all cameras and computing intersections.
              */
             _this._afterRenderStage = BABYLON.Stage.Create();
@@ -27093,14 +27105,12 @@ var BABYLON;
                         this.onPointerObservable.notifyObservers(pi, type_1);
                     }
                 }
-                if (pickResult.pickedMesh.actionManager) {
-                    if (clickInfo.ignore) {
-                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
-                    }
-                    if (!clickInfo.hasSwiped && !clickInfo.ignore && clickInfo.singleClick) {
+                if (pickResult.pickedMesh.actionManager && !clickInfo.ignore) {
+                    pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
+                    if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
-                    if (clickInfo.doubleClick && !clickInfo.ignore && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
+                    if (clickInfo.doubleClick && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnDoublePickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
                 }
@@ -29726,11 +29736,13 @@ var BABYLON;
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();
@@ -49222,6 +49234,7 @@ var BABYLON;
         TargetCamera.prototype._updateRigCameras = function () {
             var camLeft = this._rigCameras[0];
             var camRight = this._rigCameras[1];
+            this.computeWorldMatrix();
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
@@ -49251,13 +49264,12 @@ var BABYLON;
             _super.prototype._updateRigCameras.call(this);
         };
         TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
-            if (!this._rigCamTransformMatrix) {
-                this._rigCamTransformMatrix = new BABYLON.Matrix();
-            }
             var target = this.getTarget();
-            BABYLON.Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), this._rigCamTransformMatrix);
-            this._rigCamTransformMatrix = this._rigCamTransformMatrix.multiply(BABYLON.Matrix.Translation(target.x, target.y, target.z));
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
+            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
         };
         /**
          * Gets the current object class name.
@@ -49266,6 +49278,8 @@ var BABYLON;
         TargetCamera.prototype.getClassName = function () {
             return "TargetCamera";
         };
+        TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         __decorate([
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
@@ -74478,8 +74492,18 @@ var BABYLON;
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);
             }
+            // Before Camera Draw
+            for (var _i = 0, _a = scene._beforeRenderTargetDrawStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this);
+            }
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
+            // After Camera Draw
+            for (var _b = 0, _c = scene._afterRenderTargetDrawStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this);
+            }
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }
@@ -78508,7 +78532,8 @@ var BABYLON;
                 dataCallback(directLoad);
                 return plugin;
             }
-            if (fileInfo.rootUrl.indexOf("file:") === -1) {
+            var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
+            if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
                 var engine = scene.getEngine();
                 var canUseOfflineSupport = engine.enableOfflineSupport;
                 if (canUseOfflineSupport) {
@@ -78533,7 +78558,6 @@ var BABYLON;
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
                 if (file) {
                     request = BABYLON.Tools.ReadFile(file, dataCallback, onProgress, useArrayBuffer);
                 }
@@ -115509,8 +115533,10 @@ var BABYLON;
          * Registers the component in a given scene
          */
         LayerSceneComponent.prototype.register = function () {
-            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawBackground);
-            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawForeground);
+            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
+            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
+            this.scene._beforeRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
+            this.scene._afterRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
         };
         /**
          * Rebuilds the elements related to this component in case of
@@ -115532,25 +115558,53 @@ var BABYLON;
                 layers[0].dispose();
             }
         };
-        LayerSceneComponent.prototype._draw = function (camera, isBackground) {
+        LayerSceneComponent.prototype._draw = function (predicate) {
             var layers = this.scene.layers;
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
-                var cameraLayerMask = camera.layerMask;
                 for (var _i = 0, layers_2 = layers; _i < layers_2.length; _i++) {
                     var layer = layers_2[_i];
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                     }
                 }
                 this._engine.setDepthBuffer(true);
             }
         };
-        LayerSceneComponent.prototype._drawBackground = function (camera) {
-            this._draw(camera, true);
+        LayerSceneComponent.prototype._drawCameraPredicate = function (layer, isBackground, cameraLayerMask) {
+            return !layer.renderOnlyInRenderTargetTextures &&
+                layer.isBackground === isBackground &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
         };
-        LayerSceneComponent.prototype._drawForeground = function (camera) {
-            this._draw(camera, false);
+        LayerSceneComponent.prototype._drawCameraBackground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, true, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawCameraForeground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, false, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetPredicate = function (layer, isBackground, cameraLayerMask, renderTargetTexture) {
+            return (layer.renderTargetTextures.length > 0) &&
+                layer.isBackground === isBackground &&
+                (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        };
+        LayerSceneComponent.prototype._drawRenderTargetBackground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, true, _this.scene.activeCamera.layerMask, renderTarget);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetForeground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, false, _this.scene.activeCamera.layerMask, renderTarget);
+            });
         };
         return LayerSceneComponent;
     }());
@@ -115600,6 +115654,15 @@ var BABYLON;
              * Define a mask to restrict the layer to only some of the scene cameras.
              */
             this.layerMask = 0x0FFFFFFF;
+            /**
+             * Define the list of render target the layer is visible into.
+             */
+            this.renderTargetTextures = [];
+            /**
+             * Define if the layer is only used in renderTarget or if it also
+             * renders in the main frame buffer of the canvas.
+             */
+            this.renderOnlyInRenderTargetTextures = false;
             this._vertexBuffers = {};
             /**
              * An event triggered when the layer is disposed.
@@ -115751,6 +115814,8 @@ var BABYLON;
                 this.texture.dispose();
                 this.texture = null;
             }
+            // Clean RTT list
+            this.renderTargetTextures = [];
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);

+ 88 - 23
dist/preview release/babylon.no-module.max.js

@@ -25369,6 +25369,7 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
@@ -25376,6 +25377,7 @@ var BABYLON;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
         SceneComponentConstants.STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -26147,6 +26149,11 @@ var BABYLON;
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a render target is drawing.
+             */
+            _this._beforeRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -26172,6 +26179,11 @@ var BABYLON;
             _this._afterCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just after a render target has been drawn.
+             */
+            _this._afterRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after rendering all cameras and computing intersections.
              */
             _this._afterRenderStage = BABYLON.Stage.Create();
@@ -27060,14 +27072,12 @@ var BABYLON;
                         this.onPointerObservable.notifyObservers(pi, type_1);
                     }
                 }
-                if (pickResult.pickedMesh.actionManager) {
-                    if (clickInfo.ignore) {
-                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
-                    }
-                    if (!clickInfo.hasSwiped && !clickInfo.ignore && clickInfo.singleClick) {
+                if (pickResult.pickedMesh.actionManager && !clickInfo.ignore) {
+                    pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
+                    if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
-                    if (clickInfo.doubleClick && !clickInfo.ignore && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
+                    if (clickInfo.doubleClick && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnDoublePickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
                 }
@@ -29693,11 +29703,13 @@ var BABYLON;
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();
@@ -49189,6 +49201,7 @@ var BABYLON;
         TargetCamera.prototype._updateRigCameras = function () {
             var camLeft = this._rigCameras[0];
             var camRight = this._rigCameras[1];
+            this.computeWorldMatrix();
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
@@ -49218,13 +49231,12 @@ var BABYLON;
             _super.prototype._updateRigCameras.call(this);
         };
         TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
-            if (!this._rigCamTransformMatrix) {
-                this._rigCamTransformMatrix = new BABYLON.Matrix();
-            }
             var target = this.getTarget();
-            BABYLON.Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), this._rigCamTransformMatrix);
-            this._rigCamTransformMatrix = this._rigCamTransformMatrix.multiply(BABYLON.Matrix.Translation(target.x, target.y, target.z));
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
+            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
         };
         /**
          * Gets the current object class name.
@@ -49233,6 +49245,8 @@ var BABYLON;
         TargetCamera.prototype.getClassName = function () {
             return "TargetCamera";
         };
+        TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         __decorate([
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
@@ -74445,8 +74459,18 @@ var BABYLON;
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);
             }
+            // Before Camera Draw
+            for (var _i = 0, _a = scene._beforeRenderTargetDrawStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this);
+            }
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
+            // After Camera Draw
+            for (var _b = 0, _c = scene._afterRenderTargetDrawStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this);
+            }
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }
@@ -78475,7 +78499,8 @@ var BABYLON;
                 dataCallback(directLoad);
                 return plugin;
             }
-            if (fileInfo.rootUrl.indexOf("file:") === -1) {
+            var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
+            if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
                 var engine = scene.getEngine();
                 var canUseOfflineSupport = engine.enableOfflineSupport;
                 if (canUseOfflineSupport) {
@@ -78500,7 +78525,6 @@ var BABYLON;
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
                 if (file) {
                     request = BABYLON.Tools.ReadFile(file, dataCallback, onProgress, useArrayBuffer);
                 }
@@ -115476,8 +115500,10 @@ var BABYLON;
          * Registers the component in a given scene
          */
         LayerSceneComponent.prototype.register = function () {
-            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawBackground);
-            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawForeground);
+            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
+            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
+            this.scene._beforeRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
+            this.scene._afterRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
         };
         /**
          * Rebuilds the elements related to this component in case of
@@ -115499,25 +115525,53 @@ var BABYLON;
                 layers[0].dispose();
             }
         };
-        LayerSceneComponent.prototype._draw = function (camera, isBackground) {
+        LayerSceneComponent.prototype._draw = function (predicate) {
             var layers = this.scene.layers;
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
-                var cameraLayerMask = camera.layerMask;
                 for (var _i = 0, layers_2 = layers; _i < layers_2.length; _i++) {
                     var layer = layers_2[_i];
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                     }
                 }
                 this._engine.setDepthBuffer(true);
             }
         };
-        LayerSceneComponent.prototype._drawBackground = function (camera) {
-            this._draw(camera, true);
+        LayerSceneComponent.prototype._drawCameraPredicate = function (layer, isBackground, cameraLayerMask) {
+            return !layer.renderOnlyInRenderTargetTextures &&
+                layer.isBackground === isBackground &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
         };
-        LayerSceneComponent.prototype._drawForeground = function (camera) {
-            this._draw(camera, false);
+        LayerSceneComponent.prototype._drawCameraBackground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, true, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawCameraForeground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, false, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetPredicate = function (layer, isBackground, cameraLayerMask, renderTargetTexture) {
+            return (layer.renderTargetTextures.length > 0) &&
+                layer.isBackground === isBackground &&
+                (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        };
+        LayerSceneComponent.prototype._drawRenderTargetBackground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, true, _this.scene.activeCamera.layerMask, renderTarget);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetForeground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, false, _this.scene.activeCamera.layerMask, renderTarget);
+            });
         };
         return LayerSceneComponent;
     }());
@@ -115567,6 +115621,15 @@ var BABYLON;
              * Define a mask to restrict the layer to only some of the scene cameras.
              */
             this.layerMask = 0x0FFFFFFF;
+            /**
+             * Define the list of render target the layer is visible into.
+             */
+            this.renderTargetTextures = [];
+            /**
+             * Define if the layer is only used in renderTarget or if it also
+             * renders in the main frame buffer of the canvas.
+             */
+            this.renderOnlyInRenderTargetTextures = false;
             this._vertexBuffers = {};
             /**
              * An event triggered when the layer is disposed.
@@ -115718,6 +115781,8 @@ var BABYLON;
                 this.texture.dispose();
                 this.texture = null;
             }
+            // Clean RTT list
+            this.renderTargetTextures = [];
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.worker.js


+ 88 - 23
dist/preview release/es6.js

@@ -25369,6 +25369,7 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
@@ -25376,6 +25377,7 @@ var BABYLON;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
         SceneComponentConstants.STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -26147,6 +26149,11 @@ var BABYLON;
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a render target is drawing.
+             */
+            _this._beforeRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -26172,6 +26179,11 @@ var BABYLON;
             _this._afterCameraDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just after a render target has been drawn.
+             */
+            _this._afterRenderTargetDrawStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after rendering all cameras and computing intersections.
              */
             _this._afterRenderStage = BABYLON.Stage.Create();
@@ -27060,14 +27072,12 @@ var BABYLON;
                         this.onPointerObservable.notifyObservers(pi, type_1);
                     }
                 }
-                if (pickResult.pickedMesh.actionManager) {
-                    if (clickInfo.ignore) {
-                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
-                    }
-                    if (!clickInfo.hasSwiped && !clickInfo.ignore && clickInfo.singleClick) {
+                if (pickResult.pickedMesh.actionManager && !clickInfo.ignore) {
+                    pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
+                    if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
-                    if (clickInfo.doubleClick && !clickInfo.ignore && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
+                    if (clickInfo.doubleClick && pickResult.pickedMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnDoublePickTrigger)) {
                         pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnDoublePickTrigger, BABYLON.ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
                 }
@@ -29693,11 +29703,13 @@ var BABYLON;
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();
@@ -49189,6 +49201,7 @@ var BABYLON;
         TargetCamera.prototype._updateRigCameras = function () {
             var camLeft = this._rigCameras[0];
             var camRight = this._rigCameras[1];
+            this.computeWorldMatrix();
             switch (this.cameraRigMode) {
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case BABYLON.Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
@@ -49218,13 +49231,12 @@ var BABYLON;
             _super.prototype._updateRigCameras.call(this);
         };
         TargetCamera.prototype._getRigCamPosition = function (halfSpace, result) {
-            if (!this._rigCamTransformMatrix) {
-                this._rigCamTransformMatrix = new BABYLON.Matrix();
-            }
             var target = this.getTarget();
-            BABYLON.Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), this._rigCamTransformMatrix);
-            this._rigCamTransformMatrix = this._rigCamTransformMatrix.multiply(BABYLON.Matrix.Translation(target.x, target.y, target.z));
-            BABYLON.Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
+            BABYLON.Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._TargetTransformMatrix.multiplyToRef(BABYLON.Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
+            BABYLON.Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
+            BABYLON.Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
         };
         /**
          * Gets the current object class name.
@@ -49233,6 +49245,8 @@ var BABYLON;
         TargetCamera.prototype.getClassName = function () {
             return "TargetCamera";
         };
+        TargetCamera._RigCamTransformMatrix = new BABYLON.Matrix();
+        TargetCamera._TargetTransformMatrix = new BABYLON.Matrix();
         __decorate([
             BABYLON.serializeAsVector3()
         ], TargetCamera.prototype, "rotation", void 0);
@@ -74445,8 +74459,18 @@ var BABYLON;
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);
             }
+            // Before Camera Draw
+            for (var _i = 0, _a = scene._beforeRenderTargetDrawStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this);
+            }
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
+            // After Camera Draw
+            for (var _b = 0, _c = scene._afterRenderTargetDrawStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this);
+            }
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }
@@ -78475,7 +78499,8 @@ var BABYLON;
                 dataCallback(directLoad);
                 return plugin;
             }
-            if (fileInfo.rootUrl.indexOf("file:") === -1) {
+            var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
+            if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
                 var engine = scene.getEngine();
                 var canUseOfflineSupport = engine.enableOfflineSupport;
                 if (canUseOfflineSupport) {
@@ -78500,7 +78525,6 @@ var BABYLON;
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                var file = BABYLON.FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
                 if (file) {
                     request = BABYLON.Tools.ReadFile(file, dataCallback, onProgress, useArrayBuffer);
                 }
@@ -115476,8 +115500,10 @@ var BABYLON;
          * Registers the component in a given scene
          */
         LayerSceneComponent.prototype.register = function () {
-            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawBackground);
-            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawForeground);
+            this.scene._beforeCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
+            this.scene._afterCameraDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
+            this.scene._beforeRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
+            this.scene._afterRenderTargetDrawStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
         };
         /**
          * Rebuilds the elements related to this component in case of
@@ -115499,25 +115525,53 @@ var BABYLON;
                 layers[0].dispose();
             }
         };
-        LayerSceneComponent.prototype._draw = function (camera, isBackground) {
+        LayerSceneComponent.prototype._draw = function (predicate) {
             var layers = this.scene.layers;
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
-                var cameraLayerMask = camera.layerMask;
                 for (var _i = 0, layers_2 = layers; _i < layers_2.length; _i++) {
                     var layer = layers_2[_i];
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                     }
                 }
                 this._engine.setDepthBuffer(true);
             }
         };
-        LayerSceneComponent.prototype._drawBackground = function (camera) {
-            this._draw(camera, true);
+        LayerSceneComponent.prototype._drawCameraPredicate = function (layer, isBackground, cameraLayerMask) {
+            return !layer.renderOnlyInRenderTargetTextures &&
+                layer.isBackground === isBackground &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
         };
-        LayerSceneComponent.prototype._drawForeground = function (camera) {
-            this._draw(camera, false);
+        LayerSceneComponent.prototype._drawCameraBackground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, true, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawCameraForeground = function (camera) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawCameraPredicate(layer, false, camera.layerMask);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetPredicate = function (layer, isBackground, cameraLayerMask, renderTargetTexture) {
+            return (layer.renderTargetTextures.length > 0) &&
+                layer.isBackground === isBackground &&
+                (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        };
+        LayerSceneComponent.prototype._drawRenderTargetBackground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, true, _this.scene.activeCamera.layerMask, renderTarget);
+            });
+        };
+        LayerSceneComponent.prototype._drawRenderTargetForeground = function (renderTarget) {
+            var _this = this;
+            this._draw(function (layer) {
+                return _this._drawRenderTargetPredicate(layer, false, _this.scene.activeCamera.layerMask, renderTarget);
+            });
         };
         return LayerSceneComponent;
     }());
@@ -115567,6 +115621,15 @@ var BABYLON;
              * Define a mask to restrict the layer to only some of the scene cameras.
              */
             this.layerMask = 0x0FFFFFFF;
+            /**
+             * Define the list of render target the layer is visible into.
+             */
+            this.renderTargetTextures = [];
+            /**
+             * Define if the layer is only used in renderTarget or if it also
+             * renders in the main frame buffer of the canvas.
+             */
+            this.renderOnlyInRenderTargetTextures = false;
             this._vertexBuffers = {};
             /**
              * An event triggered when the layer is disposed.
@@ -115718,6 +115781,8 @@ var BABYLON;
                 this.texture.dispose();
                 this.texture = null;
             }
+            // Clean RTT list
+            this.renderTargetTextures = [];
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 1
dist/preview release/what's new.md

@@ -60,6 +60,7 @@
 - Added opacity texture support to `GridMaterial` ([Deltakosh](https://github.com/deltakosh))
 - Added support for deserializing morph target animations in animation groups
 - AssetContainer dispose method ([TrevorDev](https://github.com/TrevorDev))
+- `Layer` are now supported in `RenderTargetTexture` ([Sebavan](https://github.com/Sebavan))
 
 ### glTF Loader
 
@@ -77,12 +78,13 @@
 - Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo scaling not consistent when camera is parented ([TrevorDev](https://github.com/TrevorDev))
-- Context loss causing unexpected results with dynamic textures ([TrevorDev](https://github.com/TrevorDev))
+- Context loss causing unexpected results with dynamic textures, geometries with the same name and reflectionTextures ([TrevorDev](https://github.com/TrevorDev))
 - CreateScreenshotUsingRenderTarget stretches mirror textures when setting both width and height ([TrevorDev](https://github.com/TrevorDev))
 - VR helper only updating vr cameras position when entering vr, rotation was missing ([TrevorDev](https://github.com/TrevorDev))
 - Fix VR controllers after gltfLoader transformNode change ([TrevorDev](https://github.com/TrevorDev))
 - Bounding Box fixedDragMeshScreenSize stopped working and allow rotating through bounding box ([TrevorDev](https://github.com/TrevorDev))
 - VR helper would rotate non vr camera while in VR ([TrevorDev](https://github.com/TrevorDev))
+- PointerDragBahavior using Mesh as base type, causing type-checking problems with AbstractMesh ([Poolminer](https://github.com/Poolminer/))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))

+ 3 - 3
src/Behaviors/Mesh/pointerDragBehavior.ts

@@ -12,9 +12,9 @@ import { Ray } from "Culling/ray";
     /**
      * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
      */
-    export class PointerDragBehavior implements Behavior<Mesh> {
+    export class PointerDragBehavior implements Behavior<AbstractMesh> {
         private static _AnyMouseID = -2;
-        private _attachedNode: Mesh;
+        private _attachedNode: AbstractMesh;
         private _dragPlane: Mesh;
         private _scene: Scene;
         private _pointerObserver: Nullable<Observer<PointerInfo>>;
@@ -127,7 +127,7 @@ import { Ray } from "Culling/ray";
          * Attaches the drag behavior the passed in mesh
          * @param ownerNode The mesh that will be dragged around once attached
          */
-        public attach(ownerNode: Mesh): void {
+        public attach(ownerNode: AbstractMesh): void {
             this._scene = ownerNode.getScene();
             this._attachedNode = ownerNode;
 

+ 9 - 7
src/Cameras/targetCamera.ts

@@ -9,6 +9,8 @@ import { Quaternion, Matrix, Vector3, Vector2, Epsilon, Tmp, Axis } from "Math/m
      * @see http://doc.babylonjs.com/features/cameras
      */
     export class TargetCamera extends Camera {
+        private static _RigCamTransformMatrix = new Matrix();
+        private static _TargetTransformMatrix = new Matrix();
 
         /**
          * Define the current direction the camera is moving to
@@ -63,7 +65,6 @@ import { Quaternion, Matrix, Vector3, Vector2, Epsilon, Tmp, Axis } from "Math/m
         public _cameraTransformMatrix = Matrix.Zero();
         /** @hidden */
         public _cameraRotationMatrix = Matrix.Zero();
-        private _rigCamTransformMatrix: Matrix;
 
         /** @hidden */
         public _referencePoint = new Vector3(0, 0, 1);
@@ -439,6 +440,8 @@ import { Quaternion, Matrix, Vector3, Vector2, Epsilon, Tmp, Axis } from "Math/m
             var camLeft = <TargetCamera>this._rigCameras[0];
             var camRight = <TargetCamera>this._rigCameras[1];
 
+            this.computeWorldMatrix();
+
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
@@ -471,15 +474,14 @@ import { Quaternion, Matrix, Vector3, Vector2, Epsilon, Tmp, Axis } from "Math/m
         }
 
         private _getRigCamPosition(halfSpace: number, result: Vector3) {
-            if (!this._rigCamTransformMatrix) {
-                this._rigCamTransformMatrix = new Matrix();
-            }
             var target = this.getTarget();
-            Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(Matrix.RotationY(halfSpace), this._rigCamTransformMatrix);
+            Matrix.TranslationToRef(-target.x, -target.y, -target.z, TargetCamera._TargetTransformMatrix);
+            TargetCamera._TargetTransformMatrix.multiplyToRef(Matrix.RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
+            Matrix.TranslationToRef(target.x, target.y, target.z, TargetCamera._TargetTransformMatrix);
 
-            this._rigCamTransformMatrix = this._rigCamTransformMatrix.multiply(Matrix.Translation(target.x, target.y, target.z));
+            TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
 
-            Vector3.TransformCoordinatesToRef(this.position, this._rigCamTransformMatrix, result);
+            Vector3.TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, result);
         }
 
         /**

+ 14 - 0
src/Layer/layer.ts

@@ -60,6 +60,17 @@ import { Constants } from "Engine/constants";
          */
         public layerMask: number = 0x0FFFFFFF;
 
+        /**
+         * Define the list of render target the layer is visible into.
+         */
+        public renderTargetTextures: RenderTargetTexture[] = [];
+
+        /**
+         * Define if the layer is only used in renderTarget or if it also
+         * renders in the main frame buffer of the canvas.
+         */
+        public renderOnlyInRenderTargetTextures = false;
+
         private _scene: Scene;
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _indexBuffer: Nullable<WebGLBuffer>;
@@ -268,6 +279,9 @@ import { Constants } from "Engine/constants";
                 this.texture = null;
             }
 
+            // Clean RTT list
+            this.renderTargetTextures = [];
+
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);

+ 40 - 9
src/Layer/layerSceneComponent.ts

@@ -46,8 +46,11 @@ declare module "abstractScene" {
          * Registers the component in a given scene
          */
         public register(): void {
-            this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawBackground);
-            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawForeground);
+            this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
+            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
+
+            this.scene._beforeRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
+            this.scene._afterRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
         }
 
         /**
@@ -73,14 +76,13 @@ declare module "abstractScene" {
             }
         }
 
-        private _draw(camera: Camera, isBackground: boolean): void {
+        private _draw(predicate: (layer: Layer) => boolean): void {
             let layers = this.scene.layers;
 
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
-                const cameraLayerMask = camera.layerMask;
                 for (let layer of layers) {
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                     }
                 }
@@ -88,11 +90,40 @@ declare module "abstractScene" {
             }
         }
 
-        private _drawBackground(camera: Camera): void {
-            this._draw(camera, true);
+        private _drawCameraPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number): boolean {
+            return !layer.renderOnlyInRenderTargetTextures &&
+                layer.isBackground === isBackground &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        }
+
+        private _drawCameraBackground(camera: Camera): void {
+            this._draw((layer: Layer) => {
+                return this._drawCameraPredicate(layer, true, camera.layerMask);
+            });
+        }
+
+        private _drawCameraForeground(camera: Camera): void {
+            this._draw((layer: Layer) => {
+                return this._drawCameraPredicate(layer, false, camera.layerMask);
+            });
+        }
+
+        private _drawRenderTargetPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number, renderTargetTexture: RenderTargetTexture): boolean {
+            return (layer.renderTargetTextures.length > 0) &&
+                layer.isBackground === isBackground &&
+                (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
+                ((layer.layerMask & cameraLayerMask) !== 0);
+        }
+
+        private _drawRenderTargetBackground(renderTarget: RenderTargetTexture): void {
+            this._draw((layer: Layer) => {
+                return this._drawRenderTargetPredicate(layer, true, this.scene.activeCamera!.layerMask, renderTarget);
+            });
         }
 
-        private _drawForeground(camera: Camera): void {
-            this._draw(camera, false);
+        private _drawRenderTargetForeground(renderTarget: RenderTargetTexture): void {
+            this._draw((layer: Layer) => {
+                return this._drawRenderTargetPredicate(layer, false, this.scene.activeCamera!.layerMask, renderTarget);
+            });
         }
     }

+ 3 - 2
src/Loading/sceneLoader.ts

@@ -416,7 +416,9 @@ import { Skeleton } from "Bones/skeleton";
                 return plugin;
             }
 
-            if (fileInfo.rootUrl.indexOf("file:") === -1) {
+            const file = FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
+
+            if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
                 let engine = scene.getEngine();
                 let canUseOfflineSupport = engine.enableOfflineSupport;
                 if (canUseOfflineSupport) {
@@ -442,7 +444,6 @@ import { Skeleton } from "Bones/skeleton";
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                const file = FilesInput.FilesToLoad[fileInfo.name.toLowerCase()];
                 if (file) {
                     request = Tools.ReadFile(file, dataCallback, onProgress, useArrayBuffer);
                 } else {

+ 3 - 3
src/Materials/Textures/internalTexture.ts

@@ -302,9 +302,9 @@ declare type BaseTexture = import("Materials/Textures/baseTexture").BaseTexture;
 
                 case InternalTexture.DATASOURCE_URL:
                     proxy = this._engine.createTexture(this.url, !this.generateMipMaps, this.invertY, null, this.samplingMode, () => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     }, null, this._buffer, undefined, this.format);
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_RAW:
@@ -369,9 +369,9 @@ declare type BaseTexture = import("Materials/Textures/baseTexture").BaseTexture;
 
                 case InternalTexture.DATASOURCE_CUBE:
                     proxy = this._engine.createCubeTexture(this.url, null, this._files, !this.generateMipMaps, () => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     }, null, this.format, this._extension);
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_CUBERAW:
@@ -383,9 +383,9 @@ declare type BaseTexture = import("Materials/Textures/baseTexture").BaseTexture;
                 case InternalTexture.DATASOURCE_CUBERAW_RGBD:
                     proxy = this._engine.createRawCubeTexture(null, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                     InternalTexture._UpdateRGBDAsync(proxy, this._bufferViewArrayArray!, this._sphericalPolynomial, this._lodGenerationScale, this._lodGenerationOffset).then(() => {
+                        proxy._swapAndDie(this);
                         this.isReady = true;
                     });
-                    proxy._swapAndDie(this);
                     return;
 
                 case InternalTexture.DATASOURCE_CUBEPREFILTERED:

+ 10 - 0
src/Materials/Textures/renderTargetTexture.ts

@@ -769,9 +769,19 @@ import { Constants } from "Engine/constants";
                 scene.updateTransformMatrix(true);
             }
 
+            // Before Camera Draw
+            for (let step of scene._beforeRenderTargetDrawStage) {
+                step.action(this);
+            }
+
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
 
+            // After Camera Draw
+            for (let step of scene._afterRenderTargetDrawStage) {
+                step.action(this);
+            }
+
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }

+ 6 - 1
src/Mesh/geometry.ts

@@ -18,10 +18,14 @@
     export class Geometry implements IGetSetVerticesData {
         // Members
         /**
-         * Gets or sets the unique ID of the geometry
+         * Gets or sets the ID of the geometry
          */
         public id: string;
         /**
+         * Gets or sets the unique ID of the geometry
+         */
+        public uniqueId: number;
+        /**
          * Gets the delay loading state of the geometry (none by default which means not delayed)
          */
         public delayLoadState = Constants.DELAYLOADSTATE_NONE;
@@ -107,6 +111,7 @@
          */
         constructor(id: string, scene: Scene, vertexData?: VertexData, updatable: boolean = false, mesh: Nullable<Mesh> = null) {
             this.id = id;
+            this.uniqueId = scene.getUniqueId();
             this._engine = scene.getEngine();
             this._meshes = [];
             this._scene = scene;

+ 28 - 7
src/scene.ts

@@ -1220,6 +1220,11 @@ import { Constants } from "Engine/constants";
         public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
          * @hidden
+         * Defines the actions happening just before a render target is drawing.
+         */
+        public _beforeRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening just before a rendering group is drawing.
          */
         public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
@@ -1245,6 +1250,11 @@ import { Constants } from "Engine/constants";
         public _afterCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
          * @hidden
+         * Defines the actions happening just after a render target has been drawn.
+         */
+        public _afterRenderTargetDrawStage = Stage.Create<RenderTargetStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening just after rendering all cameras and computing intersections.
          */
         public _afterRenderStage = Stage.Create<SimpleStageAction>();
@@ -1772,14 +1782,13 @@ import { Constants } from "Engine/constants";
                         this.onPointerObservable.notifyObservers(pi, type);
                     }
                 }
-                if (pickResult.pickedMesh.actionManager) {
-                    if (clickInfo.ignore) {
-                        pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
-                    }
-                    if (!clickInfo.hasSwiped && !clickInfo.ignore && clickInfo.singleClick) {
+                if (pickResult.pickedMesh.actionManager && !clickInfo.ignore) {
+                    pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
+
+                    if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                         pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnPickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
-                    if (clickInfo.doubleClick && !clickInfo.ignore && pickResult.pickedMesh.actionManager.hasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
+                    if (clickInfo.doubleClick && pickResult.pickedMesh.actionManager.hasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
                         pickResult.pickedMesh.actionManager.processTrigger(ActionManager.OnDoublePickTrigger, ActionEvent.CreateNew(pickResult.pickedMesh, evt));
                     }
                 }
@@ -3661,6 +3670,16 @@ import { Constants } from "Engine/constants";
             return null;
         }
 
+        private _getGeometryByUniqueID(id: number): Nullable<Geometry> {
+            for (var index = 0; index < this.geometries.length; index++) {
+                if (this.geometries[index].uniqueId === id) {
+                    return this.geometries[index];
+                }
+            }
+
+            return null;
+        }
+
         /**
          * Add a new geometry to this scene
          * @param geometry defines the geometry to be added to the scene.
@@ -3668,7 +3687,7 @@ import { Constants } from "Engine/constants";
          * @return a boolean defining if the geometry was added or not
          */
         public pushGeometry(geometry: Geometry, force?: boolean): boolean {
-            if (!force && this.getGeometryByID(geometry.id)) {
+            if (!force && this._getGeometryByUniqueID(geometry.uniqueId)) {
                 return false;
             }
 
@@ -4830,11 +4849,13 @@ import { Constants } from "Engine/constants";
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();

+ 9 - 0
src/sceneComponent.ts

@@ -45,6 +45,8 @@ import { AbstractScene } from "abstractScene";
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_BEFORECAMERADRAW_LAYER = 1;
 
+        public static readonly STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
+
         public static readonly STEP_BEFORERENDERINGMESH_OUTLINE = 0;
 
         public static readonly STEP_AFTERRENDERINGMESH_OUTLINE = 0;
@@ -57,6 +59,8 @@ import { AbstractScene } from "abstractScene";
 
         public static readonly STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
 
+        public static readonly STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
+
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -156,6 +160,11 @@ import { AbstractScene } from "abstractScene";
     export type CameraStageAction = (camera: Camera) => void;
 
     /**
+     * Strong typing of a Render Target related stage step action
+     */
+    export type RenderTargetStageAction = (renderTarget: RenderTargetTexture) => void;
+
+    /**
      * Strong typing of a RenderingGroup related stage step action
      */
     export type RenderingGroupStageAction = (renderingGroupId: number) => void;