瀏覽代碼

standard material now works with velocity

Benjamin Guignabert 5 年之前
父節點
當前提交
07522eea07

文件差異過大導致無法顯示
+ 1684 - 1
dist/preview release/babylon.ktx2Decoder.js


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

@@ -1,73 +0,0 @@
-import { UniformBuffer } from "../../Materials/uniformBuffer";
-import { Matrix } from "../../Maths/math.vector";
-import { Mesh } from "../../Meshes/mesh";
-import { Scene } from "../../scene";
-import { Constants } from "../../Engines/constants";
-
-export class PBRAdditionnalPrePassConfiguration {
-    public previousWorldMatrices: { [index: number]: Matrix } = {};
-    public previousViewProjection: Matrix;
-    public previousBones: { [index: number]: number[] } = {};
-
-    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, mesh: Mesh, world: Matrix, isFrozen: boolean): void {
-
-        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
-            if (scene.prePassRenderer && scene.prePassRenderer.enabled) {
-                if (scene.prePassRenderer.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE) !== -1) {
-                    if (!this.previousWorldMatrices[mesh.uniqueId]) {
-                        this.previousWorldMatrices[mesh.uniqueId] = Matrix.Identity();
-                    }
-
-                    if (!this.previousViewProjection) {
-                        this.previousViewProjection = scene.getTransformMatrix();
-                    }
-                    
-                    uniformBuffer.updateMatrix("previousWorld", this.previousWorldMatrices[mesh.uniqueId]);
-                    uniformBuffer.updateMatrix("previousViewProjection", this.previousViewProjection);
-
-                    this.previousWorldMatrices[mesh.uniqueId] = world.clone();
-                    this.previousViewProjection = scene.getTransformMatrix().clone();
-                }
-            }
-        }
-
-    }
-}

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

@@ -16,7 +16,7 @@ import { IMaterialAnisotropicDefines, PBRAnisotropicConfiguration } from "./pbrA
 import { IMaterialBRDFDefines, PBRBRDFConfiguration } from "./pbrBRDFConfiguration";
 import { IMaterialBRDFDefines, PBRBRDFConfiguration } from "./pbrBRDFConfiguration";
 import { IMaterialSheenDefines, PBRSheenConfiguration } from "./pbrSheenConfiguration";
 import { IMaterialSheenDefines, PBRSheenConfiguration } from "./pbrSheenConfiguration";
 import { IMaterialSubSurfaceDefines, PBRSubSurfaceConfiguration } from "./pbrSubSurfaceConfiguration";
 import { IMaterialSubSurfaceDefines, PBRSubSurfaceConfiguration } from "./pbrSubSurfaceConfiguration";
-import { PBRAdditionnalPrePassConfiguration } from "./pbrAdditionnalPrePassConfiguration";
+import { PrePassConfiguration } from "../PrePassConfiguration";
 import { Color3, TmpColors } from '../../Maths/math.color';
 import { Color3, TmpColors } from '../../Maths/math.color';
 import { Scalar } from "../../Maths/math.scalar";
 import { Scalar } from "../../Maths/math.scalar";
 
 
@@ -182,6 +182,7 @@ export class PBRMaterialDefines extends MaterialDefines
     public NUM_BONE_INFLUENCERS = 0;
     public NUM_BONE_INFLUENCERS = 0;
     public BonesPerMesh = 0;
     public BonesPerMesh = 0;
     public BONETEXTURE = false;
     public BONETEXTURE = false;
+    public BONES_VELOCITY_ENABLED = false;
 
 
     public NONUNIFORMSCALING = false;
     public NONUNIFORMSCALING = false;
 
 
@@ -826,7 +827,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     /**
     /**
      * Defines additionnal PrePass parameters for the material.
      * Defines additionnal PrePass parameters for the material.
      */
      */
-    public readonly additionnalPrePass: PBRAdditionnalPrePassConfiguration;
+    public readonly prePassConfiguration: PrePassConfiguration;
 
 
     /**
     /**
      * Defines the detail map parameters for the material.
      * Defines the detail map parameters for the material.
@@ -861,7 +862,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
 
         this._environmentBRDFTexture = BRDFTextureTools.GetEnvironmentBRDFTexture(scene);
         this._environmentBRDFTexture = BRDFTextureTools.GetEnvironmentBRDFTexture(scene);
         this.subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this), this._markScenePrePassDirty.bind(this), scene);
         this.subSurface = new PBRSubSurfaceConfiguration(this._markAllSubMeshesAsTexturesDirty.bind(this), this._markScenePrePassDirty.bind(this), scene);
-        this.additionnalPrePass = new PBRAdditionnalPrePassConfiguration();
+        this.prePassConfiguration = new PrePassConfiguration();
     }
     }
 
 
     /**
     /**
@@ -1294,8 +1295,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.AddUniforms(uniforms);
         PBRSheenConfiguration.AddUniforms(uniforms);
         PBRSheenConfiguration.AddSamplers(samplers);
         PBRSheenConfiguration.AddSamplers(samplers);
 
 
-        PBRAdditionnalPrePassConfiguration.AddUniforms(uniforms);
-        PBRAdditionnalPrePassConfiguration.AddSamplers(uniforms);
+        PrePassConfiguration.AddUniforms(uniforms);
+        PrePassConfiguration.AddSamplers(uniforms);
 
 
         if (ImageProcessingConfiguration) {
         if (ImageProcessingConfiguration) {
             ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
             ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
@@ -1709,7 +1710,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         PBRSheenConfiguration.PrepareUniformBuffer(ubo);
         PBRSheenConfiguration.PrepareUniformBuffer(ubo);
         PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
         PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
         DetailMapConfiguration.PrepareUniformBuffer(ubo);
         DetailMapConfiguration.PrepareUniformBuffer(ubo);
-        PBRAdditionnalPrePassConfiguration.PrepareUniformBuffer(ubo);
 
 
         ubo.create();
         ubo.create();
     }
     }
@@ -1763,7 +1763,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         // Matrices
         // Matrices
         if (!defines.INSTANCES || defines.THIN_INSTANCES) {
         if (!defines.INSTANCES || defines.THIN_INSTANCES) {
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this.additionnalPrePass.bindForSubMesh(ubo, scene, mesh, world, this.isFrozen);
+            this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);
         }
         }
 
 
         // Normal Matrix
         // Normal Matrix
@@ -1775,7 +1775,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
         let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
 
 
         // Bones
         // Bones
-        MaterialHelper.BindBonesParameters(mesh, this._activeEffect, this.additionnalPrePass);
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect, this.prePassConfiguration);
 
 
         let reflectionTexture: Nullable<BaseTexture> = null;
         let reflectionTexture: Nullable<BaseTexture> = null;
         if (mustRebind) {
         if (mustRebind) {

+ 26 - 3
src/Materials/materialHelper.ts

@@ -9,7 +9,8 @@ import { Mesh } from "../Meshes/mesh";
 import { VertexBuffer } from "../Meshes/buffer";
 import { VertexBuffer } from "../Meshes/buffer";
 import { Light } from "../Lights/light";
 import { Light } from "../Lights/light";
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
-import { PBRAdditionnalPrePassConfiguration } from "../Materials/PBR/pbrAdditionnalPrePassConfiguration";
+import { PrePassConfiguration } from "../Materials/prePassConfiguration";
+import { MotionBlurConfiguration } from "../Rendering/motionBlurConfiguration";
 
 
 import { UniformBuffer } from "./uniformBuffer";
 import { UniformBuffer } from "./uniformBuffer";
 import { Effect, IEffectCreationOptions } from "./effect";
 import { Effect, IEffectCreationOptions } from "./effect";
@@ -204,6 +205,15 @@ export class MaterialHelper {
             } else {
             } else {
                 defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                 defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                 defines["BONETEXTURE"] = materialSupportsBoneTexture ? false : undefined;
                 defines["BONETEXTURE"] = materialSupportsBoneTexture ? false : undefined;
+
+                const prePassRenderer = mesh.getScene().prePassRenderer;
+                if (prePassRenderer) {
+                    const motionBlurConfiguration = prePassRenderer.getEffectConfiguration("motionBlur");
+                    if (motionBlurConfiguration) {
+                        const nonExcluded = (motionBlurConfiguration as MotionBlurConfiguration).excludedSkinnedMesh.indexOf(mesh) === -1;
+                        defines["BONES_VELOCITY_ENABLED"] = nonExcluded;
+                    }
+                }
             }
             }
         } else {
         } else {
             defines["NUM_BONE_INFLUENCERS"] = 0;
             defines["NUM_BONE_INFLUENCERS"] = 0;
@@ -822,7 +832,7 @@ export class MaterialHelper {
      * @param mesh The mesh we are binding the information to render
      * @param mesh The mesh we are binding the information to render
      * @param effect The effect we are binding the data to
      * @param effect The effect we are binding the data to
      */
      */
-    public static BindBonesParameters(mesh?: AbstractMesh, effect?: Effect, prePassConfiguration?: PBRAdditionnalPrePassConfiguration): void {
+    public static BindBonesParameters(mesh?: AbstractMesh, effect?: Effect, prePassConfiguration?: PrePassConfiguration): void {
         if (!effect || !mesh) {
         if (!effect || !mesh) {
             return;
             return;
         }
         }
@@ -843,13 +853,26 @@ export class MaterialHelper {
                 if (matrices) {
                 if (matrices) {
                     effect.setMatrices("mBones", matrices);
                     effect.setMatrices("mBones", matrices);
                     if (prePassConfiguration && mesh.getScene().prePassRenderer && mesh.getScene().prePassRenderer!.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE)) {
                     if (prePassConfiguration && mesh.getScene().prePassRenderer && mesh.getScene().prePassRenderer!.getIndex(Constants.PREPASS_VELOCITY_TEXTURE_TYPE)) {
-                        effect.setMatrices("mPreviousBones", prePassConfiguration.previousBones[mesh.uniqueId]);
+                        if (prePassConfiguration.previousBones[mesh.uniqueId]) {
+                            effect.setMatrices("mPreviousBones", prePassConfiguration.previousBones[mesh.uniqueId]);
+                        }
+
+                        MaterialHelper._CopyBonesTransformationMatrices(matrices, prePassConfiguration.previousBones[mesh.uniqueId]);
                     }
                     }
                 }
                 }
             }
             }
         }
         }
     }
     }
 
 
+    // Copies the bones transformation matrices into the target array and returns the target's reference
+    private static _CopyBonesTransformationMatrices(source: Float32Array, target: Float32Array): Float32Array {
+        for (let i = 0; i < source.length; i++) {
+            target[i] = source[i];
+        }
+
+        return target;
+    }
+
     /**
     /**
      * Binds the morph targets information from the mesh to the effect.
      * Binds the morph targets information from the mesh to the effect.
      * @param abstractMesh The mesh we are binding the information to render
      * @param abstractMesh The mesh we are binding the information to render

+ 18 - 0
src/Materials/standardMaterial.ts

@@ -11,6 +11,7 @@ import { VertexBuffer } from "../Meshes/buffer";
 import { SubMesh } from "../Meshes/subMesh";
 import { SubMesh } from "../Meshes/subMesh";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
 import { Mesh } from "../Meshes/mesh";
+import { PrePassConfiguration } from "./PrePassConfiguration";
 
 
 import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } from "./imageProcessingConfiguration";
 import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } from "./imageProcessingConfiguration";
 import { ColorCurves } from "./colorCurves";
 import { ColorCurves } from "./colorCurves";
@@ -86,6 +87,7 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public NUM_BONE_INFLUENCERS = 0;
     public NUM_BONE_INFLUENCERS = 0;
     public BonesPerMesh = 0;
     public BonesPerMesh = 0;
     public BONETEXTURE = false;
     public BONETEXTURE = false;
+    public BONES_VELOCITY_ENABLED = false;
     public INSTANCES = false;
     public INSTANCES = false;
     public THIN_INSTANCES = false;
     public THIN_INSTANCES = false;
     public GLOSSINESS = false;
     public GLOSSINESS = false;
@@ -132,6 +134,12 @@ export class StandardMaterialDefines extends MaterialDefines implements IImagePr
     public PREPASS_ALBEDO_INDEX = -1;
     public PREPASS_ALBEDO_INDEX = -1;
     public PREPASS_DEPTHNORMAL = false;
     public PREPASS_DEPTHNORMAL = false;
     public PREPASS_DEPTHNORMAL_INDEX = -1;
     public PREPASS_DEPTHNORMAL_INDEX = -1;
+    public PREPASS_POSITION = false;
+    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 SCENE_MRT_COUNT = 0;
 
 
     public RGBDLIGHTMAP = false;
     public RGBDLIGHTMAP = false;
@@ -581,6 +589,11 @@ export class StandardMaterial extends PushMaterial {
     }
     }
 
 
     /**
     /**
+     * Defines additionnal PrePass parameters for the material.
+     */
+    public readonly prePassConfiguration: PrePassConfiguration;
+
+    /**
      * Gets wether the color curves effect is enabled.
      * Gets wether the color curves effect is enabled.
      */
      */
     public get cameraColorCurvesEnabled(): boolean {
     public get cameraColorCurvesEnabled(): boolean {
@@ -713,6 +726,7 @@ export class StandardMaterial extends PushMaterial {
 
 
         // Setup the default processing configuration to the scene.
         // Setup the default processing configuration to the scene.
         this._attachImageProcessingConfiguration(null);
         this._attachImageProcessingConfiguration(null);
+        this.prePassConfiguration = new PrePassConfiguration();
 
 
         this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
         this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
             this._renderTargets.reset();
             this._renderTargets.reset();
@@ -1190,6 +1204,9 @@ export class StandardMaterial extends PushMaterial {
             DetailMapConfiguration.AddUniforms(uniforms);
             DetailMapConfiguration.AddUniforms(uniforms);
             DetailMapConfiguration.AddSamplers(samplers);
             DetailMapConfiguration.AddSamplers(samplers);
 
 
+            PrePassConfiguration.AddUniforms(uniforms);
+            PrePassConfiguration.AddSamplers(uniforms);
+
             if (ImageProcessingConfiguration) {
             if (ImageProcessingConfiguration) {
                 ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
                 ImageProcessingConfiguration.PrepareUniforms(uniforms, defines);
                 ImageProcessingConfiguration.PrepareSamplers(samplers, defines);
                 ImageProcessingConfiguration.PrepareSamplers(samplers, defines);
@@ -1360,6 +1377,7 @@ export class StandardMaterial extends PushMaterial {
         // Matrices
         // Matrices
         if (!defines.INSTANCES || defines.THIN_INSTANCES) {
         if (!defines.INSTANCES || defines.THIN_INSTANCES) {
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
+            this.prePassConfiguration.bindForSubMesh(this._activeEffect, scene, mesh, world, this.isFrozen);
         }
         }
 
 
         // Normal Matrix
         // Normal Matrix

+ 1 - 1
src/PostProcesses/motionBlurPostProcess.ts

@@ -175,7 +175,7 @@ export class MotionBlurPostProcess extends PostProcess {
         }
         }
 
 
         cfg.enabled = true;
         cfg.enabled = true;
-        this._motionBlurConfiguration = prePassRenderer.addEffectConfiguration(cfg);
+        this._motionBlurConfiguration = prePassRenderer.addEffectConfiguration(cfg) as MotionBlurConfiguration;
         return true;
         return true;
     }
     }
 
 

+ 6 - 0
src/Rendering/motionBlurConfiguration.ts

@@ -1,6 +1,7 @@
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
 import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
 import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
 import { _DevTools } from '../Misc/devTools';
 import { _DevTools } from '../Misc/devTools';
+import { AbstractMesh } from '../Meshes/abstractMesh';
 
 
 /**
 /**
  * Contains all parameters needed for the prepass to perform
  * Contains all parameters needed for the prepass to perform
@@ -18,6 +19,11 @@ export class MotionBlurConfiguration implements PrePassEffectConfiguration {
     public name = "motionBlur";
     public name = "motionBlur";
 
 
     /**
     /**
+     * Stores skinned mesh excluded from the effect
+     */
+    public excludedSkinnedMesh: AbstractMesh[] = [];
+
+    /**
      * Textures that should be present in the MRT for this effect to work
      * Textures that should be present in the MRT for this effect to work
      */
      */
     public readonly texturesRequired: number[] = [
     public readonly texturesRequired: number[] = [

+ 17 - 0
src/Rendering/prePassRenderer.ts

@@ -8,6 +8,7 @@ import { Effect } from "../Materials/effect";
 import { _DevTools } from '../Misc/devTools';
 import { _DevTools } from '../Misc/devTools';
 import { Color4 } from "../Maths/math.color";
 import { Color4 } from "../Maths/math.color";
 import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
 import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
+import { Nullable } from "../types";
 /**
 /**
  * Renders a pre pass of the scene
  * Renders a pre pass of the scene
  * This means every mesh in the scene will be rendered to a render target texture
  * This means every mesh in the scene will be rendered to a render target texture
@@ -267,6 +268,22 @@ export class PrePassRenderer {
         return cfg;
         return cfg;
     }
     }
 
 
+
+    /**
+     * Returns an effect configuration
+     * @param cfg the effect configuration
+     * @return the effect configuration now used by the prepass
+     */
+    public getEffectConfiguration(name: string) : Nullable<PrePassEffectConfiguration> {
+        for (let i = 0; i < this._effectConfigurations.length; i++) {
+            if (this._effectConfigurations[i].name === name) {
+                return this._effectConfigurations[i];
+            }
+        }
+
+        return null;
+    }
+
     /**
     /**
      * Returns the index of a texture in the multi render target texture array.
      * Returns the index of a texture in the multi render target texture array.
      * @param type Texture type
      * @param type Texture type

+ 4 - 1
src/Shaders/ShadersInclude/bonesDeclaration.fx

@@ -4,7 +4,10 @@
 		uniform float boneTextureWidth;
 		uniform float boneTextureWidth;
 	#else
 	#else
 		uniform mat4 mBones[BonesPerMesh];
 		uniform mat4 mBones[BonesPerMesh];
-	#endif	
+		#ifdef BONES_VELOCITY_ENABLED
+		    uniform mat4 mPreviousBones[BonesPerMesh];
+		#endif
+	#endif
 
 
 	attribute vec4 matricesIndices;
 	attribute vec4 matricesIndices;
 	attribute vec4 matricesWeights;
 	attribute vec4 matricesWeights;

+ 0 - 10
src/Shaders/ShadersInclude/pbrFragmentDeclaration.fx

@@ -140,14 +140,4 @@ uniform mat4 view;
     #ifdef PREPASS_IRRADIANCE
     #ifdef PREPASS_IRRADIANCE
         uniform float scatteringDiffusionProfile;
         uniform float scatteringDiffusionProfile;
     #endif
     #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
 #endif

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

@@ -27,14 +27,4 @@ varying vec3 vPositionW;
 
 
 #ifdef VERTEXCOLOR
 #ifdef VERTEXCOLOR
     varying vec4 vColor;
     varying vec4 vColor;
-#endif
-
-#ifdef PREPASS
-    #ifdef PREPASS_DEPTHNORMAL
-        varying vec3 vViewPos;
-    #endif
-    #ifdef PREPASS_VELOCITY
-        varying vec4 vCurrentPosition;
-        varying vec4 vPreviousPosition;
-    #endif
-#endif
+#endif

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

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

+ 9 - 0
src/Shaders/ShadersInclude/prePassDeclaration.fx

@@ -2,4 +2,13 @@
 #extension GL_EXT_draw_buffers : require
 #extension GL_EXT_draw_buffers : require
 layout(location = 0) out vec4 glFragData[{X}];
 layout(location = 0) out vec4 glFragData[{X}];
 vec4 gl_FragColor;
 vec4 gl_FragColor;
+
+#ifdef PREPASS_DEPTHNORMAL
+    varying vec3 vViewPos;
+#endif
+#ifdef PREPASS_VELOCITY
+    varying vec4 vCurrentPosition;
+    varying vec4 vPreviousPosition;
+#endif
+
 #endif
 #endif

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

@@ -37,10 +37,6 @@ varying vec4 vColor;
 	varying vec2 vMainUV2;
 	varying vec2 vMainUV2;
 #endif
 #endif
 
 
-#ifdef PREPASS
-	varying vec3 vViewPos;
-#endif
-
 // Helper functions
 // Helper functions
 #include<helperFunctions>
 #include<helperFunctions>
 
 
@@ -483,6 +479,16 @@ color.rgb = max(color.rgb, 0.);
 #ifdef PREPASS
 #ifdef PREPASS
     gl_FragData[0] = color; // We can't split irradiance on std material
     gl_FragData[0] = color; // We can't split irradiance on std material
 
 
+    #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
     #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
         gl_FragData[PREPASS_IRRADIANCE_INDEX] = vec4(0.0, 0.0, 0.0, 1.0); //  We can't split irradiance on std material
     #endif
     #endif

+ 46 - 5
src/Shaders/default.vertex.fx

@@ -26,10 +26,7 @@ attribute vec4 color;
 
 
 // Uniforms
 // Uniforms
 #include<instancesDeclaration>
 #include<instancesDeclaration>
-
-#ifdef PREPASS
-varying vec3 vViewPos;
-#endif
+#include<prePassVertexDeclaration>
 
 
 #ifdef MAINUV1
 #ifdef MAINUV1
 	varying vec2 vMainUV1;
 	varying vec2 vMainUV1;
@@ -128,6 +125,13 @@ void main(void) {
 #define CUSTOM_VERTEX_UPDATE_NORMAL
 #define CUSTOM_VERTEX_UPDATE_NORMAL
 
 
 #include<instancesVertex>
 #include<instancesVertex>
+
+#if defined(PREPASS) && defined(PREPASS_VELOCITY) && !defined(BONES_VELOCITY_ENABLED)
+    // Compute velocity before bones computation
+    vCurrentPosition = viewProjection * finalWorld * vec4(positionUpdated, 1.0);
+    vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);
+#endif
+
 #include<bonesVertex>
 #include<bonesVertex>
 
 
 	vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
 	vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
@@ -160,10 +164,47 @@ void main(void) {
 #endif	
 #endif	
 
 
 	vPositionW = vec3(worldPos);
 	vPositionW = vec3(worldPos);
-	#ifdef PREPASS
+	
+#ifdef PREPASS
+	#ifdef PREPASS_DEPTHNORMAL
 	    vViewPos = (view * worldPos).rgb;
 	    vViewPos = (view * worldPos).rgb;
 	#endif
 	#endif
 
 
+	#if defined(PREPASS_VELOCITY) && defined(BONES_VELOCITY_ENABLED)
+	    vCurrentPosition = viewProjection * worldPos;
+
+	#if NUM_BONE_INFLUENCERS > 0
+	    mat4 previousInfluence;
+	    previousInfluence = mPreviousBones[int(matricesIndices[0])] * matricesWeights[0];
+	    #if NUM_BONE_INFLUENCERS > 1
+	        previousInfluence += mPreviousBones[int(matricesIndices[1])] * matricesWeights[1];
+	    #endif  
+	    #if NUM_BONE_INFLUENCERS > 2
+	        previousInfluence += mPreviousBones[int(matricesIndices[2])] * matricesWeights[2];
+	    #endif  
+	    #if NUM_BONE_INFLUENCERS > 3
+	        previousInfluence += mPreviousBones[int(matricesIndices[3])] * matricesWeights[3];
+	    #endif
+	    #if NUM_BONE_INFLUENCERS > 4
+	        previousInfluence += mPreviousBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	    #endif  
+	    #if NUM_BONE_INFLUENCERS > 5
+	        previousInfluence += mPreviousBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	    #endif  
+	    #if NUM_BONE_INFLUENCERS > 6
+	        previousInfluence += mPreviousBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	    #endif  
+	    #if NUM_BONE_INFLUENCERS > 7
+	        previousInfluence += mPreviousBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	    #endif
+
+	    vPreviousPosition = previousViewProjection * previousWorld * previousInfluence * vec4(positionUpdated, 1.0);
+	#else
+	    vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);
+	#endif
+	#endif
+#endif
+
 #if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)
 #if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)
 	vDirectionW = normalize(vec3(finalWorld * vec4(positionUpdated, 0.0)));
 	vDirectionW = normalize(vec3(finalWorld * vec4(positionUpdated, 0.0)));
 #endif
 #endif

+ 0 - 5
src/Shaders/geometry.vertex.fx

@@ -58,11 +58,6 @@ varying vec3 vPositionW;
 #ifdef VELOCITY
 #ifdef VELOCITY
 uniform mat4 previousWorld;
 uniform mat4 previousWorld;
 uniform mat4 previousViewProjection;
 uniform mat4 previousViewProjection;
-#ifdef BONES_VELOCITY_ENABLED
-#if NUM_BONE_INFLUENCERS > 0
-uniform mat4 mPreviousBones[BonesPerMesh];
-#endif
-#endif
 
 
 varying vec4 vCurrentPosition;
 varying vec4 vCurrentPosition;
 varying vec4 vPreviousPosition;
 varying vec4 vPreviousPosition;

+ 30 - 41
src/Shaders/pbr.vertex.fx

@@ -33,16 +33,7 @@ attribute vec4 color;
 
 
 // Uniforms
 // Uniforms
 #include<instancesDeclaration>
 #include<instancesDeclaration>
-
-#ifdef PREPASS
-#ifdef PREPASS_DEPTHNORMAL
-    varying vec3 vViewPos;
-#endif
-#ifdef PREPASS_VELOCITY
-    varying vec4 vCurrentPosition;
-    varying vec4 vPreviousPosition;
-#endif
-#endif
+#include<prePassVertexDeclaration>
 
 
 #if defined(ALBEDO) && ALBEDODIRECTUV == 0
 #if defined(ALBEDO) && ALBEDODIRECTUV == 0
 varying vec2 vAlbedoUV;
 varying vec2 vAlbedoUV;
@@ -190,7 +181,7 @@ void main(void) {
 
 
     vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
     vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
     vPositionW = vec3(worldPos);
     vPositionW = vec3(worldPos);
-#ifdef PREPASS
+
     #ifdef PREPASS_DEPTHNORMAL
     #ifdef PREPASS_DEPTHNORMAL
         vViewPos = (view * worldPos).rgb;
         vViewPos = (view * worldPos).rgb;
     #endif
     #endif
@@ -198,39 +189,37 @@ void main(void) {
     #if defined(PREPASS_VELOCITY) && defined(BONES_VELOCITY_ENABLED)
     #if defined(PREPASS_VELOCITY) && defined(BONES_VELOCITY_ENABLED)
         vCurrentPosition = viewProjection * worldPos;
         vCurrentPosition = viewProjection * worldPos;
 
 
-        #if NUM_BONE_INFLUENCERS > 0
-            mat4 previousInfluence;
-            previousInfluence = mPreviousBones[int(matricesIndices[0])] * matricesWeights[0];
-            #if NUM_BONE_INFLUENCERS > 1
-                previousInfluence += mPreviousBones[int(matricesIndices[1])] * matricesWeights[1];
-            #endif  
-            #if NUM_BONE_INFLUENCERS > 2
-                previousInfluence += mPreviousBones[int(matricesIndices[2])] * matricesWeights[2];
-            #endif  
-            #if NUM_BONE_INFLUENCERS > 3
-                previousInfluence += mPreviousBones[int(matricesIndices[3])] * matricesWeights[3];
-            #endif  
-
-            #if NUM_BONE_INFLUENCERS > 4
-                previousInfluence += mPreviousBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-            #endif  
-            #if NUM_BONE_INFLUENCERS > 5
-                previousInfluence += mPreviousBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-            #endif  
-            #if NUM_BONE_INFLUENCERS > 6
-                previousInfluence += mPreviousBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-            #endif  
-            #if NUM_BONE_INFLUENCERS > 7
-                previousInfluence += mPreviousBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-            #endif
-
-            vPreviousPosition = previousViewProjection * previousWorld * previousInfluence * vec4(positionUpdated, 1.0);
-        #else
-            vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);
+    #if NUM_BONE_INFLUENCERS > 0
+        mat4 previousInfluence;
+        previousInfluence = mPreviousBones[int(matricesIndices[0])] * matricesWeights[0];
+        #if NUM_BONE_INFLUENCERS > 1
+            previousInfluence += mPreviousBones[int(matricesIndices[1])] * matricesWeights[1];
+        #endif  
+        #if NUM_BONE_INFLUENCERS > 2
+            previousInfluence += mPreviousBones[int(matricesIndices[2])] * matricesWeights[2];
+        #endif  
+        #if NUM_BONE_INFLUENCERS > 3
+            previousInfluence += mPreviousBones[int(matricesIndices[3])] * matricesWeights[3];
         #endif
         #endif
+        #if NUM_BONE_INFLUENCERS > 4
+            previousInfluence += mPreviousBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+        #endif  
+        #if NUM_BONE_INFLUENCERS > 5
+            previousInfluence += mPreviousBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+        #endif  
+        #if NUM_BONE_INFLUENCERS > 6
+            previousInfluence += mPreviousBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+        #endif  
+        #if NUM_BONE_INFLUENCERS > 7
+            previousInfluence += mPreviousBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+        #endif
+
+        vPreviousPosition = previousViewProjection * previousWorld * previousInfluence * vec4(positionUpdated, 1.0);
+    #else
+        vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);
+    #endif
     #endif
     #endif
 
 
-#endif
 
 
 #ifdef NORMAL
 #ifdef NORMAL
     mat3 normalWorld = mat3(finalWorld);
     mat3 normalWorld = mat3(finalWorld);