Forráskód Böngészése

buggy version where _enabled flag is separate

Benjamin Guignabert 4 éve
szülő
commit
b61c038658

+ 9 - 4
src/Materials/Textures/prePassRenderTarget.ts

@@ -24,6 +24,11 @@ export class PrePassRenderTarget extends MultiRenderTarget {
 	 */
 	public mrtCount: number = 0;
 
+	/**
+	 * Is rendering on this prepass texture enabled
+	 */
+	public enabled: boolean = false;
+
 	public _mrtFormats: number[] = [];
 	public _mrtLayout: number[];
     public _textureIndices: number[] = [];
@@ -32,6 +37,8 @@ export class PrePassRenderTarget extends MultiRenderTarget {
     public _defaultAttachments: number[];
     public _clearAttachments: number[];
 
+    public _isDirty: boolean = false;
+
     public _beforeCompositionPostProcesses: PostProcess[] = [];
     /**
      * Image processing post process for composition
@@ -283,10 +290,8 @@ export class PrePassRenderTarget extends MultiRenderTarget {
 	public dispose() {
 		super.dispose();
 
-		for (let i = 0; i < this._effectConfigurations.length; i++) {
-		    if (this._effectConfigurations[i].dispose) {
-		        this._effectConfigurations[i].dispose!();
-		    }
+		if (this._scene.prePassRenderer) {
+			this._scene.prePassRenderer.renderTargets.splice(this._scene.prePassRenderer.renderTargets.indexOf(this));
 		}
 
 		if (this.imageProcessingPostProcess) {

+ 11 - 8
src/Materials/Textures/renderTargetTexture.ts

@@ -111,12 +111,7 @@ export class RenderTargetTexture extends Texture {
      * Define if sprites should be rendered in your texture.
      */
     public renderSprites = false;
-    /**
-    * @hidden
-     * Defines if prepass should be rendered in your texture.
-     * This is automatically set by the prepass renderer
-     */
-    public _renderPrePass = false;
+
     /**
      * Define the camera used to render the texture.
      */
@@ -149,6 +144,10 @@ export class RenderTargetTexture extends Texture {
     private _postProcesses: PostProcess[];
     private _resizeObserver: Nullable<Observer<Engine>>;
 
+    private get _prePass() {
+        return !!this._prePassRenderTarget && this._prePassRenderTarget.enabled;
+    }
+
     /**
     * An event triggered when the texture is unbind.
     */
@@ -862,7 +861,7 @@ export class RenderTargetTexture extends Texture {
         }
 
         // Bind
-        if (!this._renderPrePass) {
+        if (!this._prePass) {
             if (this._postProcessManager) {
                 this._postProcessManager._prepareFrame(this._texture, this._postProcesses);
             }
@@ -904,7 +903,7 @@ export class RenderTargetTexture extends Texture {
         if (this.onClearObservable.hasObservers()) {
             this.onClearObservable.notifyObservers(engine);
         } else {
-            if (!this._renderPrePass) {
+            if (!this._prePass) {
                 engine.clear(this.clearColor || scene.clearColor, true, true, true);
             }
         }
@@ -1071,6 +1070,10 @@ export class RenderTargetTexture extends Texture {
             this._postProcessManager = null;
         }
 
+        if (this._prePassRenderTarget) {
+            this._prePassRenderTarget.dispose();
+        }
+
         this.clearPostProcesses(true);
 
         if (this._resizeObserver) {

+ 45 - 22
src/Rendering/prePassRenderer.ts

@@ -40,7 +40,6 @@ export class PrePassRenderer {
 
     private _scene: Scene;
     private _engine: Engine;
-    private _isDirty: boolean = false;
 
     /**
      * The render target where the scene is directly rendered
@@ -65,7 +64,11 @@ export class PrePassRenderer {
     }
 
     private _currentTarget: PrePassRenderTarget;
-    private _renderTargets: PrePassRenderTarget[] = [];
+
+    /**
+      * All the render targets generated by prepass
+      */
+    public renderTargets: PrePassRenderTarget[] = [];
 
     private readonly _clearColor = new Color4(0, 0, 0, 0);
 
@@ -105,7 +108,7 @@ export class PrePassRenderer {
             { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: [] });
         rt.samples = 1;
 
-        this._renderTargets.push(rt);
+        this.renderTargets.push(rt);
         return rt;
     }
 
@@ -122,7 +125,7 @@ export class PrePassRenderer {
      * @param subMesh Submesh on which the effect is applied
      */
     public bindAttachmentsForEffect(effect: Effect, subMesh: SubMesh) {
-        if (this.enabled) {
+        if (this.enabled && this._currentTarget.enabled) {
             if (effect._multiTarget) {
                 this._engine.bindAttachments(this._currentTarget._multiRenderAttachments);
             } else {
@@ -152,11 +155,16 @@ export class PrePassRenderer {
      * @hidden
      */
     public _beforeDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
-        if (this._isDirty) {
-            this._update(this._currentTarget);
+        let postProcesses = undefined;
+        if (texture) {
+            postProcesses = texture.postProcesses || texture.activeCamera?._postProcesses || [];       
+        } 
+
+        if (this._currentTarget._isDirty) {
+            this._update(this._currentTarget, postProcesses);
         }
 
-        if (!this._enabled) {
+        if (!this._enabled || !this._currentTarget.enabled) {
             // Prepass disabled, we render only on 1 color attachment
             if (texture) {
                 texture._bindFrameBuffer();
@@ -173,14 +181,14 @@ export class PrePassRenderer {
             this._currentTarget._geometryBuffer.renderList!.length = 0;
         }
 
-        this._setupOutputForThisPass(this._currentTarget, camera, texture ? texture.postProcesses : []);
+        this._setupOutputForThisPass(this._currentTarget, camera, postProcesses);
     }
 
     /**
      * @hidden
      */
     public _afterDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
-        if (this._enabled) {
+        if (this._enabled && this._currentTarget.enabled) {
             this._scene.postProcessManager._prepareFrame();
             const firstCameraPP = camera && camera._getFirstPostProcess();
             let outputTexture = firstCameraPP ? firstCameraPP.inputTexture : (texture ? texture.getInternalTexture() : null);
@@ -215,7 +223,7 @@ export class PrePassRenderer {
      * Clears the render target (in the sense of settings pixels to the scene clear color value)
      */
     public _clear() {
-        if (this._enabled) {
+        if (this._enabled && this._currentTarget.enabled) {
             this._bindFrameBuffer(this._currentTarget);
 
             // Clearing other attachment with 0 on all other attachments
@@ -232,7 +240,7 @@ export class PrePassRenderer {
     }
 
     private _bindFrameBuffer(prePassRenderTarget: PrePassRenderTarget) {
-        if (this._enabled) {
+        if (this._enabled && this._currentTarget.enabled) {
             this._currentTarget._checkSize();
             var internalTexture = this._currentTarget.getInternalTexture();
             if (internalTexture) {
@@ -244,8 +252,7 @@ export class PrePassRenderer {
     private _setState(prePassRenderTarget: PrePassRenderTarget, enabled: boolean) {
         this._enabled = enabled;
 
-        // TODO : generalize flag to signalize we are rendering to prepass for this frame
-        this._scene.prePass = enabled;
+        prePassRenderTarget.enabled = enabled;
 
         if (prePassRenderTarget.imageProcessingPostProcess) {
             prePassRenderTarget.imageProcessingPostProcess.imageProcessingConfiguration.applyByPostProcess = enabled;
@@ -389,7 +396,9 @@ export class PrePassRenderer {
      * Marks the prepass renderer as dirty, triggering a check if the prepass is necessary for the next rendering.
      */
     public markAsDirty() {
-        this._isDirty = true;
+        for (let i = 0; i < this.renderTargets.length; i++) {
+            this.renderTargets[i]._isDirty = true;
+        }
     }
 
     /**
@@ -409,7 +418,7 @@ export class PrePassRenderer {
         }
     }
 
-    private _update(prePassRenderTarget: PrePassRenderTarget) {
+    private _update(prePassRenderTarget: PrePassRenderTarget, forcePostProcesses?: PostProcess[]) {
         this._disable(prePassRenderTarget);
         let enablePrePass = false;
 
@@ -419,12 +428,20 @@ export class PrePassRenderer {
             }
         }
 
-        const camera = this._scene.activeCamera;
-        if (!camera) {
-            return;
+        let postProcesses;
+
+        if (forcePostProcesses) {
+            postProcesses = forcePostProcesses;
+        } else {
+            const camera = this._scene.activeCamera;
+            if (!camera) {
+                return;
+            }
+
+            postProcesses = camera._postProcesses;
         }
 
-        const postProcesses = (<Nullable<PostProcess[]>>camera._postProcesses.filter((pp) => { return pp != null; }));
+        postProcesses = (<Nullable<PostProcess[]>>postProcesses.filter((pp) => { return pp != null; }));
 
         if (postProcesses) {
             for (let i = 0; i < postProcesses.length; i++) {
@@ -435,7 +452,7 @@ export class PrePassRenderer {
         }
 
         this._markAllMaterialsAsPrePassDirty();
-        this._isDirty = false;
+        prePassRenderTarget._isDirty = false;
 
         if (enablePrePass) {
             this._enable(prePassRenderTarget);
@@ -454,8 +471,14 @@ export class PrePassRenderer {
      * Disposes the prepass renderer.
      */
     public dispose() {
-        for (let i = 0; i < this._renderTargets.length; i++) {
-            this._renderTargets[i].dispose();
+        for (let i = this.renderTargets.length - 1; i >= 0; i--) {
+
+            for (let j = 0; j < this.renderTargets[i]._effectConfigurations.length; j++) {
+                if (this.renderTargets[i]._effectConfigurations[j].dispose) {
+                    this.renderTargets[i]._effectConfigurations[j].dispose!();
+                }
+            }
+            this.renderTargets[i].dispose();
         }
     }
 

+ 5 - 5
src/Rendering/prePassRendererSceneComponent.ts

@@ -36,7 +36,7 @@ declare module "../abstractScene" {
 
 declare module "../Materials/Textures/renderTargetTexture" {
     export interface RenderTargetTexture {
-        prePassRenderTarget: PrePassRenderTarget;
+        _prePassRenderTarget: PrePassRenderTarget;
     }
 }
 
@@ -119,10 +119,11 @@ export class PrePassRendererSceneComponent implements ISceneComponent {
 
     private _beforeRenderTargetDraw(renderTarget: RenderTargetTexture) {
         if (this.scene.prePassRenderer) {
-            if (!renderTarget.prePassRenderTarget) {
-                renderTarget.prePassRenderTarget = this.scene.prePassRenderer._createRenderTarget();
+            if (!renderTarget._prePassRenderTarget) {
+                renderTarget._prePassRenderTarget = this.scene.prePassRenderer._createRenderTarget();
             }
-            this.scene.prePassRenderer._setRenderTarget(renderTarget.prePassRenderTarget);
+            this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);
+            this.scene.prePassRenderer._clear();
             this.scene.prePassRenderer._beforeDraw(null, renderTarget);
         }
     }
@@ -148,7 +149,6 @@ export class PrePassRendererSceneComponent implements ISceneComponent {
 
     private _beforeClearStage() {
         if (this.scene.prePassRenderer) {
-            // TODO choose the right rt
             this.scene.prePassRenderer._setRenderTarget(null)
             this.scene.prePassRenderer._clear();
         }

+ 3 - 1
src/scene.ts

@@ -896,7 +896,9 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
     /**
     * Flag indicating that the frame buffer binding is handled by another component
     */
-    public prePass: boolean = false;
+    public get prePass(): boolean {
+        return !!this.prePassRenderer && this.prePassRenderer.defaultRT.enabled;
+    }
 
     // Lights
     private _shadowsEnabled = true;