Jelajahi Sumber

Merge pull request #5469 from sebavan/master

Allow Layers in RTT
sebavan 6 tahun lalu
induk
melakukan
7baa60966a

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

@@ -60,6 +60,7 @@
 - Added opacity texture support to `GridMaterial` ([Deltakosh](https://github.com/deltakosh))
 - Added opacity texture support to `GridMaterial` ([Deltakosh](https://github.com/deltakosh))
 - Added support for deserializing morph target animations in animation groups
 - Added support for deserializing morph target animations in animation groups
 - AssetContainer dispose method ([TrevorDev](https://github.com/TrevorDev))
 - AssetContainer dispose method ([TrevorDev](https://github.com/TrevorDev))
+- `Layer` are now supported in `RenderTargetTexture` ([Sebavan](https://github.com/Sebavan))
 
 
 ### glTF Loader
 ### glTF Loader
 
 

+ 15 - 1
src/Layer/babylon.layer.ts

@@ -48,6 +48,17 @@ module BABYLON {
          */
          */
         public layerMask: number = 0x0FFFFFFF;
         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 _scene: Scene;
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _indexBuffer: Nullable<WebGLBuffer>;
         private _indexBuffer: Nullable<WebGLBuffer>;
@@ -198,7 +209,7 @@ module BABYLON {
 
 
             // Check
             // Check
             if (!currentEffect.isReady() || !this.texture || !this.texture.isReady()) {
             if (!currentEffect.isReady() || !this.texture || !this.texture.isReady()) {
-                return;
+                return;
             }
             }
 
 
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
@@ -256,6 +267,9 @@ module BABYLON {
                 this.texture = null;
                 this.texture = null;
             }
             }
 
 
+            // Clean RTT list
+            this.renderTargetTextures = [];
+
             // Remove from scene
             // Remove from scene
             var index = this._scene.layers.indexOf(this);
             var index = this._scene.layers.indexOf(this);
             this._scene.layers.splice(index, 1);
             this._scene.layers.splice(index, 1);

+ 40 - 9
src/Layer/babylon.layerSceneComponent.ts

@@ -37,8 +37,11 @@ module BABYLON {
          * Registers the component in a given scene
          * Registers the component in a given scene
          */
          */
         public register(): void {
         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);
         }
         }
 
 
         /**
         /**
@@ -64,14 +67,13 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        private _draw(camera: Camera, isBackground: boolean): void {
+        private _draw(predicate: (layer: Layer) => boolean): void {
             let layers = this.scene.layers;
             let layers = this.scene.layers;
 
 
             if (layers.length) {
             if (layers.length) {
                 this._engine.setDepthBuffer(false);
                 this._engine.setDepthBuffer(false);
-                const cameraLayerMask = camera.layerMask;
                 for (let layer of layers) {
                 for (let layer of layers) {
-                    if (layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0)) {
+                    if (predicate(layer)) {
                         layer.render();
                         layer.render();
                     }
                     }
                 }
                 }
@@ -79,12 +81,41 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        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);
+            });
         }
         }
     }
     }
 }
 }

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

@@ -754,9 +754,19 @@ module BABYLON {
                 scene.updateTransformMatrix(true);
                 scene.updateTransformMatrix(true);
             }
             }
 
 
+            // Before Camera Draw
+            for (let step of scene._beforeRenderTargetDrawStage) {
+                step.action(this);
+            }
+
             // Render
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
             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) {
             if (this._postProcessManager) {
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
                 this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
             }
             }

+ 12 - 0
src/babylon.scene.ts

@@ -1172,6 +1172,11 @@ module BABYLON {
         public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();
         public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
         /**
          * @hidden
          * @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.
          * Defines the actions happening just before a rendering group is drawing.
          */
          */
         public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
         public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
@@ -1197,6 +1202,11 @@ module BABYLON {
         public _afterCameraDrawStage = Stage.Create<CameraStageAction>();
         public _afterCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
         /**
          * @hidden
          * @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.
          * Defines the actions happening just after rendering all cameras and computing intersections.
          */
          */
         public _afterRenderStage = Stage.Create<SimpleStageAction>();
         public _afterRenderStage = Stage.Create<SimpleStageAction>();
@@ -4782,11 +4792,13 @@ module BABYLON {
             this._activeMeshStage.clear();
             this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderTargetDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._beforeRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             this._afterCameraDrawStage.clear();
+            this._afterRenderTargetDrawStage.clear();
             this._afterRenderStage.clear();
             this._afterRenderStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeCameraUpdateStage.clear();
             this._beforeClearStage.clear();
             this._beforeClearStage.clear();

+ 9 - 0
src/babylon.sceneComponent.ts

@@ -35,6 +35,8 @@ module BABYLON {
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_BEFORECAMERADRAW_LAYER = 1;
         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_BEFORERENDERINGMESH_OUTLINE = 0;
 
 
         public static readonly STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         public static readonly STEP_AFTERRENDERINGMESH_OUTLINE = 0;
@@ -47,6 +49,8 @@ module BABYLON {
 
 
         public static readonly STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
         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_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -146,6 +150,11 @@ module BABYLON {
     export type CameraStageAction = (camera: Camera) => void;
     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
      * Strong typing of a RenderingGroup related stage step action
      */
      */
     export type RenderingGroupStageAction = (renderingGroupId: number) => void;
     export type RenderingGroupStageAction = (renderingGroupId: number) => void;