소스 검색

Merge pull request #2 from BabylonJS/master

Refresh from main repo
Etienne Margraff 9 년 전
부모
커밋
92ce49cde3
87개의 변경된 파일2326개의 추가작업 그리고 2668개의 파일을 삭제
  1. 1 2
      Tools/Gulp/config.json
  2. 21 21
      dist/preview release/babylon.core.js
  3. 201 247
      dist/preview release/babylon.d.ts
  4. 28 28
      dist/preview release/babylon.js
  5. 217 481
      dist/preview release/babylon.max.js
  6. 28 28
      dist/preview release/babylon.noworker.js
  7. 4 3
      dist/preview release/what's new.md
  8. 8 10
      materialsLibrary/dist/babylon.fireMaterial.js
  9. 1 1
      materialsLibrary/dist/babylon.fireMaterial.min.js
  10. 10 19
      materialsLibrary/dist/babylon.lavaMaterial.js
  11. 1 1
      materialsLibrary/dist/babylon.lavaMaterial.min.js
  12. 8 10
      materialsLibrary/dist/babylon.normalMaterial.js
  13. 1 1
      materialsLibrary/dist/babylon.normalMaterial.min.js
  14. 116 97
      materialsLibrary/dist/babylon.pbrMaterial.js
  15. 3 3
      materialsLibrary/dist/babylon.pbrMaterial.min.js
  16. 8 10
      materialsLibrary/dist/babylon.simpleMaterial.js
  17. 1 1
      materialsLibrary/dist/babylon.simpleMaterial.min.js
  18. 8 10
      materialsLibrary/dist/babylon.terrainMaterial.js
  19. 1 1
      materialsLibrary/dist/babylon.terrainMaterial.min.js
  20. 11 13
      materialsLibrary/dist/babylon.waterMaterial.js
  21. 1 1
      materialsLibrary/dist/babylon.waterMaterial.min.js
  22. 7 9
      materialsLibrary/materials/fire/babylon.fireMaterial.ts
  23. 18 38
      materialsLibrary/materials/fire/fire.vertex.fx
  24. 8 19
      materialsLibrary/materials/lava/babylon.lavaMaterial.ts
  25. 4 5
      materialsLibrary/materials/lava/lava.fragment.fx
  26. 18 37
      materialsLibrary/materials/lava/lava.vertex.fx
  27. 9 11
      materialsLibrary/materials/normal/babylon.normalMaterial.ts
  28. 18 38
      materialsLibrary/materials/normal/normal.vertex.fx
  29. 136 121
      materialsLibrary/materials/pbr/babylon.pbrMaterial.ts
  30. 164 70
      materialsLibrary/materials/pbr/legacypbr.fragment.fx
  31. 35 35
      materialsLibrary/materials/pbr/legacypbr.vertex.fx
  32. 210 133
      materialsLibrary/materials/pbr/pbr.fragment.fx
  33. 46 38
      materialsLibrary/materials/pbr/pbr.vertex.fx
  34. 7 9
      materialsLibrary/materials/simple/babylon.simpleMaterial.ts
  35. 18 38
      materialsLibrary/materials/simple/simple.vertex.fx
  36. 7 9
      materialsLibrary/materials/terrain/babylon.terrainMaterial.ts
  37. 19 38
      materialsLibrary/materials/terrain/terrain.vertex.fx
  38. 9 11
      materialsLibrary/materials/water/babylon.waterMaterial.ts
  39. 50 0
      materialsLibrary/materials/water/readme.md
  40. 19 13
      materialsLibrary/materials/water/water.fragment.fx
  41. 19 37
      materialsLibrary/materials/water/water.vertex.fx
  42. 164 16
      materialsLibrary/test/add/addpbr.js
  43. 72 0
      materialsLibrary/test/add/addwater.js
  44. 16 17
      materialsLibrary/test/index.html
  45. 46 26
      materialsLibrary/test/index.js
  46. BIN
      materialsLibrary/test/textures/mixMap.png
  47. 1 0
      readme.md
  48. 54 14
      src/Animations/babylon.animation.js
  49. 56 20
      src/Animations/babylon.animation.ts
  50. 5 4
      src/Cameras/babylon.arcRotateCamera.js
  51. 5 4
      src/Cameras/babylon.arcRotateCamera.ts
  52. 8 0
      src/Debug/babylon.debugLayer.js
  53. 48 41
      src/Debug/babylon.debugLayer.ts
  54. 2 1
      src/Layer/babylon.layer.js
  55. 2 1
      src/Layer/babylon.layer.ts
  56. 38 6
      src/Loading/Plugins/babylon.babylonFileLoader.js
  57. 44 7
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  58. 0 368
      src/Materials/Textures/Procedurals/babylon.standardProceduralTexture.ts
  59. 1 0
      src/Materials/Textures/babylon.texture.js
  60. 1 0
      src/Materials/Textures/babylon.texture.ts
  61. 4 0
      src/Materials/babylon.standardMaterial.js
  62. 4 0
      src/Materials/babylon.standardMaterial.ts
  63. 14 0
      src/Math/babylon.math.js
  64. 18 0
      src/Math/babylon.math.ts
  65. 59 27
      src/Mesh/babylon.mesh.vertexData.js
  66. 59 33
      src/Mesh/babylon.mesh.vertexData.ts
  67. 4 4
      src/Particles/babylon.particleSystem.js
  68. 7 7
      src/Particles/babylon.particleSystem.ts
  69. 5 0
      src/Physics/Plugins/babylon.cannonJSPlugin.js
  70. 9 7
      src/Physics/Plugins/babylon.cannonJSPlugin.ts
  71. 5 1
      src/Physics/Plugins/babylon.oimoJSPlugin.js
  72. 10 5
      src/Physics/Plugins/babylon.oimoJSPlugin.ts
  73. 6 0
      src/Physics/babylon.physicsEngine.js
  74. 11 2
      src/Physics/babylon.physicsEngine.ts
  75. 0 69
      src/Shaders/bricktexture.fragment.fx
  76. 0 35
      src/Shaders/cloudtexture.fragment.fx
  77. 15 6
      src/Shaders/default.fragment.fx
  78. 2 2
      src/Shaders/default.vertex.fx
  79. 0 45
      src/Shaders/firetexture.fragment.fx
  80. 0 37
      src/Shaders/grasstexture.fragment.fx
  81. 0 85
      src/Shaders/marbletexture.fragment.fx
  82. 0 30
      src/Shaders/roadtexture.fragment.fx
  83. 0 33
      src/Shaders/woodtexture.fragment.fx
  84. 8 0
      src/Tools/babylon.sceneSerializer.js
  85. 11 8
      src/Tools/babylon.sceneSerializer.ts
  86. 2 1
      src/babylon.engine.js
  87. 11 9
      src/babylon.engine.ts

+ 1 - 2
Tools/Gulp/config.json

@@ -5,7 +5,7 @@
     "minNoWorkerFilename": "babylon.noworker.js",
     "minCoreFilename": "babylon.core.js",
     "declarationFilename": "babylon.d.ts",
-    "outputDirectory": "../../dist/",
+    "outputDirectory": "../../dist/preview release",
     "srcOutputDirectory": "../../src/"
   },
   "core": {
@@ -61,7 +61,6 @@
       "../../src/Materials/Textures/babylon.videoTexture.js",
       "../../src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js",
       "../../src/Materials/Textures/babylon.proceduralTexture.js",
-      "../../src/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js",
       "../../src/Materials/babylon.effect.js",
       "../../src/Materials/babylon.material.js",
       "../../src/Materials/babylon.standardMaterial.js",

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 21 - 21
dist/preview release/babylon.core.js


+ 201 - 247
dist/preview release/babylon.d.ts

@@ -1237,6 +1237,16 @@ declare module BABYLON {
         to: number;
         constructor(name: string, from: number, to: number);
     }
+    /**
+     * Composed of a frame, and an action function
+     */
+    class AnimationEvent {
+        frame: number;
+        action: () => void;
+        onlyOnce: boolean;
+        isDone: boolean;
+        constructor(frame: number, action: () => void, onlyOnce?: boolean);
+    }
     class Animation {
         name: string;
         targetProperty: string;
@@ -1249,6 +1259,7 @@ declare module BABYLON {
         private _stopped;
         _target: any;
         private _easingFunction;
+        private _events;
         targetPropertyPath: string[];
         currentFrame: number;
         allowMatricesInterpolation: boolean;
@@ -1257,6 +1268,15 @@ declare module BABYLON {
         static CreateAndStartAnimation(name: string, node: Node, targetProperty: string, framePerSecond: number, totalFrame: number, from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Animatable;
         static CreateMergeAndStartAnimation(name: string, node: Node, targetProperty: string, framePerSecond: number, totalFrame: number, from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Animatable;
         constructor(name: string, targetProperty: string, framePerSecond: number, dataType: number, loopMode?: number);
+        /**
+         * Add an event to this animation.
+         */
+        addEvent(event: AnimationEvent): void;
+        /**
+         * Remove all events found at the given frame
+         * @param frame
+         */
+        removeEvents(frame: number): void;
         createRange(name: string, from: number, to: number): void;
         deleteRange(name: string): void;
         getRange(name: string): AnimationRange;
@@ -2224,66 +2244,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class BoundingBox {
-        minimum: Vector3;
-        maximum: Vector3;
-        vectors: Vector3[];
-        center: Vector3;
-        extendSize: Vector3;
-        directions: Vector3[];
-        vectorsWorld: Vector3[];
-        minimumWorld: Vector3;
-        maximumWorld: Vector3;
-        private _worldMatrix;
-        constructor(minimum: Vector3, maximum: Vector3);
-        getWorldMatrix(): Matrix;
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersectsSphere(sphere: BoundingSphere): boolean;
-        intersectsMinMax(min: Vector3, max: Vector3): boolean;
-        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
-        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
-        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingInfo {
-        minimum: Vector3;
-        maximum: Vector3;
-        boundingBox: BoundingBox;
-        boundingSphere: BoundingSphere;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        _checkCollision(collider: Collider): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingSphere {
-        minimum: Vector3;
-        maximum: Vector3;
-        center: Vector3;
-        radius: number;
-        centerWorld: Vector3;
-        radiusWorld: number;
-        private _tempRadiusVector;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
-    }
-}
-
-declare module BABYLON {
     class DebugLayer {
         private _scene;
         private _camera;
@@ -2347,6 +2307,7 @@ declare module BABYLON {
         isBackground: boolean;
         color: Color4;
         onDispose: () => void;
+        alphaBlendingMode: number;
         private _scene;
         private _vertexDeclaration;
         private _vertexStrideSize;
@@ -2360,6 +2321,66 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class BoundingBox {
+        minimum: Vector3;
+        maximum: Vector3;
+        vectors: Vector3[];
+        center: Vector3;
+        extendSize: Vector3;
+        directions: Vector3[];
+        vectorsWorld: Vector3[];
+        minimumWorld: Vector3;
+        maximumWorld: Vector3;
+        private _worldMatrix;
+        constructor(minimum: Vector3, maximum: Vector3);
+        getWorldMatrix(): Matrix;
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersectsSphere(sphere: BoundingSphere): boolean;
+        intersectsMinMax(min: Vector3, max: Vector3): boolean;
+        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
+        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
+        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingInfo {
+        minimum: Vector3;
+        maximum: Vector3;
+        boundingBox: BoundingBox;
+        boundingSphere: BoundingSphere;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        _checkCollision(collider: Collider): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingSphere {
+        minimum: Vector3;
+        maximum: Vector3;
+        center: Vector3;
+        radius: number;
+        centerWorld: Vector3;
+        radiusWorld: number;
+        private _tempRadiusVector;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
+    }
+}
+
+declare module BABYLON {
     class LensFlare {
         size: number;
         position: number;
@@ -2402,6 +2423,38 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface ISceneLoaderPlugin {
+        extensions: string;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        private static _registeredPlugins;
+        private static _getPluginForFilename(sceneFilename);
+        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         direction: Vector3;
         position: Vector3;
@@ -2521,38 +2574,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface ISceneLoaderPlugin {
-        extensions: string;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        private static _registeredPlugins;
-        private static _getPluginForFilename(sceneFilename);
-        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     class EffectFallbacks {
         private _defines;
         private _currentRank;
@@ -3158,6 +3179,7 @@ declare module BABYLON {
         static ScalingToRef(x: number, y: number, z: number, result: Matrix): void;
         static Translation(x: number, y: number, z: number): Matrix;
         static TranslationToRef(x: number, y: number, z: number, result: Matrix): void;
+        static Lerp(startValue: Matrix, endValue: Matrix, gradient: number): Matrix;
         static LookAtLH(eye: Vector3, target: Vector3, up: Vector3): Matrix;
         static LookAtLHToRef(eye: Vector3, target: Vector3, up: Vector3, result: Matrix): void;
         static OrthoLH(width: number, height: number, znear: number, zfar: number): Matrix;
@@ -4634,6 +4656,65 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface IPhysicsEnginePlugin {
+        name: string;
+        initialize(iterations?: number): any;
+        setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
+        runOneStep(delta: number): void;
+        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        unregisterMesh(mesh: AbstractMesh): any;
+        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        dispose(): void;
+        isSupported(): boolean;
+        updateBodyPosition(mesh: AbstractMesh): void;
+        getWorldObject(): any;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+    }
+    interface PhysicsBodyCreationOptions {
+        mass: number;
+        friction: number;
+        restitution: number;
+    }
+    interface PhysicsCompoundBodyPart {
+        mesh: Mesh;
+        impostor: number;
+    }
+    class PhysicsEngine {
+        gravity: Vector3;
+        private _currentPlugin;
+        constructor(plugin?: IPhysicsEnginePlugin);
+        _initialize(gravity?: Vector3): void;
+        _runOneStep(delta: number): void;
+        _setGravity(gravity: Vector3): void;
+        _getGravity(): Vector3;
+        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        _unregisterMesh(mesh: AbstractMesh): void;
+        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        _updateBodyPosition(mesh: AbstractMesh): void;
+        dispose(): void;
+        isSupported(): boolean;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+        getPhysicsPluginName(): string;
+        static NoImpostor: number;
+        static SphereImpostor: number;
+        static BoxImpostor: number;
+        static PlaneImpostor: number;
+        static MeshImpostor: number;
+        static CapsuleImpostor: number;
+        static ConeImpostor: number;
+        static CylinderImpostor: number;
+        static ConvexHullImpostor: number;
+        static HeightmapImpostor: number;
+        static Epsilon: number;
+    }
+}
+
+declare module BABYLON {
     class Particle {
         position: Vector3;
         direction: Vector3;
@@ -4684,8 +4765,8 @@ declare module BABYLON {
         color2: Color4;
         colorDead: Color4;
         textureMask: Color4;
-        startDirectionFunction: (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3) => void;
-        startPositionFunction: (worldMatrix: Matrix, positionToUpdate: Vector3) => void;
+        startDirectionFunction: (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle) => void;
+        startPositionFunction: (worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle) => void;
         private particles;
         private _capacity;
         private _scene;
@@ -4854,57 +4935,23 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface IPhysicsEnginePlugin {
-        initialize(iterations?: number): any;
-        setGravity(gravity: Vector3): void;
-        runOneStep(delta: number): void;
-        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        unregisterMesh(mesh: AbstractMesh): any;
-        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        dispose(): void;
-        isSupported(): boolean;
-        updateBodyPosition(mesh: AbstractMesh): void;
-        getWorldObject(): any;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-    }
-    interface PhysicsBodyCreationOptions {
-        mass: number;
-        friction: number;
-        restitution: number;
-    }
-    interface PhysicsCompoundBodyPart {
-        mesh: Mesh;
-        impostor: number;
-    }
-    class PhysicsEngine {
-        gravity: Vector3;
-        private _currentPlugin;
-        constructor(plugin?: IPhysicsEnginePlugin);
-        _initialize(gravity?: Vector3): void;
-        _runOneStep(delta: number): void;
-        _setGravity(gravity: Vector3): void;
-        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        _unregisterMesh(mesh: AbstractMesh): void;
-        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        _updateBodyPosition(mesh: AbstractMesh): void;
+    class ReflectionProbe {
+        name: string;
+        private _scene;
+        private _renderTargetTexture;
+        private _projectionMatrix;
+        private _viewMatrix;
+        private _target;
+        private _add;
+        private _attachedMesh;
+        position: Vector3;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        refreshRate: number;
+        getScene(): Scene;
+        cubeTexture: RenderTargetTexture;
+        renderList: AbstractMesh[];
+        attachToMesh(mesh: AbstractMesh): void;
         dispose(): void;
-        isSupported(): boolean;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-        static NoImpostor: number;
-        static SphereImpostor: number;
-        static BoxImpostor: number;
-        static PlaneImpostor: number;
-        static MeshImpostor: number;
-        static CapsuleImpostor: number;
-        static ConeImpostor: number;
-        static CylinderImpostor: number;
-        static ConvexHullImpostor: number;
-        static HeightmapImpostor: number;
-        static Epsilon: number;
     }
 }
 
@@ -5478,27 +5525,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class ReflectionProbe {
-        name: string;
-        private _scene;
-        private _renderTargetTexture;
-        private _projectionMatrix;
-        private _viewMatrix;
-        private _target;
-        private _add;
-        private _attachedMesh;
-        position: Vector3;
-        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
-        refreshRate: number;
-        getScene(): Scene;
-        cubeTexture: RenderTargetTexture;
-        renderList: AbstractMesh[];
-        attachToMesh(mesh: AbstractMesh): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;
@@ -6410,6 +6436,9 @@ declare module BABYLON {
     }
 }
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
     class ShadowGenerator {
         private static _FILTER_NONE;
@@ -6465,9 +6494,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
     class BaseTexture {
         name: string;
@@ -6616,6 +6642,7 @@ declare module BABYLON {
         static SKYBOX_MODE: number;
         static INVCUBIC_MODE: number;
         static EQUIRECTANGULAR_MODE: number;
+        static FIXED_EQUIRECTANGULAR_MODE: number;
         static CLAMP_ADDRESSMODE: number;
         static WRAP_ADDRESSMODE: number;
         static MIRROR_ADDRESSMODE: number;
@@ -6672,10 +6699,13 @@ declare module BABYLON {
         private _world;
         private _registeredMeshes;
         private _physicsMaterials;
+        private _gravity;
+        name: string;
         initialize(iterations?: number): void;
         private _checkWithEpsilon(value);
         runOneStep(delta: number): void;
         setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
         registerMesh(mesh: AbstractMesh, impostor: number, options?: PhysicsBodyCreationOptions): any;
         private _createShape(mesh, impostor);
         private _createConvexPolyhedron(rawVerts, rawFaces, mesh);
@@ -6699,9 +6729,12 @@ declare module BABYLON {
     class OimoJSPlugin implements IPhysicsEnginePlugin {
         private _world;
         private _registeredMeshes;
+        name: string;
+        private _gravity;
         private _checkWithEpsilon(value);
         initialize(iterations?: number): void;
         setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
         registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
         registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
         private _createBodyAsCompound(part, options, initialMesh);
@@ -6889,82 +6922,3 @@ declare module BABYLON {
         dispose(): void;
     }
 }
-
-declare module BABYLON {
-    class WoodProceduralTexture extends ProceduralTexture {
-        private _ampScale;
-        private _woodColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        ampScale: number;
-        woodColor: Color3;
-    }
-    class FireProceduralTexture extends ProceduralTexture {
-        private _time;
-        private _speed;
-        private _autoGenerateTime;
-        private _fireColors;
-        private _alphaThreshold;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        render(useCameraPostProcess?: boolean): void;
-        static PurpleFireColors: Color3[];
-        static GreenFireColors: Color3[];
-        static RedFireColors: Color3[];
-        static BlueFireColors: Color3[];
-        fireColors: Color3[];
-        time: number;
-        speed: Vector2;
-        alphaThreshold: number;
-    }
-    class CloudProceduralTexture extends ProceduralTexture {
-        private _skyColor;
-        private _cloudColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        skyColor: Color4;
-        cloudColor: Color4;
-    }
-    class GrassProceduralTexture extends ProceduralTexture {
-        private _grassColors;
-        private _herb1;
-        private _herb2;
-        private _herb3;
-        private _groundColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        grassColors: Color3[];
-        groundColor: Color3;
-    }
-    class RoadProceduralTexture extends ProceduralTexture {
-        private _roadColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        roadColor: Color3;
-    }
-    class BrickProceduralTexture extends ProceduralTexture {
-        private _numberOfBricksHeight;
-        private _numberOfBricksWidth;
-        private _jointColor;
-        private _brickColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        numberOfBricksHeight: number;
-        numberOfBricksWidth: number;
-        jointColor: Color3;
-        brickColor: Color3;
-    }
-    class MarbleProceduralTexture extends ProceduralTexture {
-        private _numberOfTilesHeight;
-        private _numberOfTilesWidth;
-        private _amplitude;
-        private _marbleColor;
-        private _jointColor;
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
-        updateShaderUniforms(): void;
-        numberOfTilesHeight: number;
-        numberOfTilesWidth: number;
-        jointColor: Color3;
-        marbleColor: Color3;
-    }
-}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 28 - 28
dist/preview release/babylon.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 217 - 481
dist/preview release/babylon.max.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 28 - 28
dist/preview release/babylon.noworker.js


+ 4 - 3
dist/preview release/what's new.md

@@ -1,6 +1,5 @@
 - 2.3.0:
   - **Major updates**
-    - Adding support for logarithmic depth buffer. [Documentation](http://doc.babylonjs.com/tutorials/Using_logarithmic_depth_buffer) ([deltakosh](https://github.com/deltakosh))
     - Point lights shadow mapping. [Demo here](http://www.babylonjs-playground.com/#LYCSQ#12) ([deltakosh](https://github.com/deltakosh))
     - Introducing [Materials Library](https://github.com/BabylonJS/Babylon.js/tree/master/materialsLibrary) ([deltakosh](https://github.com/deltakosh))
       - Water material: http://doc.babylonjs.com/extensions/Water ([julien-moreau](https://github.com/julien-moreau))
@@ -19,10 +18,11 @@
     - New `Mesh.CreateIcoSphere()` method. [Demo here](http://www.babylonjs-playground.com/#24DUYD) (G'kar)
     - Introducing [babylon.core.js](http://doc.babylonjs.com/generals/Framework_versions) ([deltakosh](https://github.com/deltakosh))
   - **Updates**
+    - New button to log the camera position in the debug layer ([temechon](https://github.com/temechon))
     - Added `Animatable.goToFrame()` ([deltakosh](https://github.com/deltakosh))   
     - Fixed behavior or `Animation.CreateAndStartAnimation` and added `Animation.CreateMergeAndStartAnimation` to reproduce previous behavior ([deltakosh](https://github.com/deltakosh))
     - Adding `StandardMaterial.linkEmissiveWithDiffuse` to, well, link emissive with diffuse value. (With)[http://www.babylonjs-playground.com/#2FPUCS#2] and (without)[http://www.babylonjs-playground.com/#2FPUCS#1] ([deltakosh](https://github.com/deltakosh))
-    - Adding support for equi-rectangular mapping. See [demo here](http://www.babylonjs-playground.com/#27FN5R#8) ([deltakosh](https://github.com/deltakosh))
+    - Adding support for equi-rectangular mapping. See [demo here](http://www.babylonjs-playground.com/#27FN5R#12) ([deltakosh](https://github.com/deltakosh))
     - Sprites and particles scheduler updated to be resolved before transparent objects ([deltakosh](https://github.com/deltakosh))
     - Added ability to deactivate ArcRotateCamera panning mechanism (by setting panningSensibility to 0) ([vouskprod](http://www.github.com/vousk))    
     - Added `DirectionalLight.autoUpdateExtends` to prevent directional lights to adapt to scene extends ([deltakosh](https://github.com/deltakosh))
@@ -37,7 +37,7 @@
     - _Arc_ feature in `CreateCylinder`, `CreateSphere`, `CreateTube`, `CreateDisc` and `CreateLathe` ([jerome](https://github.com/jbousquie))
     - _Slice_ feature in `MeshBuilder.CreateSphere()` ([jerome](https://github.com/jbousquie))
     - `closed` parameter in `MeshBuilder.CreateLathe()` ([jerome](https://github.com/jbousquie))
-    - `diameter` parameter in `MeshBuilder.CreateCreateCylinder()` ([jerome](https://github.com/jbousquie))
+    - `diameter`, `hasRings`, `enclose` parameters in `MeshBuilder.CreateCreateCylinder()` ([jerome](https://github.com/jbousquie))
     - `Material.dispose()` now removes disposed material from meshes ([deltakosh](https://github.com/deltakosh))
     - New `Material.getBindedMeshes()` function ([deltakosh](https://github.com/deltakosh))
     - OimoJS Plugin now uses Quaternions exclusively and calculates body rotations correctly. [PR](https://github.com/BabylonJS/Babylon.js/pull/761) ([RaananW](https://github.com/RaananW))
@@ -47,6 +47,7 @@
     - AbstractMesh.onPhysicsCollide will be triggered when a physics-enabled mesh collides against another. [PR](https://github.com/BabylonJS/Babylon.js/pull/806) ([RaananW](https://github.com/RaananW))
     - Added scene onPointerMove public callback. [PR](https://github.com/BabylonJS/Babylon.js/pull/810) ([RaananW](https://github.com/RaananW))
     - Added streaming support for BABYLON.Sound ([davrous](https://github.com/davrous))
+    - Added collisionsEnabled and workerCollisions for serialization [PR](https://github.com/BabylonJS/Babylon.js/pull/830) ([Dad72](https://github.com/dad72))
   - **Bug fixes**
     - Fixed a bug with spherical mapping ([deltakosh](https://github.com/deltakosh)) 
     - Fixed a bug with clone and createInstance which was forcing the recomputation of bounding boxes ([deltakosh](https://github.com/deltakosh)) 

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8 - 10
materialsLibrary/dist/babylon.fireMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 19
materialsLibrary/dist/babylon.lavaMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.lavaMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8 - 10
materialsLibrary/dist/babylon.normalMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.normalMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 116 - 97
materialsLibrary/dist/babylon.pbrMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 3 - 3
materialsLibrary/dist/babylon.pbrMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8 - 10
materialsLibrary/dist/babylon.simpleMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8 - 10
materialsLibrary/dist/babylon.terrainMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.terrainMaterial.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 11 - 13
materialsLibrary/dist/babylon.waterMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.waterMaterial.min.js


+ 7 - 9
materialsLibrary/materials/fire/babylon.fireMaterial.ts

@@ -13,7 +13,8 @@ module BABYLON {
         public NORMAL = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -146,8 +147,9 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -168,8 +170,8 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -187,13 +189,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 18 - 38
materialsLibrary/materials/fire/fire.vertex.fx

@@ -14,6 +14,10 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#endif
 
 // Uniforms
 
@@ -33,15 +37,8 @@ uniform mat4 viewProjection;
 varying vec2 vDiffuseUV;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
 #endif
 
 #ifdef POINTSIZE
@@ -84,36 +81,19 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
-#endif
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
 
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
+#endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 8 - 19
materialsLibrary/materials/lava/babylon.lavaMaterial.ts

@@ -47,7 +47,8 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -62,9 +63,6 @@ module BABYLON {
         public noiseTexture: BaseTexture;
         public fogColor: Color3;
         public speed : number = 1;
-        public movingSpeed : number = 1;
-        public lowFrequencySpeed : number = 1;
-        public fogDensity : number = 0.15;
 
         private _lastTime : number = 0;
 
@@ -265,10 +263,10 @@ module BABYLON {
                         this._defines.VERTEXALPHA = true;
                     }
                 }
-                
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -311,8 +309,8 @@ module BABYLON {
                     }
                 }
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -334,13 +332,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {
@@ -364,8 +358,7 @@ module BABYLON {
                         "vDiffuseInfos", 
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3","time", "speed","movingSpeed",
-                        "fogColor","fogDensity", "lowFrequencySpeed"
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3","time", "speed", "fogColor"
                     ],
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3", "noiseTexture"
@@ -501,10 +494,6 @@ module BABYLON {
                 this.fogColor = Color3.Black();
             }
             this._effect.setColor3("fogColor", this.fogColor);
-            this._effect.setFloat("fogDensity", this.fogDensity);
-
-            this._effect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
-            this._effect.setFloat("movingSpeed", this.movingSpeed);
 
 
             super.bind(world, mesh);

+ 4 - 5
materialsLibrary/materials/lava/lava.fragment.fx

@@ -10,10 +10,8 @@ varying vec3 vPositionW;
 // MAGMAAAA
 uniform float time;
 uniform float speed;
-uniform float movingSpeed;
 uniform vec3 fogColor;
 uniform sampler2D noiseTexture;
-uniform float fogDensity;
 
 // Varying
 varying float noise;
@@ -404,16 +402,17 @@ void main(void) {
 
 	T1.x += noiseTex.x * 2.0;
 	T1.y += noiseTex.y * 2.0;
-	T2.x -= noiseTex.y * 0.2 + time*0.001*movingSpeed;
-	T2.y += noiseTex.z * 0.2 + time*0.002*movingSpeed;
+	T2.x -= noiseTex.y * 0.2;
+	T2.y += noiseTex.z * 0.2;
 
 	float p = texture2D( noiseTexture, T1 * 3.0 ).a;
 
 	vec4 lavaColor = texture2D( diffuseSampler, T2 * 4.0);
-	vec4 temp = lavaColor * ( vec4( p, p, p, p ) * 2. ) + ( lavaColor * lavaColor - 0.1 );
+	vec4 temp = lavaColor * ( vec4( p, p, p, p ) * 2.0 ) + ( lavaColor * lavaColor - 0.1 );
 
 	baseColor = temp;
 
+	float fogDensity = 0.15;
 	float depth = gl_FragCoord.z * 4.0;
 	const float LOG2 = 1.442695;
     float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );

+ 18 - 37
materialsLibrary/materials/lava/lava.vertex.fx

@@ -1,7 +1,7 @@
 precision highp float;
 // Inputs
 uniform float time;
-uniform float lowFrequencySpeed;
+uniform float speed;
 // Varying
 varying float noise;
 
@@ -19,6 +19,10 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#endif
 
 // Uniforms
 
@@ -40,15 +44,8 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
 #endif
 
 #ifdef POINTSIZE
@@ -210,41 +207,25 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
 
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
 
-	finalWorld = finalWorld * influence;
 #endif
 
 
     // get a turbulent 3d noise using the normal, normal to high freq
     noise = 10.0 *  -.10 * turbulence( .5 * normal + time*1.15 );
     // get a 3d noise using the position, low frequency
-    float b = lowFrequencySpeed * 5.0 * pnoise( 0.05 * position +vec3(time*1.025), vec3( 100.0 ) );
+    float b = 5.0 * pnoise( 0.05 * position +vec3(time*1.025), vec3( 100.0 ) );
     // compose both noises
     float displacement = - 1.5 * noise + b;
 

+ 9 - 11
materialsLibrary/materials/normal/babylon.normalMaterial.ts

@@ -47,7 +47,8 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -258,8 +259,9 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -301,9 +303,9 @@ module BABYLON {
                         fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
                     }
                 }
-                
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+             
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -324,14 +326,10 @@ module BABYLON {
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                 }
-                                
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 18 - 38
materialsLibrary/materials/normal/normal.vertex.fx

@@ -14,16 +14,9 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
 #endif
 
 // Uniforms
@@ -46,6 +39,9 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
+#endif
 
 #ifdef POINTSIZE
 uniform float pointSize;
@@ -98,34 +94,18 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
+
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 136 - 121
materialsLibrary/materials/pbr/babylon.pbrMaterial.ts

@@ -52,9 +52,7 @@ module BABYLON {
         public SHADOWPCF1 = false;
         public SHADOWPCF2 = false;
         public SHADOWPCF3 = false;
-        public DIFFUSEFRESNEL = false;
         public OPACITYFRESNEL = false;
-        public REFLECTIONFRESNEL = false;
         public EMISSIVEFRESNEL = false;
         public FRESNEL = false;
         public NORMAL = false;
@@ -65,11 +63,9 @@ module BABYLON {
         public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
-        public GLOSSINESS = false;
-        public ROUGHNESS = false;
+        public GLOSSINESSFROMSPECULARMAP = false;
         public EMISSIVEASILLUMINATION = false;
         public LINKEMISSIVEWITHDIFFUSE = false;
-        public REFLECTIONFRESNELFROMSPECULAR = false;
         public LIGHTMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public REFLECTIONMAP_3D = false;
@@ -81,6 +77,11 @@ module BABYLON {
         public REFLECTIONMAP_EXPLICIT = false;
         public REFLECTIONMAP_EQUIRECTANGULAR = false;
         public INVERTCUBICMAP = false;
+        public LOGARITHMICDEPTH = false;
+        public CAMERATONEMAP = false;
+        public CAMERACONTRAST = false;
+        public OVERLOADEDVALUES = false;
+        public OVERLOADEDSHADOWVALUES = false;
 
         constructor() {
             super();
@@ -93,11 +94,11 @@ module BABYLON {
         public directIntensity: number = 1.0;
         public emissiveIntensity: number = 1.0;
         public environmentIntensity: number = 1.0;
-        public _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, 0.0);
+        private _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, 0.0);
 
-        public shadowIntensity: number = 1.0;
-        public shadeIntensity: number = 1.0;
-        private _shadowInfos: Vector4 = new Vector4(this.shadowIntensity, this.shadeIntensity, 0.0, 0.0);
+        public overloadedShadowIntensity: number = 1.0;
+        public overloadedShadeIntensity: number = 1.0;
+        private _overloadedShadowInfos: Vector4 = new Vector4(this.overloadedShadowIntensity, this.overloadedShadeIntensity, 0.0, 0.0);
 
         public cameraExposure: number = 1.0;
         public cameraContrast: number = 1.0;
@@ -108,14 +109,17 @@ module BABYLON {
         public overloadedSpecularIntensity: number = 0.0;
         public overloadedEmissiveIntensity: number = 0.0;
         private _overloadedIntensity: Vector4 = new Vector4(this.overloadedAmbientIntensity, this.overloadedDiffuseIntensity, this.overloadedSpecularIntensity, this.overloadedEmissiveIntensity);
+
         public overloadedAmbient: Color3 = BABYLON.Color3.White();
         public overloadedDiffuse: Color3 = BABYLON.Color3.White();
         public overloadedSpecular: Color3 = BABYLON.Color3.White();
         public overloadedEmissive: Color3 = BABYLON.Color3.White();
+        public overloadedReflection: Color3 = BABYLON.Color3.White();
 
-        public overloadedSmoothness: number = 0.0;
-        public overloadedSmoothnessIntensity: number = 0.0;
-        private _overloadedSmoothness: Vector3 = new Vector3(this.overloadedSmoothness, this.overloadedSmoothnessIntensity, 0.0);
+        public overloadedGlossiness: number = 0.0;
+        public overloadedGlossinessIntensity: number = 0.0;
+        public overloadedReflectionIntensity: number = 0.0;
+        private _overloadedGlossiness: Vector3 = new Vector3(this.overloadedGlossiness, this.overloadedGlossinessIntensity, this.overloadedReflectionIntensity);
        
         public disableBumpMap: boolean = false;
 
@@ -131,22 +135,18 @@ module BABYLON {
         public ambientColor = new Color3(0, 0, 0);
         public diffuseColor = new Color3(1, 1, 1);
         public specularColor = new Color3(1, 1, 1);
-        public specularPower = 64;
+        public reflectionColor = new Color3(0.5, 0.5, 0.5);
+        public glossiness = 0.5;
         public emissiveColor = new Color3(0, 0, 0);
         public useAlphaFromDiffuseTexture = false;
         public useEmissiveAsIllumination = false;
         public linkEmissiveWithDiffuse = false;
-        public useReflectionFresnelFromSpecular = false;
         public useSpecularOverAlpha = true;
         public disableLighting = false;
 
-        public roughness = 0;
-
         public useLightmapAsShadowmap = false;
-
-        public diffuseFresnelParameters: FresnelParameters;
+        
         public opacityFresnelParameters: FresnelParameters;
-        public reflectionFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
 
         public useGlossinessFromSpecularMapAlpha = false;
@@ -161,6 +161,8 @@ module BABYLON {
         private _defines = new PBRMaterialDefines();
         private _cachedDefines = new PBRMaterialDefines();
 
+        private _useLogarithmicDepth: boolean;
+
         constructor(name: string, scene: Scene) {
             super(name, scene);
 
@@ -177,6 +179,14 @@ module BABYLON {
             }
         }
 
+        public get useLogarithmicDepth(): boolean {
+            return this._useLogarithmicDepth;
+        }
+
+        public set useLogarithmicDepth(value: boolean) {
+            this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+        }
+
         public needAlphaBlending(): boolean {
             return (this.alpha < 1.0) || (this.opacityTexture != null) || this._shouldUseAlphaFromDiffuseTexture() || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled;
         }
@@ -298,6 +308,7 @@ module BABYLON {
         private static _scaledDiffuse = new Color3();
         private static _scaledSpecular = new Color3();
         private static _scaledEmissive = new Color3();
+        private static _scaledReflection = new Color3();
 
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
@@ -366,7 +377,7 @@ module BABYLON {
             }
 
             var scene = this.getScene();
-            
+
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                     if (this._checkCache(scene, mesh, useInstances)) {
@@ -421,10 +432,6 @@ module BABYLON {
                         needNormals = true;
                         this._defines.REFLECTION = true;
 
-                        if (this.roughness > 0) {
-                            this._defines.ROUGHNESS = true;
-                        }
-
                         if (this.reflectionTexture.coordinatesMode === Texture.INVCUBIC_MODE) {
                             this._defines.INVERTCUBICMAP = true;
                         }
@@ -483,7 +490,7 @@ module BABYLON {
                     } else {
                         needUVs = true;
                         this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESS = this.useGlossinessFromSpecularMapAlpha;
+                        this._defines.GLOSSINESSFROMSPECULARMAP = this.useGlossinessFromSpecularMapAlpha;
                     }
                 }
             }
@@ -518,8 +525,30 @@ module BABYLON {
                 this._defines.LINKEMISSIVEWITHDIFFUSE = true;
             }
 
-            if (this.useReflectionFresnelFromSpecular) {
-                this._defines.REFLECTIONFRESNELFROMSPECULAR = true;
+            if (this.useLogarithmicDepth) {
+                this._defines.LOGARITHMICDEPTH = true;
+            }
+
+            if (this.cameraContrast != 1) {
+                this._defines.CAMERACONTRAST = true;
+            }
+
+            if (this.cameraExposure != 1) {
+                this._defines.CAMERATONEMAP = true;
+            }
+
+            if (this.overloadedShadeIntensity != 1 ||
+                this.overloadedShadowIntensity != 1) {
+                this._defines.OVERLOADEDSHADOWVALUES = true;
+            }
+
+            if (this.overloadedGlossinessIntensity > 0 ||
+                this.overloadedEmissiveIntensity > 0 ||
+                this.overloadedSpecularIntensity > 0 ||
+                this.overloadedDiffuseIntensity > 0 ||
+                this.overloadedAmbientIntensity > 0 ||
+                this.overloadedReflectionIntensity > 0) {
+                this._defines.OVERLOADEDVALUES = true;
             }
 
             // Point size
@@ -538,23 +567,13 @@ module BABYLON {
 
             if (StandardMaterial.FresnelEnabled) {
                 // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled ||
-                    this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
-                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled ||
-                    this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._defines.DIFFUSEFRESNEL = true;
-                    }
+                if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled ||
+                    this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
 
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                         this._defines.OPACITYFRESNEL = true;
                     }
 
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._defines.REFLECTIONFRESNEL = true;
-                    }
-
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                         this._defines.EMISSIVEFRESNEL = true;
                     }
@@ -599,7 +618,7 @@ module BABYLON {
                 }
             }
 
-            // Get correct effect      
+            // Get correct effect
             if (!this._defines.isEqual(this._cachedDefines)) {
                 this._defines.cloneTo(this._cachedDefines);
 
@@ -627,6 +646,14 @@ module BABYLON {
                     fallbacks.addFallback(1, "FOG");
                 }
 
+                if (this._defines.POINTSIZE) {
+                    fallbacks.addFallback(0, "POINTSIZE");
+                }
+
+                if (this._defines.LOGARITHMICDEPTH) {
+                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
+                }
+
                 for (let lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
                     if (!this._defines["LIGHT" + lightIndex]) {
                         continue;
@@ -653,28 +680,20 @@ module BABYLON {
                     fallbacks.addFallback(0, "SPECULARTERM");
                 }
 
-                if (this._defines.DIFFUSEFRESNEL) {
-                    fallbacks.addFallback(1, "DIFFUSEFRESNEL");
-                }
-
                 if (this._defines.OPACITYFRESNEL) {
-                    fallbacks.addFallback(2, "OPACITYFRESNEL");
-                }
-
-                if (this._defines.REFLECTIONFRESNEL) {
-                    fallbacks.addFallback(3, "REFLECTIONFRESNEL");
+                    fallbacks.addFallback(1, "OPACITYFRESNEL");
                 }
 
                 if (this._defines.EMISSIVEFRESNEL) {
-                    fallbacks.addFallback(4, "EMISSIVEFRESNEL");
+                    fallbacks.addFallback(2, "EMISSIVEFRESNEL");
                 }
 
                 if (this._defines.FRESNEL) {
-                    fallbacks.addFallback(4, "FRESNEL");
+                    fallbacks.addFallback(3, "FRESNEL");
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
 
                 //Attributes
@@ -695,7 +714,7 @@ module BABYLON {
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                 }
-                
+
                 if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
@@ -720,7 +739,7 @@ module BABYLON {
                 var join = this._defines.toString();
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor",
+                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor", "vReflectionColor",
                         "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -730,9 +749,9 @@ module BABYLON {
                         "mBones",
                         "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
                         "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
-                        "roughness",
-                        "vPBRLightingIntensity", "vPBRShadowIntensity", "vPBROverloadedIntensity", "vPBRCameraInfos", "vPBROverloadedDiffuse", "vPBROverloadedSpecular", "vPBROverloadedEmissive", "vPBROverloadedSmoothness"
+                        "opacityParts", "emissiveLeftColor", "emissiveRightColor",
+                        "vLightingIntensity", "vOverloadedShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedDiffuse", "vOverloadedReflection", "vOverloadedSpecular", "vOverloadedEmissive", "vOverloadedGlossiness",
+                        "logarithmicDepthConstant"
                     ],
                     ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -788,21 +807,10 @@ module BABYLON {
             if (this._myScene.getCachedMaterial() !== (<BABYLON.Material>this)) {
 
                 if (StandardMaterial.FresnelEnabled) {
-                    // Fresnel
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
-                        this._effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
-                    }
-
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                         this._effect.setColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
                     }
 
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
-                        this._effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
-                    }
-
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                         this._effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
                         this._effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
@@ -839,7 +847,7 @@ module BABYLON {
                     }
 
                     this._effect.setMatrix("reflectionMatrix", this.reflectionTexture.getReflectionTextureMatrix());
-                    this._effect.setFloat2("vReflectionInfos", this.reflectionTexture.level, this.roughness);
+                    this._effect.setFloat2("vReflectionInfos", this.reflectionTexture.level, 0);
                 }
 
                 if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
@@ -893,12 +901,16 @@ module BABYLON {
                 this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
 
                 if (this._defines.SPECULARTERM) {
-                    this._effect.setColor4("vSpecularColor", PBRMaterial._scaledSpecular, this.specularPower);
+                    this._effect.setColor4("vSpecularColor", PBRMaterial._scaledSpecular, this.glossiness);
                 }
 
                 // GAMMA CORRECTION.
                 this.emissiveColor.toLinearSpaceToRef(PBRMaterial._scaledEmissive); 
                 this._effect.setColor3("vEmissiveColor", PBRMaterial._scaledEmissive);
+
+                // GAMMA CORRECTION.
+                this.reflectionColor.toLinearSpaceToRef(PBRMaterial._scaledReflection);
+                this._effect.setColor3("vReflectionColor", PBRMaterial._scaledReflection);
             }
 
             // GAMMA CORRECTION.
@@ -920,39 +932,46 @@ module BABYLON {
                 this._effect.setFloat4("vFogInfos", this._myScene.fogMode, this._myScene.fogStart, this._myScene.fogEnd, this._myScene.fogDensity);
                 this._effect.setColor3("vFogColor", this._myScene.fogColor);
             }
-            
 
             this._lightingInfos.x = this.directIntensity;
             this._lightingInfos.y = this.emissiveIntensity;
             this._lightingInfos.z = this.environmentIntensity;
-            this._effect.setVector4("vPBRLightingIntensity", this._lightingInfos);
+            this._effect.setVector4("vLightingIntensity", this._lightingInfos);
 
-            this._shadowInfos.x = this.shadowIntensity;
-            this._shadowInfos.y = this.shadeIntensity;
-            this._effect.setVector4("vPBRShadowIntensity", this._shadowInfos);
+            this._overloadedShadowInfos.x = this.overloadedShadowIntensity;
+            this._overloadedShadowInfos.y = this.overloadedShadeIntensity;
+            this._effect.setVector4("vOverloadedShadowIntensity", this._overloadedShadowInfos);
 
             this._cameraInfos.x = this.cameraExposure;
             this._cameraInfos.y = this.cameraContrast;
-            this._effect.setVector4("vPBRCameraInfos", this._cameraInfos);
+            this._effect.setVector4("vCameraInfos", this._cameraInfos);
 
             this._overloadedIntensity.x = this.overloadedAmbientIntensity;
             this._overloadedIntensity.y = this.overloadedDiffuseIntensity;
             this._overloadedIntensity.z = this.overloadedSpecularIntensity;
             this._overloadedIntensity.w = this.overloadedEmissiveIntensity;
-            this._effect.setVector4("vPBROverloadedIntensity", this._overloadedIntensity);
+            this._effect.setVector4("vOverloadedIntensity", this._overloadedIntensity);
 
             this.overloadedAmbient.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedAmbient", this._tempColor);
+            this._effect.setColor3("vOverloadedAmbient", this._tempColor);
             this.overloadedDiffuse.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedDiffuse", this._tempColor);
+            this._effect.setColor3("vOverloadedDiffuse", this._tempColor);
             this.overloadedSpecular.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedSpecular", this._tempColor);
+            this._effect.setColor3("vOverloadedSpecular", this._tempColor);
             this.overloadedEmissive.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vPBROverloadedEmissive", this._tempColor);
-
-            this._overloadedSmoothness.x = this.overloadedSmoothness;
-            this._overloadedSmoothness.y = this.overloadedSmoothnessIntensity;
-            this._effect.setVector3("vPBROverloadedSmoothness", this._overloadedSmoothness);
+            this._effect.setColor3("vOverloadedEmissive", this._tempColor);
+            this.overloadedReflection.toLinearSpaceToRef(this._tempColor);
+            this._effect.setColor3("vOverloadedReflection", this._tempColor);
+
+            this._overloadedGlossiness.x = this.overloadedGlossiness;
+            this._overloadedGlossiness.y = this.overloadedGlossinessIntensity;
+            this._overloadedGlossiness.z = this.overloadedReflectionIntensity;
+            this._effect.setVector3("vOverloadedGlossiness", this._overloadedGlossiness);
+
+            // Log. depth
+            if (this._defines.LOGARITHMICDEPTH) {
+                this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(this._myScene.activeCamera.maxZ + 1.0) / Math.LN2));
+            }
 
             super.bind(world, mesh);
 
@@ -1031,7 +1050,33 @@ module BABYLON {
             // Base material
             this.copyTo(newPBRMaterial);
 
-            // PBR material
+            newPBRMaterial.directIntensity = this.directIntensity;
+            newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
+            newPBRMaterial.environmentIntensity = this.environmentIntensity;
+        
+            newPBRMaterial.cameraExposure = this.cameraExposure;
+            newPBRMaterial.cameraContrast = this.cameraContrast;
+
+            newPBRMaterial.overloadedShadowIntensity = this.overloadedShadowIntensity;
+            newPBRMaterial.overloadedShadeIntensity = this.overloadedShadeIntensity;
+        
+            newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
+            newPBRMaterial.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
+            newPBRMaterial.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
+            newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
+            newPBRMaterial.overloadedAmbient = this.overloadedAmbient;
+            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse;
+            newPBRMaterial.overloadedSpecular = this.overloadedSpecular;
+            newPBRMaterial.overloadedEmissive = this.overloadedEmissive;
+            newPBRMaterial.overloadedReflection = this.overloadedReflection;
+
+            newPBRMaterial.overloadedGlossiness = this.overloadedGlossiness;
+            newPBRMaterial.overloadedGlossinessIntensity = this.overloadedGlossinessIntensity;
+            newPBRMaterial.overloadedReflectionIntensity = this.overloadedReflectionIntensity;
+        
+            newPBRMaterial.disableBumpMap = this.disableBumpMap;
+
+            // Standard material
             if (this.diffuseTexture && this.diffuseTexture.clone) {
                 newPBRMaterial.diffuseTexture = this.diffuseTexture.clone();
             }
@@ -1061,48 +1106,18 @@ module BABYLON {
             newPBRMaterial.ambientColor = this.ambientColor.clone();
             newPBRMaterial.diffuseColor = this.diffuseColor.clone();
             newPBRMaterial.specularColor = this.specularColor.clone();
-            newPBRMaterial.specularPower = this.specularPower;
+            newPBRMaterial.reflectionColor = this.reflectionColor.clone();
+            newPBRMaterial.glossiness = this.glossiness;
             newPBRMaterial.emissiveColor = this.emissiveColor.clone();
             newPBRMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
             newPBRMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
             newPBRMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
-            newPBRMaterial.useReflectionFresnelFromSpecular = this.useReflectionFresnelFromSpecular;
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
-            newPBRMaterial.roughness = this.roughness;
-
-            newPBRMaterial.diffuseFresnelParameters = this.diffuseFresnelParameters.clone();
+            
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
-            newPBRMaterial.reflectionFresnelParameters = this.reflectionFresnelParameters.clone();
             newPBRMaterial.opacityFresnelParameters = this.opacityFresnelParameters.clone();
-            
-            newPBRMaterial.directIntensity = this.directIntensity;
-            newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
-            newPBRMaterial.environmentIntensity = this.environmentIntensity;
-    
-            newPBRMaterial.shadowIntensity = this.shadowIntensity;
-            newPBRMaterial.shadeIntensity = this.shadeIntensity;
-    
-            newPBRMaterial.cameraExposure = this.cameraExposure;
-            newPBRMaterial.cameraContrast = this.cameraContrast;
-    
-            newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
-            newPBRMaterial.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
-            newPBRMaterial.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
-            newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
-            newPBRMaterial.overloadedAmbient = this.overloadedAmbient.clone();
-            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse.clone();
-            newPBRMaterial.overloadedSpecular = this.overloadedSpecular.clone();
-            newPBRMaterial.overloadedEmissive = this.overloadedEmissive.clone();
-    
-            newPBRMaterial.overloadedSmoothness = this.overloadedSmoothness;
-            newPBRMaterial.overloadedSmoothnessIntensity = this.overloadedSmoothnessIntensity;
-        
-            newPBRMaterial.disableBumpMap = this.disableBumpMap;
 
             return newPBRMaterial;
         }
     }
-} 
-
-
-/* jshint ignore:end */
+}

+ 164 - 70
materialsLibrary/materials/pbr/legacypbr.fragment.fx

@@ -2,22 +2,30 @@
 
 // Constants
 #define RECIPROCAL_PI2 0.15915494
+#define FRESNEL_MAXIMUM_ON_ROUGH 0.25
 
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
 uniform vec4 vDiffuseColor;
+uniform vec3 vReflectionColor;
 
-// PBR CUSTOM CONTROLS
-uniform vec4 vPBRLightingIntensity;
-uniform vec4 vPBRShadowIntensity;
-uniform vec4 vPBRCameraInfos;
+// CUSTOM CONTROLS
+uniform vec4 vLightingIntensity;
+uniform vec4 vCameraInfos;
 
-uniform vec4 vPBROverloadedIntensity;
-uniform vec3 vPBROverloadedAmbient;
-uniform vec3 vPBROverloadedDiffuse;
-uniform vec3 vPBROverloadedSpecular;
-uniform vec3 vPBROverloadedEmissive;
-uniform vec3 vPBROverloadedSmoothness;
+#ifdef OVERLOADEDVALUES
+uniform vec4 vOverloadedIntensity;
+uniform vec3 vOverloadedAmbient;
+uniform vec3 vOverloadedDiffuse;
+uniform vec3 vOverloadedSpecular;
+uniform vec3 vOverloadedEmissive;
+uniform vec3 vOverloadedReflection;
+uniform vec3 vOverloadedGlossiness;
+#endif
+
+#ifdef OVERLOADEDSHADOWVALUES
+uniform vec4 vOverloadedShadowIntensity;
+#endif
 
 // PBR CUSTOM CONSTANTS
 const float kPi = 3.1415926535897932384626433832795;
@@ -70,6 +78,13 @@ vec3 fresnelSchlickGGX(float VdotH, vec3 reflectance0, vec3 reflectance90)
     return reflectance0 + (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotH, 0., 1.), 5.0);
 }
 
+vec3 FresnelSchlickEnvironmentGGX(float VdotN, vec3 reflectance0, vec3 reflectance90, float smoothness)
+{
+    // Schlick fresnel approximation, extended with basic smoothness term so that rough surfaces do not approach reflectance90 at grazing angle
+    float weight = mix(FRESNEL_MAXIMUM_ON_ROUGH, 1.0, smoothness);
+    return reflectance0 + weight * (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotN, 0., 1.), 5.0);
+}
+
 // Cook Torance Specular computation.
 vec3 computeSpecularTerm(float NdotH, float NdotL, float NdotV, float VdotH, float roughness, vec3 specularColor)
 {
@@ -121,38 +136,42 @@ vec3 toGammaSpace(vec3 color)
     return vec3(pow(color.r, 1.0 / 2.2), pow(color.g, 1.0 / 2.2), pow(color.b, 1.0 / 2.2));
 }
 
-vec3 toneMaps(vec3 color)
-{
-    color = max(color, 0.0);
-
-    // TONE MAPPING / EXPOSURE
-    color.rgb = color.rgb * vPBRCameraInfos.x;
-
-    float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
-    vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
-    color.rgb = mix(color.rgb, tonemapped, 1.0);
-    return color;
-}
+#ifdef CAMERATONEMAP
+    vec3 toneMaps(vec3 color)
+    {
+        color = max(color, 0.0);
 
-vec4 contrasts(vec4 color)
-{
-    color = clamp(color, 0.0, 1.0);
+        // TONE MAPPING / EXPOSURE
+        color.rgb = color.rgb * vCameraInfos.x;
 
-    vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
-    float contrast = vPBRCameraInfos.y;
-    if (contrast < 1.0)
-    {
-        // Decrease contrast: interpolate towards zero-contrast image (flat grey)
-        color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
+        vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
+        color.rgb = mix(color.rgb, tonemapped, 1.0);
+        return color;
     }
-    else
+#endif
+
+#ifdef CAMERACONTRAST
+    vec4 contrasts(vec4 color)
     {
-        // Increase contrast: apply simple shoulder-toe high contrast curve
-        color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        color = clamp(color, 0.0, 1.0);
+
+        vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
+        float contrast = vCameraInfos.y;
+        if (contrast < 1.0)
+        {
+            // Decrease contrast: interpolate towards zero-contrast image (flat grey)
+            color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        }
+        else
+        {
+            // Increase contrast: apply simple shoulder-toe high contrast curve
+            color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        }
+
+        return color;
     }
-
-    return color;
-}
+#endif
 // END PBR HELPER METHODS
 
 #ifdef SPECULARTERM
@@ -448,12 +467,15 @@ void main(void) {
     baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
-    baseColor.rgb = mix(baseColor.rgb, vPBROverloadedDiffuse, vPBROverloadedIntensity.y);
-
 #ifdef VERTEXCOLOR
     baseColor.rgb *= vColor.rgb;
 #endif
 
+#ifdef OVERLOADEDVALUES
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+    diffuseColor.rgb = mix(diffuseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+#endif
+
     // Bump
 #ifdef NORMAL
     vec3 normalW = normalize(vNormalW);
@@ -466,7 +488,9 @@ void main(void) {
 
 #ifdef AMBIENT
     baseAmbientColor = texture2D(ambientSampler, vAmbientUV).rgb * vAmbientInfos.y;
-    baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vPBROverloadedAmbient, vPBROverloadedIntensity.x);
+    #ifdef OVERLOADEDVALUES
+        baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vOverloadedAmbient, vOverloadedIntensity.x);
+    #endif
 #endif
 
     // Specular map
@@ -474,24 +498,41 @@ void main(void) {
     float glossiness = vSpecularColor.a;
     vec3 specularColor = vSpecularColor.rgb;
 
-#ifdef SPECULAR
-    vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
-    specularColor *= toLinearSpace(specularMapColor.rgb);
-#ifdef GLOSSINESS
-    glossiness = specularMapColor.a;
-#endif
-#endif
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
-    glossiness = computeDefaultGlossiness(glossiness, specularColor);
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
-    #else
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
+
+    #ifdef SPECULAR
+            vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
+            specularColor = toLinearSpace(specularMapColor.rgb);
+
+        #ifdef OVERLOADEDVALUES
+                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        #endif
+
+        #ifdef GLOSSINESSFROMSPECULARMAP
+            glossiness = specularMapColor.a;
+        #else
+            glossiness = computeDefaultGlossiness(glossiness, specularColor);
+        #endif
+    #endif
+
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
+    #endif
+#else
     float glossiness = 0.;
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
+    #endif
+
     vec3 specularColor = vec3(0., 0., 0);
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    #ifdef OVERLOADEDVALUES
+            specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 #endif
 
-    // Apply Energy Conservation.
+    // Apply Energy Conservation taking in account the environment level only if the environment is present.
     float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
@@ -506,7 +547,11 @@ void main(void) {
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
-    vec3 shadowedOnly = vPBROverloadedDiffuse;
+
+#ifdef OVERLOADEDSHADOWVALUES
+    vec3 shadowedOnlyDiffuseBase = vec3(1., 1., 1.);
+#endif
+
 #ifdef SPECULARTERM
     vec3 specularBase = vec3(0., 0., 0.);
 #endif
@@ -528,7 +573,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -551,7 +598,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -574,7 +623,9 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -597,15 +648,32 @@ void main(void) {
 
     shadow = 1.;
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
 #endif
 #endif
 
-    // Reflection
-    vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vReflectionColor.rgb;
+vec3 ambientReflectionColor = vReflectionColor.rgb;
+
+reflectionColor *= vLightingIntensity.z;
+ambientReflectionColor *= vLightingIntensity.z;
+
+// Compute reflection specular fresnel
+vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
+vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
+reflectionColor *= specularEnvironmentReflectanceViewer;
+
+#ifdef OVERLOADEDVALUES
+    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
+    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
+#endif
 
 #ifdef OPACITY
     vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
@@ -628,20 +696,41 @@ void main(void) {
 #ifdef EMISSIVE
     vec3 emissiveColorTex = texture2D(emissiveSampler, vEmissiveUV).rgb;
     emissiveColor = toLinearSpace(emissiveColorTex.rgb) * emissiveColor * vEmissiveInfos.y;
-    emissiveColor = mix(emissiveColor, vPBROverloadedEmissive, vPBROverloadedIntensity.w);
+#endif
+
+#ifdef OVERLOADEDVALUES
+    emissiveColor = mix(emissiveColor, vOverloadedEmissive, vOverloadedIntensity.w);
 #endif
 
     // Composition
 #ifdef EMISSIVEASILLUMINATION
     vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+
+    #ifdef OVERLOADEDSHADOWVALUES
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    #endif
 #else
     #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #ifdef OVERLOADEDSHADOWVALUES
+                shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #endif
     #else
-        vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #ifdef OVERLOADEDSHADOWVALUES
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #endif
     #endif
 #endif
 
+#ifdef OVERLOADEDSHADOWVALUES
+      finalDiffuse = mix(finalDiffuse, shadowedOnlyDiffuseBase, (1.0 - vOverloadedShadowIntensity.y));
+#endif
+
+// diffuse lighting from environment 0.2 replaces Harmonic...
+// Ambient Reflection already includes the environment intensity.
+finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
+
 #ifdef SPECULARTERM
     vec3 finalSpecular = specularBase * specularColor;
 #else
@@ -652,20 +741,25 @@ void main(void) {
     alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif
 
-    // Composition
+// Composition
+// Reflection already includes the environment intensity.
 #ifdef EMISSIVEASILLUMINATION
-    vec4 color = vec4(finalDiffuse * baseAmbientColor * vPBRLightingIntensity.x + finalSpecular * vPBRLightingIntensity.x + reflectionColor * vPBRLightingIntensity.z + emissiveColor * vPBRLightingIntensity.y, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor + emissiveColor * vLightingIntensity.y, alpha);
 #else
-    vec4 color = vec4(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor, alpha);
 #endif
 
     color = max(color, 0.0);
 
+#ifdef CAMERATONEMAP
     color.rgb = toneMaps(color.rgb);
+#endif
+
     color.rgb = toGammaSpace(color.rgb);
-    color = contrasts(color);
 
-    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vPBRShadowIntensity.y));
+#ifdef CAMERACONTRAST
+    color = contrasts(color);
+#endif
 
     gl_FragColor = color;
-}
+}

+ 35 - 35
materialsLibrary/materials/pbr/legacypbr.vertex.fx

@@ -14,14 +14,14 @@ attribute vec4 color;
 #endif
 
 #if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
+uniform mat4 mBones[BonesPerMesh];
 
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniforms
@@ -73,36 +73,36 @@ varying float fClipDistance;
 #endif
 
 void main(void) {
-	mat4 finalWorld = world;
+    mat4 finalWorld = world;
 
 #if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
+    mat4 influence;
+    influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+#if NUM_BONE_INFLUENCERS > 1
+    influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+#endif 
+#if NUM_BONE_INFLUENCERS > 2
+    influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+    influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
+
+#if NUM_BONE_INFLUENCERS > 4
+    influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+#endif
+#if NUM_BONE_INFLUENCERS > 5
+    influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+    influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+    influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
+
+    finalWorld = finalWorld * influence;
 #endif
 
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);

+ 210 - 133
materialsLibrary/materials/pbr/pbr.fragment.fx

@@ -1,4 +1,12 @@
-precision highp float;
+#ifdef BUMP
+#extension GL_OES_standard_derivatives : enable
+#endif
+
+#ifdef LOGARITHMICDEPTH
+#extension GL_EXT_frag_depth : enable
+#endif
+
+precision highp float;
 
 // Constants
 #define RECIPROCAL_PI2 0.15915494
@@ -6,19 +14,26 @@
 
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
+uniform vec3 vReflectionColor;
 uniform vec4 vDiffuseColor;
 
-// PBR CUSTOM CONTROLS
-uniform vec4 vPBRLightingIntensity;
-uniform vec4 vPBRShadowIntensity;
-uniform vec4 vPBRCameraInfos;
+// CUSTOM CONTROLS
+uniform vec4 vLightingIntensity;
+uniform vec4 vCameraInfos;
 
-uniform vec4 vPBROverloadedIntensity;
-uniform vec3 vPBROverloadedAmbient;
-uniform vec3 vPBROverloadedDiffuse;
-uniform vec3 vPBROverloadedSpecular;
-uniform vec3 vPBROverloadedEmissive;
-uniform vec3 vPBROverloadedSmoothness;
+#ifdef OVERLOADEDVALUES
+    uniform vec4 vOverloadedIntensity;
+    uniform vec3 vOverloadedAmbient;
+    uniform vec3 vOverloadedDiffuse;
+    uniform vec3 vOverloadedSpecular;
+    uniform vec3 vOverloadedEmissive;
+    uniform vec3 vOverloadedReflection;
+    uniform vec3 vOverloadedGlossiness;
+#endif
+
+#ifdef OVERLOADEDSHADOWVALUES
+    uniform vec4 vOverloadedShadowIntensity;
+#endif
 
 // PBR CUSTOM CONSTANTS
 const float kPi = 3.1415926535897932384626433832795;
@@ -130,40 +145,44 @@ vec3 toGammaSpace(vec3 color)
     return vec3(pow(color.r, 1.0 / 2.2), pow(color.g, 1.0 / 2.2), pow(color.b, 1.0 / 2.2));
 }
 
-vec3 toneMaps(vec3 color)
-{
-    color = max(color, 0.0);
-
-    // TONE MAPPING / EXPOSURE
-    color.rgb = color.rgb * vPBRCameraInfos.x;
-
-    float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
-    // PI Test
-    // tuning *=  kPi;
-    vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
-    color.rgb = mix(color.rgb, tonemapped, 1.0);
-    return color;
-}
+#ifdef CAMERATONEMAP
+    vec3 toneMaps(vec3 color)
+    {
+        color = max(color, 0.0);
 
-vec4 contrasts(vec4 color)
-{
-    color = clamp(color, 0.0, 1.0);
+        // TONE MAPPING / EXPOSURE
+        color.rgb = color.rgb * vCameraInfos.x;
 
-    vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
-    float contrast = vPBRCameraInfos.y;
-    if (contrast < 1.0)
-    {
-        // Decrease contrast: interpolate towards zero-contrast image (flat grey)
-        color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        float tuning = 1.5; // TODO: sync up so e.g. 18% greys are matched to exposure appropriately
+        // PI Test
+        // tuning *=  kPi;
+        vec3 tonemapped = 1.0 - exp2(-color.rgb * tuning); // simple local photographic tonemapper
+        color.rgb = mix(color.rgb, tonemapped, 1.0);
+        return color;
     }
-    else
+#endif
+
+#ifdef CAMERACONTRAST
+    vec4 contrasts(vec4 color)
     {
-        // Increase contrast: apply simple shoulder-toe high contrast curve
-        color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        color = clamp(color, 0.0, 1.0);
+
+        vec3 resultHighContrast = color.rgb * color.rgb * (3.0 - 2.0 * color.rgb);
+        float contrast = vCameraInfos.y;
+        if (contrast < 1.0)
+        {
+            // Decrease contrast: interpolate towards zero-contrast image (flat grey)
+            color.rgb = mix(vec3(0.5, 0.5, 0.5), color.rgb, contrast);
+        }
+        else
+        {
+            // Increase contrast: apply simple shoulder-toe high contrast curve
+            color.rgb = mix(color.rgb, resultHighContrast, contrast - 1.0);
+        }
+
+        return color;
     }
-
-    return color;
-}
+#endif
 // END PBR HELPER METHODS
 
 #ifdef SPECULARTERM
@@ -321,11 +340,6 @@ float computeFresnelTerm(vec3 viewDirection, vec3 worldNormal, float bias, float
 }
 #endif
 
-#ifdef DIFFUSEFRESNEL
-uniform vec4 diffuseLeftColor;
-uniform vec4 diffuseRightColor;
-#endif
-
 #ifdef OPACITYFRESNEL
 uniform vec4 opacityParts;
 #endif
@@ -412,11 +426,6 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 #endif
 }
 
-#ifdef REFLECTIONFRESNEL
-uniform vec4 reflectionLeftColor;
-uniform vec4 reflectionRightColor;
-#endif
-
 #endif
 
 // Shadows
@@ -442,7 +451,11 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 
     if (depth > shadow)
     {
-        return mix(1.0, darkness, vPBRShadowIntensity.x);
+#ifdef OVERLOADEDSHADOWVALUES
+        return mix(1.0, darkness, vOverloadedShadowIntensity.x);
+#else
+        return darkness;
+#endif
     }
     return 1.0;
 }
@@ -473,7 +486,11 @@ float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, fl
     if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
     if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
 
-    return  min(1.0, mix(1.0, visibility + darkness, vPBRShadowIntensity.x));
+#ifdef OVERLOADEDSHADOWVALUES
+    return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
+#else
+    return  min(1.0, visibility + darkness);
+#endif
 }
 #endif
 
@@ -493,7 +510,11 @@ float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float dark
 
     if (depth.z > shadow)
     {
-        return mix(1.0, darkness, vPBRShadowIntensity.x);
+#ifdef OVERLOADEDSHADOWVALUES
+        return mix(1.0, darkness, vOverloadedShadowIntensity.x);
+#else
+        return darkness;
+#endif
     }
     return 1.;
 }
@@ -525,7 +546,11 @@ float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, flo
     if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
     if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
 
-    return  min(1.0, mix(1.0, visibility + darkness, vPBRShadowIntensity.x));
+#ifdef OVERLOADEDSHADOWVALUES
+    return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
+#else
+    return  min(1.0, visibility + darkness);
+#endif
 }
 
 // Thanks to http://devmaster.net/
@@ -562,7 +587,11 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
     vec4 texel = texture2D(shadowSampler, uv);
 
     vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-    return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vPBRShadowIntensity.x));
+#ifdef OVERLOADEDSHADOWVALUES
+    return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vOverloadedShadowIntensity.x));
+#else
+    return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
+#endif
 }
 #endif
 
@@ -570,7 +599,6 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 
 // Bump
 #ifdef BUMP
-#extension GL_OES_standard_derivatives : enable
 varying vec2 vBumpUV;
 uniform vec2 vBumpInfos;
 uniform sampler2D bumpSampler;
@@ -608,6 +636,11 @@ vec3 perturbNormal(vec3 viewDir)
 varying float fClipDistance;
 #endif
 
+#ifdef LOGARITHMICDEPTH
+uniform float logarithmicDepthConstant;
+varying float vFragmentDepth;
+#endif
+
 // Fog
 #ifdef FOG
 
@@ -788,13 +821,15 @@ void main(void) {
     baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
-    baseColor.rgb = mix(baseColor.rgb, vPBROverloadedDiffuse, vPBROverloadedIntensity.y);
-
-
 #ifdef VERTEXCOLOR
     baseColor.rgb *= vColor.rgb;
 #endif
 
+#ifdef OVERLOADEDVALUES
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+    diffuseColor.rgb = mix(diffuseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+#endif
+
     // Bump
 #ifdef NORMAL
     vec3 normalW = normalize(vNormalW);
@@ -812,36 +847,52 @@ void main(void) {
 
 #ifdef AMBIENT
     baseAmbientColor = texture2D(ambientSampler, vAmbientUV).rgb * vAmbientInfos.y;
-    baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vPBROverloadedAmbient, vPBROverloadedIntensity.x);
+    
+    #ifdef OVERLOADEDVALUES
+        baseAmbientColor.rgb = mix(baseAmbientColor.rgb, vOverloadedAmbient, vOverloadedIntensity.x);
+    #endif
 #endif
 
     // Specular map
 #ifdef SPECULARTERM
     float glossiness = vSpecularColor.a;
     vec3 specularColor = vSpecularColor.rgb;
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 
     #ifdef SPECULAR
         vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
         specularColor = toLinearSpace(specularMapColor.rgb);
-        specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
 
-        #ifdef GLOSSINESS
+        #ifdef OVERLOADEDVALUES
+                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        #endif
+
+        #ifdef GLOSSINESSFROMSPECULARMAP
             glossiness = specularMapColor.a;
         #else
             glossiness = computeDefaultGlossiness(glossiness, specularColor);
         #endif
     #endif
 
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
+    #endif
 #else
     float glossiness = 0.;
-    glossiness = mix(glossiness, vPBROverloadedSmoothness.x, vPBROverloadedSmoothness.y);
+    #ifdef OVERLOADEDVALUES
+        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
+    #endif
+    
     vec3 specularColor = vec3(0., 0., 0);
-    specularColor.rgb = mix(specularColor.rgb, vPBROverloadedSpecular, vPBROverloadedIntensity.z);
+    #ifdef OVERLOADEDVALUES
+        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+    #endif
 #endif
 
-    // Apply Energy Conservation.
+    // Apply Energy Conservation taking in account the environment level only if the environment is present.
     float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
@@ -856,7 +907,10 @@ void main(void) {
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
-    vec3 shadowedOnly = vPBROverloadedDiffuse;
+    
+#ifdef OVERLOADEDSHADOWVALUES
+    vec3 shadowedOnlyDiffuseBase = vec3(1., 1., 1.);
+#endif
 
 #ifdef SPECULARTERM
     vec3 specularBase = vec3(0., 0., 0.);
@@ -898,7 +952,9 @@ void main(void) {
     shadow = 1.;
 #endif
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -941,7 +997,9 @@ void main(void) {
 #endif
 
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -984,7 +1042,9 @@ void main(void) {
 #endif
 
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
@@ -1026,43 +1086,38 @@ void main(void) {
     shadow = 1.;
 #endif
 
-
     diffuseBase += info.diffuse * shadow;
-    shadowedOnly *= shadow;
+#ifdef OVERLOADEDSHADOWVALUES
+    shadowedOnlyDiffuseBase *= shadow;
+#endif
 
 #ifdef SPECULARTERM
     specularBase += info.specular * shadow;
 #endif
 #endif
 
-    // Reflection
-    vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vReflectionColor.rgb;
+vec3 ambientReflectionColor = vReflectionColor.rgb;
 
 #ifdef REFLECTION
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
-    vec3 ambientReflectionColor = vec3(0.1, 0.1, 0.1);
 
     #ifdef REFLECTIONMAP_3D
         float bias = 0.;
 
-        #ifdef ROUGHNESS
-            bias = 20.;
-            
-            #ifdef SPECULARTERM
-                bias *= (1.0 - glossiness);
-            #endif
+        #ifdef SPECULARTERM
+            // Go mat -> blurry reflexion according to glossiness
+            bias = 20. * (1.0 - glossiness);
         #endif
 
-            reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
-            reflectionColor = toLinearSpace(reflectionColor.rgb);
-
-            ambientReflectionColor = textureCube(reflectionCubeSampler, normalW, 20.).rgb;
-            ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
+        reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
+        reflectionColor = toLinearSpace(reflectionColor.rgb);
 
-            reflectionColor = reflectionColor * vReflectionInfos.y;
-            //reflectionColor = reflectionColor * vReflectionInfos.y * shadow;
+        ambientReflectionColor = textureCube(reflectionCubeSampler, normalW, 20.).rgb * vReflectionInfos.x;
+        ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
     #else
-            vec2 coords = vReflectionUVW.xy;
+        vec2 coords = vReflectionUVW.xy;
 
         #ifdef REFLECTIONMAP_PROJECTION
             coords /= vReflectionUVW.z;
@@ -1073,33 +1128,34 @@ void main(void) {
         reflectionColor = texture2D(reflection2DSampler, coords).rgb * vReflectionInfos.x;
         reflectionColor = toLinearSpace(reflectionColor.rgb);
 
-        ambientReflectionColor = texture2D(reflection2DSampler, coords, 10.).rgb;
+        ambientReflectionColor = texture2D(reflection2DSampler, coords, 20.).rgb * vReflectionInfos.x;
         ambientReflectionColor = toLinearSpace(ambientReflectionColor.rgb);
     #endif
+#endif
 
-    #ifdef REFLECTIONFRESNEL
-        #ifdef REFLECTIONFRESNELFROMSPECULAR
-            // Compute reflection specular fresnel
-            vec3 specularEnvironmentR0 = specularColor.rgb;
-            vec3 specularEnvironmentR90 = reflectionLeftColor.rgb;
-            vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
-            reflectionColor *= specularEnvironmentReflectanceViewer;
-        #else
-            float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
-            reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-        #endif
-    #endif
+#ifdef OVERLOADEDVALUES
+    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
+    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
 #endif
 
+reflectionColor *= vLightingIntensity.z;
+ambientReflectionColor *= vLightingIntensity.z;
+
+// Compute reflection specular fresnel
+vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
+vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
+reflectionColor *= specularEnvironmentReflectanceViewer;
+
 #ifdef OPACITY
     vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
 
-#ifdef OPACITYRGB
-    opacityMap.rgb = opacityMap.rgb * vec3(0.3, 0.59, 0.11);
-    alpha *= (opacityMap.x + opacityMap.y + opacityMap.z)* vOpacityInfos.y;
-#else
-    alpha *= opacityMap.a * vOpacityInfos.y;
-#endif
+    #ifdef OPACITYRGB
+        opacityMap.rgb = opacityMap.rgb * vec3(0.3, 0.59, 0.11);
+        alpha *= (opacityMap.x + opacityMap.y + opacityMap.z)* vOpacityInfos.y;
+    #else
+        alpha *= opacityMap.a * vOpacityInfos.y;
+    #endif
 
 #endif
 
@@ -1118,7 +1174,10 @@ void main(void) {
 #ifdef EMISSIVE
     vec3 emissiveColorTex = texture2D(emissiveSampler, vEmissiveUV).rgb;
     emissiveColor = toLinearSpace(emissiveColorTex.rgb) * emissiveColor * vEmissiveInfos.y;
-    emissiveColor = mix(emissiveColor, vPBROverloadedEmissive, vPBROverloadedIntensity.w);
+#endif
+
+#ifdef OVERLOADEDVALUES
+    emissiveColor = mix(emissiveColor, vOverloadedEmissive, vOverloadedIntensity.w);
 #endif
 
 #ifdef EMISSIVEFRESNEL
@@ -1127,67 +1186,85 @@ void main(void) {
     emissiveColor *= emissiveLeftColor.rgb * (1.0 - emissiveFresnelTerm) + emissiveFresnelTerm * emissiveRightColor.rgb;
 #endif
 
-    // Fresnel
-#ifdef DIFFUSEFRESNEL
-    float diffuseFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, diffuseRightColor.a, diffuseLeftColor.a);
-
-    diffuseBase *= diffuseLeftColor.rgb * (1.0 - diffuseFresnelTerm) + diffuseFresnelTerm * diffuseRightColor.rgb;
-#endif
-
     // Composition
 #ifdef EMISSIVEASILLUMINATION
     vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    
+    #ifdef OVERLOADEDSHADOWVALUES
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    #endif
 #else
     #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+
+        #ifdef OVERLOADEDSHADOWVALUES
+            shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #endif
     #else
-        vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
+        vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+
+        #ifdef OVERLOADEDSHADOWVALUES
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+        #endif
     #endif
 #endif
 
-#ifdef REFLECTION
-    // diffuse lighting from environment
-    finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2 * vPBRLightingIntensity.z;
+#ifdef OVERLOADEDSHADOWVALUES
+    finalDiffuse = mix(finalDiffuse, shadowedOnlyDiffuseBase, (1.0 - vOverloadedShadowIntensity.y));
 #endif
 
+// diffuse lighting from environment 0.2 replaces Harmonic...
+// Ambient Reflection already includes the environment intensity.
+finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
+
 #ifdef SPECULARTERM
     vec3 finalSpecular = specularBase * specularColor;
 #else
     vec3 finalSpecular = vec3(0.0);
 #endif
 
+#ifdef OVERLOADEDSHADOWVALUES
+    finalSpecular = mix(finalSpecular, vec3(0.0), (1.0 - vOverloadedShadowIntensity.y));
+#endif
+
 #ifdef SPECULAROVERALPHA
     alpha = clamp(alpha + dot(finalSpecular, vec3(0.3, 0.59, 0.11)), 0., 1.);
 #endif
 
-    // Composition
+// Composition
+// Reflection already includes the environment intensity.
 #ifdef EMISSIVEASILLUMINATION
-    vec4 color = vec4(finalDiffuse * baseAmbientColor * vPBRLightingIntensity.x + finalSpecular * vPBRLightingIntensity.x + reflectionColor * vPBRLightingIntensity.z + emissiveColor * vPBRLightingIntensity.y, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor + emissiveColor * vLightingIntensity.y, alpha);
 #else
-    vec4 color = vec4(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor, alpha);
+    vec4 color = vec4(finalDiffuse * baseAmbientColor * vLightingIntensity.x + finalSpecular * vLightingIntensity.x + reflectionColor, alpha);
 #endif
 
 #ifdef LIGHTMAP
     vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV).rgb * vLightmapInfos.y;
 
-#ifdef USELIGHTMAPASSHADOWMAP
-    color.rgb *= lightmapColor;
-#else
-    color.rgb += lightmapColor;
-#endif
+    #ifdef USELIGHTMAPASSHADOWMAP
+        color.rgb *= lightmapColor;
+    #else
+        color.rgb += lightmapColor;
+    #endif
 #endif
 
 #ifdef FOG
     float fog = CalcFogFactor();
     color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
 #endif
+
     color = max(color, 0.0);
 
+#ifdef CAMERATONEMAP
     color.rgb = toneMaps(color.rgb);
+#endif
+
     color.rgb = toGammaSpace(color.rgb);
-    color = contrasts(color);
 
-    color.rgb = mix(color.rgb, shadowedOnly, (1.0 - vPBRShadowIntensity.y));
+#ifdef CAMERACONTRAST
+    color = contrasts(color);
+#endif
 
     // Normal Display.
     // gl_FragColor = vec4(normalW * 0.5 + 0.5, 1.0);
@@ -1215,4 +1292,4 @@ void main(void) {
     //gl_FragColor = vec4(test.x, test.y, 1.0, 1.0);
 
     gl_FragColor = color;
-}
+}

+ 46 - 38
materialsLibrary/materials/pbr/pbr.vertex.fx

@@ -14,16 +14,15 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-
 #if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
+uniform mat4 mBones[BonesPerMesh];
 
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniforms
@@ -132,49 +131,52 @@ varying vec3 vPositionUVW;
 varying vec3 vDirectionW;
 #endif
 
+#ifdef LOGARITHMICDEPTH
+uniform float logarithmicDepthConstant;
+varying float vFragmentDepth;
+#endif
+
 void main(void) {
-    mat4 finalWorld;
 
 #ifdef REFLECTIONMAP_SKYBOX
     vPositionUVW = position;
 #endif 
 
 #ifdef INSTANCES
-    finalWorld = mat4(world0, world1, world2, world3);
+    mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-    finalWorld = world;
+    mat4 finalWorld = world;
 #endif
 
 #if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
+    mat4 influence;
+    influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+#if NUM_BONE_INFLUENCERS > 1
+    influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+#endif 
+#if NUM_BONE_INFLUENCERS > 2
+    influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+    influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
+
+#if NUM_BONE_INFLUENCERS > 4
+    influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
 #endif
+#if NUM_BONE_INFLUENCERS > 5
+    influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+    influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+    influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
 
+    finalWorld = finalWorld * influence;
+#endif
 
     gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
@@ -309,4 +311,10 @@ void main(void) {
 #ifdef POINTSIZE
     gl_PointSize = pointSize;
 #endif
+
+    // Log. depth
+#ifdef LOGARITHMICDEPTH
+    vFragmentDepth = 1.0 + gl_Position.w;
+    gl_Position.z = log2(max(0.000001, vFragmentDepth)) * logarithmicDepthConstant;
+#endif
 }

+ 7 - 9
materialsLibrary/materials/simple/babylon.simpleMaterial.ts

@@ -47,7 +47,8 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -258,8 +259,9 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -302,8 +304,8 @@ module BABYLON {
                     }
                 }
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -325,13 +327,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 18 - 38
materialsLibrary/materials/simple/simple.vertex.fx

@@ -14,6 +14,10 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#endif
 
 // Uniforms
 
@@ -35,15 +39,8 @@ uniform mat4 diffuseMatrix;
 uniform vec2 vDiffuseInfos;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
 #endif
 
 #ifdef POINTSIZE
@@ -97,36 +94,19 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
-#endif
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
 
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
+#endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 7 - 9
materialsLibrary/materials/terrain/babylon.terrainMaterial.ts

@@ -49,7 +49,8 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
 
@@ -281,8 +282,9 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -325,8 +327,8 @@ module BABYLON {
                     }
                 }
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -348,13 +350,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 19 - 38
materialsLibrary/materials/terrain/terrain.vertex.fx

@@ -14,15 +14,9 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
 #endif
 
 // Uniforms
@@ -45,6 +39,10 @@ uniform mat4 textureMatrix;
 uniform vec2 vTextureInfos;
 #endif
 
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
+#endif
+
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -96,36 +94,19 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
-#endif
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
 
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
+#endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 9 - 11
materialsLibrary/materials/water/babylon.waterMaterial.ts

@@ -49,7 +49,8 @@ module BABYLON {
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
+        public BONES = false;
+        public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public SPECULARTERM = false;
@@ -346,8 +347,9 @@ module BABYLON {
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
+                    this._defines.BONES = true;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -392,8 +394,8 @@ module BABYLON {
                     }
                 }
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0){
-                    fallbacks.addCPUSkinningFallback(0, mesh);    
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
                 }
 
                 //Attributes
@@ -415,13 +417,9 @@ module BABYLON {
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (this._defines.BONES) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
-                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
-                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
-                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
-                    }
                 }
 
                 if (this._defines.INSTANCES) {
@@ -628,7 +626,7 @@ module BABYLON {
 				clipPlane = scene.clipPlane;
                 
                 var positiony = this._mesh ? this._mesh.position.y : 0.0;
-				scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony, 0), new Vector3(0, 1, 0));
+				scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony + 0.05, 0), new Vector3(0, 1, 0));
 			};
 			
 			this._refractionRTT.onAfterRender = () => {
@@ -650,7 +648,7 @@ module BABYLON {
 				clipPlane = scene.clipPlane;
                 
                 var positiony = this._mesh ? this._mesh.position.y : 0.0;
-				scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony, 0), new Vector3(0, -1, 0));
+				scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony - 0.05, 0), new Vector3(0, -1, 0));
 				
 				// Transform
 				Matrix.ReflectionToRef(scene.clipPlane, mirrorMatrix);

+ 50 - 0
materialsLibrary/materials/water/readme.md

@@ -0,0 +1,50 @@
+# Water material
+
+## [Playground example](http://www.babylonjs-playground.com/#1SLLOJ#6)
+
+## Water material by demo
+
+- [Calm lake](http://www.babylonjs-playground.com/#1SLLOJ#15)
+- [Ocean, play with waves](http://www.babylonjs-playground.com/#1SLLOJ#17)
+- [Deep water, play with water color](http://www.babylonjs-playground.com/#1SLLOJ#18)
+- [Beach](http://www.babylonjs-playground.com/#1SLLOJ#19)
+
+## Using the water material
+
+The water material needs at least only a bump texture to render properly.
+Just create a new reference of the material and assign its bump texture:
+
+```
+var ground = BABYLON.Mesh.CreateGround("ground", 512, 512, 32, scene);
+
+var waterMaterial = new BABYLON.WaterMaterial("water_material", scene);
+waterMaterial.bumpTexture = new BABYLON.Texture("bump.png", scene); // Set the bump texture
+
+ground.material = waterMaterial;
+```
+
+To reflect and refract the world, you just have to add the wanted meshes to the render list:
+
+```
+waterMaterial.addToRenderList(skybox);
+waterMaterial.addToRenderList(mesh1);
+waterMaterial.addToRenderList(mesh2);
+// ... etc.
+```
+
+That's all.
+
+## Customize the water material
+
+You can customize special properties of the material:
+
+```
+waterMaterial.windForce = 45; // Represents the wind force applied on the water surface
+waterMaterial.waveHeight = 1.3; // Represents the height of the waves
+waterMaterial.bumpHeight = 0.3; // According to the bump map, represents the pertubation of reflection and refraction
+waterMaterial.windDirection = new BABYLON.Vector2(1.0, 1.0); // The wind direction on the water surface (on width and height)
+waterMaterial.waterColor = new BABYLON.Color3(0.1, 0.1, 0.6); // Represents the water color mixed with the reflected and refracted world
+waterMaterial.colorBlendFactor = 2.0; // Factor to determine how the water color is blended with the reflected and refracted world
+waterMaterial.waveLength = 0.1; // The lenght of waves. With smaller values, more waves are generated
+```
+

+ 19 - 13
materialsLibrary/materials/water/water.fragment.fx

@@ -357,12 +357,14 @@ lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData,
 
 	// Specular
 #ifdef SPECULARTERM
-	vec3 angleW = normalize(viewDirectionW - lightVectorW);
-	vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+	vec3 angleW = normalize(viewDirectionW + lightVectorW);
+	vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
+	vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x, perturbation.y, perturbation.z));
 	
-	vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x, perturbation.y, 0.0) * max(1., glossiness));
-	float temp = pow(dot(vNormal, halfvec), max(1., glossiness));
-	result.specular = specularColor * temp * attenuation;
+	float temp = max(0., dot(vNormal, halfvec));
+	temp = pow(temp, max(1., glossiness));
+	
+	result.specular = temp * specularColor * attenuation;
 #endif
 
 	return result;
@@ -390,11 +392,13 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
 
 		// Specular
 #ifdef SPECULARTERM		
-		vec3 angleW = normalize(viewDirectionW - lightVectorW);
-		vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+		vec3 angleW = normalize(viewDirectionW - lightDirection.xyz);
+		vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
+		vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, perturbation.z));
+		
+		float temp = max(0., dot(vNormal, halfvec));
+		temp = pow(temp, max(1., glossiness));
 		
-		vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, 0.0) * max(1., glossiness));
-		float temp = pow(dot(halfvec, vNormal), max(1., glossiness));
 		result.specular = specularColor * temp * spotAtten * attenuation;
 #endif
 		return result;
@@ -418,11 +422,13 @@ lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4
 	// Specular
 #ifdef SPECULARTERM
 	vec3 angleW = normalize(viewDirectionW + lightData.xyz);
-	vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+	vec3 perturbation = bumpHeight * (bumpColor.rgb - 0.5);
+	vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, perturbation.z));
+	
+	float temp = max(0.0, dot(vNormal, halfvec));
+	temp = pow(temp, max(1.0, glossiness));
 	
-	vec3 halfvec = normalize(angleW + vec3(perturbation.x, perturbation.y, 0.0) * max(1., glossiness));
-	float temp = pow(dot(halfvec, vNormal), max(1., glossiness));
-	result.specular = specularColor * temp;
+	result.specular = temp * specularColor;
 #endif
 
 	return result;

+ 19 - 37
materialsLibrary/materials/water/water.vertex.fx

@@ -14,15 +14,9 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#if NUM_BONE_INFLUENCERS > 0
-	uniform mat4 mBones[BonesPerMesh];
-
-	attribute vec4 matricesIndices;
-	attribute vec4 matricesWeights;
-	#if NUM_BONE_INFLUENCERS > 4
-		attribute vec4 matricesIndicesExtra;
-		attribute vec4 matricesWeightsExtra;
-	#endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
 #endif
 
 // Uniforms
@@ -45,6 +39,10 @@ uniform mat4 normalMatrix;
 uniform vec2 vNormalInfos;
 #endif
 
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
+#endif
+
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -110,34 +108,18 @@ void main(void) {
 	finalWorld = world;
 #endif
 
-#if NUM_BONE_INFLUENCERS > 0
-	mat4 influence;
-	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
-
-	#if NUM_BONE_INFLUENCERS > 1
-		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
-	#endif 
-	#if NUM_BONE_INFLUENCERS > 2
-		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 3
-		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
-	#endif	
-
-	#if NUM_BONE_INFLUENCERS > 4
-		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
-	#endif
-	#if NUM_BONE_INFLUENCERS > 5
-		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 6
-		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
-	#endif	
-	#if NUM_BONE_INFLUENCERS > 7
-		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
-	#endif	
-
-	finalWorld = finalWorld * influence;
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
+
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
 #endif
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 164 - 16
materialsLibrary/test/add/addpbr.js

@@ -3,28 +3,176 @@ window.preparePBR = function() {
 	pbr.diffuseTexture = new BABYLON.Texture("textures/amiga.jpg", scene);
 	pbr.diffuseTexture.uScale = 5;
 	pbr.diffuseTexture.vScale = 5;
-	pbr.specularColor = BABYLON.Color3.Gray();
-	pbr.specularPower = 0.8;
-	pbr.roughness = 6.0;
+	pbr.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/TropicalSunnyDay", scene);	
+	pbr.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3);
+	pbr.glossiness = 0.9;
 	
-	pbr.reflectionFresnelParameters = new BABYLON.FresnelParameters();
-	pbr.useReflectionFresnelFromSpecular = true;
-	pbr.reflectionFresnelParameters.power = 1.0;
-	pbr.reflectionFresnelParameters.bias = 0.0;
+	registerButtonUI("pbr", "Default", function() {
+		setRangeValues({
+		  "directIntensity": 1,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 1,
+		  "ShadowIntensity": 1,
+		  "ShadeIntensity": 1,
+		  "cameraExposure": 1,
+		  "cameraContrast": 1,
+		  "glossiness": 0.9,
+		  "specularColorR": 0.3,
+		  "specularColorG": 0.3,
+		  "specularColorB": 0.3,
+		  "diffuseColorR": 1,
+		  "diffuseColorG": 1,
+		  "diffuseColorB": 1,
+		  "diffuseColorLevel": 0
+		});
+	});
+	registerButtonUI("pbr", "Rough Gold", function() {
+		setRangeValues({
+		  "directIntensity": 1.3439461727881254,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 0.3685013699580344,
+		  "ShadowIntensity": 1,
+		  "ShadeIntensity": 1,
+		  "cameraExposure": 0.7153261887420668,
+		  "cameraContrast": 1.6474178892241538,
+		  "glossiness": 0.42269274789303946,
+		  "specularColorR": 1,
+		  "specularColorG": 0.8453854957860789,
+		  "specularColorB": 0.5093989525890475,
+		  "diffuseColorR": 0,
+		  "diffuseColorG": 0,
+		  "diffuseColorB": 0,
+		  "diffuseColorLevel": 1
+		});
+	});
+	registerButtonUI("pbr", "Plastic", function() {
+		setRangeValues({
+		  "directIntensity": 0.9971213540040931,
+		  "emissiveIntensity": 1,
+		  "environmentIntensity": 0.3685013699580344,
+		  "ShadowIntensity": 0.975444802830091,
+		  "ShadeIntensity": 0.8020323934380749,
+		  "cameraExposure": 0.7586792910900708,
+		  "cameraContrast": 1.5823882357021477,
+		  "glossiness": 0.8562237713730799,
+		  "specularColorR": 0.05,
+		  "specularColorG": 0.05,
+		  "specularColorB": 0.05,
+		  "diffuseColorR": 0.20592723615301922,
+		  "diffuseColorG": 0.942929976069088,
+		  "diffuseColorB": 1,
+		  "diffuseColorLevel": 1
+		});
+	});
+	registerButtonUI("pbr", "Shiny Copper", function() {
+		setRangeValues({
+		  "directIntensity": 1.2355634169181153,
+		  "emissiveIntensity": 0.910415149308085,
+		  "environmentIntensity": 0.21676551174002023,
+		  "ShadowIntensity": 1.018797905178095,
+		  "ShadeIntensity": 0.975444802830091,
+		  "cameraExposure": 1.0621510075260991,
+		  "cameraContrast": 1.0404744563520971,
+		  "glossiness": 0.888738598134083,
+		  "specularColorR": 0.98,
+		  "specularColorG": 0.78,
+		  "specularColorB": 0.706,
+		  "diffuseColorR": 0.1,
+		  "diffuseColorG": 0.1,
+		  "diffuseColorB": 0.1,
+		  "diffuseColorLevel": 1
+		});
+	});
+
+	registerRangeUI("pbr", "directIntensity", 0, 2, function(value) {
+		pbr.directIntensity = value;
+	}, function() {
+		return pbr.directIntensity;
+	});
+	
+	registerRangeUI("pbr", "emissiveIntensity", 0, 2, function(value) {
+		pbr.emissiveIntensity = value;
+	}, function() {
+		return pbr.emissiveIntensity;
+	});
+	
+	registerRangeUI("pbr", "environmentIntensity", 0, 2, function(value) {
+		pbr.environmentIntensity = value;
+	}, function() {
+		return pbr.environmentIntensity;
+	});
+	
+	registerRangeUI("pbr", "ShadowIntensity", 0, 2, function(value) {
+		pbr.overloadedShadowIntensity = value;
+	}, function() {
+		return pbr.overloadedShadowIntensity;
+	});
+	
+	registerRangeUI("pbr", "ShadeIntensity", 0, 2, function(value) {
+		pbr.overloadedShadeIntensity = value;
+	}, function() {
+		return pbr.overloadedShadeIntensity;
+	});
 	
-	pbr.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/TropicalSunnyDay", scene);
-					
-	registerRangeUI("pbr", "specularPower", 0, 1, function(value) {
-		pbr.specularPower = value;
+	registerRangeUI("pbr", "cameraExposure", 0, 2, function(value) {
+		pbr.cameraExposure = value;
+	}, function() {
+		return pbr.cameraExposure;
+	});
+
+	registerRangeUI("pbr", "cameraContrast", 0, 2, function(value) {
+		pbr.cameraContrast = value;
 	}, function() {
-		return pbr.specularPower;
+		return pbr.cameraContrast;
 	});
 	
-	registerRangeUI("pbr", "roughness", 0, 10, function(value) {
-		pbr.roughness = value;
+	registerRangeUI("pbr", "glossiness", 0, 1, function(value) {
+		pbr.glossiness = value;
+	}, function() {
+		return pbr.glossiness;
+	});
+
+	registerRangeUI("pbr", "specularColorR", 0, 1, function(value) {
+		pbr.specularColor.r = value;
+	}, function() {
+		return pbr.specularColor.r;
+	});
+
+	registerRangeUI("pbr", "specularColorG", 0, 1, function(value) {
+		pbr.specularColor.g = value;
+	}, function() {
+		return pbr.specularColor.g;
+	});
+
+	registerRangeUI("pbr", "specularColorB", 0, 1, function(value) {
+		pbr.specularColor.b = value;
+	}, function() {
+		return pbr.specularColor.b;
+	});
+
+	registerRangeUI("pbr", "diffuseColorR", 0, 1, function(value) {
+		pbr.overloadedDiffuse.r = value;
+	}, function() {
+		return pbr.overloadedDiffuse.r;
+	});
+
+	registerRangeUI("pbr", "diffuseColorG", 0, 1, function(value) {
+		pbr.overloadedDiffuse.g = value;
+	}, function() {
+		return pbr.overloadedDiffuse.g;
+	});
+
+	registerRangeUI("pbr", "diffuseColorB", 0, 1, function(value) {
+		pbr.overloadedDiffuse.b = value;
+	}, function() {
+		return pbr.overloadedDiffuse.b;
+	});
+
+	registerRangeUI("pbr", "diffuseColorLevel", 0, 1, function(value) {
+		pbr.overloadedDiffuseIntensity = value;
 	}, function() {
-		return pbr.roughness;
+		return pbr.overloadedDiffuseIntensity;
 	});
-		
+
 	return pbr;
 }

+ 72 - 0
materialsLibrary/test/add/addwater.js

@@ -0,0 +1,72 @@
+window.prepareWater = function() {
+	var water = new BABYLON.WaterMaterial("water", scene);
+	water.backFaceCulling = false;
+	water.enableRenderTargets(false);
+	water.bumpTexture = new BABYLON.Texture("textures/waterbump.png", scene);
+	water.windForce = 45;
+	water.waveHeight = 1.3;
+	water.windDirection = new BABYLON.Vector2(1, 1);
+					
+	registerRangeUI("water", "windForce", 0, 100, function(value) {
+		water.windForce = value;
+	}, function() {
+		return water.windForce;
+	});
+	
+	registerRangeUI("water", "waveHeight", 0, 20, function(value) {
+		water.waveHeight = value;
+	}, function() {
+		return water.waveHeight;
+	});
+	
+	registerRangeUI("water", "bumpHeight", 0, 10, function(value) {
+		water.bumpHeight = value;
+	}, function() {
+		return water.bumpHeight;
+	});
+	
+	registerRangeUI("water", "colorBlendFactor", 0, 1, function(value) {
+		water.colorBlendFactor = value;
+	}, function() {
+		return water.colorBlendFactor;
+	});
+	
+	registerRangeUI("water", "waveLength", 0, 1, function(value) {
+		water.waveLength = value;
+	}, function() {
+		return water.waveLength;
+	});
+	
+	registerRangeUI("water", "waveSpeed", 0, 100, function(value) {
+		water.waveSpeed = value;
+	}, function() {
+		return water.waveSpeed;
+	});
+	
+	// Specular color
+	registerRangeUI("water", "specularColorR", 0, 1, function(value) {
+		water.specularColor.r = value;
+	}, function() {
+		return water.specularColor.r;
+	});
+	
+	registerRangeUI("water", "specularColorG", 0, 1, function(value) {
+		water.specularColor.g = value;
+	}, function() {
+		return water.specularColor.g;
+	});
+	
+	registerRangeUI("water", "specularColorB", 0, 1, function(value) {
+		water.specularColor.b = value;
+	}, function() {
+		return water.specularColor.b;
+	});
+	
+	registerRangeUI("water", "specularPower", 0, 512, function(value) {
+		water.specularPower = value;
+	}, function() {
+		return water.specularPower;
+	});
+		
+	return water;
+}

+ 16 - 17
materialsLibrary/test/index.html

@@ -45,9 +45,9 @@
 	<canvas id="renderCanvas"></canvas>
 
 	<script src="index.js"></script>
-    <script src="add/addpbr.js"></script>
-    <script src="add/addlava.js"></script>
-    <script src="add/addnormal.js"></script>
+	<script src="add/addpbr.js"></script>
+	<script src="add/addwater.js"></script>
+	
 	<script>
 		if (BABYLON.Engine.isSupported()) {
 			var canvas = document.getElementById("renderCanvas");
@@ -158,19 +158,23 @@
 				std.diffuseTexture.uScale = 5;
 				std.diffuseTexture.vScale = 5;
 
+                // Lava
+                var lava = new BABYLON.LavaMaterial("lava", scene);
+                lava.diffuseTexture = new BABYLON.Texture("textures/lava/lavatile.jpg", scene);
+                lava.diffuseTexture.uScale = 0.5;
+                lava.diffuseTexture.vScale = 0.5;
+				lava.noiseTexture = new BABYLON.Texture("textures/lava/cloud.png", scene);
+				lava.fogColor = BABYLON.Color3.Black();
+				lava.speed = 2.5;
 
 				var simple = new BABYLON.SimpleMaterial("simple", scene);
 				simple.diffuseTexture = new BABYLON.Texture("textures/amiga.jpg", scene);
 				simple.diffuseTexture.uScale = 5;
 				simple.diffuseTexture.vScale = 5;
 
-				var water = new BABYLON.WaterMaterial("water", scene);
-				water.backFaceCulling = false;
-				water.enableRenderTargets(false);
-				water.bumpTexture = new BABYLON.Texture("textures/waterbump.png", scene);
-				water.windForce = -45;
-				water.waveHeight = 1.3;
-				water.windDirection = new BABYLON.Vector2(1, 1);
+				var normal = new BABYLON.NormalMaterial("normal", scene);
+				
+				var water = prepareWater();
 				water.addToRenderList(skybox);
 				water.addToRenderList(shadowCaster);
 				water.addToRenderList(shadowCaster2);
@@ -196,13 +200,8 @@
 				terrain.diffuseTexture1.uScale = terrain.diffuseTexture1.vScale = 10;
 				terrain.diffuseTexture2.uScale = terrain.diffuseTexture2.vScale = 10;
 				terrain.diffuseTexture3.uScale = terrain.diffuseTexture3.vScale = 10;
-
-                // PBR
-				var pbr         = preparePBR();
-                // Normal
-                var normal      = prepareNormal();
-                // Lava
-                var lava        = prepareLava();
+				
+				var pbr = preparePBR();
 								
 				// Default to std
 				var currentMaterial = std;

+ 46 - 26
materialsLibrary/test/index.js

@@ -15,19 +15,6 @@ var options = {
 var registeredUIs = {};
 var materialgui;
 
-window.registerColorPicker = function(material, name, color, onChange, onSet) {
-    if (!registeredUIs[material]) {
-        registeredUIs[material] = [];
-    }
-
-    registeredUIs[material].push({
-        name: name,
-        color: "#ff0000",
-        onChange: onChange,
-        onSet: onSet
-    });
-};
-
 
 window.registerRangeUI = function(material, name, minValue, maxValue, onChange, onSet) {
 	if (!registeredUIs[material]) {
@@ -39,22 +26,55 @@ window.registerRangeUI = function(material, name, minValue, maxValue, onChange,
 		minValue: minValue,
 		maxValue: maxValue,
 		onChange: onChange,
-		onSet: onSet
+		onSet: onSet,
+		type: "Range"
 	});
 }
 
-var setUi = function(ui) {
-	options[ui.name] = ui.onSet();
+window.setRangeValues = function(json) {
+	for (var key in json) {
+		if (json.hasOwnProperty(key)) {
+			setRangeValue(key, json[key]);
+		}
+	}
+}
 
-    if (ui.color) {
-        materialgui.addColor(options, ui.name).onChange(function(value) {
-            ui.onChange(value);
-        });
-    } else {
-        materialgui.add(options, ui.name, ui.minValue, ui.maxValue).onChange(function(value) {
-            ui.onChange(value);
-        });
-    }
+window.setRangeValue = function(name, value) {
+	if (!materialgui) {
+		return;
+	}
+	
+	var controllers = materialgui.__controllers;
+	for (var i = 0; i < controllers.length; i++) {
+		if (controllers[i].property == name) {
+			controllers[i].setValue(value);
+		}
+	}
+}
+
+window.registerButtonUI = function(material, name, onClick) {
+	if (!registeredUIs[material]) {
+		registeredUIs[material] = [];
+	}
+	
+	registeredUIs[material].push({
+		name: name, 
+		onClick: onClick,
+		type: "Button"
+	});
+}
+
+var setUi = function(ui) {
+	if (ui.type == "Range") {
+		options[ui.name] = ui.onSet();
+		var test = materialgui.add(options, ui.name, ui.minValue, ui.maxValue).onChange(function(value) {
+			ui.onChange(value);
+		});
+	}
+	else if (ui.type == "Button") {
+		options[ui.name] = ui.onClick;
+		materialgui.add(options, ui.name);
+	}
 }
 
 window.enableMaterial = function(material) {
@@ -69,6 +89,6 @@ window.enableMaterial = function(material) {
 			var ui = registeredUIs[material][index];
 			
 			setUi(ui);
-		}	
+		}
 	}
 }

BIN
materialsLibrary/test/textures/mixMap.png


+ 1 - 0
readme.md

@@ -58,6 +58,7 @@ You can help by testing or contributing to the next version.
  - Debug layer to help you optimize and debug scenes
  - SIMD.js support
  - Collisions can be offloaded on webworkers
+ - Merge meshes
 - Standard material is a per pixel material that supports:
  - Diffuse lightning and texture
  - Ambient lightning and texture

+ 54 - 14
src/Animations/babylon.animation.js

@@ -9,6 +9,19 @@ var BABYLON;
         return AnimationRange;
     })();
     BABYLON.AnimationRange = AnimationRange;
+    /**
+     * Composed of a frame, and an action function
+     */
+    var AnimationEvent = (function () {
+        function AnimationEvent(frame, action, onlyOnce) {
+            this.frame = frame;
+            this.action = action;
+            this.onlyOnce = onlyOnce;
+            this.isDone = false;
+        }
+        return AnimationEvent;
+    })();
+    BABYLON.AnimationEvent = AnimationEvent;
     var Animation = (function () {
         function Animation(name, targetProperty, framePerSecond, dataType, loopMode) {
             this.name = name;
@@ -19,6 +32,8 @@ var BABYLON;
             this._offsetsCache = {};
             this._highLimitsCache = {};
             this._stopped = false;
+            // The set of event that will be linked to this animation
+            this._events = new Array();
             this.allowMatricesInterpolation = false;
             this._ranges = new Array();
             this.targetPropertyPath = targetProperty.split(".");
@@ -64,7 +79,25 @@ var BABYLON;
             node.animations.push(animation);
             return node.getScene().beginAnimation(node, 0, totalFrame, (animation.loopMode === 1), 1.0, onAnimationEnd);
         };
-        // Methods   
+        // Methods
+        /**
+         * Add an event to this animation.
+         */
+        Animation.prototype.addEvent = function (event) {
+            this._events.push(event);
+        };
+        /**
+         * Remove all events found at the given frame
+         * @param frame
+         */
+        Animation.prototype.removeEvents = function (frame) {
+            for (var index = 0; index < this._events.length; index++) {
+                if (this._events[index].frame === frame) {
+                    this._events.splice(index, 1);
+                    index--;
+                }
+            }
+        };
         Animation.prototype.createRange = function (name, from, to) {
             this._ranges.push(new AnimationRange(name, from, to));
         };
@@ -117,19 +150,7 @@ var BABYLON;
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
         };
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
-            var startScale = new BABYLON.Vector3(0, 0, 0);
-            var startRotation = new BABYLON.Quaternion();
-            var startTranslation = new BABYLON.Vector3(0, 0, 0);
-            startValue.decompose(startScale, startRotation, startTranslation);
-            var endScale = new BABYLON.Vector3(0, 0, 0);
-            var endRotation = new BABYLON.Quaternion();
-            var endTranslation = new BABYLON.Vector3(0, 0, 0);
-            endValue.decompose(endScale, endRotation, endTranslation);
-            var resultScale = this.vector3InterpolateFunction(startScale, endScale, gradient);
-            var resultRotation = this.quaternionInterpolateFunction(startRotation, endRotation, gradient);
-            var resultTranslation = this.vector3InterpolateFunction(startTranslation, endTranslation, gradient);
-            var result = BABYLON.Matrix.Compose(resultScale, resultRotation, resultTranslation);
-            return result;
+            return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
         };
         Animation.prototype.clone = function () {
             var clone = new Animation(this.name, this.targetPropertyPath.join("."), this.framePerSecond, this.dataType, this.loopMode);
@@ -356,6 +377,25 @@ var BABYLON;
             var repeatCount = (ratio / range) >> 0;
             var currentFrame = returnValue ? from + ratio % range : to;
             var currentValue = this._interpolate(currentFrame, repeatCount, this.loopMode, offsetValue, highLimitValue);
+            // Check events
+            for (var index = 0; index < this._events.length; index++) {
+                if (currentFrame >= this._events[index].frame) {
+                    var event = this._events[index];
+                    if (!event.isDone) {
+                        // If event should be done only once, remove it.
+                        if (event.onlyOnce) {
+                            this._events.splice(index, 1);
+                            index--;
+                        }
+                        event.isDone = true;
+                        event.action();
+                    } // Don't do anything if the event has already be done.
+                }
+                else if (this._events[index].isDone && !this._events[index].onlyOnce) {
+                    // reset event, the animation is looping
+                    this._events[index].isDone = false;
+                }
+            }
             // Set value
             this.setValue(currentValue);
             if (!returnValue) {

+ 56 - 20
src/Animations/babylon.animation.ts

@@ -1,6 +1,15 @@
 module BABYLON {
     export class AnimationRange {
-        constructor(public name: string, public from: number, public to: number) {            
+        constructor(public name: string, public from: number, public to: number) {
+        }
+    }
+
+    /**
+     * Composed of a frame, and an action function
+     */
+    export class AnimationEvent {
+        public isDone: boolean = false;
+        constructor(public frame: number, public action: () => void, public onlyOnce?: boolean) {
         }
     }
 
@@ -12,6 +21,9 @@
         public _target;
         private _easingFunction: IEasingFunction;
 
+        // The set of event that will be linked to this animation
+        private _events = new Array<AnimationEvent>();
+
         public targetPropertyPath: string[];
         public currentFrame: number;
 
@@ -79,7 +91,27 @@
             this.loopMode = loopMode === undefined ? Animation.ANIMATIONLOOPMODE_CYCLE : loopMode;
         }
 
-        // Methods   
+        // Methods
+        /**
+         * Add an event to this animation.
+         */
+        public addEvent(event: AnimationEvent): void {
+            this._events.push(event);
+        }
+
+        /**
+         * Remove all events found at the given frame
+         * @param frame
+         */
+        public removeEvents(frame: number): void {
+            for (var index = 0; index < this._events.length; index++) {
+                if (this._events[index].frame === frame) {
+                    this._events.splice(index, 1);
+                    index--;
+                }
+            }
+        }
+
         public createRange(name: string, from: number, to: number): void {
             this._ranges.push(new AnimationRange(name, from, to));
         }
@@ -95,7 +127,7 @@
 
         public getRange(name: string): AnimationRange {
             for (var index = 0; index < this._ranges.length; index++) {
-                if (this._ranges[index].name === name) {                    
+                if (this._ranges[index].name === name) {
                     return this._ranges[index];
                 }
             }
@@ -146,23 +178,7 @@
         }
 
         public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
-            startValue.decompose(startScale, startRotation, startTranslation);
-
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
-            endValue.decompose(endScale, endRotation, endTranslation);
-
-            var resultScale = this.vector3InterpolateFunction(startScale, endScale, gradient);
-            var resultRotation = this.quaternionInterpolateFunction(startRotation, endRotation, gradient);
-            var resultTranslation = this.vector3InterpolateFunction(startTranslation, endTranslation, gradient);
-
-            var result = Matrix.Compose(resultScale, resultRotation, resultTranslation);
-
-            return result;
+            return Matrix.Lerp(startValue, endValue, gradient);
         }
 
         public clone(): Animation {
@@ -421,6 +437,25 @@
             var currentFrame = returnValue ? from + ratio % range : to;
             var currentValue = this._interpolate(currentFrame, repeatCount, this.loopMode, offsetValue, highLimitValue);
 
+            // Check events
+            for (var index = 0; index < this._events.length; index++) {
+                if (currentFrame >= this._events[index].frame) {
+                    var event = this._events[index];
+                    if (!event.isDone) {
+                        // If event should be done only once, remove it.
+                        if (event.onlyOnce) {
+                            this._events.splice(index, 1);
+                            index--;
+                        }
+                        event.isDone = true;
+                        event.action();
+                    } // Don't do anything if the event has already be done.
+                } else if (this._events[index].isDone && !this._events[index].onlyOnce) {
+                    // reset event, the animation is looping
+                    this._events[index].isDone = false;
+                }
+            }
+
             // Set value
             this.setValue(currentValue);
 
@@ -482,3 +517,4 @@
     }
 } 
 
+

+ 5 - 4
src/Cameras/babylon.arcRotateCamera.js

@@ -73,7 +73,7 @@ var BABYLON;
                 _this.position.copyFrom(_this._newPosition);
                 var up = _this.upVector;
                 if (_this.allowUpsideDown && _this.beta < 0) {
-                    var up = up.clone();
+                    up = up.clone();
                     up = up.negate();
                 }
                 BABYLON.Matrix.LookAtLHToRef(_this.position, target, up, _this._viewMatrix);
@@ -148,7 +148,7 @@ var BABYLON;
             if (this._onPointerDown === undefined) {
                 this._onPointerDown = function (evt) {
                     // Manage panning with right click
-                    _this._isRightClick = evt.button === 2 ? true : false;
+                    _this._isRightClick = evt.button === 2;
                     // manage pointers
                     pointers.add(evt.pointerId, { x: evt.clientX, y: evt.clientY, type: evt.pointerType });
                     cacheSoloPointer = pointers.item(evt.pointerId);
@@ -376,7 +376,7 @@ var BABYLON;
                 }
             }
             // Inertia
-            if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset != 0) {
+            if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset !== 0) {
                 this.alpha += this.beta <= 0 ? -this.inertialAlphaOffset : this.inertialAlphaOffset;
                 this.beta += this.inertialBetaOffset;
                 this.radius -= this.inertialRadiusOffset;
@@ -481,7 +481,7 @@ var BABYLON;
                 this.position.copyFrom(this._newPosition);
                 var up = this.upVector;
                 if (this.allowUpsideDown && this.beta < 0) {
-                    var up = up.clone();
+                    up = up.clone();
                     up = up.negate();
                 }
                 BABYLON.Matrix.LookAtLHToRef(this.position, target, up, this._viewMatrix);
@@ -530,6 +530,7 @@ var BABYLON;
                     var alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
                     return new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
             }
+            return null;
         };
         /**
          * @override

+ 5 - 4
src/Cameras/babylon.arcRotateCamera.ts

@@ -142,7 +142,7 @@
             if (this._onPointerDown === undefined) {
                 this._onPointerDown = evt => {
                     // Manage panning with right click
-                    this._isRightClick = evt.button === 2 ? true : false;
+                    this._isRightClick = evt.button === 2;
 
                     // manage pointers
                     pointers.add(evt.pointerId, { x: evt.clientX, y: evt.clientY, type: evt.pointerType });
@@ -408,7 +408,7 @@
             }			
 			
             // Inertia
-            if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset != 0) {
+            if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset !== 0) {
                 this.alpha += this.beta <= 0 ? -this.inertialAlphaOffset : this.inertialAlphaOffset;
                 this.beta += this.inertialBetaOffset;
                 this.radius -= this.inertialRadiusOffset;
@@ -529,7 +529,7 @@
 
                 var up = this.upVector;
                 if (this.allowUpsideDown && this.beta < 0) {
-                    var up = up.clone();
+                    up = up.clone();
                     up = up.negate();
                 }
 
@@ -567,7 +567,7 @@
 
             var up = this.upVector;
             if (this.allowUpsideDown && this.beta < 0) {
-                var up = up.clone();
+                up = up.clone();
                 up = up.negate();
             }
 
@@ -624,6 +624,7 @@
                     var alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
                     return new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
             }
+            return null;
         }
         
         /**

+ 8 - 0
src/Debug/babylon.debugLayer.js

@@ -557,6 +557,14 @@ var BABYLON;
                 this._generateTexBox(this._optionsSubsetDiv, "<b>Tools:</b>", this.accentColor);
                 this._generateButton(this._optionsSubsetDiv, "Dump rendertargets", function (element) { _this._scene.dumpNextRenderTargets = true; });
                 this._generateButton(this._optionsSubsetDiv, "Run SceneOptimizer", function (element) { BABYLON.SceneOptimizer.OptimizeAsync(_this._scene); });
+                this._generateButton(this._optionsSubsetDiv, "Log camera object", function (element) {
+                    if (_this._camera) {
+                        console.log(_this._camera);
+                    }
+                    else {
+                        console.warn("No camera defined, or debug layer created before camera creation!");
+                    }
+                });
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
                 this._globalDiv.appendChild(this._statsDiv);
                 this._globalDiv.appendChild(this._logDiv);

+ 48 - 41
src/Debug/babylon.debugLayer.ts

@@ -393,7 +393,7 @@
             this._rootElement.appendChild(this._globalDiv);
 
             this._generateDOMelements();
-            
+
             engine.getRenderingCanvas().addEventListener("click", this._onCanvasClick);
 
             this._syncPositions();
@@ -489,10 +489,10 @@
             button.style.width = "150px";
             button.style.marginBottom = "5px";
             button.style.color = "#444444";
-            button.style.border = "1px solid white"; 
+            button.style.border = "1px solid white";
             button.className = "debugLayerButton";
 
-            button.addEventListener("click",(evt: Event) => {
+            button.addEventListener("click", (evt: Event) => {
                 task(evt.target, tag);
             });
 
@@ -700,8 +700,15 @@
                 this._generateTexBox(this._optionsSubsetDiv, "<b>Tools:</b>", this.accentColor);
                 this._generateButton(this._optionsSubsetDiv, "Dump rendertargets", (element) => { this._scene.dumpNextRenderTargets = true; });
                 this._generateButton(this._optionsSubsetDiv, "Run SceneOptimizer", (element) => { SceneOptimizer.OptimizeAsync(this._scene); });
+                this._generateButton(this._optionsSubsetDiv, "Log camera object", (element) => {
+                    if (this._camera) {
+                        console.log(this._camera);
+                    } else {
+                        console.warn("No camera defined, or debug layer created before camera creation!");
+                    }
+                });
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
-  
+
                 this._globalDiv.appendChild(this._statsDiv);
                 this._globalDiv.appendChild(this._logDiv);
                 this._globalDiv.appendChild(this._optionsDiv);
@@ -715,46 +722,46 @@
             var glInfo = engine.getGlInfo();
 
             this._statsSubsetDiv.innerHTML = "Babylon.js v" + Engine.Version + " - <b>" + Tools.Format(engine.getFps(), 0) + " fps</b><br><br>"
-                + "<div style='column-count: 2;-moz-column-count:2;-webkit-column-count:2'>"
-                + "<b>Count</b><br>"
-                + "Total meshes: " + scene.meshes.length + "<br>"
-                + "Total vertices: " + scene.getTotalVertices() + "<br>"
-                + "Total materials: " + scene.materials.length + "<br>"
-                + "Total textures: " + scene.textures.length + "<br>"
-                + "Active meshes: " + scene.getActiveMeshes().length + "<br>"
-                + "Active indices: " + scene.getActiveIndices() + "<br>"
-                + "Active bones: " + scene.getActiveBones() + "<br>"
-                + "Active particles: " + scene.getActiveParticles() + "<br>"
-                + "<b>Draw calls: " + engine.drawCalls + "</b><br><br>"
-                + "<b>Duration</b><br>"
-                + "Meshes selection:</i> " + Tools.Format(scene.getEvaluateActiveMeshesDuration()) + " ms<br>"
-                + "Render Targets: " + Tools.Format(scene.getRenderTargetsDuration()) + " ms<br>"
-                + "Particles: " + Tools.Format(scene.getParticlesDuration()) + " ms<br>"
-                + "Sprites: " + Tools.Format(scene.getSpritesDuration()) + " ms<br><br>"
-                + "Render: <b>" + Tools.Format(scene.getRenderDuration()) + " ms</b><br>"
-                + "Frame: " + Tools.Format(scene.getLastFrameDuration()) + " ms<br>"
-                + "Potential FPS: " + Tools.Format(1000.0 / scene.getLastFrameDuration(), 0) + "<br><br>"
-                + "</div>"
-                + "<div style='column-count: 2;-moz-column-count:2;-webkit-column-count:2'>"
-                + "<b>Extensions</b><br>"
-                + "Std derivatives: " + (engine.getCaps().standardDerivatives ? "Yes" : "No") + "<br>"
-                + "Compressed textures: " + (engine.getCaps().s3tc ? "Yes" : "No") + "<br>"
-                + "Hardware instances: " + (engine.getCaps().instancedArrays ? "Yes" : "No") + "<br>"
-                + "Texture float: " + (engine.getCaps().textureFloat ? "Yes" : "No") + "<br>"
-                + "32bits indices: " + (engine.getCaps().uintIndices ? "Yes" : "No") + "<br>"
-                + "Fragment depth: " + (engine.getCaps().fragmentDepthSupported ? "Yes" : "No") + "<br>"
-                + "<b>Caps.</b><br>"
-                + "Max textures units: " + engine.getCaps().maxTexturesImageUnits + "<br>"
-                + "Max textures size: " + engine.getCaps().maxTextureSize + "<br>"
-                + "Max anisotropy: " + engine.getCaps().maxAnisotropy + "<br><br><br>"
-                + "</div><br>"
-                + "<b>Info</b><br>"
-                + glInfo.version + "<br>"
-                + glInfo.renderer + "<br>";
+            + "<div style='column-count: 2;-moz-column-count:2;-webkit-column-count:2'>"
+            + "<b>Count</b><br>"
+            + "Total meshes: " + scene.meshes.length + "<br>"
+            + "Total vertices: " + scene.getTotalVertices() + "<br>"
+            + "Total materials: " + scene.materials.length + "<br>"
+            + "Total textures: " + scene.textures.length + "<br>"
+            + "Active meshes: " + scene.getActiveMeshes().length + "<br>"
+            + "Active indices: " + scene.getActiveIndices() + "<br>"
+            + "Active bones: " + scene.getActiveBones() + "<br>"
+            + "Active particles: " + scene.getActiveParticles() + "<br>"
+            + "<b>Draw calls: " + engine.drawCalls + "</b><br><br>"
+            + "<b>Duration</b><br>"
+            + "Meshes selection:</i> " + Tools.Format(scene.getEvaluateActiveMeshesDuration()) + " ms<br>"
+            + "Render Targets: " + Tools.Format(scene.getRenderTargetsDuration()) + " ms<br>"
+            + "Particles: " + Tools.Format(scene.getParticlesDuration()) + " ms<br>"
+            + "Sprites: " + Tools.Format(scene.getSpritesDuration()) + " ms<br><br>"
+            + "Render: <b>" + Tools.Format(scene.getRenderDuration()) + " ms</b><br>"
+            + "Frame: " + Tools.Format(scene.getLastFrameDuration()) + " ms<br>"
+            + "Potential FPS: " + Tools.Format(1000.0 / scene.getLastFrameDuration(), 0) + "<br><br>"
+            + "</div>"
+            + "<div style='column-count: 2;-moz-column-count:2;-webkit-column-count:2'>"
+            + "<b>Extensions</b><br>"
+            + "Std derivatives: " + (engine.getCaps().standardDerivatives ? "Yes" : "No") + "<br>"
+            + "Compressed textures: " + (engine.getCaps().s3tc ? "Yes" : "No") + "<br>"
+            + "Hardware instances: " + (engine.getCaps().instancedArrays ? "Yes" : "No") + "<br>"
+            + "Texture float: " + (engine.getCaps().textureFloat ? "Yes" : "No") + "<br>"
+            + "32bits indices: " + (engine.getCaps().uintIndices ? "Yes" : "No") + "<br>"
+            + "Fragment depth: " + (engine.getCaps().fragmentDepthSupported ? "Yes" : "No") + "<br>"
+            + "<b>Caps.</b><br>"
+            + "Max textures units: " + engine.getCaps().maxTexturesImageUnits + "<br>"
+            + "Max textures size: " + engine.getCaps().maxTextureSize + "<br>"
+            + "Max anisotropy: " + engine.getCaps().maxAnisotropy + "<br><br><br>"
+            + "</div><br>"
+            + "<b>Info</b><br>"
+            + glInfo.version + "<br>"
+            + glInfo.renderer + "<br>";
 
             if (this.customStatsFunction) {
                 this._statsSubsetDiv.innerHTML += this._statsSubsetDiv.innerHTML;
             }
         }
     }
-}
+}

+ 2 - 1
src/Layer/babylon.layer.js

@@ -3,6 +3,7 @@ var BABYLON;
     var Layer = (function () {
         function Layer(name, imgUrl, scene, isBackground, color) {
             this.name = name;
+            this.alphaBlendingMode = BABYLON.Engine.ALPHA_COMBINE;
             this._vertexDeclaration = [2];
             this._vertexStrideSize = 2 * 4;
             this.texture = imgUrl ? new BABYLON.Texture(imgUrl, scene, true) : null;
@@ -45,7 +46,7 @@ var BABYLON;
             // VBOs
             engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
             // Draw order
-            engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
+            engine.setAlphaMode(this.alphaBlendingMode);
             engine.draw(true, 0, 6);
             engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
         };

+ 2 - 1
src/Layer/babylon.layer.ts

@@ -4,6 +4,7 @@
         public isBackground: boolean;
         public color: Color4;
         public onDispose: () => void;
+        public alphaBlendingMode = Engine.ALPHA_COMBINE;
 
         private _scene: Scene;
         private _vertexDeclaration = [2];
@@ -70,7 +71,7 @@
             engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
 
             // Draw order
-            engine.setAlphaMode(Engine.ALPHA_COMBINE);
+            engine.setAlphaMode(this.alphaBlendingMode);
             engine.draw(true, 0, 6);
             engine.setAlphaMode(Engine.ALPHA_DISABLE);
         }

+ 38 - 6
src/Loading/Plugins/babylon.babylonFileLoader.js

@@ -101,7 +101,10 @@ var BABYLON;
             fresnelParameters.power = parsedFresnelParameters.power || 1.0;
             return fresnelParameters;
         };
-        var parseMaterial = function (parsedMaterial, scene, rootUrl) {
+        var parseCustomMaterial = function (parsedMaterial, scene, rootUrl) {
+            return null;
+        };
+        var parseStandardMaterial = function (parsedMaterial, scene, rootUrl) {
             var material;
             material = new BABYLON.StandardMaterial(parsedMaterial.name, scene);
             material.ambientColor = BABYLON.Color3.FromArray(parsedMaterial.ambient);
@@ -161,6 +164,12 @@ var BABYLON;
             }
             return material;
         };
+        var parseMaterial = function (parsedMaterial, scene, rootUrl) {
+            if (!parsedMaterial.customType) {
+                return parseStandardMaterial(parsedMaterial, scene, rootUrl);
+            }
+            return parseCustomMaterial(parsedMaterial, scene, rootUrl);
+        };
         var parseMaterialById = function (id, parsedData, scene, rootUrl) {
             for (var index = 0; index < parsedData.materials.length; index++) {
                 var parsedMaterial = parsedData.materials[index];
@@ -1136,7 +1145,8 @@ var BABYLON;
                 var loadedSkeletonsIds = [];
                 var loadedMaterialsIds = [];
                 var hierarchyIds = [];
-                for (var index = 0; index < parsedData.meshes.length; index++) {
+                var index;
+                for (index = 0; index < parsedData.meshes.length; index++) {
                     var parsedMesh = parsedData.meshes[index];
                     if (!meshesNames || isDescendantOf(parsedMesh, meshesNames, hierarchyIds)) {
                         if (meshesNames instanceof Array) {
@@ -1236,8 +1246,9 @@ var BABYLON;
                     }
                 }
                 // Connecting parents
+                var currentMesh;
                 for (index = 0; index < scene.meshes.length; index++) {
-                    var currentMesh = scene.meshes[index];
+                    currentMesh = scene.meshes[index];
                     if (currentMesh._waitingParentId) {
                         currentMesh.parent = scene.getLastEntryByID(currentMesh._waitingParentId);
                         currentMesh._waitingParentId = undefined;
@@ -1245,7 +1256,7 @@ var BABYLON;
                 }
                 // freeze world matrix application
                 for (index = 0; index < scene.meshes.length; index++) {
-                    var currentMesh = scene.meshes[index];
+                    currentMesh = scene.meshes[index];
                     if (currentMesh._waitingFreezeWorldMatrix) {
                         currentMesh.freezeWorldMatrix();
                         currentMesh._waitingFreezeWorldMatrix = undefined;
@@ -1269,7 +1280,9 @@ var BABYLON;
                 scene.autoClear = parsedData.autoClear;
                 scene.clearColor = BABYLON.Color3.FromArray(parsedData.clearColor);
                 scene.ambientColor = BABYLON.Color3.FromArray(parsedData.ambientColor);
-                scene.gravity = BABYLON.Vector3.FromArray(parsedData.gravity);
+                if (parsedData.gravity) {
+                    scene.gravity = BABYLON.Vector3.FromArray(parsedData.gravity);
+                }
                 // Fog
                 if (parsedData.fogMode && parsedData.fogMode !== 0) {
                     scene.fogMode = parsedData.fogMode;
@@ -1278,8 +1291,27 @@ var BABYLON;
                     scene.fogEnd = parsedData.fogEnd;
                     scene.fogDensity = parsedData.fogDensity;
                 }
+                //Physics
+                if (parsedData.physicsEnabled) {
+                    var physicsPlugin;
+                    if (parsedData.physicsEngine === "cannon") {
+                        physicsPlugin = new BABYLON.CannonJSPlugin();
+                    }
+                    else if (parsedData.physicsEngine === "oimo") {
+                        physicsPlugin = new BABYLON.OimoJSPlugin();
+                    }
+                    //else - default engine, which is currently oimo
+                    var physicsGravity = parsedData.physicsGravity ? BABYLON.Vector3.FromArray(parsedData.physicsGravity) : null;
+                    scene.enablePhysics(physicsGravity, physicsPlugin);
+                }
+                //collisions, if defined. otherwise, default is true
+                if (parsedData.collisionsEnabled != undefined) {
+                    scene.collisionsEnabled = parsedData.collisionsEnabled;
+                }
+                scene.workerCollisions = !!parsedData.workerCollisions;
                 // Lights
-                for (var index = 0; index < parsedData.lights.length; index++) {
+                var index;
+                for (index = 0; index < parsedData.lights.length; index++) {
                     var parsedLight = parsedData.lights[index];
                     parseLight(parsedLight, scene);
                 }

+ 44 - 7
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -119,7 +119,11 @@
         return fresnelParameters;
     }
 
-    var parseMaterial = (parsedMaterial, scene, rootUrl) => {
+    var parseCustomMaterial = (parsedMaterial, scene, rootUrl): Material => {
+        return null;
+    }
+
+    var parseStandardMaterial = (parsedMaterial, scene, rootUrl): Material => {
         var material;
         material = new BABYLON.StandardMaterial(parsedMaterial.name, scene);
 
@@ -199,6 +203,14 @@
         return material;
     };
 
+    var parseMaterial = (parsedMaterial, scene, rootUrl): Material => {
+        if (!parsedMaterial.customType) {
+            return parseStandardMaterial(parsedMaterial, scene, rootUrl);
+        }
+
+        return parseCustomMaterial(parsedMaterial, scene, rootUrl);
+    }
+
     var parseMaterialById = (id, parsedData, scene, rootUrl) => {
         for (var index = 0; index < parsedData.materials.length; index++) {
             var parsedMaterial = parsedData.materials[index];
@@ -1402,7 +1414,8 @@
             var loadedSkeletonsIds = [];
             var loadedMaterialsIds = [];
             var hierarchyIds = [];
-            for (var index = 0; index < parsedData.meshes.length; index++) {
+            var index: number;
+            for (index = 0; index < parsedData.meshes.length; index++) {
                 var parsedMesh = parsedData.meshes[index];
 
                 if (!meshesNames || isDescendantOf(parsedMesh, meshesNames, hierarchyIds)) {
@@ -1513,8 +1526,9 @@
             }
 
             // Connecting parents
+            var currentMesh: AbstractMesh;
             for (index = 0; index < scene.meshes.length; index++) {
-                var currentMesh = scene.meshes[index];
+                currentMesh = scene.meshes[index];
                 if (currentMesh._waitingParentId) {
                     currentMesh.parent = scene.getLastEntryByID(currentMesh._waitingParentId);
                     currentMesh._waitingParentId = undefined;
@@ -1523,7 +1537,7 @@
 
             // freeze world matrix application
             for (index = 0; index < scene.meshes.length; index++) {
-                var currentMesh = scene.meshes[index];
+                currentMesh = scene.meshes[index];
                 if (currentMesh._waitingFreezeWorldMatrix) {
                     currentMesh.freezeWorldMatrix();
                     currentMesh._waitingFreezeWorldMatrix = undefined;
@@ -1551,8 +1565,10 @@
             scene.autoClear = parsedData.autoClear;
             scene.clearColor = BABYLON.Color3.FromArray(parsedData.clearColor);
             scene.ambientColor = BABYLON.Color3.FromArray(parsedData.ambientColor);
-            scene.gravity = BABYLON.Vector3.FromArray(parsedData.gravity);
-
+            if (parsedData.gravity) {
+                scene.gravity = BABYLON.Vector3.FromArray(parsedData.gravity);
+            }
+            
             // Fog
             if (parsedData.fogMode && parsedData.fogMode !== 0) {
                 scene.fogMode = parsedData.fogMode;
@@ -1561,9 +1577,29 @@
                 scene.fogEnd = parsedData.fogEnd;
                 scene.fogDensity = parsedData.fogDensity;
             }
+            
+            //Physics
+            if (parsedData.physicsEnabled) {
+                var physicsPlugin;
+                if (parsedData.physicsEngine === "cannon") {
+                    physicsPlugin = new BABYLON.CannonJSPlugin();
+                } else if (parsedData.physicsEngine === "oimo") {
+                    physicsPlugin = new BABYLON.OimoJSPlugin();
+                }
+                //else - default engine, which is currently oimo
+                var physicsGravity = parsedData.physicsGravity ? BABYLON.Vector3.FromArray(parsedData.physicsGravity) : null;
+                scene.enablePhysics(physicsGravity, physicsPlugin);
+            }
+            
+            //collisions, if defined. otherwise, default is true
+            if (parsedData.collisionsEnabled != undefined) {
+                scene.collisionsEnabled = parsedData.collisionsEnabled;
+            }
+            scene.workerCollisions = !!parsedData.workerCollisions;            
 
             // Lights
-            for (var index = 0; index < parsedData.lights.length; index++) {
+            var index: number;
+            for (index = 0; index < parsedData.lights.length; index++) {
                 var parsedLight = parsedData.lights[index];
                 parseLight(parsedLight, scene);
             }
@@ -1772,3 +1808,4 @@
 }
 
 
+

+ 0 - 368
src/Materials/Textures/Procedurals/babylon.standardProceduralTexture.ts

@@ -1,368 +0,0 @@
-module BABYLON {
-    export class WoodProceduralTexture extends ProceduralTexture {
-        private _ampScale: number = 100.0;
-        private _woodColor: Color3 = new Color3(0.32, 0.17, 0.09);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "woodtexture", scene, fallbackTexture, generateMipMaps);
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setFloat("ampScale", this._ampScale);
-            this.setColor3("woodColor", this._woodColor);
-        }
-
-        public get ampScale(): number {
-            return this._ampScale;
-        }
-
-        public set ampScale(value: number) {
-            this._ampScale = value;
-            this.updateShaderUniforms();
-        }
-
-        public get woodColor(): Color3 {
-            return this._woodColor;
-        }
-
-        public set woodColor(value: Color3) {
-            this._woodColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class FireProceduralTexture extends ProceduralTexture {
-        private _time: number = 0.0;
-        private _speed = new Vector2(0.5, 0.3);
-        private _autoGenerateTime: boolean = true;
-        private _fireColors: Color3[];
-        private _alphaThreshold: number = 0.5;
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "firetexture", scene, fallbackTexture, generateMipMaps);
-            this._fireColors = FireProceduralTexture.RedFireColors;
-            this.updateShaderUniforms();
-            this.refreshRate = 1;
-        }
-
-        public updateShaderUniforms() {
-            this.setFloat("time", this._time);
-            this.setVector2("speed", this._speed);
-            this.setColor3("c1", this._fireColors[0]);
-            this.setColor3("c2", this._fireColors[1]);
-            this.setColor3("c3", this._fireColors[2]);
-            this.setColor3("c4", this._fireColors[3]);
-            this.setColor3("c5", this._fireColors[4]);
-            this.setColor3("c6", this._fireColors[5]);
-            this.setFloat("alphaThreshold", this._alphaThreshold);
-        }
-
-        public render(useCameraPostProcess?: boolean) {
-            if (this._autoGenerateTime) {
-                this._time += this.getScene().getAnimationRatio() * 0.03;
-                this.updateShaderUniforms();
-            }
-            super.render(useCameraPostProcess);
-        }
-
-        public static get PurpleFireColors(): Color3[] {
-            return [
-                new Color3(0.5, 0.0, 1.0),
-                new Color3(0.9, 0.0, 1.0),
-                new Color3(0.2, 0.0, 1.0),
-                new Color3(1.0, 0.9, 1.0),
-                new Color3(0.1, 0.1, 1.0),
-                new Color3(0.9, 0.9, 1.0)
-            ];
-        }
-
-        public static get GreenFireColors(): Color3[] {
-            return [
-                new Color3(0.5, 1.0, 0.0),
-                new Color3(0.5, 1.0, 0.0),
-                new Color3(0.3, 0.4, 0.0),
-                new Color3(0.5, 1.0, 0.0),
-                new Color3(0.2, 0.0, 0.0),
-                new Color3(0.5, 1.0, 0.0)
-            ];
-        }
-
-        public static get RedFireColors(): Color3[] {
-            return [
-                new Color3(0.5, 0.0, 0.1),
-                new Color3(0.9, 0.0, 0.0),
-                new Color3(0.2, 0.0, 0.0),
-                new Color3(1.0, 0.9, 0.0),
-                new Color3(0.1, 0.1, 0.1),
-                new Color3(0.9, 0.9, 0.9)
-            ];
-        }
-
-        public static get BlueFireColors(): Color3[] {
-            return [
-                new Color3(0.1, 0.0, 0.5),
-                new Color3(0.0, 0.0, 0.5),
-                new Color3(0.1, 0.0, 0.2),
-                new Color3(0.0, 0.0, 1.0),
-                new Color3(0.1, 0.2, 0.3),
-                new Color3(0.0, 0.2, 0.9)
-            ];
-        }
-
-        public get fireColors(): Color3[] {
-            return this._fireColors;
-        }
-
-        public set fireColors(value: Color3[]) {
-            this._fireColors = value;
-            this.updateShaderUniforms();
-        }
-
-        public get time(): number {
-            return this._time;
-        }
-
-        public set time(value: number) {
-            this._time = value;
-            this.updateShaderUniforms();
-        }
-
-        public get speed(): Vector2 {
-            return this._speed;
-        }
-
-        public set speed(value: Vector2) {
-            this._speed = value;
-            this.updateShaderUniforms();
-        }
-
-        public get alphaThreshold(): number {
-            return this._alphaThreshold;
-        }
-
-        public set alphaThreshold(value: number) {
-            this._alphaThreshold = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class CloudProceduralTexture extends ProceduralTexture {
-        private _skyColor = new Color4(0.15, 0.68, 1.0, 1.0);
-        private _cloudColor = new Color4(1, 1, 1, 1.0);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "cloudtexture", scene, fallbackTexture, generateMipMaps);
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setColor4("skyColor", this._skyColor);
-            this.setColor4("cloudColor", this._cloudColor);
-        }
-
-        public get skyColor(): Color4 {
-            return this._skyColor;
-        }
-
-        public set skyColor(value: Color4) {
-            this._skyColor = value;
-            this.updateShaderUniforms();
-        }
-
-        public get cloudColor(): Color4 {
-            return this._cloudColor;
-        }
-
-        public set cloudColor(value: Color4) {
-            this._cloudColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class GrassProceduralTexture extends ProceduralTexture {
-        private _grassColors: Color3[];
-        private _herb1 = new Color3(0.29, 0.38, 0.02);
-        private _herb2 = new Color3(0.36, 0.49, 0.09);
-        private _herb3 = new Color3(0.51, 0.6, 0.28);
-        private _groundColor = new Color3(1, 1, 1);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "grasstexture", scene, fallbackTexture, generateMipMaps);
-
-            this._grassColors = [
-                new Color3(0.29, 0.38, 0.02),
-                new Color3(0.36, 0.49, 0.09),
-                new Color3(0.51, 0.6, 0.28)
-            ];
-
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setColor3("herb1Color", this._grassColors[0]);
-            this.setColor3("herb2Color", this._grassColors[1]);
-            this.setColor3("herb3Color", this._grassColors[2]);
-            this.setColor3("groundColor", this._groundColor);
-        }
-
-        public get grassColors(): Color3[] {
-            return this._grassColors;
-        }
-
-        public set grassColors(value: Color3[]) {
-            this._grassColors = value;
-            this.updateShaderUniforms();
-        }
-
-        public get groundColor(): Color3 {
-            return this._groundColor;
-        }
-
-        public set groundColor(value: Color3) {
-            this.groundColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class RoadProceduralTexture extends ProceduralTexture {
-        private _roadColor = new Color3(0.53, 0.53, 0.53);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "roadtexture", scene, fallbackTexture, generateMipMaps);
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setColor3("roadColor", this._roadColor);
-        }
-
-        public get roadColor(): Color3 {
-            return this._roadColor;
-        }
-
-        public set roadColor(value: Color3) {
-            this._roadColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class BrickProceduralTexture extends ProceduralTexture {
-        private _numberOfBricksHeight: number = 15;
-        private _numberOfBricksWidth: number = 5;
-        private _jointColor = new Color3(0.72, 0.72, 0.72);
-        private _brickColor = new Color3(0.77, 0.47, 0.40);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "bricktexture", scene, fallbackTexture, generateMipMaps);
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
-            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
-            this.setColor3("brickColor", this._brickColor);
-            this.setColor3("jointColor", this._jointColor);
-        }
-
-        public get numberOfBricksHeight(): number {
-            return this._numberOfBricksHeight;
-        }
-
-        public set numberOfBricksHeight(value: number) {
-            this._numberOfBricksHeight = value;
-            this.updateShaderUniforms();
-        }
-
-        public get numberOfBricksWidth(): number {
-            return this._numberOfBricksWidth;
-        }
-
-        public set numberOfBricksWidth(value: number) {
-            this._numberOfBricksWidth = value;
-            this.updateShaderUniforms();
-        }
-
-        public get jointColor(): Color3 {
-            return this._jointColor;
-        }
-
-        public set jointColor(value: Color3) {
-            this._jointColor = value;
-            this.updateShaderUniforms();
-        }
-
-        public get brickColor(): Color3 {
-            return this._brickColor;
-        }
-
-        public set brickColor(value: Color3) {
-            this._brickColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-
-    export class MarbleProceduralTexture extends ProceduralTexture {
-        private _numberOfTilesHeight: number = 3;
-        private _numberOfTilesWidth: number = 3;
-        private _amplitude: number = 9.0;
-        private _marbleColor = new Color3(0.77, 0.47, 0.40);
-        private _jointColor = new Color3(0.72, 0.72, 0.72);
-
-        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
-            super(name, size, "marbletexture", scene, fallbackTexture, generateMipMaps);
-            this.updateShaderUniforms();
-            this.refreshRate = 0;
-        }
-
-        public updateShaderUniforms() {
-            this.setFloat("numberOfTilesHeight", this._numberOfTilesHeight);
-            this.setFloat("numberOfTilesWidth", this._numberOfTilesWidth);
-            this.setFloat("amplitude", this._amplitude);
-            this.setColor3("marbleColor", this._marbleColor);
-            this.setColor3("jointColor", this._jointColor);
-        }
-
-        public get numberOfTilesHeight(): number {
-            return this._numberOfTilesHeight;
-        }
-
-        public set numberOfTilesHeight(value: number) {
-            this._numberOfTilesHeight = value;
-            this.updateShaderUniforms();
-        }
-
-        public get numberOfTilesWidth(): number {
-            return this._numberOfTilesWidth;
-        }
-
-        public set numberOfTilesWidth(value: number) {
-            this._numberOfTilesWidth = value;
-            this.updateShaderUniforms();
-        }
-
-        public get jointColor(): Color3 {
-            return this._jointColor;
-        }
-
-        public set jointColor(value: Color3) {
-            this._jointColor = value;
-            this.updateShaderUniforms();
-        }
-
-        public get marbleColor(): Color3 {
-            return this._marbleColor;
-        }
-
-        public set marbleColor(value: Color3) {
-            this._marbleColor = value;
-            this.updateShaderUniforms();
-        }
-    }
-}
-

+ 1 - 0
src/Materials/Textures/babylon.texture.js

@@ -199,6 +199,7 @@ var BABYLON;
         Texture.SKYBOX_MODE = 5;
         Texture.INVCUBIC_MODE = 6;
         Texture.EQUIRECTANGULAR_MODE = 7;
+        Texture.FIXED_EQUIRECTANGULAR_MODE = 8;
         Texture.CLAMP_ADDRESSMODE = 0;
         Texture.WRAP_ADDRESSMODE = 1;
         Texture.MIRROR_ADDRESSMODE = 2;

+ 1 - 0
src/Materials/Textures/babylon.texture.ts

@@ -13,6 +13,7 @@
         public static SKYBOX_MODE = 5;
         public static INVCUBIC_MODE = 6;
         public static EQUIRECTANGULAR_MODE = 7;
+        public static FIXED_EQUIRECTANGULAR_MODE = 8;
 
         public static CLAMP_ADDRESSMODE = 0;
         public static WRAP_ADDRESSMODE = 1;

+ 4 - 0
src/Materials/babylon.standardMaterial.js

@@ -102,6 +102,7 @@ var BABYLON;
             this.REFLECTIONMAP_SKYBOX = false;
             this.REFLECTIONMAP_EXPLICIT = false;
             this.REFLECTIONMAP_EQUIRECTANGULAR = false;
+            this.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
             this.INVERTCUBICMAP = false;
             this.LOGARITHMICDEPTH = false;
             this._keys = Object.keys(this);
@@ -382,6 +383,9 @@ var BABYLON;
                             case BABYLON.Texture.EQUIRECTANGULAR_MODE:
                                 this._defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
                                 break;
+                            case BABYLON.Texture.FIXED_EQUIRECTANGULAR_MODE:
+                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
+                                break;
                         }
                     }
                 }

+ 4 - 0
src/Materials/babylon.standardMaterial.ts

@@ -94,6 +94,7 @@
         public REFLECTIONMAP_SKYBOX = false;
         public REFLECTIONMAP_EXPLICIT = false;
         public REFLECTIONMAP_EQUIRECTANGULAR = false;
+        public REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
         public INVERTCUBICMAP = false;
         public LOGARITHMICDEPTH = false;
 
@@ -440,6 +441,9 @@
                             case Texture.EQUIRECTANGULAR_MODE:
                                 this._defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
                                 break;
+                            case Texture.FIXED_EQUIRECTANGULAR_MODE:
+                                this._defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
+                                break;
                         }
                     }
                 }

+ 14 - 0
src/Math/babylon.math.js

@@ -1925,6 +1925,20 @@ var BABYLON;
         Matrix.TranslationToRef = function (x, y, z, result) {
             Matrix.FromValuesToRef(1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, x, y, z, 1.0, result);
         };
+        Matrix.Lerp = function (startValue, endValue, gradient) {
+            var startScale = new Vector3(0, 0, 0);
+            var startRotation = new Quaternion();
+            var startTranslation = new Vector3(0, 0, 0);
+            startValue.decompose(startScale, startRotation, startTranslation);
+            var endScale = new Vector3(0, 0, 0);
+            var endRotation = new Quaternion();
+            var endTranslation = new Vector3(0, 0, 0);
+            endValue.decompose(endScale, endRotation, endTranslation);
+            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
+            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
+            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
+            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+        };
         Matrix.LookAtLH = function (eye, target, up) {
             var result = Matrix.Zero();
             Matrix.LookAtLHToRef(eye, target, up, result);

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

@@ -2413,6 +2413,24 @@
                 x, y, z, 1.0, result);
         }
 
+        public static Lerp(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
+            var startScale = new Vector3(0, 0, 0);
+            var startRotation = new Quaternion();
+            var startTranslation = new Vector3(0, 0, 0);
+            startValue.decompose(startScale, startRotation, startTranslation);
+
+            var endScale = new Vector3(0, 0, 0);
+            var endRotation = new Quaternion();
+            var endTranslation = new Vector3(0, 0, 0);
+            endValue.decompose(endScale, endRotation, endTranslation);
+
+            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
+            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
+            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
+
+            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+        }    
+
         public static LookAtLH(eye: Vector3, target: Vector3, up: Vector3): Matrix {
             var result = Matrix.Zero();
 

+ 59 - 27
src/Mesh/babylon.mesh.vertexData.js

@@ -628,7 +628,7 @@ var BABYLON;
                     var afterRotZ = BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.Up(), rotationZ);
                     var complete = BABYLON.Vector3.TransformCoordinates(afterRotZ, rotationY);
                     var vertex = complete.multiply(radius);
-                    var normal = BABYLON.Vector3.Normalize(vertex);
+                    var normal = complete.divide(radius).normalize();
                     positions.push(vertex.x, vertex.y, vertex.z);
                     normals.push(normal.x, normal.y, normal.z);
                     uvs.push(normalizedY, normalizedZ);
@@ -671,14 +671,14 @@ var BABYLON;
             // default face colors and UV if undefined
             var quadNb = (arc !== 1 && enclose) ? 2 : 0;
             var ringNb = (hasRings) ? subdivisions : 1;
-            var colorNb = 2 + (1 + quadNb) * ringNb;
+            var surfaceNb = 2 + (1 + quadNb) * ringNb;
             var f;
-            for (f = 0; f < colorNb; f++) {
+            for (f = 0; f < surfaceNb; f++) {
                 if (faceColors && faceColors[f] === undefined) {
                     faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
                 }
             }
-            for (f = 0; f < 3; f++) {
+            for (f = 0; f < surfaceNb; f++) {
                 if (faceUV && faceUV[f] === undefined) {
                     faceUV[f] = new BABYLON.Vector4(0, 0, 1, 1);
                 }
@@ -704,11 +704,20 @@ var BABYLON;
             var j;
             var r;
             var ringIdx = 1;
+            var s = 1; // surface index
+            var cs = 0;
+            var v = 0;
             for (i = 0; i <= subdivisions; i++) {
                 h = i / subdivisions;
                 radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
                 ringIdx = (hasRings && i !== 0 && i !== subdivisions) ? 2 : 1;
                 for (r = 0; r < ringIdx; r++) {
+                    if (hasRings) {
+                        s += r;
+                    }
+                    if (enclose) {
+                        s += 2 * r;
+                    }
                     for (j = 0; j <= tessellation; j++) {
                         angle = j * angle_step;
                         // position
@@ -728,16 +737,22 @@ var BABYLON;
                             ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;
                             ringNormal.normalize();
                         }
-                        // keep first values for enclose
+                        // keep first ring vertex values for enclose
                         if (j === 0) {
                             ringFirstVertex.copyFrom(ringVertex);
                             ringFirstNormal.copyFrom(ringNormal);
                         }
                         positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
                         normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x) * j / tessellation, faceUV[1].y + (faceUV[1].w - faceUV[1].y) * h);
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s].y : faceUV[s].w;
+                        }
+                        else {
+                            v = faceUV[s].y + (faceUV[s].w - faceUV[s].y) * h;
+                        }
+                        uvs.push(faceUV[s].x + (faceUV[s].z - faceUV[s].x) * j / tessellation, v);
                         if (faceColors) {
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[s].r, faceColors[s].g, faceColors[s].b, faceColors[s].a);
                         }
                     }
                     // if enclose, add four vertices and their dedicated normals
@@ -752,17 +767,32 @@ var BABYLON;
                         BABYLON.Vector3.CrossToRef(ringFirstNormal, Y, quadNormal);
                         quadNormal.normalize();
                         normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s + 1].y : faceUV[s + 1].w;
+                        }
+                        else {
+                            v = faceUV[s + 1].y + (faceUV[s + 1].w - faceUV[s + 1].y) * h;
+                        }
+                        uvs.push(faceUV[s + 1].x, v);
+                        uvs.push(faceUV[s + 1].z, v);
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s + 2].y : faceUV[s + 2].w;
+                        }
+                        else {
+                            v = faceUV[s + 2].y + (faceUV[s + 2].w - faceUV[s + 2].y) * h;
+                        }
+                        uvs.push(faceUV[s + 2].x, v);
+                        uvs.push(faceUV[s + 2].z, v);
                         if (faceColors) {
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
+                            colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
+                            colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
+                            colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
                         }
                     }
+                    if (cs !== s) {
+                        cs = s;
+                    }
                 }
             }
             // indices
@@ -796,10 +826,10 @@ var BABYLON;
                 var angle;
                 var circleVector;
                 var i;
-                var u = (isTop) ? faceUV[2] : faceUV[0];
+                var u = (isTop) ? faceUV[surfaceNb - 1] : faceUV[0];
                 var c;
                 if (faceColors) {
-                    c = (isTop) ? faceColors[colorNb - 1] : faceColors[0];
+                    c = (isTop) ? faceColors[surfaceNb - 1] : faceColors[0];
                 }
                 // cap center
                 var vbase = positions.length / 3;
@@ -1297,7 +1327,7 @@ var BABYLON;
                 0, 0, 0, 0, 1,
                 0, 0, 1, 1, 0,
                 0, 0, 1, 1, 0,
-                0, 1, 1, 1, 0,
+                0, 1, 1, 1, 0 //  15 - 19
             ];
             var indices = [];
             var positions = [];
@@ -1307,14 +1337,15 @@ var BABYLON;
             // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
             var face_vertex_pos = new Array(3);
             var face_vertex_uv = new Array(3);
-            for (var v012 = 0; v012 < 3; v012++) {
+            var v012;
+            for (v012 = 0; v012 < 3; v012++) {
                 face_vertex_pos[v012] = BABYLON.Vector3.Zero();
                 face_vertex_uv[v012] = BABYLON.Vector2.Zero();
             }
             // create all with normals
             for (var face = 0; face < 20; face++) {
                 // 3 vertex per face
-                for (var v012 = 0; v012 < 3; v012++) {
+                for (v012 = 0; v012 < 3; v012++) {
                     // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)
                     var v_id = ico_indices[3 * face + v012];
                     // vertex have 3D position (x,y,z)
@@ -1368,25 +1399,26 @@ var BABYLON;
                     var pos_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
                     var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : BABYLON.Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
                     pos_interp.normalize();
-                    pos_interp.x *= radiusX;
-                    pos_interp.y *= radiusY;
-                    pos_interp.z *= radiusZ;
                     var vertex_normal;
                     if (flat) {
                         // in flat mode, recalculate normal as face centroid normal
                         var centroid_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
                         var centroid_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
-                        var centroid_interp = BABYLON.Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
-                        vertex_normal = BABYLON.Vector3.Normalize(centroid_interp);
+                        vertex_normal = BABYLON.Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
                     }
                     else {
                         // in smooth mode, recalculate normal from each single vertex position
-                        vertex_normal = BABYLON.Vector3.Normalize(pos_interp);
+                        vertex_normal = new BABYLON.Vector3(pos_interp.x, pos_interp.y, pos_interp.z);
                     }
+                    // Vertex normal need correction due to X,Y,Z radius scaling
+                    vertex_normal.x /= radiusX;
+                    vertex_normal.y /= radiusY;
+                    vertex_normal.z /= radiusZ;
+                    vertex_normal.normalize();
                     var uv_x0 = BABYLON.Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
                     var uv_x1 = BABYLON.Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
                     var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : BABYLON.Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
-                    positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
+                    positions.push(pos_interp.x * radiusX, pos_interp.y * radiusY, pos_interp.z * radiusZ);
                     normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
                     uvs.push(uv_interp.x, uv_interp.y);
                     // push each vertex has member of a face

+ 59 - 33
src/Mesh/babylon.mesh.vertexData.ts

@@ -769,7 +769,7 @@
                     var complete = Vector3.TransformCoordinates(afterRotZ, rotationY);
 
                     var vertex = complete.multiply(radius);
-                    var normal = Vector3.Normalize(vertex);
+                    var normal = complete.divide(radius).normalize();
 
                     positions.push(vertex.x, vertex.y, vertex.z);
                     normals.push(normal.x, normal.y, normal.z);
@@ -821,14 +821,14 @@
             // default face colors and UV if undefined
             var quadNb: number = (arc !== 1 && enclose) ? 2 : 0;
             var ringNb: number = (hasRings) ? subdivisions : 1;
-            var colorNb: number = 2 + (1 + quadNb) * ringNb;
+            var surfaceNb: number = 2 + (1 + quadNb) * ringNb;
             var f: number;
-            for (f = 0; f < colorNb; f++) {
+            for (f = 0; f < surfaceNb; f++) {
                 if (faceColors && faceColors[f] === undefined) {
                     faceColors[f] = new Color4(1, 1, 1, 1);
                 }
             }
-            for (f = 0; f < 3; f++) {
+            for (f = 0; f < surfaceNb; f++) {
                 if (faceUV && faceUV[f] === undefined) {
                     faceUV[f] = new Vector4(0, 0, 1, 1);
                 }
@@ -857,12 +857,21 @@
             var j: number;
             var r: number;
             var ringIdx: number = 1;
+            var s: number = 1;      // surface index
+            var cs: number = 0;
+            var v: number = 0;
 
             for (i = 0; i <= subdivisions; i++) {
                 h = i / subdivisions;
                 radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
                 ringIdx = (hasRings && i !== 0 && i !== subdivisions) ? 2 : 1;
                 for (r = 0; r < ringIdx; r++) {
+                    if (hasRings) {
+                        s += r;
+                    }
+                    if (enclose) {
+                        s += 2 * r;
+                    }
                     for (j = 0; j <= tessellation; j++) {
                         angle = j * angle_step;
 
@@ -885,7 +894,7 @@
                             ringNormal.normalize();
                         }
 
-                        // keep first values for enclose
+                        // keep first ring vertex values for enclose
                         if (j === 0) {
                             ringFirstVertex.copyFrom(ringVertex);
                             ringFirstNormal.copyFrom(ringNormal);
@@ -893,9 +902,14 @@
 
                         positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
                         normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x) * j / tessellation, faceUV[1].y + (faceUV[1].w - faceUV[1].y) * h);
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s].y : faceUV[s].w;
+                        } else {
+                            v = faceUV[s].y + (faceUV[s].w - faceUV[s].y) * h;
+                        }
+                        uvs.push(faceUV[s].x + (faceUV[s].z - faceUV[s].x) * j / tessellation, v);
                         if (faceColors) {
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[s].r, faceColors[s].g, faceColors[s].b, faceColors[s].a);
                         }
                     }
 
@@ -911,18 +925,33 @@
                         Vector3.CrossToRef(ringFirstNormal, Y, quadNormal);
                         quadNormal.normalize();
                         normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
-                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s + 1].y : faceUV[s + 1].w;
+                        } else {
+                            v = faceUV[s + 1].y + (faceUV[s + 1].w - faceUV[s + 1].y) * h;
+                        }
+                        uvs.push(faceUV[s + 1].x, v);
+                        uvs.push(faceUV[s + 1].z, v);
+                        if (hasRings) {
+                            v = (cs !== s) ? faceUV[s + 2].y : faceUV[s + 2].w;
+                        } else {
+                            v = faceUV[s + 2].y + (faceUV[s + 2].w - faceUV[s + 2].y) * h;
+                        }
+                        uvs.push(faceUV[s + 2].x, v);
+                        uvs.push(faceUV[s + 2].z, v);
                         if (faceColors) {
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
-                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
+                            colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
+                            colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
+                            colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
                         }
                     }
+                    if (cs !== s) {
+                        cs = s;
+                    }
+
                 }
+
             }
 
             // indices
@@ -958,10 +987,10 @@
                 var angle;
                 var circleVector;
                 var i: number;
-                var u: Vector4 = (isTop) ? faceUV[2] : faceUV[0];
+                var u: Vector4 = (isTop) ? faceUV[surfaceNb - 1] : faceUV[0];
                 var c: Color4;
                 if (faceColors) {
-                    c = (isTop) ? faceColors[colorNb - 1] : faceColors[0];
+                    c = (isTop) ? faceColors[surfaceNb - 1] : faceColors[0];
                 }
                 // cap center
                 var vbase = positions.length / 3;
@@ -1566,7 +1595,7 @@
                 0, 0, 0, 0, 1, //  0 - 4
                 0, 0, 1, 1, 0, //  5 - 9
                 0, 0, 1, 1, 0, //  10 - 14
-                0, 1, 1, 1, 0, //  15 - 19
+                0, 1, 1, 1, 0 //  15 - 19
             ];
 
             var indices = [];
@@ -1578,14 +1607,15 @@
             // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
             var face_vertex_pos = new Array(3);
             var face_vertex_uv = new Array(3);
-            for (var v012 = 0; v012 < 3; v012++) {
+            var v012;
+            for (v012 = 0; v012 < 3; v012++) {
                 face_vertex_pos[v012] = Vector3.Zero();
                 face_vertex_uv[v012] = Vector2.Zero();
             }
             // create all with normals
             for (var face = 0; face < 20; face++) {
                 // 3 vertex per face
-                for (var v012 = 0; v012 < 3; v012++) {
+                for (v012 = 0; v012 < 3; v012++) {
                     // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)
                     var v_id = ico_indices[3 * face + v012];
                     // vertex have 3D position (x,y,z)
@@ -1647,26 +1677,27 @@
                     var pos_x1 = Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
                     var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
                     pos_interp.normalize();
-                    pos_interp.x *= radiusX;
-                    pos_interp.y *= radiusY;
-                    pos_interp.z *= radiusZ;
 
                     var vertex_normal;
                     if (flat) {
                         // in flat mode, recalculate normal as face centroid normal
                         var centroid_x0 = Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
                         var centroid_x1 = Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
-                        var centroid_interp = Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
-                        vertex_normal = Vector3.Normalize(centroid_interp);
+                        vertex_normal = Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
                     } else {
                         // in smooth mode, recalculate normal from each single vertex position
-                        vertex_normal = Vector3.Normalize(pos_interp);
+                        vertex_normal = new Vector3(pos_interp.x, pos_interp.y, pos_interp.z);
                     }
+                    // Vertex normal need correction due to X,Y,Z radius scaling
+                    vertex_normal.x /= radiusX;
+                    vertex_normal.y /= radiusY;
+                    vertex_normal.z /= radiusZ;
+                    vertex_normal.normalize();
 
                     var uv_x0 = Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
                     var uv_x1 = Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
                     var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
-                    positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
+                    positions.push(pos_interp.x * radiusX, pos_interp.y * radiusY, pos_interp.z * radiusZ);
                     normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
                     uvs.push(uv_interp.x, uv_interp.y);
                     // push each vertex has member of a face
@@ -2068,9 +2099,4 @@
             }
         }
     }
-}
-
-
-
-
-
+}

+ 4 - 4
src/Particles/babylon.particleSystem.js

@@ -72,13 +72,13 @@ var BABYLON;
             this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
             this._vertices = new Float32Array(capacity * this._vertexStrideSize);
             // Default behaviors
-            this.startDirectionFunction = function (emitPower, worldMatrix, directionToUpdate) {
+            this.startDirectionFunction = function (emitPower, worldMatrix, directionToUpdate, particle) {
                 var randX = randomNumber(_this.direction1.x, _this.direction2.x);
                 var randY = randomNumber(_this.direction1.y, _this.direction2.y);
                 var randZ = randomNumber(_this.direction1.z, _this.direction2.z);
                 BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
             };
-            this.startPositionFunction = function (worldMatrix, positionToUpdate) {
+            this.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
                 var randX = randomNumber(_this.minEmitBox.x, _this.maxEmitBox.x);
                 var randY = randomNumber(_this.minEmitBox.y, _this.maxEmitBox.y);
                 var randZ = randomNumber(_this.minEmitBox.z, _this.maxEmitBox.z);
@@ -170,11 +170,11 @@ var BABYLON;
                 }
                 this.particles.push(particle);
                 var emitPower = randomNumber(this.minEmitPower, this.maxEmitPower);
-                this.startDirectionFunction(emitPower, worldMatrix, particle.direction);
+                this.startDirectionFunction(emitPower, worldMatrix, particle.direction, particle);
                 particle.lifeTime = randomNumber(this.minLifeTime, this.maxLifeTime);
                 particle.size = randomNumber(this.minSize, this.maxSize);
                 particle.angularSpeed = randomNumber(this.minAngularSpeed, this.maxAngularSpeed);
-                this.startPositionFunction(worldMatrix, particle.position);
+                this.startPositionFunction(worldMatrix, particle.position, particle);
                 var step = randomNumber(0, 1.0);
                 BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
                 this.colorDead.subtractToRef(particle.color, this._colorDiff);

+ 7 - 7
src/Particles/babylon.particleSystem.ts

@@ -55,8 +55,8 @@
         public color2 = new Color4(1.0, 1.0, 1.0, 1.0);
         public colorDead = new Color4(0, 0, 0, 1.0);
         public textureMask = new Color4(1.0, 1.0, 1.0, 1.0);
-        public startDirectionFunction: (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3) => void;
-        public startPositionFunction: (worldMatrix: Matrix, positionToUpdate: Vector3) => void;
+        public startDirectionFunction: (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle) => void;
+        public startPositionFunction: (worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle) => void;
 
         private particles = new Array<Particle>();
 
@@ -115,7 +115,7 @@
             this._vertices = new Float32Array(capacity * this._vertexStrideSize);
 
             // Default behaviors
-            this.startDirectionFunction = (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3): void => {
+            this.startDirectionFunction = (emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void => {
                 var randX = randomNumber(this.direction1.x, this.direction2.x);
                 var randY = randomNumber(this.direction1.y, this.direction2.y);
                 var randZ = randomNumber(this.direction1.z, this.direction2.z);
@@ -123,7 +123,7 @@
                 Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
             }
 
-            this.startPositionFunction = (worldMatrix: Matrix, positionToUpdate: Vector3): void => {
+            this.startPositionFunction = (worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void => {
                 var randX = randomNumber(this.minEmitBox.x, this.maxEmitBox.x);
                 var randY = randomNumber(this.minEmitBox.y, this.maxEmitBox.y);
                 var randZ = randomNumber(this.minEmitBox.z, this.maxEmitBox.z);
@@ -236,14 +236,14 @@
 
                 var emitPower = randomNumber(this.minEmitPower, this.maxEmitPower);
 
-                this.startDirectionFunction(emitPower, worldMatrix, particle.direction);
+                this.startDirectionFunction(emitPower, worldMatrix, particle.direction, particle);
 
                 particle.lifeTime = randomNumber(this.minLifeTime, this.maxLifeTime);
 
                 particle.size = randomNumber(this.minSize, this.maxSize);
                 particle.angularSpeed = randomNumber(this.minAngularSpeed, this.maxAngularSpeed);
 
-                this.startPositionFunction(worldMatrix, particle.position);
+                this.startPositionFunction(worldMatrix, particle.position, particle);
 
                 var step = randomNumber(0, 1.0);
 
@@ -446,4 +446,4 @@
             return result;
         }
     }
-}  
+}  

+ 5 - 0
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -4,6 +4,7 @@ var BABYLON;
         function CannonJSPlugin() {
             this._registeredMeshes = [];
             this._physicsMaterials = [];
+            this.name = "cannon";
             this.updateBodyPosition = function (mesh) {
                 for (var index = 0; index < this._registeredMeshes.length; index++) {
                     var registeredMesh = this._registeredMeshes[index];
@@ -89,8 +90,12 @@ var BABYLON;
             });
         };
         CannonJSPlugin.prototype.setGravity = function (gravity) {
+            this._gravity = gravity;
             this._world.gravity.set(gravity.x, gravity.y, gravity.z);
         };
+        CannonJSPlugin.prototype.getGravity = function () {
+            return this._gravity;
+        };
         CannonJSPlugin.prototype.registerMesh = function (mesh, impostor, options) {
             this.unregisterMesh(mesh);
             if (!mesh.rotationQuaternion) {

+ 9 - 7
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -17,6 +17,9 @@
         private _world: any;
         private _registeredMeshes: Array<IRegisteredMesh> = [];
         private _physicsMaterials = [];
+        private _gravity: Vector3;
+
+        public name = "cannon";
 
         public initialize(iterations: number = 10): void {
             this._world = new CANNON.World();
@@ -70,9 +73,14 @@
         }
 
         public setGravity(gravity: Vector3): void {
+            this._gravity = gravity;
             this._world.gravity.set(gravity.x, gravity.y, gravity.z);
         }
 
+        public getGravity(): Vector3 {
+            return this._gravity;
+        }
+
         public registerMesh(mesh: AbstractMesh, impostor: number, options?: PhysicsBodyCreationOptions): any {
             this.unregisterMesh(mesh);
 
@@ -479,10 +487,4 @@
             return null;
         }
     }
-}
-
-
-
-
-
-
+}

+ 5 - 1
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -3,6 +3,7 @@ var BABYLON;
     var OimoJSPlugin = (function () {
         function OimoJSPlugin() {
             this._registeredMeshes = [];
+            this.name = "oimo";
             /**
              * Update the body position according to the mesh position
              * @param mesh
@@ -42,7 +43,10 @@ var BABYLON;
             this._world.clear();
         };
         OimoJSPlugin.prototype.setGravity = function (gravity) {
-            this._world.gravity = gravity;
+            this._gravity = this._world.gravity = gravity;
+        };
+        OimoJSPlugin.prototype.getGravity = function () {
+            return this._gravity;
         };
         OimoJSPlugin.prototype.registerMesh = function (mesh, impostor, options) {
             this.unregisterMesh(mesh);

+ 10 - 5
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -5,6 +5,10 @@ module BABYLON {
         private _world;
         private _registeredMeshes = [];
 
+        public name = "oimo";
+
+        private _gravity: Vector3;
+
         private _checkWithEpsilon(value: number): number {
             return value < PhysicsEngine.Epsilon ? PhysicsEngine.Epsilon : value;
         }
@@ -15,7 +19,11 @@ module BABYLON {
         }
 
         public setGravity(gravity: Vector3): void {
-            this._world.gravity = gravity;
+            this._gravity = this._world.gravity = gravity;
+        }
+
+        public getGravity(): Vector3 {
+            return this._gravity;
         }
 
         public registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any {
@@ -402,7 +410,4 @@ module BABYLON {
             }
         }
     }
-}
-
-
-
+}

+ 6 - 0
src/Physics/babylon.physicsEngine.js

@@ -21,6 +21,9 @@ var BABYLON;
             this.gravity = gravity || new BABYLON.Vector3(0, -9.807, 0);
             this._currentPlugin.setGravity(this.gravity);
         };
+        PhysicsEngine.prototype._getGravity = function () {
+            return this._currentPlugin.getGravity();
+        };
         PhysicsEngine.prototype._registerMesh = function (mesh, impostor, options) {
             return this._currentPlugin.registerMesh(mesh, impostor, options);
         };
@@ -48,6 +51,9 @@ var BABYLON;
         PhysicsEngine.prototype.getPhysicsBodyOfMesh = function (mesh) {
             return this._currentPlugin.getPhysicsBodyOfMesh(mesh);
         };
+        PhysicsEngine.prototype.getPhysicsPluginName = function () {
+            return this._currentPlugin.name;
+        };
         // Statics
         PhysicsEngine.NoImpostor = 0;
         PhysicsEngine.SphereImpostor = 1;

+ 11 - 2
src/Physics/babylon.physicsEngine.ts

@@ -1,7 +1,9 @@
 module BABYLON {
     export interface IPhysicsEnginePlugin {
+        name: string;
         initialize(iterations?: number);
         setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
         runOneStep(delta: number): void;
         registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
         registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
@@ -55,6 +57,10 @@
             this._currentPlugin.setGravity(this.gravity);
         }
 
+        public _getGravity(): Vector3 {
+            return this._currentPlugin.getGravity();
+        }
+
         public _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any {
             return this._currentPlugin.registerMesh(mesh, impostor, options);
         }
@@ -91,6 +97,10 @@
             return this._currentPlugin.getPhysicsBodyOfMesh(mesh);
         }
 
+        public getPhysicsPluginName(): string {
+            return this._currentPlugin.name;
+        }
+
         // Statics
         public static NoImpostor = 0;
         public static SphereImpostor = 1;
@@ -104,5 +114,4 @@
         public static HeightmapImpostor = 9;
         public static Epsilon = 0.001;
     }
-}
-
+}

+ 0 - 69
src/Shaders/bricktexture.fragment.fx

@@ -1,69 +0,0 @@
-precision highp float;
-
-varying vec2 vPosition;
-varying vec2 vUV;
-
-uniform float numberOfBricksHeight;
-uniform float numberOfBricksWidth;
-uniform vec3 brickColor;
-uniform vec3 jointColor;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-float round(float number){
-	return sign(number)*floor(abs(number) + 0.5);
-}
-
-void main(void)
-{
-	float brickW = 1.0 / numberOfBricksWidth;
-	float brickH = 1.0 / numberOfBricksHeight;
-	float jointWPercentage = 0.01;
-	float jointHPercentage = 0.05;
-	vec3 color = brickColor;
-	float yi = vUV.y / brickH;
-	float nyi = round(yi);
-	float xi = vUV.x / brickW;
-
-	if (mod(floor(yi), 2.0) == 0.0){
-		xi = xi - 0.5;
-	}
-
-	float nxi = round(xi);
-	vec2 brickvUV = vec2((xi - floor(xi)) / brickH, (yi - floor(yi)) /  brickW);
-
-	if (yi < nyi + jointHPercentage && yi > nyi - jointHPercentage){
-		color = mix(jointColor, vec3(0.37, 0.25, 0.25), (yi - nyi) / jointHPercentage + 0.2);
-	}
-	else if (xi < nxi + jointWPercentage && xi > nxi - jointWPercentage){
-		color = mix(jointColor, vec3(0.44, 0.44, 0.44), (xi - nxi) / jointWPercentage + 0.2);
-	}
-	else {
-		float brickColorSwitch = mod(floor(yi) + floor(xi), 3.0);
-
-		if (brickColorSwitch == 0.0)
-			color = mix(color, vec3(0.33, 0.33, 0.33), 0.3);
-		else if (brickColorSwitch == 2.0)
-			color = mix(color, vec3(0.11, 0.11, 0.11), 0.3);
-	}
-
-	gl_FragColor = vec4(color, 1.0);
-}

+ 0 - 35
src/Shaders/cloudtexture.fragment.fx

@@ -1,35 +0,0 @@
-precision highp float;
-
-varying vec2 vUV;
-
-uniform vec4 skyColor;
-uniform vec4 cloudColor;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-void main() {
-
-	vec2 p = vUV * 12.0;
-	vec4 c = mix(skyColor, cloudColor, fbm(p));
-	gl_FragColor = c;
-
-}
-

+ 15 - 6
src/Shaders/default.fragment.fx

@@ -196,7 +196,7 @@ uniform sampler2D reflection2DSampler;
 #ifdef REFLECTIONMAP_SKYBOX
 varying vec3 vPositionUVW;
 #else
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
 varying vec3 vDirectionW;
 #endif
 
@@ -210,7 +210,7 @@ uniform mat4 view;
 
 vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 {
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
 	vec3 direction = normalize(vDirectionW);
 
 	float t = clamp(direction.y * -0.5 + 0.5, 0., 1.0);
@@ -219,6 +219,16 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 	return vec3(s, t, 0);
 #endif
 
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+
+	vec3 cameraToVertex = normalize(worldPos.xyz - vEyePosition);
+	vec3 r = reflect(cameraToVertex, worldNormal);
+	float t = clamp(r.y * -0.5 + 0.5, 0., 1.0);
+	float s = atan(r.z, r.x) * RECIPROCAL_PI2 + 0.5;
+
+	return vec3(s, t, 0);
+#endif
+
 #ifdef REFLECTIONMAP_SPHERICAL
 	vec3 viewDir = normalize(vec3(view * worldPos));
 	vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
@@ -546,16 +556,15 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
 
 	// diffuse
 	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
-	float spotAtten = 0.0;
 
 	if (cosAngle >= lightDirection.w)
 	{
 		cosAngle = max(0., pow(cosAngle, lightData.w));
-		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
+		attenuation *= cosAngle;
 
 		// Diffuse
 		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
-		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
+		result.diffuse = ndl * diffuseColor * attenuation;
 
 #ifdef SPECULARTERM
 		// Specular
@@ -563,7 +572,7 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
 		float specComp = max(0., dot(vNormal, angleW));
 		specComp = pow(specComp, max(1., glossiness));
 
-		result.specular = specComp * specularColor * spotAtten * attenuation;
+		result.specular = specComp * specularColor * attenuation;
 #endif
 
 		return result;

+ 2 - 2
src/Shaders/default.vertex.fx

@@ -128,7 +128,7 @@ varying vec4 vPositionFromLight3;
 varying vec3 vPositionUVW;
 #endif
 
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
 varying vec3 vDirectionW;
 #endif
 
@@ -186,7 +186,7 @@ void main(void) {
 	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
 #endif
 
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
 	vDirectionW = normalize(vec3(finalWorld * vec4(position, 0.0)));
 #endif
 

+ 0 - 45
src/Shaders/firetexture.fragment.fx

@@ -1,45 +0,0 @@
-precision highp float;
-
-uniform float time;
-uniform vec3 c1;
-uniform vec3 c2;
-uniform vec3 c3;
-uniform vec3 c4;
-uniform vec3 c5;
-uniform vec3 c6;
-uniform vec2 speed;
-uniform float shift;
-uniform float alphaThreshold;
-
-varying vec2 vUV;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-void main() {
-	vec2 p = vUV * 8.0;
-	float q = fbm(p - time * 0.1);
-	vec2 r = vec2(fbm(p + q + time * speed.x - p.x - p.y), fbm(p + q - time * speed.y));
-	vec3 c = mix(c1, c2, fbm(p + r)) + mix(c3, c4, r.x) - mix(c5, c6, r.y);
-	vec3 color = c * cos(shift * vUV.y);
-	float luminance = dot(color.rgb, vec3(0.3, 0.59, 0.11));
-
-	gl_FragColor = vec4(color, luminance * alphaThreshold + (1.0 - alphaThreshold));
-}

+ 0 - 37
src/Shaders/grasstexture.fragment.fx

@@ -1,37 +0,0 @@
-precision highp float;
-
-varying vec2 vPosition;
-varying vec2 vUV;
-
-uniform vec3 herb1Color;
-uniform vec3 herb2Color;
-uniform vec3 herb3Color;
-uniform vec3 groundColor;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-void main(void) {
-	vec3 color = mix(groundColor, herb1Color, rand(gl_FragCoord.xy * 4.0));
-	color = mix(color, herb2Color, rand(gl_FragCoord.xy * 8.0));
-	color = mix(color, herb3Color, rand(gl_FragCoord.xy));
-	color = mix(color, herb1Color, fbm(gl_FragCoord.xy * 16.0));
-	gl_FragColor = vec4(color, 1.0);
-}

+ 0 - 85
src/Shaders/marbletexture.fragment.fx

@@ -1,85 +0,0 @@
-precision highp float;
-
-varying vec2 vPosition;
-varying vec2 vUV;
-
-uniform float numberOfTilesHeight;
-uniform float numberOfTilesWidth;
-uniform float amplitude;
-uniform vec3 brickColor;
-uniform vec3 jointColor;
-
-const vec3 tileSize = vec3(1.1, 1.0, 1.1);
-const vec3 tilePct = vec3(0.98, 1.0, 0.98);
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float turbulence(vec2 P)
-{
-	float val = 0.0;
-	float freq = 1.0;
-	for (int i = 0; i < 4; i++)
-	{
-		val += abs(noise(P*freq) / freq);
-		freq *= 2.07;
-	}
-	return val;
-}
-
-float round(float number){
-	return sign(number)*floor(abs(number) + 0.5);
-}
-
-vec3 marble_color(float x)
-{
-	vec3 col;
-	x = 0.5*(x + 1.);
-	x = sqrt(x);             
-	x = sqrt(x);
-	x = sqrt(x);
-	col = vec3(.2 + .75*x);  
-	col.b *= 0.95;           
-	return col;
-}
-
-void main()
-{
-	float brickW = 1.0 / numberOfTilesWidth;
-	float brickH = 1.0 / numberOfTilesHeight;
-	float jointWPercentage = 0.01;
-	float jointHPercentage = 0.01;
-	vec3 color = brickColor;
-	float yi = vUV.y / brickH;
-	float nyi = round(yi);
-	float xi = vUV.x / brickW;
-
-	if (mod(floor(yi), 2.0) == 0.0){
-		xi = xi - 0.5;
-	}
-
-	float nxi = round(xi);
-	vec2 brickvUV = vec2((xi - floor(xi)) / brickH, (yi - floor(yi)) / brickW);
-
-	if (yi < nyi + jointHPercentage && yi > nyi - jointHPercentage){
-		color = mix(jointColor, vec3(0.37, 0.25, 0.25), (yi - nyi) / jointHPercentage + 0.2);
-	}
-	else if (xi < nxi + jointWPercentage && xi > nxi - jointWPercentage){
-		color = mix(jointColor, vec3(0.44, 0.44, 0.44), (xi - nxi) / jointWPercentage + 0.2);
-	}
-	else {
-		float t = 6.28 * brickvUV.x / (tileSize.x + noise(vec2(vUV)*6.0));
-		t += amplitude * turbulence(brickvUV.xy);
-		t = sin(t);
-		color = marble_color(t);
-	}
-
-	gl_FragColor = vec4(color, 0.0);
-}

+ 0 - 30
src/Shaders/roadtexture.fragment.fx

@@ -1,30 +0,0 @@
-precision highp float;
-
-varying vec2 vUV;                    
-uniform vec3 roadColor;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-void main(void) {
-	float ratioy = mod(gl_FragCoord.y * 100.0 , fbm(vUV * 2.0));
-	vec3 color = roadColor * ratioy;
-	gl_FragColor = vec4(color, 1.0);
-}

+ 0 - 33
src/Shaders/woodtexture.fragment.fx

@@ -1,33 +0,0 @@
-precision highp float;
-
-varying vec2 vPosition;
-varying vec2 vUV;
-
-uniform float ampScale;
-uniform vec3 woodColor;
-
-float rand(vec2 n) {
-	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
-}
-
-float noise(vec2 n) {
-	const vec2 d = vec2(0.0, 1.0);
-	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
-	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
-}
-
-float fbm(vec2 n) {
-	float total = 0.0, amplitude = 1.0;
-	for (int i = 0; i < 4; i++) {
-		total += noise(n) * amplitude;
-		n += n;
-		amplitude *= 0.5;
-	}
-	return total;
-}
-
-void main(void) {
-	float ratioy = mod(vUV.x * ampScale, 2.0 + fbm(vUV * 0.8));
-	vec3 wood = woodColor * ratioy;
-	gl_FragColor = vec4(wood, 1.0);
-}

+ 8 - 0
src/Tools/babylon.sceneSerializer.js

@@ -671,6 +671,8 @@ var BABYLON;
             serializationObject.clearColor = scene.clearColor.asArray();
             serializationObject.ambientColor = scene.ambientColor.asArray();
             serializationObject.gravity = scene.gravity.asArray();
+            serializationObject.collisionsEnabled = scene.collisionsEnabled;
+            serializationObject.workerCollisions = scene.workerCollisions;
             // Fog
             if (scene.fogMode && scene.fogMode !== 0) {
                 serializationObject.fogMode = scene.fogMode;
@@ -679,6 +681,12 @@ var BABYLON;
                 serializationObject.fogEnd = scene.fogEnd;
                 serializationObject.fogDensity = scene.fogDensity;
             }
+            //Physics
+            if (scene.isPhysicsEnabled()) {
+                serializationObject.physicsEnabled = true;
+                serializationObject.physicsGravity = scene.getPhysicsEngine()._getGravity().asArray();
+                serializationObject.physicsEngine = scene.getPhysicsEngine().getPhysicsPluginName();
+            }
             // Lights
             serializationObject.lights = [];
             var index;

+ 11 - 8
src/Tools/babylon.sceneSerializer.ts

@@ -801,7 +801,9 @@
             serializationObject.clearColor = scene.clearColor.asArray();
             serializationObject.ambientColor = scene.ambientColor.asArray();
             serializationObject.gravity = scene.gravity.asArray();
-
+            serializationObject.collisionsEnabled = scene.collisionsEnabled;
+            serializationObject.workerCollisions = scene.workerCollisions;
+            
             // Fog
             if (scene.fogMode && scene.fogMode !== 0) {
                 serializationObject.fogMode = scene.fogMode;
@@ -810,6 +812,13 @@
                 serializationObject.fogEnd = scene.fogEnd;
                 serializationObject.fogDensity = scene.fogDensity;
             }
+            
+            //Physics
+            if (scene.isPhysicsEnabled()) {
+                serializationObject.physicsEnabled = true;
+                serializationObject.physicsGravity = scene.getPhysicsEngine()._getGravity().asArray();
+                serializationObject.physicsEngine = scene.getPhysicsEngine().getPhysicsPluginName();
+            }
 
             // Lights
             serializationObject.lights = [];
@@ -951,10 +960,4 @@
             return serializationObject;
         }
     }
-}
-
-
-
-
-
-
+}

+ 2 - 1
src/babylon.engine.js

@@ -315,6 +315,7 @@ var BABYLON;
         scene._removePendingData(texture);
     };
     var partialLoad = function (url, index, loadedImages, scene, onfinish) {
+        var img;
         var onload = function () {
             loadedImages[index] = img;
             loadedImages._internalCount++;
@@ -326,7 +327,7 @@ var BABYLON;
         var onerror = function () {
             scene._removePendingData(img);
         };
-        var img = BABYLON.Tools.LoadImage(url, onload, onerror, scene.database);
+        img = BABYLON.Tools.LoadImage(url, onload, onerror, scene.database);
         scene._addPendingData(img);
     };
     var cascadeLoad = function (rootUrl, scene, onfinish, extensions) {

+ 11 - 9
src/babylon.engine.ts

@@ -336,6 +336,8 @@
     var partialLoad = (url: string, index: number, loadedImages: any, scene,
         onfinish: (images: HTMLImageElement[]) => void) => {
 
+        var img: HTMLImageElement;
+
         var onload = () => {
             loadedImages[index] = img;
             loadedImages._internalCount++;
@@ -351,7 +353,7 @@
             scene._removePendingData(img);
         };
 
-        var img = Tools.LoadImage(url, onload, onerror, scene.database);
+        img = Tools.LoadImage(url, onload, onerror, scene.database);
         scene._addPendingData(img);
     }
 
@@ -1028,9 +1030,9 @@
             this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vbo);
 
             if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.STATIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, <Float32Array>vertices, this._gl.STATIC_DRAW);
             } else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.STATIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(<number[]>vertices), this._gl.STATIC_DRAW);
             }
 
             this._resetVertexBufferBinding();
@@ -1055,9 +1057,9 @@
             }
 
             if (vertices instanceof Float32Array) {
-                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
+                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, <Float32Array>vertices);
             } else {
-                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
+                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(<number[]>vertices));
             }
 
             this._resetVertexBufferBinding();
@@ -1365,28 +1367,28 @@
             if (!uniform)
                 return;
 
-            this._gl.uniform1fv(uniform, array);
+            this._gl.uniform1fv(uniform, <any>array);
         }
 
         public setArray2(uniform: WebGLUniformLocation, array: number[]): void {
             if (!uniform || array.length % 2 !== 0)
                 return;
 
-            this._gl.uniform2fv(uniform, array);
+            this._gl.uniform2fv(uniform, <any>array);
         }
 
         public setArray3(uniform: WebGLUniformLocation, array: number[]): void {
             if (!uniform || array.length % 3 !== 0)
                 return;
 
-            this._gl.uniform3fv(uniform, array);
+            this._gl.uniform3fv(uniform, <any>array);
         }
 
         public setArray4(uniform: WebGLUniformLocation, array: number[]): void {
             if (!uniform || array.length % 4 !== 0)
                 return;
 
-            this._gl.uniform4fv(uniform, array);
+            this._gl.uniform4fv(uniform, <any>array);
         }
 
         public setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void {