ソースを参照

reflectivity + plugging motion blur WIP

Benjamin Guignabert 5 年 前
コミット
ce966ba519

+ 74 - 0
src/Materials/PBR/pbrAdditionnalPrePassConfiguration.ts

@@ -0,0 +1,74 @@
+import { UniformBuffer } from "../../Materials/uniformBuffer";
+import { Matrix } from "../../Maths/math.vector";
+import { Scene } from "../../scene";
+import { PrePassRenderer } from "../../Rendering/prePassRenderer";
+
+export class PBRAdditionnalPrePassConfiguration {
+    public previousWorld: Matrix;
+    public previousViewProjection: Matrix;
+
+    constructor() {
+
+    }
+
+    /**
+     * Add the required uniforms to the current buffer.
+     * @param uniformBuffer defines the current uniform buffer.
+     */
+    public static PrepareUniformBuffer(uniformBuffer: UniformBuffer): void {
+        uniformBuffer.addUniform("previousWorld", 16);
+        uniformBuffer.addUniform("previousViewProjection", 16);
+    }
+
+    /**
+     * Add the required uniforms to the current list.
+     * @param uniforms defines the current uniform list.
+     */
+    public static AddUniforms(uniforms: string[]): void {
+        uniforms.push("previousWorld", "previousViewProjection");
+    }
+
+    /**
+     * Add the required samplers to the current list.
+     * @param samplers defines the current sampler list.
+     */
+    public static AddSamplers(samplers: string[]): void {
+        // pass
+    }
+
+    /**
+     * Binds the material data.
+     * @param uniformBuffer defines the Uniform buffer to fill in.
+     * @param scene defines the scene the material belongs to.
+     * @param engine defines the engine the material belongs to.
+     * @param isFrozen defines whether the material is frozen or not.
+     * @param lodBasedMicrosurface defines whether the material relies on lod based microsurface or not.
+     * @param realTimeFiltering defines whether the textures should be filtered on the fly.
+     */
+    public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, world: Matrix, isFrozen: boolean): void {
+
+        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
+            if (scene.prePassRenderer && scene.prePassRenderer.enabled) {
+                // TODO : cache for better performance
+                if (scene.prePassRenderer.getIndex(PrePassRenderer.VELOCITY_TEXTURE_TYPE) !== -1) {
+                    if (this.previousWorld) {
+                        uniformBuffer.updateMatrix("previousWorld", this.previousWorld);
+                        uniformBuffer.updateMatrix("previousViewProjection", this.previousViewProjection);
+                    }
+
+                    this.previousWorld = world.clone();
+                    this.previousViewProjection = scene.getTransformMatrix().clone();
+                }
+
+                // if (scene.prePassRenderer.getIndex(PrePassRenderer.REFLECTIVITY_TEXTURE_TYPE) !== -1) {
+                //     // Roughness
+                //     if (material instanceof PBRMaterial && material.reflectivityTexture) {
+                //         this._effect.setMatrix("reflectivityMatrix", material.reflectivityTexture.getTextureMatrix());
+                //         this._effect.setTexture("reflectivitySampler", material.reflectivityTexture);
+                //     }
+                // }
+            }
+        }
+
+    }
+}

+ 10 - 8
src/Materials/PBR/pbrBaseMaterial.ts

@@ -16,7 +16,7 @@ import { IMaterialAnisotropicDefines, PBRAnisotropicConfiguration } from "./pbrA
 import { IMaterialBRDFDefines, PBRBRDFConfiguration } from "./pbrBRDFConfiguration";
 import { IMaterialSheenDefines, PBRSheenConfiguration } from "./pbrSheenConfiguration";
 import { IMaterialSubSurfaceDefines, PBRSubSurfaceConfiguration } from "./pbrSubSurfaceConfiguration";
-import { PBRPrePassConfiguration } from "./pbrPrePassConfiguration";
+import { PBRAdditionnalPrePassConfiguration } from "./pbrAdditionnalPrePassConfiguration";
 import { Color3, TmpColors } from '../../Maths/math.color';
 import { Scalar } from "../../Maths/math.scalar";
 
@@ -175,6 +175,8 @@ export class PBRMaterialDefines extends MaterialDefines
     public PREPASS_POSITION_INDEX = -1;
     public PREPASS_VELOCITY = false;
     public PREPASS_VELOCITY_INDEX = -1;
+    public PREPASS_REFLECTIVITY = false;
+    public PREPASS_REFLECTIVITY_INDEX = -1;
     public SCENE_MRT_COUNT = 0;
 
     public NUM_BONE_INFLUENCERS = 0;
@@ -822,9 +824,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     public readonly subSurface: PBRSubSurfaceConfiguration;
 
     /**
-     * Defines the PrePass parameters for the material.
+     * Defines additionnal PrePass parameters for the material.
      */
-    public readonly prePass: PBRPrePassConfiguration;
+    public readonly additionnalPrePass: PBRAdditionnalPrePassConfiguration;
 
     /**
      * Defines the detail map parameters for the material.
@@ -859,7 +861,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
         this._environmentBRDFTexture = BRDFTextureTools.GetEnvironmentBRDFTexture(scene);
         this.subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this), this._markScenePrePassDirty.bind(this), scene);
-        this.prePass = new PBRPrePassConfiguration();
+        this.additionnalPrePass = new PBRAdditionnalPrePassConfiguration();
     }
 
     /**
@@ -1292,8 +1294,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.AddUniforms(uniforms);
         PBRSheenConfiguration.AddSamplers(samplers);
 
-        PBRPrePassConfiguration.AddUniforms(uniforms);
-        PBRPrePassConfiguration.AddSamplers(uniforms);
+        PBRAdditionnalPrePassConfiguration.AddUniforms(uniforms);
+        PBRAdditionnalPrePassConfiguration.AddSamplers(uniforms);
 
         if (ImageProcessingConfiguration) {
             ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
@@ -1707,7 +1709,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.PrepareUniformBuffer(ubo);
         PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
         DetailMapConfiguration.PrepareUniformBuffer(ubo);
-        PBRPrePassConfiguration.PrepareUniformBuffer(ubo);
+        PBRAdditionnalPrePassConfiguration.PrepareUniformBuffer(ubo);
 
         ubo.create();
     }
@@ -2017,7 +2019,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             this.clearCoat.bindForSubMesh(ubo, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
             this.anisotropy.bindForSubMesh(ubo, scene, this.isFrozen);
             this.sheen.bindForSubMesh(ubo, scene, this.isFrozen);
-            this.prePass.bindForSubMesh(ubo, scene, world, this.isFrozen);
+            this.additionnalPrePass.bindForSubMesh(ubo, scene, world, this.isFrozen);
 
             // Clip plane
             MaterialHelper.BindClipPlane(this._activeEffect, scene);

+ 18 - 8
src/Materials/PBR/pbrPrePassConfiguration.ts

@@ -3,7 +3,7 @@ import { Matrix } from "../../Maths/math.vector";
 import { Scene } from "../../scene";
 import { PrePassRenderer } from "../../Rendering/prePassRenderer";
 
-export class PBRPrePassConfiguration {
+export class PBRAdditionnalPrePassConfiguration {
     public previousWorld: Matrix;
     public previousViewProjection: Matrix;
 
@@ -48,15 +48,25 @@ export class PBRPrePassConfiguration {
     public bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, world: Matrix, isFrozen: boolean): void {
 
         if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
-            // TODO : cache for better performance
-            if (scene.prePassRenderer && scene.prePassRenderer.enabled && scene.prePassRenderer.getIndex(PrePassRenderer.VELOCITY_TEXTURE_TYPE) !== -1) {
-                if (this.previousWorld) {
-                    uniformBuffer.updateMatrix("previousWorld", this.previousWorld);
-                    uniformBuffer.updateMatrix("previousViewProjection", this.previousViewProjection);
+            if (scene.prePassRenderer && scene.prePassRenderer.enabled) {
+                // TODO : cache for better performance
+                if (scene.prePassRenderer.getIndex(PrePassRenderer.VELOCITY_TEXTURE_TYPE) !== -1) {
+                    if (this.previousWorld) {
+                        uniformBuffer.updateMatrix("previousWorld", this.previousWorld);
+                        uniformBuffer.updateMatrix("previousViewProjection", this.previousViewProjection);
+                    }
+
+                    this.previousWorld = world.clone();
+                    this.previousViewProjection = scene.getTransformMatrix().clone();
                 }
 
-                this.previousWorld = world.clone();
-                this.previousViewProjection = scene.getTransformMatrix().clone();
+                // if (scene.prePassRenderer.getIndex(PrePassRenderer.REFLECTIVITY_TEXTURE_TYPE) !== -1) {
+                //     // Roughness
+                //     if (material instanceof PBRMaterial && material.reflectivityTexture) {
+                //         this._effect.setMatrix("reflectivityMatrix", material.reflectivityTexture.getTextureMatrix());
+                //         this._effect.setTexture("reflectivitySampler", material.reflectivityTexture);
+                //     }
+                // }
             }
         }
 

+ 40 - 38
src/Materials/materialHelper.ts

@@ -303,51 +303,53 @@ export class MaterialHelper {
      * @param canRenderToMRT Indicates if this material renders to several textures in the prepass
      */
     public static PrepareDefinesForPrePass(scene: Scene, defines: any, canRenderToMRT: boolean) {
-        var previousPrePass = defines.PREPASS;
+        const previousPrePass = defines.PREPASS;
+        const texturesList = [
+        {
+            type: PrePassRenderer.POSITION_TEXTURE_TYPE,
+            define: "PREPASS_POSITION",
+            index: "POSITION_TEXTURE_TYPE",
+        },
+        {
+            type: PrePassRenderer.VELOCITY_TEXTURE_TYPE,
+            define: "PREPASS_VELOCITY",
+            index: "PREPASS_VELOCITY_INDEX",
+        },
+        {
+            type: PrePassRenderer.REFLECTIVITY_TEXTURE_TYPE,
+            define: "PREPASS_REFLECTIVITY",
+            index: "PREPASS_REFLECTIVITY_INDEX",
+        },
+        {
+            type: PrePassRenderer.IRRADIANCE_TEXTURE_TYPE,
+            define: "PREPASS_IRRADIANCE",
+            index: "PREPASS_IRRADIANCE_INDEX",
+        },
+        {
+            type: PrePassRenderer.ALBEDO_TEXTURE_TYPE,
+            define: "PREPASS_ALBEDO",
+            index: "PREPASS_ALBEDO_INDEX",
+        },
+        {
+            type: PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE,
+            define: "PREPASS_DEPTHNORMAL",
+            index: "PREPASS_DEPTHNORMAL_INDEX",
+        }];
 
         if (scene.prePassRenderer && scene.prePassRenderer.enabled && canRenderToMRT) {
             defines.PREPASS = true;
             defines.SCENE_MRT_COUNT = scene.prePassRenderer.mrtCount;
 
-            const positionIndex = scene.prePassRenderer.getIndex(PrePassRenderer.POSITION_TEXTURE_TYPE);
-            if (positionIndex !== -1) {
-                defines.PREPASS_POSITION = true;
-                defines.PREPASS_POSITION_INDEX = positionIndex;
-            } else {
-                defines.PREPASS_POSITION = false;
-            }
-
-            const velocityIndex = scene.prePassRenderer.getIndex(PrePassRenderer.VELOCITY_TEXTURE_TYPE);
-            if (velocityIndex !== -1) {
-                defines.PREPASS_VELOCITY = true;
-                defines.PREPASS_VELOCITY_INDEX = velocityIndex;
-            } else {
-                defines.PREPASS_VELOCITY = false;
-            }
-
-            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;
+            for (let i = 0; i < texturesList.length; i++) {
+                const index = scene.prePassRenderer.getIndex(texturesList[i].type);
+                if (index !== -1) {
+                    defines[texturesList[i].define] = true;
+                    defines[texturesList[i].index] = index;
+                } else {
+                    defines[texturesList[i].define] = 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;
         }

+ 45 - 7
src/PostProcesses/motionBlurPostProcess.ts

@@ -8,6 +8,8 @@ import { Constants } from "../Engines/constants";
 import { GeometryBufferRenderer } from "../Rendering/geometryBufferRenderer";
 import { Scene } from "../scene";
 import { AbstractMesh } from "../Meshes/abstractMesh";
+import { MotionBlurConfiguration } from "../Rendering/motionBlurConfiguration";
+import { PrePassRenderer } from "../Rendering/prePassRenderer";
 
 import "../Animations/animatable";
 import '../Rendering/geometryBufferRendererSceneComponent';
@@ -51,9 +53,17 @@ export class MotionBlurPostProcess extends PostProcess {
         }
     }
 
+    /**
+     * Force rendering the geometry through geometry buffer
+     */
+    private _forceGeometryBuffer: boolean = false;
+
     private _motionBlurSamples: number = 32;
     private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
 
+    private _prePassRenderer: PrePassRenderer;
+    private _motionBlurConfiguration: MotionBlurConfiguration;
+
     /**
      * Creates a new instance MotionBlurPostProcess
      * @param name The name of the effect.
@@ -66,19 +76,28 @@ export class MotionBlurPostProcess extends PostProcess {
      * @param textureType Type of textures used when performing the post process. (default: 0)
      * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
      */
-    constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
+    constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false, forceGeometryBuffer = false) {
         super(name, "motionBlur", ["motionStrength", "motionScale", "screenSize"], ["velocitySampler"], options, camera, samplingMode, engine, reusable, "#define GEOMETRY_SUPPORTED\n#define SAMPLES 64.0", textureType, undefined, null, blockCompilation);
 
-        this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
+        this._forceGeometryBuffer = forceGeometryBuffer;
+
+        // Set up assets
+        if (this._forceGeometryBuffer) {
+            this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
+
+            if (this._geometryBufferRenderer) {
+                this._geometryBufferRenderer.enableVelocity = true;
+            }
+        } else {
+            this._prePassRenderer = <PrePassRenderer>scene.enablePrePassRenderer();
+            this._prePassRenderer.markAsDirty();
+        }
 
-        if (!this._geometryBufferRenderer) {
-            // Geometry buffer renderer is not supported. So, work as a passthrough.
+        if (!this._geometryBufferRenderer && !this._prePassRenderer) {
+            // We can't get a velocity texture. So, work as a passthrough.
             Logger.Warn("Multiple Render Target support needed to compute object based motion blur");
             this.updateEffect();
         } else {
-            // Geometry buffer renderer is supported.
-            this._geometryBufferRenderer.enableVelocity = true;
-
             this.onApply = (effect: Effect) => {
                 effect.setVector2("screenSize", new Vector2(this.width, this.height));
 
@@ -88,6 +107,9 @@ export class MotionBlurPostProcess extends PostProcess {
                 if (this._geometryBufferRenderer) {
                     const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE);
                     effect.setTexture("velocitySampler", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);
+                } else {
+                    const velocityIndex = this._prePassRenderer.getIndex(PrePassRenderer.VELOCITY_TEXTURE_TYPE);
+                    effect.setTexture("velocitySampler", this._prePassRenderer.prePassRT.textures[velocityIndex]);
                 }
             };
         }
@@ -132,4 +154,20 @@ export class MotionBlurPostProcess extends PostProcess {
 
         super.dispose(camera);
     }
+
+    /**
+     * 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 {
+        let cfg = this._motionBlurConfiguration;
+        if (!cfg) {
+            cfg = new MotionBlurConfiguration();
+        }
+
+        cfg.enabled = true;
+        this._motionBlurConfiguration = prePassRenderer.addEffectConfiguration(cfg);
+        return true;
+    }
 }

+ 11 - 0
src/PostProcesses/postProcess.ts

@@ -17,6 +17,7 @@ declare type Scene = import("../scene").Scene;
 declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture;
 declare type WebVRFreeCamera = import("../Cameras/VR/webVRCamera").WebVRFreeCamera;
 declare type Animation = import("../Animations/animation").Animation;
+declare type PrePassRenderer = import("../Rendering/prePassRenderer").PrePassRenderer;
 
 /**
  * Size options for a post process
@@ -657,6 +658,16 @@ export class PostProcess {
     }
 
     /**
+     * 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 post process.
      * @param camera The camera to dispose the post process on.
      */

+ 38 - 0
src/Rendering/motionBlurConfiguration.ts

@@ -0,0 +1,38 @@
+import { PrePassRenderer } from "./prePassRenderer";
+import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
+import { _DevTools } from '../Misc/devTools';
+
+/**
+ * Contains all parameters needed for the prepass to perform
+ * motion blur
+ */
+export class MotionBlurConfiguration implements PrePassEffectConfiguration {
+    /**
+     * Is motion blur enabled
+     */
+    public enabled = false;
+
+    /**
+     * Name of the configuration
+     */
+    public name = "motionBlur";
+
+    /**
+     * Textures that should be present in the MRT for this effect to work
+     */
+    public readonly texturesRequired: number[] = [
+        PrePassRenderer.VELOCITY_TEXTURE_TYPE
+    ];
+
+    /**
+     * Builds a motion blur configuration object
+     * @param scene The scene
+     */
+    constructor() {
+
+    }
+
+    public dispose() {
+
+    }
+}

+ 7 - 0
src/Rendering/prePassRenderer.ts

@@ -444,6 +444,13 @@ export class PrePassRenderer {
             }
         }
 
+        const postProcesses = this._scene.postProcesses;
+        for (let i = 0; i < postProcesses.length; i++) {
+            if (postProcesses[i].setPrePassRenderer(this)) {
+                enablePrePass = true;
+            }
+        }
+
         this._isDirty = false;
 
         if (enablePrePass) {

+ 1 - 2
src/Rendering/ssao2Configuration.ts

@@ -21,8 +21,7 @@ export class SSAO2Configuration implements PrePassEffectConfiguration {
      * Textures that should be present in the MRT for this effect to work
      */
     public readonly texturesRequired: number[] = [
-        PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE,
-        PrePassRenderer.VELOCITY_TEXTURE_TYPE,
+        PrePassRenderer.DEPTHNORMAL_TEXTURE_TYPE
     ];
 
     /**

+ 9 - 0
src/Shaders/pbr.fragment.fx

@@ -143,6 +143,7 @@ void main(void) {
 
 #if defined(REFLECTIVITY)
     vec4 surfaceMetallicOrReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
+    vec4 baseReflectivity = surfaceMetallicOrReflectivityColorMap;
     #ifndef METALLICWORKFLOW
         surfaceMetallicOrReflectivityColorMap = toLinearSpace(surfaceMetallicOrReflectivityColorMap);
         surfaceMetallicOrReflectivityColorMap.rgb *= vReflectivityInfos.y;
@@ -539,6 +540,14 @@ void main(void) {
     #ifdef PREPASS_ALBEDO
         gl_FragData[PREPASS_ALBEDO_INDEX] = vec4(sqAlbedo, 1.0); // albedo, for pre and post scatter
     #endif
+
+    #ifdef PREPASS_REFLECTIVITY
+        #if defined(REFLECTIVITY)
+            gl_FragData[PREPASS_REFLECTIVITY_INDEX] = baseReflectivity;
+        #else
+            gl_FragData[PREPASS_REFLECTIVITY_INDEX] = vec4(0.0, 0.0, 0.0, 1.0);
+        #endif
+    #endif
 #endif
 
     gl_FragColor = finalColor;