Browse Source

Proposed PrePass changes (#8551)

sebavan 5 years ago
parent
commit
dcbcb73ea1

+ 20 - 9
src/Materials/PBR/pbrBaseMaterial.ts

@@ -42,6 +42,8 @@ import "../../Shaders/pbr.vertex";
 import { EffectFallbacks } from '../effectFallbacks';
 import { IMaterialDetailMapDefines, DetailMapConfiguration } from '../material.detailMapConfiguration';
 
+declare type PrePassRenderer = import("../../Rendering/prePassRenderer").PrePassRenderer;
+
 const onCreatedEffectParameters = { effect: null as unknown as Effect, subMesh: null as unknown as Nullable<SubMesh> };
 
 /**
@@ -676,14 +678,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     }
 
     /**
-     * Should this material render to several textures at once
+     * Can this material render to several textures at once
      */
-    public get shouldRenderToMRT() {
-        const ppr = this.getScene().prePassRenderer;
-
-        return (!!ppr &&
-            (ppr.materialsShouldRenderGeometry ||
-            ppr.materialsShouldRenderIrradiance));
+    public get canRenderToMRT() {
+        return true;
     }
 
     /**
@@ -1308,7 +1306,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             onError: onError,
             indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS },
             processFinalCode: csnrOptions.processFinalCode,
-            multiTarget: this.shouldRenderToMRT
+            multiTarget: defines.PREPASS
         }, engine);
     }
 
@@ -1324,7 +1322,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         MaterialHelper.PrepareDefinesForMultiview(scene, defines);
 
         // PrePass
-        MaterialHelper.PrepareDefinesForPrePass(scene, defines, this.shouldRenderToMRT);
+        MaterialHelper.PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT);
 
         // Textures
         defines.METALLICWORKFLOW = this.isMetallicWorkflow();
@@ -2229,6 +2227,19 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     }
 
     /**
+     * Sets the required values to the prepass renderer.
+     * @param prePassRenderer defines the prepass renderer to setup
+     */
+    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
+        if (this.subSurface.isScatteringEnabled) {
+            prePassRenderer.subSurfaceConfiguration.enabled = true;
+            prePassRenderer.materialsShouldRenderIrradiance = true;
+        }
+
+        return true;
+    }
+
+    /**
      * Disposes the resources of the material.
      * @param forceDisposeEffect - Forces the disposal of effects.
      * @param forceDisposeTextures - Forces the disposal of all textures.

+ 13 - 2
src/Materials/material.ts

@@ -21,6 +21,7 @@ import { IInspectable } from '../Misc/iInspectable';
 import { Plane } from '../Maths/math.plane';
 import { ShadowDepthWrapper } from './shadowDepthWrapper';
 
+declare type PrePassRenderer = import("../Rendering/prePassRenderer").PrePassRenderer;
 declare type Mesh = import("../Meshes/mesh").Mesh;
 declare type Animation = import("../Animations/animation").Animation;
 declare type InstancedMesh = import('../Meshes/instancedMesh').InstancedMesh;
@@ -230,9 +231,9 @@ export class Material implements IAnimatable {
     public state = "";
 
     /**
-     * If the material should be rendered to several textures with MRT extension
+     * If the material can be rendered to several textures with MRT extension
      */
-    public get shouldRenderToMRT() : boolean {
+    public get canRenderToMRT() : boolean {
         // By default, shaders are not compatible with MRTs
         // Base classes should override that if their shader supports MRT
         return false;
@@ -1319,6 +1320,16 @@ export class Material implements IAnimatable {
     }
 
     /**
+     * Sets the required values to the prepass renderer.
+     * @param prePassRenderer defines the prepass renderer to setup.
+     * @returns true if the pre pass is needed.
+     */
+    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
+        // Do Nothing by default
+        return false;
+    }
+
+    /**
      * Disposes the material
      * @param forceDisposeEffect specifies if effects should be forcefully disposed
      * @param forceDisposeTextures specifies if textures should be forcefully disposed

+ 3 - 3
src/Materials/materialHelper.ts

@@ -299,12 +299,12 @@ export class MaterialHelper {
      * Prepares the defines related to the prepass
      * @param scene The scene we are intending to draw
      * @param defines The defines to update
-     * @param shouldRenderToMRT Indicates if this material renders to several textures in the prepass
+     * @param canRenderToMRT Indicates if this material renders to several textures in the prepass
      */
-    public static PrepareDefinesForPrePass(scene: Scene, defines: any, shouldRenderToMRT: boolean) {
+    public static PrepareDefinesForPrePass(scene: Scene, defines: any, canRenderToMRT: boolean) {
         var previousPrePass = defines.PREPASS;
 
-        if (scene.prePassRenderer && shouldRenderToMRT) {
+        if (scene.prePassRenderer && canRenderToMRT) {
             defines.PREPASS = true;
             defines.SCENE_MRT_COUNT = scene.prePassRenderer.mrtCount;
         } else {

+ 5 - 6
src/Materials/standardMaterial.ts

@@ -677,11 +677,10 @@ export class StandardMaterial extends PushMaterial {
     }
 
     /**
-     * Should this material render to several textures at once
+     * Can this material render to several textures at once
      */
-    public get shouldRenderToMRT() {
-        const ppr = this.getScene().prePassRenderer;
-        return (!!ppr && ppr.materialsShouldRenderGeometry);
+    public get canRenderToMRT() {
+        return true;
     }
 
     /**
@@ -834,7 +833,7 @@ export class StandardMaterial extends PushMaterial {
         MaterialHelper.PrepareDefinesForMultiview(scene, defines);
 
         // PrePass
-        MaterialHelper.PrepareDefinesForPrePass(scene, defines, this.shouldRenderToMRT);
+        MaterialHelper.PrepareDefinesForPrePass(scene, defines, this.canRenderToMRT);
 
         // Textures
         if (defines._areTexturesDirty) {
@@ -1218,7 +1217,7 @@ export class StandardMaterial extends PushMaterial {
                 onError: this.onError,
                 indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS },
                 processFinalCode: csnrOptions.processFinalCode,
-                multiTarget: this.shouldRenderToMRT
+                multiTarget: defines.PREPASS
             }, engine);
 
             if (effect) {

+ 12 - 1
src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts

@@ -9,7 +9,6 @@ import { PostProcess } from "../../../PostProcesses/postProcess";
 import { PostProcessRenderPipeline } from "../../../PostProcesses/RenderPipeline/postProcessRenderPipeline";
 import { PostProcessRenderEffect } from "../../../PostProcesses/RenderPipeline/postProcessRenderEffect";
 import { PassPostProcess } from "../../../PostProcesses/passPostProcess";
-import { PrePassRenderer } from "../../../Rendering/prePassRenderer";
 import { Scene } from "../../../scene";
 import { _TypeStore } from '../../../Misc/typeStore';
 import { EngineStore } from '../../../Engines/engineStore';
@@ -20,6 +19,8 @@ import "../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSc
 import "../../../Shaders/ssao2.fragment";
 import "../../../Shaders/ssaoCombine.fragment";
 
+declare type PrePassRenderer = import("../../../Rendering/prePassRenderer").PrePassRenderer;
+
 /**
  * Render pipeline to produce ssao effect
  */
@@ -504,6 +505,16 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
     public static Parse(source: any, scene: Scene, rootUrl: string): SSAO2RenderingPipeline {
         return SerializationHelper.Parse(() => new SSAO2RenderingPipeline(source._name, scene, source._ratio), source, scene, rootUrl);
     }
+
+    /**
+     * Sets the required values to the prepass renderer.
+     * @param prePassRenderer defines the prepass renderer to setup
+     * @returns true if the pre pass is needed.
+     */
+    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
+        prePassRenderer.materialsShouldRenderGeometry = prePassRenderer.materialsShouldRenderGeometry || true;
+        return true;
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.SSAO2RenderingPipeline"] = SSAO2RenderingPipeline;

+ 13 - 0
src/PostProcesses/RenderPipeline/postProcessRenderPipeline.ts

@@ -5,6 +5,9 @@ import { Camera } from "../../Cameras/camera";
 import { Engine } from "../../Engines/engine";
 import { PostProcessRenderEffect } from "./postProcessRenderEffect";
 import { IInspectable } from '../../Misc/iInspectable';
+
+declare type PrePassRenderer = import("../../Rendering/prePassRenderer").PrePassRenderer;
+
 /**
  * PostProcessRenderPipeline
  * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
@@ -228,6 +231,16 @@ export class PostProcessRenderPipeline {
     }
 
     /**
+     * Sets the required values to the prepass renderer.
+     * @param prePassRenderer defines the prepass renderer to setup.
+     * @returns true if the pre pass is needed.
+     */
+    public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
+        // Do Nothing by default
+        return false;
+    }
+
+    /**
      * Disposes of the pipeline
      */
     public dispose() {

+ 2 - 13
src/Rendering/prePassRenderer.ts

@@ -1,4 +1,3 @@
-import { PBRBaseMaterial } from "../Materials/PBR/pbrBaseMaterial";
 import { MultiRenderTarget } from "../Materials/Textures/multiRenderTarget";
 import { Scene } from "../scene";
 import { Engine } from "../Engines/engine";
@@ -9,7 +8,6 @@ import { Effect } from "../Materials/effect";
 import { _DevTools } from '../Misc/devTools';
 import { Color4 } from "../Maths/math.color";
 import { SubSurfaceConfiguration } from "./subSurfaceConfiguration";
-import { SSAO2RenderingPipeline } from "../PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline";
 
 /**
  * Renders a pre pass of the scene
@@ -287,24 +285,15 @@ export class PrePassRenderer {
 
         // Subsurface scattering
         for (let i = 0; i < this._scene.materials.length; i++) {
-            const material = this._scene.materials[i] as PBRBaseMaterial;
-
-            if (material.subSurface && material.subSurface.isScatteringEnabled) {
-                this.subSurfaceConfiguration.enabled = true;
-                this.materialsShouldRenderIrradiance = true;
+            if (this._scene.materials[i].setPrePassRenderer(this)) {
                 enablePrePass = true;
-
-                // 1 subsurface material is enough to activate post process
-                break;
             }
         }
 
         const pipelines = this._scene.postProcessRenderPipelineManager.supportedPipelines;
         for (let i = 0; i < pipelines.length; i++) {
-            if (pipelines[i] instanceof SSAO2RenderingPipeline) {
-                this.materialsShouldRenderGeometry = true;
+            if (pipelines[i].setPrePassRenderer(this)) {
                 enablePrePass = true;
-                break;
             }
         }