浏览代码

prepass in render target OK

Benjamin Guignabert 4 年之前
父节点
当前提交
dc9d804bf0

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

@@ -847,6 +847,15 @@ export class RenderTargetTexture extends Texture {
         });
     }
 
+    public _prepareFrame(scene: Scene, faceIndex?: number, layer?: number, useCameraPostProcess?: boolean) {
+        if (this._postProcessManager) {
+            this._postProcessManager._prepareFrame(this._texture, this._postProcesses);
+        }
+        else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
+            this._bindFrameBuffer(faceIndex, layer);
+        }
+    }
+
     private renderToTarget(faceIndex: number, useCameraPostProcess: boolean, dumpForDebug: boolean, layer = 0, camera: Nullable<Camera> = null): void {
         var scene = this.getScene();
 
@@ -862,12 +871,7 @@ export class RenderTargetTexture extends Texture {
 
         // Bind
         if (!this._prePass) {
-            if (this._postProcessManager) {
-                this._postProcessManager._prepareFrame(this._texture, this._postProcesses);
-            }
-            else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
-                this._bindFrameBuffer(faceIndex, layer);
-            }
+            this._prepareFrame(scene, faceIndex, layer, useCameraPostProcess);
         }
 
         if (this.is2DArray) {
@@ -914,7 +918,7 @@ export class RenderTargetTexture extends Texture {
 
         // Before Camera Draw
         for (let step of scene._beforeRenderTargetDrawStage) {
-            step.action(this);
+            step.action(this, faceIndex, layer);
         }
 
         // Render
@@ -922,7 +926,7 @@ export class RenderTargetTexture extends Texture {
 
         // After Camera Draw
         for (let step of scene._afterRenderTargetDrawStage) {
-            step.action(this);
+            step.action(this, faceIndex, layer);
         }
 
         if (this._postProcessManager) {

+ 4 - 2
src/PostProcesses/postProcess.ts

@@ -303,8 +303,10 @@ export class PostProcess {
     * the only way to unset it is to use this function to restore its internal state
     */
     public restoreDefaultInputTexture() {
-        this._forcedOutputTexture = null;
-        this.markTextureDirty();
+        if (this._forcedOutputTexture) {
+            this._forcedOutputTexture = null;
+            this.markTextureDirty();
+        }
     }
 
     /**

+ 59 - 41
src/Rendering/prePassRenderer.ts

@@ -178,6 +178,7 @@ export class PrePassRenderer {
     private _enabled: boolean = false;
 
     private _needsCompositionForThisPass = false;
+    private _postProcessesSourceForThisPass: Nullable<PostProcess>[];
 
     /**
      * Indicates if the prepass is enabled
@@ -331,20 +332,17 @@ export class PrePassRenderer {
     /**
      * @hidden
      */
-    public _beforeDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
-        let postProcesses = undefined;
-        if (texture) {
-            postProcesses = texture.postProcesses || texture.activeCamera?._postProcesses || [];
-        }
-
+    public _beforeDraw(camera?: Camera, faceIndex?: number, layer?: number) {
         if (this._isDirty) {
             this._update();
         }
 
+        const texture = this._currentTarget.renderTargetTexture;
+
         if (!this._enabled || !this._currentTarget.enabled) {
             // Prepass disabled, we render only on 1 color attachment
             if (texture) {
-                texture._bindFrameBuffer();
+                texture._prepareFrame(this._scene, faceIndex, layer, texture.useCameraPostProcesses);
                 this._engine.restoreSingleAttachmentForRenderTarget();
             } else {
                 this._engine.restoreDefaultFramebuffer();
@@ -359,41 +357,45 @@ export class PrePassRenderer {
             this._geometryBuffer.renderList!.length = 0;
         }
 
-        this._setupOutputForThisPass(this._currentTarget, camera, postProcesses);
+        this._setupOutputForThisPass(this._currentTarget, camera);
     }
 
-    /**
-     * @hidden
-     */
-    public _afterDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
-        if (this._enabled && this._currentTarget.enabled) {
+    private _prepareFrame(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number, layer?: number) {
+        if (prePassRenderTarget.renderTargetTexture) {
+            prePassRenderTarget.renderTargetTexture._prepareFrame(this._scene, faceIndex, layer, prePassRenderTarget.renderTargetTexture.useCameraPostProcesses);
+        } else if (this._postProcessesSourceForThisPass.length) {
             this._scene.postProcessManager._prepareFrame();
-            const firstCameraPP = camera && camera._getFirstPostProcess();
-            let outputTexture = firstCameraPP ? firstCameraPP.inputTexture : (texture ? texture.getInternalTexture() : null);
+        } else {
+            this._engine.restoreDefaultFramebuffer();
+        }
+    }
 
-            // Build post process chain for this prepass post draw
-            let postProcessChain = this._currentTarget._beforeCompositionPostProcesses;
+    private _renderPostProcesses(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number) {
+        const firstPP = this._postProcessesSourceForThisPass[0];
+        let outputTexture = firstPP ? firstPP.inputTexture : (prePassRenderTarget.renderTargetTexture ? prePassRenderTarget.renderTargetTexture.getInternalTexture() : null);
 
-            // For now we do not support effect configuration post processes in render targets
-            if (this._currentTarget !== this.defaultRT) {
-                postProcessChain = [];
-            }
+        // Build post process chain for this prepass post draw
+        let postProcessChain = this._currentTarget._beforeCompositionPostProcesses;
 
-            if (this._needsCompositionForThisPass) {
-                postProcessChain = postProcessChain.concat([this._currentTarget.imageProcessingPostProcess]);
-            }
+        if (this._needsCompositionForThisPass) {
+            postProcessChain = postProcessChain.concat([this._currentTarget.imageProcessingPostProcess]);
+        }
 
-            // Activates the chain
-            if (postProcessChain.length) {
-                this._scene.postProcessManager._prepareFrame(this._currentTarget.getInternalTexture()!, postProcessChain);
-            }
+        // Activates and renders the chain
+        if (postProcessChain.length) {
+            this._scene.postProcessManager._prepareFrame(this._currentTarget.getInternalTexture()!, postProcessChain);
+            this._scene.postProcessManager.directRender(postProcessChain, outputTexture, false, faceIndex);
+        }
 
-            // Renders the post process chain
-            this._scene.postProcessManager.directRender(postProcessChain, outputTexture);
+    }
 
-            if (!outputTexture) {
-                this._engine.restoreDefaultFramebuffer();
-            }
+    /**
+     * @hidden
+     */
+    public _afterDraw(faceIndex?: number, layer?: number) {
+        if (this._enabled && this._currentTarget.enabled) {
+            this._prepareFrame(this._currentTarget, faceIndex, layer);
+            this._renderPostProcesses(this._currentTarget, faceIndex);
         }
     }
 
@@ -523,26 +525,42 @@ export class PrePassRenderer {
     //         }
     //     }
     // }
+    private _getPostProcessesSource(prePassRenderTarget: PrePassRenderTarget, camera?: Camera) : Nullable<PostProcess>[] {
+        if (camera) {
+            return camera._postProcesses;
+        } else if (prePassRenderTarget.renderTargetTexture) {
+            if (prePassRenderTarget.renderTargetTexture.useCameraPostProcesses) {
+                const camera = prePassRenderTarget.renderTargetTexture.activeCamera ? prePassRenderTarget.renderTargetTexture.activeCamera : this._scene.activeCamera;
+                return camera ? camera._postProcesses : [];
+            } else if (prePassRenderTarget.renderTargetTexture.postProcesses) {
+                return prePassRenderTarget.renderTargetTexture.postProcesses;
+            } else {
+                return [];
+            }
+        } else {
+            return this._scene.activeCamera ? this._scene.activeCamera._postProcesses : [];
+        }
+    }
 
-    private _setupOutputForThisPass(prePassRenderTarget: PrePassRenderTarget, camera: Nullable<Camera>, postProcesses: Nullable<PostProcess>[] = []) {
-        // Here we search for an image composition post process
-        // If no ipp if found, we use the prepass built-in
-        // We also set the framebuffer to the input texture of the first post process that is to come
+    private _setupOutputForThisPass(prePassRenderTarget: PrePassRenderTarget, camera?: Camera) {
         // Order is : draw ===> prePassRenderTarget._postProcesses ==> ipp ==> camera._postProcesses
         const secondaryCamera = camera && this._scene.activeCameras && !!this._scene.activeCameras.length && this._scene.activeCameras.indexOf(camera) !== 0;
-        const postProcessesSource = camera ? camera._postProcesses : postProcesses;
-        this._needsCompositionForThisPass = !this._hasImageProcessing(postProcessesSource) &&
+        this._postProcessesSourceForThisPass = this._getPostProcessesSource(prePassRenderTarget, camera);
+        this._postProcessesSourceForThisPass = (this._postProcessesSourceForThisPass.filter((pp) => { return pp != null; }));
+
+        this._needsCompositionForThisPass = !this._hasImageProcessing(this._postProcessesSourceForThisPass) &&
             !this.disableGammaTransform &&
             !secondaryCamera;
-        const firstCameraPP = this._getFirstPostProcess(postProcessesSource);
+
+        const firstCameraPP = this._getFirstPostProcess(this._postProcessesSourceForThisPass);
         const firstPrePassPP = prePassRenderTarget._beforeCompositionPostProcesses && prePassRenderTarget._beforeCompositionPostProcesses[0];
         let firstPP = null;
 
-        prePassRenderTarget.imageProcessingPostProcess.restoreDefaultInputTexture();
 
         // Setting the prePassRenderTarget as input texture of the first PP
         if (firstPrePassPP) {
             firstPrePassPP.inputTexture = prePassRenderTarget.getInternalTexture()!;
+            prePassRenderTarget.imageProcessingPostProcess.restoreDefaultInputTexture();
             firstPP = firstPrePassPP;
         } else if (this._needsCompositionForThisPass) {
             prePassRenderTarget.imageProcessingPostProcess.inputTexture = prePassRenderTarget.getInternalTexture()!;

+ 7 - 7
src/Rendering/prePassRendererSceneComponent.ts

@@ -117,39 +117,39 @@ export class PrePassRendererSceneComponent implements ISceneComponent {
         this.scene._afterRenderingMeshStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGMESH_PREPASS, this, this._afterRenderingMeshStage);
     }
 
-    private _beforeRenderTargetDraw(renderTarget: RenderTargetTexture) {
+    private _beforeRenderTargetDraw(renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) {
         if (this.scene.prePassRenderer) {
             if (!renderTarget._prePassRenderTarget) {
                 renderTarget._prePassRenderTarget = this.scene.prePassRenderer._createRenderTarget(renderTarget.name + "_prePassRTT", renderTarget);
             }
             this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);
             this.scene.prePassRenderer._clear();
-            this.scene.prePassRenderer._beforeDraw(null, renderTarget);
+            this.scene.prePassRenderer._beforeDraw(undefined, faceIndex, layer);
         }
     }
 
-    private _afterRenderTargetDraw(renderTarget: RenderTargetTexture) {
+    private _afterRenderTargetDraw(renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) {
         if (this.scene.prePassRenderer) {
-            this.scene.prePassRenderer._afterDraw(null, renderTarget);
+            this.scene.prePassRenderer._afterDraw(faceIndex, layer);
         }
     }
 
     private _beforeCameraDraw(camera: Camera) {
         if (this.scene.prePassRenderer) {
             this.scene.prePassRenderer._setRenderTarget(null);
-            this.scene.prePassRenderer._beforeDraw(camera, null);
+            this.scene.prePassRenderer._beforeDraw(camera);
         }
     }
 
     private _afterCameraDraw(camera: Camera) {
         if (this.scene.prePassRenderer) {
-            this.scene.prePassRenderer._afterDraw(camera, null);
+            this.scene.prePassRenderer._afterDraw();
         }
     }
 
     private _beforeClearStage() {
         if (this.scene.prePassRenderer) {
-            this.scene.prePassRenderer._setRenderTarget(null)
+            this.scene.prePassRenderer._setRenderTarget(null);
             this.scene.prePassRenderer._clear();
         }
     }

+ 1 - 1
src/sceneComponent.ts

@@ -181,7 +181,7 @@ export type CameraStageFrameBufferAction = (camera: Camera) => boolean;
 /**
  * Strong typing of a Render Target related stage step action
  */
-export type RenderTargetStageAction = (renderTarget: RenderTargetTexture) => void;
+export type RenderTargetStageAction = (renderTarget: RenderTargetTexture, faceIndex?: number, layer?: number) => void;
 
 /**
  * Strong typing of a RenderingGroup related stage step action