Przeglądaj źródła

variable indexes in PrePass

Benjamin Guignabert 5 lat temu
rodzic
commit
43ea9bc8c8

+ 6 - 1
src/Materials/PBR/pbrBaseMaterial.ts

@@ -164,6 +164,12 @@ export class PBRMaterialDefines extends MaterialDefines
     public THIN_INSTANCES = false;
 
     public PREPASS = false;
+    public PREPASS_IRRADIANCE = false;
+    public PREPASS_IRRADIANCE_INDEX = -1;
+    public PREPASS_ALBEDO = false;
+    public PREPASS_ALBEDO_INDEX = -1;
+    public PREPASS_DEPTHNORMAL = false;
+    public PREPASS_DEPTHNORMAL_INDEX = -1;
     public SCENE_MRT_COUNT = 0;
 
     public NUM_BONE_INFLUENCERS = 0;
@@ -2236,7 +2242,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             if (subSurfaceConfiguration) {
                 subSurfaceConfiguration.enabled = true;
             }
-            prePassRenderer.materialsShouldRenderIrradiance = true;
 
             return true;
         }

+ 17 - 2
src/Materials/Textures/multiRenderTarget.ts

@@ -176,10 +176,14 @@ export class MultiRenderTarget extends RenderTargetTexture {
     }
 
     /** @hidden */
-    public _rebuild(): void {
+    public _rebuild(forceFullRebuild: boolean = false): void {
         this.releaseInternalTextures();
         this._createInternalTextures();
 
+        if (forceFullRebuild) {
+            this._createTextures();
+        }
+
         for (var i = 0; i < this._internalTextures.length; i++) {
             var texture = this._textures[i];
             texture._texture = this._internalTextures[i];
@@ -226,7 +230,7 @@ export class MultiRenderTarget extends RenderTargetTexture {
 
     /**
      * Resize all the textures in the multi render target.
-     * Be carrefull as it will recreate all the data in the new texture.
+     * Be careful as it will recreate all the data in the new texture.
      * @param size Define the new size
      */
     public resize(size: any) {
@@ -234,6 +238,17 @@ export class MultiRenderTarget extends RenderTargetTexture {
         this._rebuild();
     }
 
+    /**
+     * Changes the number of render targets in this MRT
+     * Be careful as it will recreate all the data in the new texture.
+     * @param size Defines
+     */
+    public updateCount(count: number) {
+        this._multiRenderTargetOptions.textureCount = count;
+        this._count = count;
+        this._rebuild(true);
+    }
+
     protected unbindFrameBuffer(engine: Engine, faceIndex: number): void {
         engine.unBindMultiColorAttachmentFramebuffer(this._internalTextures, this.isCube, () => {
             this.onAfterRenderObservable.notifyObservers(faceIndex);

+ 19 - 2
src/Materials/materialHelper.ts

@@ -305,16 +305,33 @@ export class MaterialHelper {
     public static PrepareDefinesForPrePass(scene: Scene, defines: any, canRenderToMRT: boolean) {
         var previousPrePass = defines.PREPASS;
 
-        if (scene.prePassRenderer && canRenderToMRT) {
+        if (scene.prePassRenderer && scene.prePassRenderer.enabled && canRenderToMRT) {
             defines.PREPASS = true;
             defines.SCENE_MRT_COUNT = scene.prePassRenderer.mrtCount;
 
-            // TODO : the rest of textures
             const irradianceIndex = scene.prePassRenderer.getIndex(PrePassRenderer.IRRADIANCE_TEXTURE_TYPE);
             if (irradianceIndex !== -1) {
+                defines.PREPASS_IRRADIANCE = true;
                 defines.PREPASS_IRRADIANCE_INDEX = irradianceIndex;
+            } else {
+                defines.PREPASS_IRRADIANCE = false;
+            }
+
+            const albedoIndex = scene.prePassRenderer.getIndex(PrePassRenderer.ALBEDO_TEXTURE_TYPE);
+            if (albedoIndex !== -1) {
+                defines.PREPASS_ALBEDO = true;
+                defines.PREPASS_ALBEDO_INDEX = albedoIndex;
+            } else {
+                defines.PREPASS_ALBEDO = false;
             }
 
+            const depthNormalIndex = scene.prePassRenderer.getIndex(PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE);
+            if (depthNormalIndex !== -1) {
+                defines.PREPASS_DEPTHNORMAL = true;
+                defines.PREPASS_DEPTHNORMAL_INDEX = depthNormalIndex;
+            } else {
+                defines.PREPASS_DEPTHNORMAL = false;
+            }
         } else {
             defines.PREPASS = false;
         }

+ 6 - 0
src/Materials/standardMaterial.ts

@@ -126,6 +126,12 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public ALPHABLEND = true;
 
     public PREPASS = false;
+    public PREPASS_IRRADIANCE = false;
+    public PREPASS_IRRADIANCE_INDEX = -1;
+    public PREPASS_ALBEDO = false;
+    public PREPASS_ALBEDO_INDEX = -1;
+    public PREPASS_DEPTHNORMAL = false;
+    public PREPASS_DEPTHNORMAL_INDEX = -1;
     public SCENE_MRT_COUNT = 0;
 
     public RGBDLIGHTMAP = false;

+ 15 - 7
src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts

@@ -12,15 +12,14 @@ import { PassPostProcess } from "../../../PostProcesses/passPostProcess";
 import { Scene } from "../../../scene";
 import { _TypeStore } from '../../../Misc/typeStore';
 import { EngineStore } from '../../../Engines/engineStore';
-import { Constants } from "../../../Engines/constants";
+import { SSAO2Configuration } from "../../../Rendering/ssao2Configuration";
+import { PrePassRenderer } from "../../../Rendering/prePassRenderer";
 
 import "../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent";
 
 import "../../../Shaders/ssao2.fragment";
 import "../../../Shaders/ssaoCombine.fragment";
 
-declare type PrePassRenderer = import("../../../Rendering/prePassRenderer").PrePassRenderer;
-
 /**
  * Render pipeline to produce ssao effect
  */
@@ -119,6 +118,8 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
     */
     private _sampleSphere: number[];
 
+    private _ssao2PrePassConfiguration: SSAO2Configuration;
+
     /**
     * Blur filter offsets
     */
@@ -267,6 +268,7 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
         }
 
         this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
+        this._ssao2PrePassConfiguration.enabled = false;
 
         super.dispose();
     }
@@ -293,7 +295,7 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
             if (this._forceGeometryBuffer) {
                 effect.setTexture("depthNormalSampler", this._scene.enableGeometryBufferRenderer()!.getGBuffer().textures[0]);
             } else {
-                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[Constants.PREPASS_DEPTHNORMAL_INDEX]);
+                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[this._prePassRenderer.getIndex(PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE)]);
             }
             effect.setArray("samplerOffsets", this._samplerOffsets);
         };
@@ -311,7 +313,7 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
             if (this._forceGeometryBuffer) {
                 effect.setTexture("depthNormalSampler", this._scene.enableGeometryBufferRenderer()!.getGBuffer().textures[0]);
             } else {
-                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[Constants.PREPASS_DEPTHNORMAL_INDEX]);
+                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[this._prePassRenderer.getIndex(PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE)]);
             }
             effect.setArray("samplerOffsets", this._samplerOffsets);
 
@@ -429,7 +431,7 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
                 effect.setTexture("depthSampler", this._scene.enableGeometryBufferRenderer()!.getGBuffer().textures[0]);
                 effect.setTexture("normalSampler", this._scene.enableGeometryBufferRenderer()!.getGBuffer().textures[1]);
             } else {
-                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[Constants.PREPASS_DEPTHNORMAL_INDEX]);
+                effect.setTexture("depthNormalSampler", this._prePassRenderer.prePassRT.textures[this._prePassRenderer.getIndex(PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE)]);
             }
             effect.setTexture("randomSampler", this._randomTexture);
         };
@@ -512,7 +514,13 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
      * @returns true if the pre pass is needed.
      */
     public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {
-        prePassRenderer.materialsShouldRenderGeometry = prePassRenderer.materialsShouldRenderGeometry || true;
+        let cfg = this._ssao2PrePassConfiguration;
+        if (!cfg) {
+            cfg = new SSAO2Configuration();
+        }
+
+        cfg.enabled = true;
+        this._ssao2PrePassConfiguration = prePassRenderer.addEffectConfiguration(cfg);
         return true;
     }
 }

+ 4 - 3
src/PostProcesses/subSurfaceScatteringPostProcess.ts

@@ -6,6 +6,7 @@ import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Engine } from "../Engines/engine";
 import { Scene } from "../scene";
 import { Constants } from "../Engines/constants";
+import { PrePassRenderer } from "../Rendering/prePassRenderer";
 import { Logger } from "../Misc/logger";
 
 import "../Shaders/imageProcessing.fragment";
@@ -35,9 +36,9 @@ export class SubSurfaceScatteringPostProcess extends PostProcess {
             var texelSize = this.texelSize;
             effect.setFloat("metersPerUnit", scene.subSurfaceConfiguration.metersPerUnit);
             effect.setFloat2("texelSize", texelSize.x, texelSize.y);
-            effect.setTexture("irradianceSampler", scene.prePassRenderer.prePassRT.textures[1]);
-            effect.setTexture("depthSampler", scene.prePassRenderer.prePassRT.textures[2]);
-            effect.setTexture("albedoSampler", scene.prePassRenderer.prePassRT.textures[3]);
+            effect.setTexture("irradianceSampler", scene.prePassRenderer.prePassRT.textures[scene.prePassRenderer.getIndex(PrePassRenderer.IRRADIANCE_TEXTURE_TYPE)]);
+            effect.setTexture("depthSampler", scene.prePassRenderer.prePassRT.textures[scene.prePassRenderer.getIndex(PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE)]);
+            effect.setTexture("albedoSampler", scene.prePassRenderer.prePassRT.textures[scene.prePassRenderer.getIndex(PrePassRenderer.ALBEDO_TEXTURE_TYPE)]);
             effect.setFloat2("viewportSize",
                 Math.tan(scene.activeCamera!.fov / 2) * scene.getEngine().getAspectRatio(scene.activeCamera!, true),
                 Math.tan(scene.activeCamera!.fov / 2));

+ 2 - 2
src/Rendering/prePassEffectConfiguration.ts

@@ -11,7 +11,7 @@ export interface PrePassEffectConfiguration {
     /**
      * Post process to attach for this effect
      */
-    postProcess: PostProcess;
+    postProcess?: PostProcess;
     /**
      * Textures required in the MRT
      */
@@ -27,5 +27,5 @@ export interface PrePassEffectConfiguration {
     /**
      * Creates the associated post process
      */
-    createPostProcess: () => PostProcess;
+    createPostProcess?: () => PostProcess;
 }

+ 27 - 12
src/Rendering/prePassRenderer.ts

@@ -170,6 +170,8 @@ export class PrePassRenderer {
         this._engine = scene.getEngine();
 
         PrePassRenderer._SceneComponentInitialization(this._scene);
+
+        this._resetLayout();
     }
 
     private _initializeAttachments() {
@@ -194,8 +196,6 @@ export class PrePassRenderer {
             { generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: this._mrtFormats });
         this.prePassRT.samples = 1;
 
-        this._initializeAttachments();
-
         this.imageProcessingPostProcess = new ImageProcessingPostProcess("sceneCompositionPass", 1, null, undefined, this._engine);
         this.imageProcessingPostProcess.autoClear = false;
     }
@@ -310,15 +310,16 @@ export class PrePassRenderer {
     /**
      * Adds an effect configuration
      */
-    public addEffectConfiguration(cfg: PrePassEffectConfiguration) {
+    public addEffectConfiguration(cfg: PrePassEffectConfiguration) : PrePassEffectConfiguration {
         // Do not add twice
         for (let i = 0; i < this._effectConfigurations.length; i++) {
             if (this._effectConfigurations[i].name === cfg.name) {
-                return;
+                return this._effectConfigurations[i];
             }
         }
 
         this._effectConfigurations.push(cfg);
+        return cfg;
     }
 
     /**
@@ -335,19 +336,34 @@ export class PrePassRenderer {
     }
 
     private _enable() {
+        const previousMrtCount = this.mrtCount;
+
+        for (let i = 0; i < this._effectConfigurations.length; i++) {
+            if (this._effectConfigurations[i].enabled) {
+                this._enableTextures(this._effectConfigurations[i].texturesRequired);
+            }
+        }
+
+        if (this.prePassRT && this.mrtCount !== previousMrtCount) {
+            this.prePassRT.updateCount(this.mrtCount);
+        }
+
         this._resetPostProcessChain();
 
         for (let i = 0; i < this._effectConfigurations.length; i++) {
             if (this._effectConfigurations[i].enabled) {
-                if (!this._effectConfigurations[i].postProcess) {
-                    this._effectConfigurations[i].createPostProcess();
-                    this._enableTextures(this._effectConfigurations[i].texturesRequired);
+                if (!this._effectConfigurations[i].postProcess && this._effectConfigurations[i].createPostProcess) {
+                    this._effectConfigurations[i].createPostProcess!();
                 }
 
-                this._postProcesses.push(this._effectConfigurations[i].postProcess);
+                if (this._effectConfigurations[i].postProcess) {
+                    this._postProcesses.push(this._effectConfigurations[i].postProcess!);
+                }
             }
         }
 
+        this._initializeAttachments();
+
         if (!this.imageProcessingPostProcess) {
             this._createCompositionEffect();
         }
@@ -364,9 +380,6 @@ export class PrePassRenderer {
         for (let i = 0; i < this._effectConfigurations.length; i++) {
             this._effectConfigurations[i].enabled = false;
         }
-
-        this.materialsShouldRenderGeometry = false;
-        this.materialsShouldRenderIrradiance = false;
     }
 
     private _resetLayout() {
@@ -388,7 +401,7 @@ export class PrePassRenderer {
 
         for (let i = 0; i < this._effectConfigurations.length; i++) {
             if (this._effectConfigurations[i].postProcess) {
-                this._effectConfigurations[i].postProcess.restoreDefaultInputTexture();
+                this._effectConfigurations[i].postProcess!.restoreDefaultInputTexture();
             }
         }
     }
@@ -447,6 +460,8 @@ export class PrePassRenderer {
             this._enable();
         }
 
+
+
         if (!this.enabled) {
             this._engine.bindAttachments(this._defaultAttachments);
         }

+ 2 - 2
src/Rendering/subSurfaceConfiguration.ts

@@ -75,10 +75,10 @@ export class SubSurfaceConfiguration implements PrePassEffectConfiguration {
      * Textures that should be present in the MRT for this effect to work
      */
     public readonly texturesRequired: number[] = [
-        PrePassRenderer.COLOR_TEXTURE_TYPE,
-        PrePassRenderer.IRRADIANCE_TEXTURE_TYPE,
         PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE,
         PrePassRenderer.ALBEDO_TEXTURE_TYPE,
+        PrePassRenderer.COLOR_TEXTURE_TYPE,
+        PrePassRenderer.IRRADIANCE_TEXTURE_TYPE,
     ];
 
     private _scene: Scene;

+ 13 - 4
src/Shaders/default.fragment.fx

@@ -481,10 +481,19 @@ color.rgb = max(color.rgb, 0.);
 
 #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
 #ifdef PREPASS
-    gl_FragData[0] = color; // Lit without irradiance
-    gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0); // Irradiance
-    gl_FragData[2] = vec4(vViewPos.z, (view * vec4(normalW, 0.0)).rgb); // Linear depth + normal
-    gl_FragData[3] = vec4(0.0, 0.0, 0.0, 1.0); // albedo, for pre and post scatter
+    gl_FragData[0] = color; // We can't split irradiance on std material
+
+    #ifdef PREPASS_IRRADIANCE
+        gl_FragData[PREPASS_IRRADIANCE_INDEX] = vec4(0.0, 0.0, 0.0, 1.0); //  We can't split irradiance on std material
+    #endif
+
+    #ifdef PREPASS_DEPTHNORMAL
+    	gl_FragData[PREPASS_DEPTHNORMAL_INDEX] = vec4(vViewPos.z, (view * vec4(normalW, 0.0)).rgb); // Linear depth + normal
+    #endif
+
+    #ifdef PREPASS_ALBEDO
+        gl_FragData[PREPASS_ALBEDO_INDEX] = vec4(0.0, 0.0, 0.0, 1.0); // We can't split albedo on std material
+    #endif
 #endif
 	gl_FragColor = color;
 

+ 18 - 15
src/Shaders/pbr.fragment.fx

@@ -502,26 +502,29 @@ void main(void) {
     #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
 
 #ifdef PREPASS
-    vec3 irradiance = finalDiffuse;
-    #ifndef UNLIT
-        #ifdef REFLECTION
-            irradiance += finalIrradiance;
+    #ifdef PREPASS_IRRADIANCE
+        vec3 irradiance = finalDiffuse;
+        #ifndef UNLIT
+            #ifdef REFLECTION
+                irradiance += finalIrradiance;
+            #endif
         #endif
+
+        vec3 sqAlbedo = sqrt(surfaceAlbedo); // for pre and post scatter
+        gl_FragData[0] = vec4(finalColor.rgb - irradiance, finalColor.a); // Split irradiance from final color
+        irradiance /= sqAlbedo;
+        gl_FragData[PREPASS_IRRADIANCE_INDEX] = vec4(tagLightingForSSS(irradiance), scatteringDiffusionProfile / 255.); // Irradiance + SS diffusion profile
+    #else
+        gl_FragData[0] = vec4(finalColor.rgb, finalColor.a);
     #endif
 
-    vec3 sqAlbedo = sqrt(surfaceAlbedo); // for pre and post scatter
+    #ifdef PREPASS_DEPTHNORMAL
+        gl_FragData[PREPASS_DEPTHNORMAL_INDEX] = vec4(vViewPos.z, (view * vec4(normalW, 0.0)).rgb); // Linear depth + normal
+    #endif
 
-    // Irradiance is diffuse * surfaceAlbedo
-    #ifdef SS_SCATTERING
-    gl_FragData[0] = vec4(finalColor.rgb - irradiance, finalColor.a); // Lit without irradiance
-    irradiance /= sqAlbedo;
-    gl_FragData[1] = vec4(tagLightingForSSS(irradiance), scatteringDiffusionProfile / 255.); // Irradiance + SS diffusion profile
-    #else
-    gl_FragData[0] = vec4(finalColor.rgb, finalColor.a); // Lit without irradiance
-    gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0); // Irradiance
+    #ifdef PREPASS_ALBEDO
+        gl_FragData[PREPASS_ALBEDO_INDEX] = vec4(sqAlbedo, 1.0); // albedo, for pre and post scatter
     #endif
-    gl_FragData[2] = vec4(vViewPos.z, (view * vec4(normalW, 0.0)).rgb); // Linear depth + normal
-    gl_FragData[3] = vec4(sqAlbedo, 1.0); // albedo, for pre and post scatter
 #endif
 
     gl_FragColor = finalColor;