Explorar o código

Fix #4463: Allow effect layer per rendering group

sebastien %!s(int64=7) %!d(string=hai) anos
pai
achega
639e60bae3

+ 19 - 2
src/Layer/babylon.effectLayer.ts

@@ -24,6 +24,11 @@
          * The camera attached to the layer.
          */
         camera: Nullable<Camera>;
+
+        /**
+         * The rendering group to draw the layer in.
+         */
+        renderingGroupId: number;
     }
 
     /**
@@ -80,6 +85,14 @@
         }
 
         /**
+         * Gets the rendering group id the layer should render in.
+         */
+        @serialize()
+        public get renderingGroupId(): number {
+            return this._effectLayerOptions.renderingGroupId;
+        }
+
+        /**
          * An event triggered when the effect layer has been disposed.
          */
         public onDisposeObservable = new Observable<EffectLayer>();
@@ -197,6 +210,7 @@
                 mainTextureRatio: 0.5,
                 alphaBlendingMode: Engine.ALPHA_COMBINE,
                 camera: null,
+                renderingGroupId: -1,
                 ...options,
             };
 
@@ -489,7 +503,10 @@
          * @returns true if the mesh will be used
          */
         public hasMesh(mesh: AbstractMesh): boolean {
-            return true;
+            if (this.renderingGroupId === -1 || mesh.renderingGroupId === this.renderingGroupId) {
+                return true;
+            }
+            return false;
         }
 
         /**
@@ -692,7 +709,7 @@
          */
         public static Parse(parsedEffectLayer: any, scene: Scene, rootUrl: string): EffectLayer {
             var effectLayerType = Tools.Instantiate(parsedEffectLayer.customType);
-            
+
             return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
         }
     }

+ 21 - 4
src/Layer/babylon.effectLayerSceneComponent.ts

@@ -85,8 +85,11 @@
             this.scene._cameraDrawRenderTargetStage.registerStep(SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER, this, this._renderMainTexture);
 
             this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER, this, this._setStencil);
+
+            this.scene._afterRenderingGroupDrawStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW, this, this._drawRenderingGroup);
+
             this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER, this, this._setStencilBack);
-            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW, this, this._draw);
+            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW, this, this._drawCamera);
         }
 
         /**
@@ -205,16 +208,30 @@
             }
         }
 
-        private _draw(camera: Camera): void {
+        private _draw(renderingGroupId: number): void {
             if (this._renderEffects) {
                 this._engine.setDepthBuffer(false);
                 for (let i = 0; i < this._effectLayers.length; i++) {
-                    if (this._effectLayers[i].shouldRender()) {
-                        this._effectLayers[i].render();
+                    const effectLayer = this._effectLayers[i];
+                    if (effectLayer.renderingGroupId === renderingGroupId) {
+                        if (effectLayer.shouldRender()) {
+                            effectLayer.render();
+                        }
                     }
                 }
                 this._engine.setDepthBuffer(true);
             }
         }
+
+        private _drawCamera(camera: Camera): void {
+            if (this._renderEffects) {
+                this._draw(-1);
+            }
+        }
+        private _drawRenderingGroup(index: number): void {
+            if (!this.scene._isInIntermediateRendering() && this._renderEffects) {
+                this._draw(index);
+            }
+        }
     }
 } 

+ 12 - 1
src/Layer/babylon.glowLayer.ts

@@ -49,6 +49,11 @@
          * Enable MSAA by chosing the number of samples.
          */
         mainTextureSamples?: number;
+
+        /**
+         * The rendering group to draw the layer in.
+         */
+        renderingGroupId: number;
     }
 
     /**
@@ -150,6 +155,7 @@
                 mainTextureFixedSize: undefined,
                 camera: null,
                 mainTextureSamples: 1,
+                renderingGroupId: -1,
                 ...options,
             };
 
@@ -158,7 +164,8 @@
                 alphaBlendingMode: Engine.ALPHA_ADD,
                 camera: this._options.camera,
                 mainTextureFixedSize: this._options.mainTextureFixedSize,
-                mainTextureRatio: this._options.mainTextureRatio
+                mainTextureRatio: this._options.mainTextureRatio,
+                renderingGroupId: this._options.renderingGroupId
             });
         }
 
@@ -443,6 +450,10 @@
          * @returns true if the mesh will be highlighted by the current glow layer
          */
         public hasMesh(mesh: AbstractMesh): boolean {
+            if (!super.hasMesh(mesh)) {
+                return false;
+            }
+
             // Included Mesh
             if (this._includedOnlyMeshes.length) {
                 return this._includedOnlyMeshes.indexOf(mesh.uniqueId) !== -1;

+ 16 - 1
src/Layer/babylon.highlightLayer.ts

@@ -80,6 +80,11 @@
          * Should we display highlight as a solid stroke?
          */
         isStroke?: boolean;
+
+        /**
+         * The rendering group to draw the layer in.
+         */
+        renderingGroupId: number;
     }
 
     /**
@@ -244,6 +249,7 @@
                 blurVerticalSize: 1.0,
                 alphaBlendingMode: Engine.ALPHA_COMBINE,
                 camera: null,
+                renderingGroupId: -1,
                 ...options,
             };
 
@@ -252,7 +258,8 @@
                 alphaBlendingMode: this._options.alphaBlendingMode,
                 camera: this._options.camera,
                 mainTextureFixedSize: this._options.mainTextureFixedSize,
-                mainTextureRatio: this._options.mainTextureRatio
+                mainTextureRatio: this._options.mainTextureRatio,
+                renderingGroupId: this._options.renderingGroupId
             });
 
             // Do not render as long as no meshes have been added
@@ -479,6 +486,10 @@
                 return false;
             };
 
+            if (!super.hasMesh(mesh)) {
+                return false;
+            }
+
             return true;
         }
 
@@ -572,6 +583,10 @@
                 return false;
             }
 
+            if (!super.hasMesh(mesh)) {
+                return false;
+            }
+
             return this._meshes[mesh.uniqueId] !== undefined && this._meshes[mesh.uniqueId] !== null;
         }
 

+ 8 - 1
src/Rendering/babylon.renderingManager.ts

@@ -110,8 +110,15 @@
                     observable.notifyObservers(info, renderingGroupMask);
                 }
 
-                if (renderingGroup)
+                if (renderingGroup) {
+                    for (let step of this._scene._beforeRenderingGroupDrawStage) {
+                        step.action(index);
+                    }
                     renderingGroup.render(customRenderFunction, renderSprites, renderParticles, activeMeshes);
+                    for (let step of this._scene._afterRenderingGroupDrawStage) {
+                        step.action(index);
+                    }
+                }
 
                 // Fire POSTTRANSPARENT stage
                 if (observable && info) {

+ 11 - 1
src/babylon.scene.ts

@@ -1205,7 +1205,15 @@
          */
         public _beforeCameraDrawStage = Stage.Create<CameraStageAction>();
         /**
-         * Defines the actions happening just after the active camera is drawing.
+         * Defines the actions happening just before a rendering group is drawing.
+         */
+        public _beforeRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
+        /**
+         * Defines the actions happening just after a rendering group has been drawn.
+         */
+        public _afterRenderingGroupDrawStage = Stage.Create<RenderingGroupStageAction>();
+        /**
+         * Defines the actions happening just after the active camera has been drawn.
          */
         public _afterCameraDrawStage = Stage.Create<CameraStageAction>();
        
@@ -5002,6 +5010,8 @@
             this._isReadyForMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
+            this._beforeRenderingGroupDrawStage.clear();
+            this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             for (let component of this._components) {
                 component.dispose();

+ 7 - 0
src/babylon.sceneComponent.ts

@@ -15,6 +15,8 @@
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_BEFORECAMERADRAW_LAYER = 1;
 
+        public static readonly STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
+
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
@@ -85,6 +87,11 @@
     export type CameraStageAction = (camera: Camera) => void;
 
     /** 
+     * Strong typing of a RenderingGroup related stage step action 
+     */
+    export type RenderingGroupStageAction = (renderingGroupId: number) => void;
+
+    /** 
      * Strong typing of a simple stage step action 
      */
     export type SimpleStageAction = () => void;