فهرست منبع

adding velocity in prepass for PBR boneless only

Benjamin Guignabert 5 سال پیش
والد
کامیت
d1e11a209a

+ 0 - 20
src/Engines/constants.ts

@@ -484,24 +484,4 @@ export class Constants {
      * Detailled logging while loading
      */
     public static readonly SCENELOADER_DETAILED_LOGGING = 3;
-
-    /**
-     * Prepass texture index for color
-     */
-    public static readonly PREPASS_COLOR_INDEX = 0;
-
-    /**
-     * Prepass texture index for irradiance
-     */
-    public static readonly PREPASS_IRRADIANCE_INDEX = 1;
-
-    /**
-     * Prepass texture index for depth + normal
-     */
-    public static readonly PREPASS_DEPTHNORMAL_INDEX = 2;
-
-    /**
-     * Prepass texture index for albedo
-     */
-    public static readonly PREPASS_ALBEDO_INDEX = 3;
 }

+ 16 - 0
src/Materials/PBR/pbrBaseMaterial.ts

@@ -16,6 +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 { Color3, TmpColors } from '../../Maths/math.color';
 import { Scalar } from "../../Maths/math.scalar";
 
@@ -170,6 +171,10 @@ export class PBRMaterialDefines extends MaterialDefines
     public PREPASS_ALBEDO_INDEX = -1;
     public PREPASS_DEPTHNORMAL = false;
     public PREPASS_DEPTHNORMAL_INDEX = -1;
+    public PREPASS_POSITION = false;
+    public PREPASS_POSITION_INDEX = -1;
+    public PREPASS_VELOCITY = false;
+    public PREPASS_VELOCITY_INDEX = -1;
     public SCENE_MRT_COUNT = 0;
 
     public NUM_BONE_INFLUENCERS = 0;
@@ -817,6 +822,11 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     public readonly subSurface: PBRSubSurfaceConfiguration;
 
     /**
+     * Defines the PrePass parameters for the material.
+     */
+    public readonly prePass: PBRPrePassConfiguration;
+
+    /**
      * Defines the detail map parameters for the material.
      */
     public readonly detailMap = new DetailMapConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this));
@@ -849,6 +859,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();
     }
 
     /**
@@ -1281,6 +1292,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.AddUniforms(uniforms);
         PBRSheenConfiguration.AddSamplers(samplers);
 
+        PBRPrePassConfiguration.AddUniforms(uniforms);
+        PBRPrePassConfiguration.AddSamplers(uniforms);
+
         if (ImageProcessingConfiguration) {
             ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
             ImageProcessingConfiguration.PrepareSamplers(samplers, defines);
@@ -1693,6 +1707,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.PrepareUniformBuffer(ubo);
         PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
         DetailMapConfiguration.PrepareUniformBuffer(ubo);
+        PBRPrePassConfiguration.PrepareUniformBuffer(ubo);
 
         ubo.create();
     }
@@ -2002,6 +2017,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);
 
             // Clip plane
             MaterialHelper.BindClipPlane(this._activeEffect, scene);

+ 64 - 0
src/Materials/PBR/pbrPrePassConfiguration.ts

@@ -0,0 +1,64 @@
+import { UniformBuffer } from "../../Materials/uniformBuffer";
+import { Matrix } from "../../Maths/math.vector";
+import { Scene } from "../../scene";
+import { PrePassRenderer } from "../../Rendering/prePassRenderer";
+
+export class PBRPrePassConfiguration {
+    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) {
+            // 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);
+                }
+
+                this.previousWorld = world.clone();
+                this.previousViewProjection = scene.getTransformMatrix().clone();
+            }
+        }
+
+    }
+}

+ 16 - 0
src/Materials/materialHelper.ts

@@ -309,6 +309,22 @@ export class MaterialHelper {
             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;

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

@@ -234,7 +234,6 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline {
         if (cameras) {
             scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
         }
-
     }
 
     // Public Methods

+ 0 - 10
src/Rendering/prePassRenderer.ts

@@ -124,16 +124,6 @@ export class PrePassRenderer {
      */
     private _effectConfigurations: PrePassEffectConfiguration[] = [];
 
-    /**
-     * Should materials render their geometry on the MRT
-     */
-    public materialsShouldRenderGeometry: boolean = false;
-
-    /**
-     * Should materials render the irradiance information on the MRT
-     */
-    public materialsShouldRenderIrradiance: boolean = false;
-
     private _mrtFormats: number[] = [];
     private _mrtLayout: number[];
 

+ 2 - 1
src/Rendering/ssao2Configuration.ts

@@ -21,7 +21,8 @@ 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.DEPTHNORMAL_TEXTURE_TYPE,
+        PrePassRenderer.VELOCITY_TEXTURE_TYPE,
     ];
 
     /**

+ 13 - 1
src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx

@@ -134,8 +134,20 @@ uniform mat4 view;
     uniform vec3 vDiffusionDistance;
     uniform vec4 vTintColor;
     uniform vec3 vSubSurfaceIntensity;
+#endif
 
-    #ifdef SS_SCATTERING
+#ifdef PREPASS
+    #ifdef PREPASS_IRRADIANCE
         uniform float scatteringDiffusionProfile;
     #endif
+
+    #ifdef PREPASS_VELOCITY
+        uniform mat4 previousWorld;
+        uniform mat4 previousViewProjection;
+        #ifdef BONES_VELOCITY_ENABLED
+            #if NUM_BONE_INFLUENCERS > 0
+                uniform mat4 mPreviousBones[BonesPerMesh];
+            #endif
+        #endif
+    #endif
 #endif

+ 7 - 1
src/Shaders/ShadersInclude/pbrFragmentExtraDeclaration.fx

@@ -30,5 +30,11 @@ varying vec3 vPositionW;
 #endif
 
 #ifdef PREPASS
-	varying vec3 vViewPos;
+    #ifdef PREPASS_DEPTHNORMAL
+        varying vec3 vViewPos;
+    #endif
+    #ifdef PREPASS_VELOCITY
+        varying vec4 vCurrentPosition;
+        varying vec4 vPreviousPosition;
+    #endif
 #endif

+ 3 - 0
src/Shaders/ShadersInclude/pbrUboDeclaration.fx

@@ -73,6 +73,9 @@ uniform Material
 
     uniform vec4 vDetailInfos;
     uniform mat4 detailMatrix;
+
+    uniform mat4 previousWorld;
+    uniform mat4 previousViewProjection;
 };
 
 uniform Scene {

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

@@ -502,6 +502,20 @@ void main(void) {
     #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
 
 #ifdef PREPASS
+    #ifdef PREPASS_POSITION
+    gl_FragData[PREPASS_POSITION_INDEX] = vec4(vPositionW, 1.0);
+    #endif
+
+    #ifdef PREPASS_VELOCITY
+    vec2 a = (vCurrentPosition.xy / vCurrentPosition.w) * 0.5 + 0.5;
+    vec2 b = (vPreviousPosition.xy / vPreviousPosition.w) * 0.5 + 0.5;
+
+    vec2 velocity = abs(a - b);
+    velocity = vec2(pow(velocity.x, 1.0 / 3.0), pow(velocity.y, 1.0 / 3.0)) * sign(a - b) * 0.5 + 0.5;
+
+    gl_FragData[PREPASS_VELOCITY_INDEX] = vec4(velocity, 0.0, 1.0);
+    #endif
+
     #ifdef PREPASS_IRRADIANCE
         vec3 irradiance = finalDiffuse;
         #ifndef UNLIT

+ 16 - 2
src/Shaders/pbr.vertex.fx

@@ -35,7 +35,13 @@ attribute vec4 color;
 #include<instancesDeclaration>
 
 #ifdef PREPASS
-varying vec3 vViewPos;
+#ifdef PREPASS_DEPTHNORMAL
+    varying vec3 vViewPos;
+#endif
+#ifdef PREPASS_VELOCITY
+    varying vec4 vCurrentPosition;
+    varying vec4 vPreviousPosition;
+#endif
 #endif
 
 #if defined(ALBEDO) && ALBEDODIRECTUV == 0
@@ -178,7 +184,15 @@ void main(void) {
     vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
     vPositionW = vec3(worldPos);
 #ifdef PREPASS
-    vViewPos = (view * worldPos).rgb;
+    #ifdef PREPASS_DEPTHNORMAL
+        vViewPos = (view * worldPos).rgb;
+    #endif
+    #if defined(PREPASS_VELOCITY) && !defined(BONES_VELOCITY_ENABLED)
+        // Compute velocity before bones computation
+        vCurrentPosition = viewProjection * worldPos;
+        vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);
+    #endif
+
 #endif
 
 #ifdef NORMAL