From f9b6e9846b03aca06826541d0f43e3293dea949f Mon Sep 17 00:00:00 2001 From: sebastien Date: Tue, 6 Nov 2018 00:29:43 +0100 Subject: [PATCH 1/2] Allow Layers in RTT --- dist/preview release/what's new.md | 1 + src/Layer/babylon.layer.ts | 20 +++++++- src/Layer/babylon.layerSceneComponent.ts | 49 +++++++++++++++---- .../Textures/babylon.renderTargetTexture.ts | 10 ++++ src/babylon.scene.ts | 12 +++++ src/babylon.sceneComponent.ts | 9 ++++ 6 files changed, 91 insertions(+), 10 deletions(-) diff --git a/dist/preview release/what's new.md b/dist/preview release/what's new.md index 5f777e1ec6b..9151f87292d 100644 --- a/dist/preview release/what's new.md +++ b/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 diff --git a/src/Layer/babylon.layer.ts b/src/Layer/babylon.layer.ts index 94026b2a6e7..e74b6d47654 100644 --- a/src/Layer/babylon.layer.ts +++ b/src/Layer/babylon.layer.ts @@ -48,6 +48,21 @@ module BABYLON { */ public layerMask: number = 0x0FFFFFFF; + /** + * Define if the layer is only used in renderTarget + */ + public renderInRenderTargets = false; + + /** + * Define if the layer is only used in renderTarget + */ + public renderInScene = true; + + /** + * Define the list of render target the layer is visible into. + */ + public renderTargetTextures: RenderTargetTexture[] = []; + private _scene: Scene; private _vertexBuffers: { [key: string]: Nullable } = {}; private _indexBuffer: Nullable; @@ -198,7 +213,7 @@ module BABYLON { // Check if (!currentEffect.isReady() || !this.texture || !this.texture.isReady()) { - return; + return; } var engine = this._scene.getEngine(); @@ -256,6 +271,9 @@ module BABYLON { this.texture = null; } + // Clean RTT list + this.renderTargetTextures = []; + // Remove from scene var index = this._scene.layers.indexOf(this); this._scene.layers.splice(index, 1); diff --git a/src/Layer/babylon.layerSceneComponent.ts b/src/Layer/babylon.layerSceneComponent.ts index a91c103d9a5..60e1f6eea17 100644 --- a/src/Layer/babylon.layerSceneComponent.ts +++ b/src/Layer/babylon.layerSceneComponent.ts @@ -37,8 +37,11 @@ module BABYLON { * 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); } /** @@ -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; 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(); } } @@ -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.renderInScene && + 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.renderInRenderTargets && + layer.isBackground === isBackground && + ((layer.layerMask & cameraLayerMask) !== 0) && + (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1); + } + + 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); + }); } } } diff --git a/src/Materials/Textures/babylon.renderTargetTexture.ts b/src/Materials/Textures/babylon.renderTargetTexture.ts index 278a29eec95..c0a101d26c9 100644 --- a/src/Materials/Textures/babylon.renderTargetTexture.ts +++ b/src/Materials/Textures/babylon.renderTargetTexture.ts @@ -754,9 +754,19 @@ module BABYLON { 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); } diff --git a/src/babylon.scene.ts b/src/babylon.scene.ts index 06922820a37..e116ddac016 100644 --- a/src/babylon.scene.ts +++ b/src/babylon.scene.ts @@ -1170,6 +1170,11 @@ module BABYLON { * Defines the actions happening just before the active camera is drawing. */ public _beforeCameraDrawStage = Stage.Create(); + /** + * @hidden + * Defines the actions happening just before a render target is drawing. + */ + public _beforeRenderTargetDrawStage = Stage.Create(); /** * @hidden * Defines the actions happening just before a rendering group is drawing. @@ -1195,6 +1200,11 @@ module BABYLON { * Defines the actions happening just after the active camera has been drawn. */ public _afterCameraDrawStage = Stage.Create(); + /** + * @hidden + * Defines the actions happening just after a render target has been drawn. + */ + public _afterRenderTargetDrawStage = Stage.Create(); /** * @hidden * Defines the actions happening just after rendering all cameras and computing intersections. @@ -4782,11 +4792,13 @@ module 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(); diff --git a/src/babylon.sceneComponent.ts b/src/babylon.sceneComponent.ts index 93e0894537b..3076a248c09 100644 --- a/src/babylon.sceneComponent.ts +++ b/src/babylon.sceneComponent.ts @@ -35,6 +35,8 @@ module BABYLON { 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; @@ -47,6 +49,8 @@ module BABYLON { 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; @@ -145,6 +149,11 @@ module BABYLON { */ 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 */ From c5ec6c889e6e4a0ff32543e94722a0d6f520242f Mon Sep 17 00:00:00 2001 From: sebastien Date: Tue, 6 Nov 2018 01:09:21 +0100 Subject: [PATCH 2/2] Remove Redundant Config --- src/Layer/babylon.layer.ts | 14 +++++--------- src/Layer/babylon.layerSceneComponent.ts | 8 ++++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/Layer/babylon.layer.ts b/src/Layer/babylon.layer.ts index e74b6d47654..98d67d316ab 100644 --- a/src/Layer/babylon.layer.ts +++ b/src/Layer/babylon.layer.ts @@ -49,19 +49,15 @@ module BABYLON { public layerMask: number = 0x0FFFFFFF; /** - * Define if the layer is only used in renderTarget - */ - public renderInRenderTargets = false; - - /** - * Define if the layer is only used in renderTarget + * Define the list of render target the layer is visible into. */ - public renderInScene = true; + public renderTargetTextures: RenderTargetTexture[] = []; /** - * Define the list of render target the layer is visible into. + * Define if the layer is only used in renderTarget or if it also + * renders in the main frame buffer of the canvas. */ - public renderTargetTextures: RenderTargetTexture[] = []; + public renderOnlyInRenderTargetTextures = false; private _scene: Scene; private _vertexBuffers: { [key: string]: Nullable } = {}; diff --git a/src/Layer/babylon.layerSceneComponent.ts b/src/Layer/babylon.layerSceneComponent.ts index 60e1f6eea17..ce93319c033 100644 --- a/src/Layer/babylon.layerSceneComponent.ts +++ b/src/Layer/babylon.layerSceneComponent.ts @@ -82,7 +82,7 @@ module BABYLON { } private _drawCameraPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number): boolean { - return layer.renderInScene && + return !layer.renderOnlyInRenderTargetTextures && layer.isBackground === isBackground && ((layer.layerMask & cameraLayerMask) !== 0); } @@ -100,10 +100,10 @@ module BABYLON { } private _drawRenderTargetPredicate(layer: Layer, isBackground: boolean, cameraLayerMask: number, renderTargetTexture: RenderTargetTexture): boolean { - return layer.renderInRenderTargets && + return (layer.renderTargetTextures.length > 0) && layer.isBackground === isBackground && - ((layer.layerMask & cameraLayerMask) !== 0) && - (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1); + (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) && + ((layer.layerMask & cameraLayerMask) !== 0); } private _drawRenderTargetBackground(renderTarget: RenderTargetTexture): void {