Browse Source

Merge pull request #6934 from BabylonJS/Light-perf-improvement

Light perf improvement
David Catuhe 5 years ago
parent
commit
80f4c752b2

+ 2 - 0
src/Lights/light.ts

@@ -334,6 +334,8 @@ export abstract class Light extends Node {
      */
     public _uniformBuffer: UniformBuffer;
 
+    /** @hidden */
+    public _renderId: number;
     /**
      * Creates a Light object in the scene.
      * Documentation : https://doc.babylonjs.com/babylon101/lights

+ 1 - 1
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -181,7 +181,7 @@ export class LightBlock extends NodeMaterialBlock {
         if (!this.light) {
             MaterialHelper.BindLights(scene, mesh, effect, true, nodeMaterial.maxSimultaneousLights, false);
         } else {
-            MaterialHelper.BindLight(this.light, this._lightId, scene, mesh, effect, true, false);
+            MaterialHelper.BindLight(this.light, this._lightId, scene, effect, true, false);
         }
     }
 

+ 30 - 32
src/Materials/materialHelper.ts

@@ -645,23 +645,6 @@ export class MaterialHelper {
     }
 
     /**
-     * Binds the light shadow information to the effect for the given mesh.
-     * @param light The light containing the generator
-     * @param scene The scene the lights belongs to
-     * @param mesh The mesh we are binding the information to render
-     * @param lightIndex The light index in the effect used to render the mesh
-     * @param effect The effect we are binding the data to
-     */
-    public static BindLightShadow(light: Light, mesh: AbstractMesh, lightIndex: string, effect: Effect): void {
-        if (light.shadowEnabled && mesh.receiveShadows) {
-            var shadowGenerator = light.getShadowGenerator();
-            if (shadowGenerator) {
-                shadowGenerator.bindShadowLight(lightIndex, effect);
-            }
-        }
-    }
-
-    /**
      * Binds the light information to the effect.
      * @param light The light containing the generator
      * @param effect The effect we are binding the data to
@@ -676,34 +659,49 @@ export class MaterialHelper {
      * @param light Light to bind
      * @param lightIndex Light index
      * @param scene The scene where the light belongs to
-     * @param mesh The mesh we are binding the information to render
      * @param effect The effect we are binding the data to
      * @param useSpecular Defines if specular is supported
      * @param usePhysicalLightFalloff Specifies whether the light falloff is defined physically or not
      * @param rebuildInParallel Specifies whether the shader is rebuilding in parallel
      */
-    public static BindLight(light: Light, lightIndex: number, scene: Scene, mesh: AbstractMesh, effect: Effect, useSpecular: boolean, usePhysicalLightFalloff = false, rebuildInParallel = false): void {
+    public static BindLight(light: Light, lightIndex: number, scene: Scene, effect: Effect, useSpecular: boolean, usePhysicalLightFalloff = false, rebuildInParallel = false): void {
         let iAsString = lightIndex.toString();
+        let needUpdate = false;
 
-        let scaledIntensity = light.getScaledIntensity();
-        if (!rebuildInParallel) {
-            light._uniformBuffer.bindToEffect(effect, "Light" + iAsString);
+        if (rebuildInParallel && light._uniformBuffer._alreadyBound) {
+            return;
         }
 
-        MaterialHelper.BindLightProperties(light, effect, lightIndex);
+        light._uniformBuffer.bindToEffect(effect, "Light" + iAsString);
+
+        if (light._renderId !== scene.getRenderId() || !light._uniformBuffer.useUbo) {
+            light._renderId = scene.getRenderId();
 
-        light.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);
-        light._uniformBuffer.updateColor4("vLightDiffuse", TmpColors.Color3[0], usePhysicalLightFalloff ? light.radius : light.range, iAsString);
-        if (useSpecular) {
-            light.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);
-            light._uniformBuffer.updateColor3("vLightSpecular", TmpColors.Color3[1], iAsString);
+            let scaledIntensity = light.getScaledIntensity();
+
+            MaterialHelper.BindLightProperties(light, effect, lightIndex);
+
+            light.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);
+            light._uniformBuffer.updateColor4("vLightDiffuse", TmpColors.Color3[0], usePhysicalLightFalloff ? light.radius : light.range, iAsString);
+            if (useSpecular) {
+                light.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);
+                light._uniformBuffer.updateColor3("vLightSpecular", TmpColors.Color3[1], iAsString);
+            }
+            needUpdate = true;
         }
 
         // Shadows
-        if (scene.shadowsEnabled) {
-            this.BindLightShadow(light, mesh, iAsString, effect);
+        if (scene.shadowsEnabled && light.shadowEnabled) {
+            var shadowGenerator = light.getShadowGenerator();
+            if (shadowGenerator) {
+                shadowGenerator.bindShadowLight(iAsString, effect);
+                needUpdate = true;
+            }
+        }
+
+        if (needUpdate) {
+            light._uniformBuffer.update();
         }
-        light._uniformBuffer.update();
     }
 
     /**
@@ -722,7 +720,7 @@ export class MaterialHelper {
         for (var i = 0; i < len; i++) {
 
             let light = mesh.lightSources[i];
-            this.BindLight(light, i, scene, mesh, effect, typeof defines === "boolean" ? defines : defines["SPECULARTERM"], usePhysicalLightFalloff, rebuildInParallel);
+            this.BindLight(light, i, scene, effect, typeof defines === "boolean" ? defines : defines["SPECULARTERM"], usePhysicalLightFalloff, rebuildInParallel);
         }
     }
 

+ 3 - 1
src/Materials/standardMaterial.ts

@@ -1505,7 +1505,9 @@ export class StandardMaterial extends PushMaterial {
             }
 
             // Log. depth
-            MaterialHelper.BindLogDepth(defines, effect, scene);
+            if (this.useLogarithmicDepth) {
+                MaterialHelper.BindLogDepth(defines, effect, scene);
+            }
 
             // image processing
             if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {

+ 3 - 0
src/Materials/uniformBuffer.ts

@@ -33,6 +33,8 @@ export class UniformBuffer {
     private _noUBO: boolean;
     private _currentEffect: Effect;
 
+    public _alreadyBound = false;
+
     // Pool for avoiding memory leaks
     private static _MAX_UNIFORM_SIZE = 256;
     private static _tempBuffer = new Float32Array(UniformBuffer._MAX_UNIFORM_SIZE);
@@ -632,6 +634,7 @@ export class UniformBuffer {
             return;
         }
 
+        this._alreadyBound = true;
         effect.bindUniformBuffer(this._buffer, name);
     }
 

+ 1 - 2
tests/validation/config.json

@@ -286,8 +286,7 @@
         {
             "title": "LOD",
             "renderCount": 10,
-            "scriptToRun": "/Demos/LOD/lod.js",
-            "functionToCall": "CreateLODTestScene",
+            "playgroundId": "#FFMFW5#0",
             "referenceImage": "lod.png"
         },
         {