Browse Source

lights moved to push mode!!!

David Catuhe 8 years ago
parent
commit
4a420ee028

File diff suppressed because it is too large
+ 3160 - 3149
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 3160 - 3149
dist/preview release/babylon.module.d.ts


+ 4 - 0
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -102,6 +102,8 @@
                 this._shadowMap.anisotropicFilteringLevel = 1;
                 this._shadowMap.updateSamplingMode(Texture.NEAREST_SAMPLINGMODE);
             }
+
+            this._light._markMeshesAsLightDirty();
         }
 
         public get useVarianceShadowMap(): boolean {
@@ -187,6 +189,7 @@
             this._mapSize = mapSize;
 
             light._shadowGenerator = this;
+            light._markMeshesAsLightDirty();
 
             // Texture type fallback from float to int if not supported.
             var textureType: number;
@@ -512,6 +515,7 @@
             }
 
             this._light._shadowGenerator = null;
+            this._light._markMeshesAsLightDirty();
         }
         /**
          * Serializes the ShadowGenerator and returns a serializationObject.  

+ 23 - 3
src/Lights/babylon.light.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 
-    export interface IShadowLight {
+    export interface IShadowLight extends Light {
         id: string;
         position: Vector3;
         transformedPosition: Vector3;
@@ -111,8 +111,20 @@
             this._resyncMeshes();
         }          
 
-        @serialize()
-        public lightmapMode = 0;
+        @serialize("lightmapMode")
+        private _lightmapMode = 0;
+        public get lightmapMode(): number {
+            return this._lightmapMode;
+        }
+
+        public set lightmapMode(value: number) {
+            if (this._lightmapMode === value) {
+                return;
+            }
+            
+            this._lightmapMode = value;
+            this._markMeshesAsLightDirty();
+        }    
 
         // PBR Properties.
         @serialize()
@@ -397,5 +409,13 @@
                 mesh._resyncLighSource(this);
             }
         }
+
+        public _markMeshesAsLightDirty() {
+            for (var mesh of this.getScene().meshes) {
+                if (mesh._lightSources.indexOf(this) !== -1) {
+                    mesh._markSubMeshesAsLightDirty();
+                }
+            }
+        }
     }
 }

+ 4 - 1
src/Materials/babylon.material.ts

@@ -2,7 +2,10 @@
     export class MaterialDefines {
         _keys: string[];
         _isDirty = true;
-        _trackIsDirty = false;
+        _trackIsDirty = false;    
+
+        public _areLightsDirty = true;
+        public _needNormals = false;
 
         constructor(trackIsDirty?: boolean) {
             this._trackIsDirty = trackIsDirty;

+ 75 - 72
src/Materials/babylon.materialHelper.ts

@@ -1,102 +1,105 @@
 module BABYLON {
     export class MaterialHelper {
-        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights = 4): boolean {
+        public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, maxSimultaneousLights = 4, disableLighting = false): boolean {
+            if (!defines._areLightsDirty) {
+                return defines._needNormals;
+            }
+
             var lightIndex = 0;
             var needNormals = false;
             var needRebuild = false;
             var needShadows = false;
             var lightmapMode = false;
 
-            var count = 0;
-            for (var light of mesh._lightSources) {
-                count++;
+            if (scene.lightsEnabled && !disableLighting) {
+                for (var light of mesh._lightSources) {
+                    needNormals = true;
 
-                needNormals = true;
+                    if (defines["LIGHT" + lightIndex] === undefined) {
+                        needRebuild = true;
+                    }
+                    defines["LIGHT" + lightIndex] = true;
+
+                    var type;
+                    if (light instanceof SpotLight) {
+                        type = "SPOTLIGHT" + lightIndex;
+                    } else if (light instanceof HemisphericLight) {
+                        type = "HEMILIGHT" + lightIndex;
+                    } else if (light instanceof PointLight) {
+                        type = "POINTLIGHT" + lightIndex;
+                    } else {
+                        type = "DIRLIGHT" + lightIndex;
+                    }
 
-                if (defines["LIGHT" + lightIndex] === undefined) {
-                    needRebuild = true;
-                }
-                defines["LIGHT" + lightIndex] = true;
-
-                var type;
-                if (light instanceof SpotLight) {
-                    type = "SPOTLIGHT" + lightIndex;
-                } else if (light instanceof HemisphericLight) {
-                    type = "HEMILIGHT" + lightIndex;
-                } else if (light instanceof PointLight) {
-                    type = "POINTLIGHT" + lightIndex;
-                } else {
-                    type = "DIRLIGHT" + lightIndex;
-                }
+                    if (!needRebuild && defines[type] === undefined) {
+                        needRebuild = true;
+                    }
 
-                if (!needRebuild && defines[type] === undefined) {
-                    needRebuild = true;
-                }
+                    defines[type] = true;
 
-                defines[type] = true;
+                    // Specular
+                    defines["SPECULARTERM"] = (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined);
 
-                // Specular
-                defines["SPECULARTERM"] = (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined);
+                    // Shadows
+                    var shadowEnabled = false;
+                    if (scene.shadowsEnabled) {
+                        var shadowGenerator = <ShadowGenerator>light.getShadowGenerator();
+                        if (mesh && mesh.receiveShadows && shadowGenerator) {
+                            if (!needRebuild && defines["SHADOW" + lightIndex] === undefined) {
+                                needRebuild = true;
+                            }
+                            defines["SHADOW" + lightIndex] = true;
 
-                // Shadows
-                var shadowEnabled = false;
-                if (scene.shadowsEnabled) {
-                    var shadowGenerator = <ShadowGenerator>light.getShadowGenerator();
-                    if (mesh && mesh.receiveShadows && shadowGenerator) {
-                        if (!needRebuild && defines["SHADOW" + lightIndex] === undefined) {
-                            needRebuild = true;
-                        }
-                        defines["SHADOW" + lightIndex] = true;
+                            shadowEnabled = true;
 
-                        shadowEnabled = true;
+                            if (shadowGenerator.usePoissonSampling) {
+                                if (!needRebuild && defines["SHADOWPCF" + lightIndex] === undefined) {
+                                    needRebuild = true;
+                                }
 
-                        if (shadowGenerator.usePoissonSampling) {
-                            if (!needRebuild && defines["SHADOWPCF" + lightIndex] === undefined) {
-                                needRebuild = true;
-                            }
+                                defines["SHADOWPCF" + lightIndex] = true;
+                            } 
+                            else if (shadowGenerator.useExponentialShadowMap || shadowGenerator.useBlurExponentialShadowMap) {
+                                if (!needRebuild && defines["SHADOWESM" + lightIndex] === undefined) {
+                                    needRebuild = true;
+                                }
 
-                            defines["SHADOWPCF" + lightIndex] = true;
-                        } 
-                        else if (shadowGenerator.useExponentialShadowMap || shadowGenerator.useBlurExponentialShadowMap) {
-                            if (!needRebuild && defines["SHADOWESM" + lightIndex] === undefined) {
-                                needRebuild = true;
+                                defines["SHADOWESM" + lightIndex] = true;
                             }
 
-                            defines["SHADOWESM" + lightIndex] = true;
+                            needShadows = true;
+                        } else {
+                            defines["SHADOW" + lightIndex] = false;
                         }
-
-                        needShadows = true;
-                    } else {
-                        defines["SHADOW" + lightIndex] = false;
                     }
-                }
 
-                defines["SHADOWS"] = shadowEnabled;
+                    defines["SHADOWS"] = shadowEnabled;
 
-                if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
-                    lightmapMode = true;
-                    if (!needRebuild && defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
-                        needRebuild = true;
-                    }
-                    if (!needRebuild && defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
-                        needRebuild = true;
+                    if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
+                        lightmapMode = true;
+                        if (!needRebuild && defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
+                            needRebuild = true;
+                        }
+                        if (!needRebuild && defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
+                            needRebuild = true;
+                        }
+                        defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
+                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = (light.lightmapMode == Light.LIGHTMAP_SHADOWSONLY);
+                    } else {
+                        defines["LIGHTMAPEXCLUDED" + lightIndex] = false;
+                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = false;
                     }
-                    defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
-                    defines["LIGHTMAPNOSPECULAR" + lightIndex] = (light.lightmapMode == Light.LIGHTMAP_SHADOWSONLY);
-                } else {
-                    defines["LIGHTMAPEXCLUDED" + lightIndex] = false;
-                    defines["LIGHTMAPNOSPECULAR" + lightIndex] = false;
-                }
 
-                lightIndex++;
-                if (lightIndex === maxSimultaneousLights)
-                    break;
+                    lightIndex++;
+                    if (lightIndex === maxSimultaneousLights)
+                        break;
+                }
             }
 
             // Resetting all other lights if any
-            for (var index = count; index < maxSimultaneousLights; index++) {
-                if (defines["LIGHT" + lightIndex] !== undefined) {
-                    defines["LIGHT" + lightIndex] = false;
+            for (var index = lightIndex; index < maxSimultaneousLights; index++) {
+                if (defines["LIGHT" + index] !== undefined) {
+                    defines["LIGHT" + index] = false;
                 }
             }
 
@@ -115,7 +118,7 @@
 
             if (needRebuild) {
                 defines.rebuild();
-            }
+            }        
 
             return needNormals;
         }

+ 40 - 11
src/Materials/babylon.standardMaterial.ts

@@ -251,8 +251,18 @@ module BABYLON {
         @serialize()
         public useReflectionOverAlpha = false;
 
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        public set disableLighting(value : boolean) {
+            if (this._disableLighting === value) {
+                return;
+            }
+            this._disableLighting = value;
+            this._markAllSubMeshesAsLightDirty();
+        }
+        public get disableLighting(): boolean {
+            return this._disableLighting;
+        }            
 
         @serialize()
         public useParallax = false;
@@ -404,6 +414,11 @@ module BABYLON {
          */
         public markAsDirty() {
             this._markAllSubMeshesAsTextureDirty();
+            this._markAllSubMeshesAsLightDirty();
+        }
+
+        public getEffect(): Effect {
+            return this._activeEffect;
         }
 
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
@@ -428,14 +443,12 @@ module BABYLON {
             var defines = <StandardMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var engine = scene.getEngine();
-            var needNormals = false;
 
             // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, this.maxSimultaneousLights);
-            }
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, this.maxSimultaneousLights, this.disableLighting);
+            defines._areLightsDirty = false;
 
-            if (!this.checkReadyOnEveryCall) {
+            if (!this.checkReadyOnEveryCall && subMesh.effect) {
                 if (this._renderId === scene.getRenderId()) {
                     return true;
                 }
@@ -483,7 +496,7 @@ module BABYLON {
                         if (!this._reflectionTexture.isReady()) {
                             return false;
                         } else {
-                            needNormals = true;
+                            defines._needNormals = true;
                             defines.REFLECTION = true;
 
                             defines.ROUGHNESS = (this.roughness > 0);
@@ -666,7 +679,7 @@ module BABYLON {
 
                     defines.EMISSIVEFRESNEL = (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) ;
 
-                    needNormals = true;
+                    defines._needNormals = true;
                     defines.FRESNEL = true;
                 }
             } else {
@@ -677,7 +690,7 @@ module BABYLON {
 
             // Attribs
             if (mesh) {
-                defines.NORMAL = (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
+                defines.NORMAL = (defines._needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
 
                 if (defines._needUVs) {
                     defines.UV1 = mesh.isVerticesDataPresent(VertexBuffer.UVKind);
@@ -832,7 +845,6 @@ module BABYLON {
             return true;
         }
 
-
         public unbind(): void {
             if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                 this._activeEffect.setTexture("reflection2DSampler", null);
@@ -1149,6 +1161,23 @@ module BABYLON {
             }
         }
 
+        private _markAllSubMeshesAsLightDirty() {
+            for (var mesh of this.getScene().meshes) {
+                if (!mesh.subMeshes) {
+                    continue;
+                }
+                for (var subMesh of mesh.subMeshes) {
+                    if (subMesh.getMaterial() !== this) {
+                        continue;
+                    }
+                    if (!subMesh._materialDefines) {
+                        subMesh._materialDefines = new StandardMaterialDefines();
+                    }
+                    subMesh._materialDefines._areLightsDirty = true;
+                }
+            }
+        }
+
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
             return SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);

+ 33 - 6
src/Mesh/babylon.abstractMesh.ts

@@ -129,7 +129,19 @@
         public isBlocker = false;
         public renderingGroupId = 0;
         public material: Material;
-        public receiveShadows = false;
+        private _receiveShadows = false;
+        public get receiveShadows(): boolean {
+            return this._receiveShadows;
+        }
+        public set receiveShadows(value: boolean) {
+            if (this._receiveShadows === value) {
+                return;
+            }
+
+            this._receiveShadows = value;
+            this._markSubMeshesAsLightDirty();
+        }
+
         public renderOutline = false;
         public outlineColor = Color3.Red();
         public outlineWidth = 0.02;
@@ -297,6 +309,8 @@
                     this._lightSources.push(light);
                 }
             }
+
+            this._markSubMeshesAsLightDirty();
         }
 
         public _resyncLighSource(light: Light): void {
@@ -309,13 +323,14 @@
                     return;
                 }
                 this._lightSources.push(light);
-                return;
+            } else {
+                if (isIn) {
+                    return;
+                }
+                this._lightSources.splice(index, 1);            
             }
 
-            if (isIn) {
-                return;
-            }
-            this._lightSources.splice(index, 1);            
+            this._markSubMeshesAsLightDirty();
         }
 
         public _removeLightSource(light: Light): void {
@@ -327,6 +342,18 @@
             this._lightSources.slice(index, 1);       
         }
 
+        public _markSubMeshesAsLightDirty() {
+            if (!this.subMeshes) {
+                return;
+            }
+            
+            for (var subMesh of this.subMeshes) {
+                if (subMesh._materialDefines) {
+                    subMesh._materialDefines._areLightsDirty = true;
+                }
+            }
+        }
+
         /**
          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z. 
          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!

+ 2 - 2
src/Mesh/babylon.mesh.ts

@@ -1132,9 +1132,9 @@
             var world = this.getWorldMatrix();
             
             if (effectiveMaterial.storeEffectOnSubMeshes) {
-                effectiveMaterial.bind(world, this);
-            } else {
                 effectiveMaterial.bindForSubMesh(world, this, subMesh);
+            } else {
+                effectiveMaterial.bind(world, this);
             }
 
             // Alpha mode

+ 5 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -275,7 +275,11 @@
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
                     var effect: Effect = this._volumetricLightScatteringPass;
                     if (mesh === this.mesh) {
-                        effect = subMesh.getMaterial().getEffect();
+                        if (subMesh.effect) {
+                            effect = subMesh.effect;
+                        } else {
+                            effect = subMesh.getMaterial().getEffect();
+                        }
                     }
 
                     engine.enableEffect(effect);

+ 26 - 2
src/babylon.scene.ts

@@ -419,12 +419,36 @@
         * is shadow enabled on this scene.
         * @type {boolean}
         */
-        public shadowsEnabled = true;
+        private _shadowsEnabled = true;
+        public set shadowsEnabled(value : boolean) {
+            if (this._shadowsEnabled === value) {
+                return;
+            }
+            this._shadowsEnabled = value;
+            this.markAllMaterialsAsDirty();
+        }
+
+        public get shadowsEnabled(): boolean {
+            return this._shadowsEnabled;
+        }       
+           
         /**
         * is light enabled on this scene.
         * @type {boolean}
         */
-        public lightsEnabled = true;
+        private _lightsEnabled = true;
+        public set lightsEnabled(value : boolean) {
+            if (this._lightsEnabled === value) {
+                return;
+            }
+            this._lightsEnabled = value;
+            this.markAllMaterialsAsDirty();
+        }
+
+        public get lightsEnabled(): boolean {
+            return this._lightsEnabled;
+        }    
+
         /**
         * All of the lights added to this scene.
         * @see BABYLON.Light