Przeglądaj źródła

Merge remote-tracking branch 'real/master' into fix_renderTargetCubeTexture

NicolasBuecher 7 lat temu
rodzic
commit
8ce69473a9

Plik diff jest za duży
+ 15272 - 15245
Playground/babylon.d.txt


Plik diff jest za duży
+ 10783 - 10756
dist/preview release/babylon.d.ts


Plik diff jest za duży
+ 49 - 49
dist/preview release/babylon.js


Plik diff jest za duży
+ 82 - 16
dist/preview release/babylon.max.js


Plik diff jest za duży
+ 50 - 50
dist/preview release/babylon.worker.js


Plik diff jest za duży
+ 5866 - 5839
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Plik diff jest za duży
+ 47 - 47
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Plik diff jest za duży
+ 82 - 16
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Plik diff jest za duży
+ 82 - 16
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


Plik diff jest za duży
+ 82 - 16
dist/preview release/es6.js


+ 5 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -163,6 +163,7 @@ declare module BABYLON.GUI {
         protected _horizontalAlignment: number;
         protected _horizontalAlignment: number;
         protected _verticalAlignment: number;
         protected _verticalAlignment: number;
         private _isDirty;
         private _isDirty;
+        _tempParentMeasure: Measure;
         protected _cachedParentMeasure: Measure;
         protected _cachedParentMeasure: Measure;
         private _paddingLeft;
         private _paddingLeft;
         private _paddingRight;
         private _paddingRight;
@@ -247,6 +248,8 @@ declare module BABYLON.GUI {
         readonly heightInPixels: number;
         readonly heightInPixels: number;
         fontFamily: string;
         fontFamily: string;
         fontStyle: string;
         fontStyle: string;
+        /** @ignore */
+        readonly _isFontSizeInPercentage: boolean;
         readonly fontSizeInPixels: number;
         readonly fontSizeInPixels: number;
         fontSize: string | number;
         fontSize: string | number;
         color: string;
         color: string;
@@ -274,6 +277,8 @@ declare module BABYLON.GUI {
         readonly centerY: number;
         readonly centerY: number;
         constructor(name?: string | undefined);
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         protected _getTypeName(): string;
+        /** @ignore */
+        _resetFontCache(): void;
         getLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getLocalCoordinatesToRef(globalCoordinates: Vector2, result: Vector2): Control;
         getLocalCoordinatesToRef(globalCoordinates: Vector2, result: Vector2): Control;
         getParentLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getParentLocalCoordinates(globalCoordinates: Vector2): Vector2;

+ 24 - 2
dist/preview release/gui/babylon.gui.js

@@ -203,6 +203,11 @@ var BABYLON;
             };
             };
             AdvancedDynamicTexture.prototype.markAsDirty = function () {
             AdvancedDynamicTexture.prototype.markAsDirty = function () {
                 this._isDirty = true;
                 this._isDirty = true;
+                this.executeOnAllControls(function (control) {
+                    if (control._isFontSizeInPercentage) {
+                        control._resetFontCache();
+                    }
+                });
             };
             };
             AdvancedDynamicTexture.prototype.addControl = function (control) {
             AdvancedDynamicTexture.prototype.addControl = function (control) {
                 this._rootContainer.addControl(control);
                 this._rootContainer.addControl(control);
@@ -826,6 +831,7 @@ var BABYLON;
                 this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
                 this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
                 this._verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
                 this._verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
                 this._isDirty = true;
                 this._isDirty = true;
+                this._tempParentMeasure = GUI.Measure.Empty();
                 this._cachedParentMeasure = GUI.Measure.Empty();
                 this._cachedParentMeasure = GUI.Measure.Empty();
                 this._paddingLeft = new GUI.ValueAndUnit(0);
                 this._paddingLeft = new GUI.ValueAndUnit(0);
                 this._paddingRight = new GUI.ValueAndUnit(0);
                 this._paddingRight = new GUI.ValueAndUnit(0);
@@ -1091,9 +1097,20 @@ var BABYLON;
                 enumerable: true,
                 enumerable: true,
                 configurable: true
                 configurable: true
             });
             });
+            Object.defineProperty(Control.prototype, "_isFontSizeInPercentage", {
+                /** @ignore */
+                get: function () {
+                    return this._fontSize.isPercentage;
+                },
+                enumerable: true,
+                configurable: true
+            });
             Object.defineProperty(Control.prototype, "fontSizeInPixels", {
             Object.defineProperty(Control.prototype, "fontSizeInPixels", {
                 get: function () {
                 get: function () {
-                    return this._fontSize.getValueInPixel(this._host, 100);
+                    if (this._fontSize.isPixel) {
+                        return this._fontSize.getValue(this._host);
+                    }
+                    return this._fontSize.getValueInPixel(this._host, this._tempParentMeasure.height || this._cachedParentMeasure.height);
                 },
                 },
                 enumerable: true,
                 enumerable: true,
                 configurable: true
                 configurable: true
@@ -1348,6 +1365,10 @@ var BABYLON;
             Control.prototype._getTypeName = function () {
             Control.prototype._getTypeName = function () {
                 return "Control";
                 return "Control";
             };
             };
+            /** @ignore */
+            Control.prototype._resetFontCache = function () {
+                this._fontSet = true;
+            };
             Control.prototype.getLocalCoordinates = function (globalCoordinates) {
             Control.prototype.getLocalCoordinates = function (globalCoordinates) {
                 var result = BABYLON.Vector2.Zero();
                 var result = BABYLON.Vector2.Zero();
                 this.getLocalCoordinatesToRef(globalCoordinates, result);
                 this.getLocalCoordinatesToRef(globalCoordinates, result);
@@ -1721,7 +1742,7 @@ var BABYLON;
                 if (!this._font && !this._fontSet) {
                 if (!this._font && !this._fontSet) {
                     return;
                     return;
                 }
                 }
-                this._font = this._fontStyle + " " + this._fontSize.getValue(this._host) + "px " + this._fontFamily;
+                this._font = this._fontStyle + " " + this.fontSizeInPixels + "px " + this._fontFamily;
                 this._fontOffset = Control._GetFontOffset(this._font);
                 this._fontOffset = Control._GetFontOffset(this._font);
             };
             };
             Control.prototype.dispose = function () {
             Control.prototype.dispose = function () {
@@ -2009,6 +2030,7 @@ var BABYLON;
                     for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
                     for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
                         var child = _a[_i];
                         var child = _a[_i];
                         if (child.isVisible && !child.notRenderable) {
                         if (child.isVisible && !child.notRenderable) {
+                            child._tempParentMeasure.copyFrom(this._measureForChildren);
                             child._draw(this._measureForChildren, context);
                             child._draw(this._measureForChildren, context);
                             if (child.onAfterDrawObservable.hasObservers()) {
                             if (child.onAfterDrawObservable.hasObservers()) {
                                 child.onAfterDrawObservable.notifyObservers(child);
                                 child.onAfterDrawObservable.notifyObservers(child);

Plik diff jest za duży
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


+ 5 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -169,6 +169,7 @@ declare module BABYLON.GUI {
         protected _horizontalAlignment: number;
         protected _horizontalAlignment: number;
         protected _verticalAlignment: number;
         protected _verticalAlignment: number;
         private _isDirty;
         private _isDirty;
+        _tempParentMeasure: Measure;
         protected _cachedParentMeasure: Measure;
         protected _cachedParentMeasure: Measure;
         private _paddingLeft;
         private _paddingLeft;
         private _paddingRight;
         private _paddingRight;
@@ -253,6 +254,8 @@ declare module BABYLON.GUI {
         readonly heightInPixels: number;
         readonly heightInPixels: number;
         fontFamily: string;
         fontFamily: string;
         fontStyle: string;
         fontStyle: string;
+        /** @ignore */
+        readonly _isFontSizeInPercentage: boolean;
         readonly fontSizeInPixels: number;
         readonly fontSizeInPixels: number;
         fontSize: string | number;
         fontSize: string | number;
         color: string;
         color: string;
@@ -280,6 +283,8 @@ declare module BABYLON.GUI {
         readonly centerY: number;
         readonly centerY: number;
         constructor(name?: string | undefined);
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         protected _getTypeName(): string;
+        /** @ignore */
+        _resetFontCache(): void;
         getLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getLocalCoordinatesToRef(globalCoordinates: Vector2, result: Vector2): Control;
         getLocalCoordinatesToRef(globalCoordinates: Vector2, result: Vector2): Control;
         getParentLocalCoordinates(globalCoordinates: Vector2): Vector2;
         getParentLocalCoordinates(globalCoordinates: Vector2): Vector2;

Plik diff jest za duży
+ 57 - 57
dist/preview release/viewer/babylon.viewer.js


+ 6 - 0
gui/src/advancedDynamicTexture.ts

@@ -196,6 +196,12 @@ module BABYLON.GUI {
 
 
         public markAsDirty() {
         public markAsDirty() {
             this._isDirty = true;
             this._isDirty = true;
+
+            this.executeOnAllControls((control) => {
+                if (control._isFontSizeInPercentage) {
+                    control._resetFontCache();
+                }
+            });
         }
         }
 
 
         public addControl(control: Control): AdvancedDynamicTexture {
         public addControl(control: Control): AdvancedDynamicTexture {

+ 1 - 0
gui/src/controls/container.ts

@@ -159,6 +159,7 @@ module BABYLON.GUI {
                 this._clipForChildren(context);
                 this._clipForChildren(context);
                 for (var child of this._children) {
                 for (var child of this._children) {
                     if (child.isVisible && !child.notRenderable) {
                     if (child.isVisible && !child.notRenderable) {
+                        child._tempParentMeasure.copyFrom(this._measureForChildren);
                         child._draw(this._measureForChildren, context);
                         child._draw(this._measureForChildren, context);
 
 
                         if (child.onAfterDrawObservable.hasObservers()) {
                         if (child.onAfterDrawObservable.hasObservers()) {

+ 18 - 2
gui/src/controls/control.ts

@@ -20,6 +20,7 @@ module BABYLON.GUI {
         protected _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
         protected _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
         protected _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
         protected _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
         private _isDirty = true;
         private _isDirty = true;
+        public _tempParentMeasure = Measure.Empty();
         protected _cachedParentMeasure = Measure.Empty();
         protected _cachedParentMeasure = Measure.Empty();
         private _paddingLeft = new ValueAndUnit(0);
         private _paddingLeft = new ValueAndUnit(0);
         private _paddingRight = new ValueAndUnit(0);
         private _paddingRight = new ValueAndUnit(0);
@@ -277,8 +278,17 @@ module BABYLON.GUI {
             this._fontSet = true;
             this._fontSet = true;
         }
         }
 
 
+        /** @ignore */
+        public get _isFontSizeInPercentage(): boolean {
+            return this._fontSize.isPercentage;
+        }
+
         public get fontSizeInPixels(): number {
         public get fontSizeInPixels(): number {
-            return this._fontSize.getValueInPixel(this._host, 100);
+            if (this._fontSize.isPixel) {
+                return this._fontSize.getValue(this._host);
+            }
+
+            return this._fontSize.getValueInPixel(this._host, this._tempParentMeasure.height || this._cachedParentMeasure.height);
         }
         }
 
 
         public get fontSize(): string | number {
         public get fontSize(): string | number {
@@ -483,6 +493,11 @@ module BABYLON.GUI {
             return "Control";
             return "Control";
         }
         }
 
 
+        /** @ignore */
+        public _resetFontCache(): void {
+            this._fontSet = true;
+        }
+
         public getLocalCoordinates(globalCoordinates: Vector2): Vector2 {
         public getLocalCoordinates(globalCoordinates: Vector2): Vector2 {
             var result = Vector2.Zero();
             var result = Vector2.Zero();
 
 
@@ -948,12 +963,13 @@ module BABYLON.GUI {
             return false;
             return false;
         }
         }
 
 
+
         private _prepareFont() {
         private _prepareFont() {
             if (!this._font && !this._fontSet) {
             if (!this._font && !this._fontSet) {
                 return;
                 return;
             }
             }
 
 
-            this._font = this._fontStyle + " " + this._fontSize.getValue(this._host) + "px " + this._fontFamily;
+            this._font = this._fontStyle + " " + this.fontSizeInPixels + "px " + this._fontFamily;
 
 
             this._fontOffset = Control._GetFontOffset(this._font);
             this._fontOffset = Control._GetFontOffset(this._font);
         }
         }

+ 0 - 28
sandbox/index.js

@@ -20,7 +20,6 @@ if (BABYLON.Engine.isSupported()) {
     var currentSkybox;
     var currentSkybox;
     var enableDebugLayer = false;
     var enableDebugLayer = false;
     var currentPluginName;
     var currentPluginName;
-    var toExecuteAfterSceneCreation;
 
 
     canvas.addEventListener("contextmenu", function (evt) {
     canvas.addEventListener("contextmenu", function (evt) {
         evt.preventDefault();
         evt.preventDefault();
@@ -129,10 +128,6 @@ if (BABYLON.Engine.isSupported()) {
             }
             }
         }
         }
 
 
-        if (toExecuteAfterSceneCreation) {
-            toExecuteAfterSceneCreation();
-        }
-
     };
     };
 
 
     var sceneError = function (sceneFile, babylonScene, message) {
     var sceneError = function (sceneFile, babylonScene, message) {
@@ -152,29 +147,6 @@ if (BABYLON.Engine.isSupported()) {
     };
     };
 
 
     filesInput = new BABYLON.FilesInput(engine, null, sceneLoaded, null, null, null, function () { BABYLON.Tools.ClearLogCache() }, null, sceneError);
     filesInput = new BABYLON.FilesInput(engine, null, sceneLoaded, null, null, null, function () { BABYLON.Tools.ClearLogCache() }, null, sceneError);
-    filesInput.onProcessFileCallback = (function (file, name, extension) {
-        if (extension === "dds") {
-            BABYLON.FilesInput.FilesToLoad[name] = file;
-            var loadTexture = () => {
-                if (currentPluginName === "gltf") { // currentPluginName is updated only once scene is loaded
-                    var newHdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("file:" + file.correctName, currentScene);
-                    if (currentSkybox) {
-                        currentSkybox.dispose();
-                    }
-                    currentSkybox = currentScene.createDefaultSkybox(newHdrTexture, true, (currentScene.activeCamera.maxZ - currentScene.activeCamera.minZ) / 2, 0.3);
-                }
-            }
-            if (currentScene) {
-                loadTexture();
-            }
-            else {
-                // Postpone texture loading until scene is loaded
-                toExecuteAfterSceneCreation = loadTexture;
-            }
-            return false;
-        }
-        return true;
-    }).bind(this);
     filesInput.monitorElementForDragNDrop(canvas);
     filesInput.monitorElementForDragNDrop(canvas);
 
 
     window.addEventListener("keydown", function (evt) {
     window.addEventListener("keydown", function (evt) {

+ 17 - 10
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -57,6 +57,7 @@
         public TANGENT = false;
         public TANGENT = false;
         public BUMP = false;
         public BUMP = false;
         public BUMPDIRECTUV = 0;
         public BUMPDIRECTUV = 0;
+        public OBJECTSPACE_NORMALMAP = false;
         public PARALLAX = false;
         public PARALLAX = false;
         public PARALLAXOCCLUSION = false;
         public PARALLAXOCCLUSION = false;
         public NORMALXYSCALE = true;
         public NORMALXYSCALE = true;
@@ -387,6 +388,11 @@
         protected _useRadianceOverAlpha = true;
         protected _useRadianceOverAlpha = true;
 
 
         /**
         /**
+         * Allows using an object space normal map (instead of tangent space).
+         */
+        protected _useObjectSpaceNormalMap = false;
+
+        /**
          * Allows using the bump map in parallax mode.
          * Allows using the bump map in parallax mode.
          */
          */
         protected _useParallax = false;
         protected _useParallax = false;
@@ -932,7 +938,7 @@
                 "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", 
                 "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos", 
                 "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                 "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                 "mBones",
                 "mBones",
-                "vClipPlane", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
+                "vClipPlane", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "normalMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
                 "vLightingIntensity",
                 "vLightingIntensity",
                 "logarithmicDepthConstant",
                 "logarithmicDepthConstant",
                 "vSphericalX", "vSphericalY", "vSphericalZ",
                 "vSphericalX", "vSphericalY", "vSphericalZ",
@@ -1139,9 +1145,11 @@
                         else {
                         else {
                             defines.PARALLAX = false;
                             defines.PARALLAX = false;
                         }
                         }
+                        
+                        defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
                     } else {
                     } else {
                         defines.BUMP = false;
                         defines.BUMP = false;
-                    }
+                    }                
 
 
                     var refractionTexture = this._getRefractionTexture();
                     var refractionTexture = this._getRefractionTexture();
                     if (refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                     if (refractionTexture && StandardMaterial.RefractionTextureEnabled) {
@@ -1299,14 +1307,6 @@
         }
         }
 
 
         /**
         /**
-         * Binds to the world matrix.
-         * @param world - The world matrix.
-         */
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._activeEffect.setMatrix("world", world);
-        }
-
-        /**
          * Binds the submesh data.
          * Binds the submesh data.
          * @param world - The world matrix.
          * @param world - The world matrix.
          * @param mesh - The BJS mesh.
          * @param mesh - The BJS mesh.
@@ -1331,6 +1331,13 @@
             // Matrices
             // Matrices
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
 
 
+            // Normal Matrix
+            if (defines.OBJECTSPACE_NORMALMAP)
+            {
+                world.toNormalMatrix(this._normalMatrix);
+                this.bindOnlyNormalMatrix(this._normalMatrix);                
+            }
+
             let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
             let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
 
 
             // Bones
             // Bones

+ 7 - 0
src/Materials/PBR/babylon.pbrMaterial.ts

@@ -358,6 +358,13 @@
         public useRadianceOverAlpha = true;
         public useRadianceOverAlpha = true;
 
 
         /**
         /**
+         * Allows using an object space normal map (instead of tangent space).
+         */
+        @serialize()
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public useObjectSpaceNormalMap = false;
+        
+        /**
          * Allows using the bump map in parallax mode.
          * Allows using the bump map in parallax mode.
          */
          */
         @serialize()
         @serialize()

+ 23 - 6
src/Materials/babylon.effect.ts

@@ -64,22 +64,39 @@
 
 
         /**
         /**
          * Removes the defines that shoould be removed when falling back.
          * Removes the defines that shoould be removed when falling back.
-         * @param currentDefines The current define statements for the shader.
+         * @param currentDefines defines the current define statements for the shader.
+         * @param effect defines the current effect we try to compile
          * @returns The resulting defines with defines of the current rank removed.
          * @returns The resulting defines with defines of the current rank removed.
          */
          */
-        public reduce(currentDefines: string): string {
+        public reduce(currentDefines: string, effect: Effect): string {
             // First we try to switch to CPU skinning
             // First we try to switch to CPU skinning
-            if (this._mesh && this._mesh.computeBonesUsingShaders && this._mesh.numBoneInfluencers > 0) {
+            if (this._mesh && this._mesh.computeBonesUsingShaders && this._mesh.numBoneInfluencers > 0 && this._mesh.material) {
                 this._mesh.computeBonesUsingShaders = false;
                 this._mesh.computeBonesUsingShaders = false;
                 currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
                 currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
-                Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
 
 
                 var scene = this._mesh.getScene();
                 var scene = this._mesh.getScene();
                 for (var index = 0; index < scene.meshes.length; index++) {
                 for (var index = 0; index < scene.meshes.length; index++) {
                     var otherMesh = scene.meshes[index];
                     var otherMesh = scene.meshes[index];
 
 
-                    if (otherMesh.material === this._mesh.material && otherMesh.computeBonesUsingShaders && otherMesh.numBoneInfluencers > 0) {
+                    if (!otherMesh.material) {
+                        continue;
+                    }
+
+                    if (!otherMesh.computeBonesUsingShaders || otherMesh.numBoneInfluencers === 0) {
+                        continue;
+                    }
+
+                    if (otherMesh.material.getEffect() === effect) {
                         otherMesh.computeBonesUsingShaders = false;
                         otherMesh.computeBonesUsingShaders = false;
+                    } else {
+                        for (var subMesh of otherMesh.subMeshes) {
+                            let subMeshEffect = subMesh.effect;
+
+                            if (subMeshEffect === effect) {
+                                otherMesh.computeBonesUsingShaders = false;
+                                break;
+                            }
+                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -808,7 +825,7 @@
 
 
                 if (fallbacks && fallbacks.isMoreFallbacks) {
                 if (fallbacks && fallbacks.isMoreFallbacks) {
                     Tools.Error("Trying next fallback.");
                     Tools.Error("Trying next fallback.");
-                    this.defines = fallbacks.reduce(this.defines);
+                    this.defines = fallbacks.reduce(this.defines, this);
                     this._prepareEffect();
                     this._prepareEffect();
                 } else { // Sorry we did everything we can
                 } else { // Sorry we did everything we can
 
 

+ 16 - 0
src/Materials/babylon.pushMaterial.ts

@@ -3,6 +3,8 @@
 
 
         protected _activeEffect: Effect;
         protected _activeEffect: Effect;
 
 
+        protected _normalMatrix : Matrix = new Matrix();
+
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
             this.storeEffectOnSubMeshes = true;
             this.storeEffectOnSubMeshes = true;
@@ -24,10 +26,24 @@
             return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances);
             return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances);
         }
         }
 
 
+         /**
+         * Binds the given world matrix to the active effect
+         * 
+         * @param world the matrix to bind
+         */
         public bindOnlyWorldMatrix(world: Matrix): void {
         public bindOnlyWorldMatrix(world: Matrix): void {
             this._activeEffect.setMatrix("world", world);
             this._activeEffect.setMatrix("world", world);
         }
         }
 
 
+        /**
+         * Binds the given normal matrix to the active effect
+         * 
+         * @param normalMatrix the matrix to bind
+         */
+        public bindOnlyNormalMatrix(normalMatrix: Matrix): void {                        
+            this._activeEffect.setMatrix("normalMatrix", normalMatrix);
+        }
+
         public bind(world: Matrix, mesh?: Mesh): void {
         public bind(world: Matrix, mesh?: Mesh): void {
             if (!mesh) {
             if (!mesh) {
                 return;
                 return;

+ 20 - 2
src/Materials/babylon.standardMaterial.ts

@@ -48,6 +48,7 @@ module BABYLON {
         public REFLECTIONFRESNELFROMSPECULAR = false;
         public REFLECTIONFRESNELFROMSPECULAR = false;
         public LIGHTMAP = false;
         public LIGHTMAP = false;
         public LIGHTMAPDIRECTUV = 0;
         public LIGHTMAPDIRECTUV = 0;
+        public OBJECTSPACE_NORMALMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public REFLECTIONMAP_3D = false;
         public REFLECTIONMAP_3D = false;
         public REFLECTIONMAP_SPHERICAL = false;
         public REFLECTIONMAP_SPHERICAL = false;
@@ -198,6 +199,14 @@ module BABYLON {
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         public disableLighting: boolean;
         public disableLighting: boolean;
 
 
+        @serialize("useObjectSpaceNormalMap")
+        private _useObjectSpaceNormalMap = false;
+        /**
+         * Allows using an object space normal map (instead of tangent space).
+         */
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public useObjectSpaceNormalMap: boolean;
+
         @serialize("useParallax")
         @serialize("useParallax")
         private _useParallax = false;
         private _useParallax = false;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
@@ -667,6 +676,8 @@ module BABYLON {
                             defines.PARALLAX = this._useParallax;
                             defines.PARALLAX = this._useParallax;
                             defines.PARALLAXOCCLUSION = this._useParallaxOcclusion;
                             defines.PARALLAXOCCLUSION = this._useParallaxOcclusion;
                         }
                         }
+
+                        defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
                     } else {
                     } else {
                         defines.BUMP = false;
                         defines.BUMP = false;
                     }
                     }
@@ -849,7 +860,7 @@ module BABYLON {
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                     "mBones",
                     "mBones",
-                    "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix", "refractionMatrix",
+                    "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "normalMatrix", "lightmapMatrix", "refractionMatrix",
                     "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                     "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                     "vReflectionPosition", "vReflectionSize",
                     "vReflectionPosition", "vReflectionSize",
                     "logarithmicDepthConstant", "vTangentSpaceParams"
                     "logarithmicDepthConstant", "vTangentSpaceParams"
@@ -973,6 +984,13 @@ module BABYLON {
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
 
 
+            // Normal Matrix
+            if (defines.OBJECTSPACE_NORMALMAP)
+            {
+                world.toNormalMatrix(this._normalMatrix);
+                this.bindOnlyNormalMatrix(this._normalMatrix);               
+            }
+
             let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
             let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
 
 
             // Bones
             // Bones
@@ -1160,7 +1178,7 @@ module BABYLON {
                 // View
                 // View
                 if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this._reflectionTexture || this._refractionTexture) {
                 if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this._reflectionTexture || this._refractionTexture) {
                     this.bindView(effect);
                     this.bindView(effect);
-                }
+                }              
 
 
                 // Fog
                 // Fog
                 MaterialHelper.BindFogParameters(scene, mesh, effect);
                 MaterialHelper.BindFogParameters(scene, mesh, effect);

+ 17 - 0
src/Math/babylon.math.ts

@@ -3894,6 +3894,22 @@
 
 
             return true;
             return true;
         }
         }
+
+        /**
+         * Writes to the given matrix a normal matrix, computed from this one (using values from identity matrix for fourth row and column).  
+         * @param ref matrix to store the result
+         */
+        public toNormalMatrix(ref : Matrix): void {            
+            this.invertToRef(ref)
+            ref.transpose();
+            var m = ref.m;
+            Matrix.FromValuesToRef(
+                m[0], m[1], m[2],  0,
+                m[4], m[5], m[6],  0,
+                m[8], m[9], m[10], 0,
+                0,    0,    0,     1, ref);
+        }
+
         /**
         /**
          * Returns a new Matrix as the extracted rotation matrix from the current one.  
          * Returns a new Matrix as the extracted rotation matrix from the current one.  
          */
          */
@@ -3902,6 +3918,7 @@
             this.getRotationMatrixToRef(result);
             this.getRotationMatrixToRef(result);
             return result;
             return result;
         }
         }
+       
         /**
         /**
          * Extracts the rotation matrix from the current one and sets it as the passed "result".  
          * Extracts the rotation matrix from the current one and sets it as the passed "result".  
          * Returns the current Matrix.  
          * Returns the current Matrix.  

+ 5 - 0
src/Shaders/ShadersInclude/bumpFragment.fx

@@ -25,5 +25,10 @@
 #endif
 #endif
 
 
 #ifdef BUMP
 #ifdef BUMP
+#ifdef OBJECTSPACE_NORMALMAP
+	normalW = normalize(texture2D(bumpSampler, vBumpUV).xyz  * 2.0 - 1.0);
+	normalW = normalize(mat3(normalMatrix) * normalW);	
+#else
 	normalW = perturbNormal(TBN, vBumpUV + uvOffset);
 	normalW = perturbNormal(TBN, vBumpUV + uvOffset);
+#endif
 #endif
 #endif

+ 4 - 0
src/Shaders/ShadersInclude/bumpFragmentFunctions.fx

@@ -11,6 +11,10 @@
 	varying mat3 vTBN;
 	varying mat3 vTBN;
 #endif
 #endif
 
 
+#ifdef OBJECTSPACE_NORMALMAP
+uniform mat4 normalMatrix;
+#endif
+
 	// Thanks to http://www.thetenthplanet.de/archives/1180
 	// Thanks to http://www.thetenthplanet.de/archives/1180
 	mat3 cotangent_frame(vec3 normal, vec3 p, vec2 uv)
 	mat3 cotangent_frame(vec3 normal, vec3 p, vec2 uv)
 	{
 	{