ソースを参照

Move MatLib to Modules

sebastien 6 年 前
コミット
7fb7c6f55b
53 ファイル変更5875 行追加5802 行削除
  1. 25 152
      Tools/Gulp/config.json
  2. 1 1
      Tools/Gulp/package.json
  3. 38 0
      materialsLibrary/package.json
  4. 0 322
      materialsLibrary/src/cell/babylon.cellMaterial.ts
  5. 324 0
      materialsLibrary/src/cell/cellMaterial.ts
  6. 1 0
      materialsLibrary/src/cell/index.ts
  7. 0 233
      materialsLibrary/src/custom/babylon.customMaterial.ts
  8. 230 0
      materialsLibrary/src/custom/customMaterial.ts
  9. 1 0
      materialsLibrary/src/custom/index.ts
  10. 0 382
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  11. 382 0
      materialsLibrary/src/fire/fireMaterial.ts
  12. 1 0
      materialsLibrary/src/fire/index.ts
  13. 0 532
      materialsLibrary/src/fur/babylon.furMaterial.ts
  14. 533 0
      materialsLibrary/src/fur/furMaterial.ts
  15. 1 0
      materialsLibrary/src/fur/index.ts
  16. 0 324
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  17. 325 0
      materialsLibrary/src/gradient/gradientMaterial.ts
  18. 1 0
      materialsLibrary/src/gradient/index.ts
  19. 0 216
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  20. 217 0
      materialsLibrary/src/grid/gridmaterial.ts
  21. 1 0
      materialsLibrary/src/grid/index.ts
  22. 15 0
      materialsLibrary/src/index.ts
  23. 0 417
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  24. 1 0
      materialsLibrary/src/lava/index.ts
  25. 418 0
      materialsLibrary/src/lava/lavaMaterial.ts
  26. 19 0
      materialsLibrary/src/legacy.ts
  27. 0 519
      materialsLibrary/src/mix/babylon.mixMaterial.ts
  28. 1 0
      materialsLibrary/src/mix/index.ts
  29. 520 0
      materialsLibrary/src/mix/mixMaterial.ts
  30. 0 357
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  31. 1 0
      materialsLibrary/src/normal/index.ts
  32. 358 0
      materialsLibrary/src/normal/normalMaterial.ts
  33. 0 244
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  34. 1 0
      materialsLibrary/src/shadowOnly/index.ts
  35. 245 0
      materialsLibrary/src/shadowOnly/shadowOnlyMaterial.ts
  36. 0 315
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  37. 1 0
      materialsLibrary/src/simple/index.ts
  38. 316 0
      materialsLibrary/src/simple/simpleMaterial.ts
  39. 0 238
      materialsLibrary/src/sky/babylon.skyMaterial.ts
  40. 1 0
      materialsLibrary/src/sky/index.ts
  41. 239 0
      materialsLibrary/src/sky/skyMaterial.ts
  42. 0 437
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts
  43. 1 0
      materialsLibrary/src/terrain/index.ts
  44. 437 0
      materialsLibrary/src/terrain/terrainMaterial.ts
  45. 0 428
      materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts
  46. 1 0
      materialsLibrary/src/triPlanar/index.ts
  47. 429 0
      materialsLibrary/src/triPlanar/triPlanarMaterial.ts
  48. 0 12
      materialsLibrary/src/tsconfig.json
  49. 0 673
      materialsLibrary/src/water/babylon.waterMaterial.ts
  50. 1 0
      materialsLibrary/src/water/index.ts
  51. 682 0
      materialsLibrary/src/water/waterMaterial.ts
  52. 31 0
      materialsLibrary/tsconfig.json
  53. 76 0
      materialsLibrary/webpack.config.js

+ 25 - 152
Tools/Gulp/config.json

@@ -1473,163 +1473,36 @@
     "materialsLibrary": {
         "libraries": [
             {
-                "files": [
-                    "../../materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/shadowOnly/shadowOnly.vertex.fx",
-                    "../../materialsLibrary/src/shadowOnly/shadowOnly.fragment.fx"
-                ],
-                "output": "babylon.shadowOnlyMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/gradient/babylon.gradientMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/gradient/gradient.vertex.fx",
-                    "../../materialsLibrary/src/gradient/gradient.fragment.fx"
-                ],
-                "output": "babylon.gradientMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/normal/babylon.normalMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/normal/normal.vertex.fx",
-                    "../../materialsLibrary/src/normal/normal.fragment.fx"
-                ],
-                "output": "babylon.normalMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/lava/babylon.lavaMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/lava/lava.vertex.fx",
-                    "../../materialsLibrary/src/lava/lava.fragment.fx"
-                ],
-                "output": "babylon.lavaMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/simple/babylon.simpleMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/simple/simple.vertex.fx",
-                    "../../materialsLibrary/src/simple/simple.fragment.fx"
-                ],
-                "output": "babylon.simpleMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/water/babylon.waterMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/water/water.vertex.fx",
-                    "../../materialsLibrary/src/water/water.fragment.fx"
-                ],
-                "output": "babylon.waterMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/fire/babylon.fireMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/fire/fire.vertex.fx",
-                    "../../materialsLibrary/src/fire/fire.fragment.fx"
-                ],
-                "output": "babylon.fireMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/fur/babylon.furMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/fur/fur.vertex.fx",
-                    "../../materialsLibrary/src/fur/fur.fragment.fx"
-                ],
-                "output": "babylon.furMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/terrain/babylon.terrainMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/terrain/terrain.vertex.fx",
-                    "../../materialsLibrary/src/terrain/terrain.fragment.fx"
-                ],
-                "output": "babylon.terrainMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/mix/babylon.mixMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/mix/mix.vertex.fx",
-                    "../../materialsLibrary/src/mix/mix.fragment.fx"
-                ],
-                "output": "babylon.mixMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/triPlanar/triplanar.vertex.fx",
-                    "../../materialsLibrary/src/triPlanar/triplanar.fragment.fx"
-                ],
-                "output": "babylon.triPlanarMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/sky/babylon.skyMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/sky/sky.vertex.fx",
-                    "../../materialsLibrary/src/sky/sky.fragment.fx"
-                ],
-                "output": "babylon.skyMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/grid/babylon.gridmaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/grid/grid.vertex.fx",
-                    "../../materialsLibrary/src/grid/grid.fragment.fx"
-                ],
-                "output": "babylon.gridMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/custom/babylon.customMaterial.ts"
-                ],
-                "output": "babylon.customMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/cell/babylon.cellMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/cell/cell.vertex.fx",
-                    "../../materialsLibrary/src/cell/cell.fragment.fx"
-                ],
-                "output": "babylon.cellMaterial.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.materials.min.js",
+                "webpack": "../../materialsLibrary/webpack.config.js",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true
             }
         ],
         "build": {
-            "srcOutputDirectory": "../../materialsLibrary/",
+            "srcOutputDirectory": "../../materialsLibrary/src/",
             "distOutputDirectory": "/materialsLibrary/",
-            "buildAsModule": true,
-            "moduleName": "babylonjs-materials",
-            "outputFilename": "babylonjs.materials",
-            "moduleDeclaration": {
-                "name": "BJSMaterials",
-                "module": "babylonjs-materials"
+            "dtsBundle": {
+                "name": "babylonjs-materials",
+                "main": "../../dist/preview release/materials/build/index.d.ts",
+                "out": "../babylon.materials.module.d.ts",
+                "baseDir": "../../dist/preview release/materials/build/",
+                "headerText": "BabylonJS Materials"
             },
-            "extendsRoot": true
+            "processDeclaration": {
+                "filename": "babylon.materials.module.d.ts",
+                "packageName": "babylonjs-materials",
+                "moduleName": "BABYLON.MATERIALS",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON"
+                }
+            }
         }
     },
     "postProcessesLibrary": {

ファイルの差分が大きいため隠しています
+ 1 - 1
Tools/Gulp/package.json


+ 38 - 0
materialsLibrary/package.json

@@ -0,0 +1,38 @@
+{
+    "name": "babylonjs-materials",
+    "version": "1.0.0",
+    "description": "The js Materials library is an extension containing extra materials for babylonjs.",
+    "scripts": {
+        "start:server": "webpack-dev-server",
+        "start:watch": "webpack -w",
+        "build:dev": "webpack",
+        "build:prod": "webpack --mode=production",
+        "test": "echo \"Error: no test specified\" && exit 1"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "keywords": [
+        "3d",
+        "webgl",
+        "viewer"
+    ],
+    "license": "Apache2",
+    "bugs": {
+        "url": "https://github.com/BabylonJS/Babylon.js/issues"
+    },
+    "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
+    "devDependencies": {
+        "@types/node": "^10.5.2",
+        "clean-webpack-plugin": "^0.1.19",
+        "ts-loader": "^4.0.0",
+        "typescript": "~3.0.1",
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "dependencies": {
+        "dts-bundle-webpack": "^1.0.0"
+    }
+}

+ 0 - 322
materialsLibrary/src/cell/babylon.cellMaterial.ts

@@ -1,322 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class CellMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-        public NDOTL = true;
-        public CUSTOMUSERLIGHTING = true;
-        public CELLBASIC = true;
-        public DEPTHPREPASS = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class CellMaterial extends PushMaterial {
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: BaseTexture;
-
-        @serializeAsColor3("diffuse")
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize("computeHighLevel")
-        public _computeHighLevel: boolean = false;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public computeHighLevel: boolean;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new CellMaterialDefines();
-            }
-
-            var defines = <CellMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (scene.texturesEnabled) {
-                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        if (!this._diffuseTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                }
-            }
-
-            // High level
-            defines.CELLBASIC = !this.computeHighLevel;
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                var shaderName = "cell";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
-                ];
-                var samplers = ["diffuseSampler"];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights - 1 }
-                    }, engine), defines);
-
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <CellMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
-                }
-
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
-                results.push(this._diffuseTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            return this._diffuseTexture === texture;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this._diffuseTexture) {
-                this._diffuseTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public getClassName(): string {
-            return "CellMaterial";
-        }
-
-        public clone(name: string): CellMaterial {
-            return SerializationHelper.Clone<CellMaterial>(() => new CellMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.CellMaterial";
-            return serializationObject;
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): CellMaterial {
-            return SerializationHelper.Parse(() => new CellMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 324 - 0
materialsLibrary/src/cell/cellMaterial.ts

@@ -0,0 +1,324 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, expandToProperty, BaseTexture, serializeAsColor3, Scene, Color3, serialize, AbstractMesh, Nullable, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs"
+
+Effect.ShadersStore["cellPixelShader"] = require("./cell.fragment.fx");
+Effect.ShadersStore["cellVertexShader"] = require("./cell.vertex.fx");
+
+class CellMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public NDOTL = true;
+    public CUSTOMUSERLIGHTING = true;
+    public CELLBASIC = true;
+    public DEPTHPREPASS = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class CellMaterial extends PushMaterial {
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: BaseTexture;
+
+    @serializeAsColor3("diffuse")
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize("computeHighLevel")
+    public _computeHighLevel: boolean = false;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public computeHighLevel: boolean;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new CellMaterialDefines();
+        }
+
+        var defines = <CellMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (scene.texturesEnabled) {
+                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this._diffuseTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+            }
+        }
+
+        // High level
+        defines.CELLBASIC = !this.computeHighLevel;
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            var shaderName = "cell";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
+            ];
+            var samplers = ["diffuseSampler"];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights - 1 }
+                }, engine), defines);
+
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <CellMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        // Lights
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        console.log("TOTO")
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
+            results.push(this._diffuseTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        return this._diffuseTexture === texture;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this._diffuseTexture) {
+            this._diffuseTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public getClassName(): string {
+        return "CellMaterial";
+    }
+
+    public clone(name: string): CellMaterial {
+        return SerializationHelper.Clone<CellMaterial>(() => new CellMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.CellMaterial";
+        return serializationObject;
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): CellMaterial {
+        return SerializationHelper.Parse(() => new CellMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 1 - 0
materialsLibrary/src/cell/index.ts

@@ -0,0 +1 @@
+export * from "./cellMaterial";

+ 0 - 233
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -1,233 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-
-    export class CustomShaderStructure {
-
-        public FragmentStore: string;
-        public VertexStore: string;
-
-        constructor() { }
-    }
-
-    export class ShaderSpecialParts {
-
-        constructor() { }
-
-        public Fragment_Begin: string;
-        public Fragment_Definitions: string;
-        public Fragment_MainBegin: string;
-
-        // diffuseColor
-        public Fragment_Custom_Diffuse: string;
-
-        // alpha
-        public Fragment_Custom_Alpha: string;
-
-        public Fragment_Before_FragColor: string;
-
-        public Vertex_Begin: string;
-        public Vertex_Definitions: string;
-        public Vertex_MainBegin: string;
-
-        // positionUpdated
-        public Vertex_Before_PositionUpdated: string;
-
-        // normalUpdated
-        public Vertex_Before_NormalUpdated: string;
-    }
-
-    export class CustomMaterial extends StandardMaterial {
-        public static ShaderIndexer = 1;
-        public CustomParts: ShaderSpecialParts;
-        _isCreatedShader: boolean;
-        _createdShaderName: string;
-        _customUniform: string[];
-        _newUniforms: string[];
-        _newUniformInstances: any[];
-        _newSamplerInstances: Texture[];
-
-        public  FragmentShader : string ;
-        public  VertexShader : string ;
-
-        public AttachAfterBind(mesh: Mesh, effect: Effect) {
-            for (var el in this._newUniformInstances) {
-                var ea = el.toString().split('-');
-                if (ea[0] == 'vec2') {
-                    effect.setVector2(ea[1], this._newUniformInstances[el]);
-                }
-                else if (ea[0] == 'vec3') {
-                    effect.setVector3(ea[1], this._newUniformInstances[el]);
-                }
-                else if (ea[0] == 'vec4') {
-                    effect.setVector4(ea[1], this._newUniformInstances[el]);
-                }
-                else if (ea[0] == 'mat4') {
-                    effect.setMatrix(ea[1], this._newUniformInstances[el]);
-                }
-                else if (ea[0] == 'float') {
-                    effect.setFloat(ea[1], this._newUniformInstances[el]);
-                }
-            }
-            for (var el in this._newSamplerInstances) {
-                var ea = el.toString().split('-');
-                if (ea[0] == 'sampler2D' && this._newSamplerInstances[el].isReady && this._newSamplerInstances[el].isReady()) {
-                    effect.setTexture(ea[1], this._newSamplerInstances[el]);
-                }
-            }
-        }
-
-        public ReviewUniform(name: string, arr: string[]): string[] {
-            if (name == "uniform") {
-                for (var ind in this._newUniforms) {
-                    if (this._customUniform[ind].indexOf('sampler') == -1) {
-                        arr.push(this._newUniforms[ind]);
-                    }
-                }
-            }
-            if (name == "sampler") {
-                for (var ind in this._newUniforms) {
-                    if (this._customUniform[ind].indexOf('sampler') != -1) {
-                        arr.push(this._newUniforms[ind]);
-                    }
-                }
-            }
-            return arr;
-        }
-
-        public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string {
-
-            if (this._isCreatedShader) {
-                return this._createdShaderName;
-            }
-            this._isCreatedShader = false;
-
-            CustomMaterial.ShaderIndexer++;
-            var name: string = "custom_" + CustomMaterial.ShaderIndexer;
-
-            this.ReviewUniform("uniform", uniforms);
-            this.ReviewUniform("sampler", samplers);
-
-            var fn_afterBind = this._afterBind.bind(this);
-            this._afterBind = (m, e) => {
-                if (!e) {
-                    return;
-                }
-                this.AttachAfterBind(m, e);
-                try { fn_afterBind(m, e); }
-                catch (e) { }
-            };
-
-            BABYLON.Effect.ShadersStore[name + "VertexShader"] = this.VertexShader
-                .replace('#define CUSTOM_VERTEX_BEGIN', (this.CustomParts.Vertex_Begin ? this.CustomParts.Vertex_Begin : ""))
-                .replace('#define CUSTOM_VERTEX_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Vertex_Definitions ? this.CustomParts.Vertex_Definitions : ""))
-                .replace('#define CUSTOM_VERTEX_MAIN_BEGIN', (this.CustomParts.Vertex_MainBegin ? this.CustomParts.Vertex_MainBegin : ""))
-                .replace('#define CUSTOM_VERTEX_UPDATE_POSITION', (this.CustomParts.Vertex_Before_PositionUpdated ? this.CustomParts.Vertex_Before_PositionUpdated : ""))
-                .replace('#define CUSTOM_VERTEX_UPDATE_NORMAL', (this.CustomParts.Vertex_Before_NormalUpdated ? this.CustomParts.Vertex_Before_NormalUpdated : ""));
-
-                // #define CUSTOM_VERTEX_MAIN_END
-
-            BABYLON.Effect.ShadersStore[name + "PixelShader"] = this.FragmentShader
-                .replace('#define CUSTOM_FRAGMENT_BEGIN', (this.CustomParts.Fragment_Begin ? this.CustomParts.Fragment_Begin : ""))
-                .replace('#define CUSTOM_FRAGMENT_MAIN_BEGIN', (this.CustomParts.Fragment_MainBegin ? this.CustomParts.Fragment_MainBegin : ""))
-                .replace('#define CUSTOM_FRAGMENT_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Fragment_Definitions ? this.CustomParts.Fragment_Definitions : ""))
-                .replace('#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE', (this.CustomParts.Fragment_Custom_Diffuse ? this.CustomParts.Fragment_Custom_Diffuse : ""))
-                .replace('#define CUSTOM_FRAGMENT_UPDATE_ALPHA', (this.CustomParts.Fragment_Custom_Alpha ? this.CustomParts.Fragment_Custom_Alpha : ""))
-                .replace('#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR', (this.CustomParts.Fragment_Before_FragColor ? this.CustomParts.Fragment_Before_FragColor : ""));
-
-                // #define CUSTOM_FRAGMENT_BEFORE_LIGHTS
-
-                // #define CUSTOM_FRAGMENT_BEFORE_FOG
-
-            this._isCreatedShader = true;
-            this._createdShaderName = name;
-
-            return name;
-        }
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-            this.CustomParts = new ShaderSpecialParts();
-            this.customShaderNameResolve = this.Builder;
-
-            this.FragmentShader = BABYLON.Effect.ShadersStore["defaultPixelShader"];
-            this.VertexShader = BABYLON.Effect.ShadersStore["defaultVertexShader"];
-        }
-
-        public AddUniform(name: string, kind: string, param: any): CustomMaterial {
-            if (!this._customUniform) {
-                this._customUniform = new Array();
-                this._newUniforms = new Array();
-                this._newSamplerInstances = new Array();
-                this._newUniformInstances = new Array();
-            }
-            if (param) {
-                if (kind.indexOf("sampler") == -1) {
-                    (<any>this._newUniformInstances)[kind + "-" + name] = param;
-                }
-                else {
-                    (<any>this._newUniformInstances)[kind + "-" + name] = param;
-                }
-            }
-            this._customUniform.push("uniform " + kind + " " + name + ";");
-            this._newUniforms.push(name);
-
-            return this;
-        }
-
-        public Fragment_Begin(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_Begin = shaderPart;
-            return this;
-        }
-
-        public Fragment_Definitions(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_Definitions = shaderPart;
-            return this;
-        }
-
-        public Fragment_MainBegin(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_MainBegin = shaderPart;
-            return this;
-        }
-
-        public Fragment_Custom_Diffuse(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_Custom_Diffuse = shaderPart.replace("result", "diffuseColor");
-            return this;
-        }
-
-        public Fragment_Custom_Alpha(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_Custom_Alpha = shaderPart.replace("result", "alpha");
-            return this;
-        }
-
-        public Fragment_Before_FragColor(shaderPart: string): CustomMaterial {
-            this.CustomParts.Fragment_Before_FragColor = shaderPart.replace("result", "color");
-            return this;
-        }
-
-        public Vertex_Begin(shaderPart: string): CustomMaterial {
-            this.CustomParts.Vertex_Begin = shaderPart;
-            return this;
-        }
-
-        public Vertex_Definitions(shaderPart: string): CustomMaterial {
-            this.CustomParts.Vertex_Definitions = shaderPart;
-            return this;
-        }
-
-        public Vertex_MainBegin(shaderPart: string): CustomMaterial {
-            this.CustomParts.Vertex_MainBegin = shaderPart;
-            return this;
-        }
-
-        public Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial {
-            this.CustomParts.Vertex_Before_PositionUpdated = shaderPart.replace("result", "positionUpdated");
-            return this;
-        }
-
-        public Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial {
-            this.CustomParts.Vertex_Before_NormalUpdated = shaderPart.replace("result", "normalUpdated");
-            return this;
-        }
-    }
-}

+ 230 - 0
materialsLibrary/src/custom/customMaterial.ts

@@ -0,0 +1,230 @@
+import { StandardMaterial, Texture, Mesh, Effect, StandardMaterialDefines, Scene } from "babylonjs";
+
+export class CustomShaderStructure {
+
+    public FragmentStore: string;
+    public VertexStore: string;
+
+    constructor() { }
+}
+
+export class ShaderSpecialParts {
+
+    constructor() { }
+
+    public Fragment_Begin: string;
+    public Fragment_Definitions: string;
+    public Fragment_MainBegin: string;
+
+    // diffuseColor
+    public Fragment_Custom_Diffuse: string;
+
+    // alpha
+    public Fragment_Custom_Alpha: string;
+
+    public Fragment_Before_FragColor: string;
+
+    public Vertex_Begin: string;
+    public Vertex_Definitions: string;
+    public Vertex_MainBegin: string;
+
+    // positionUpdated
+    public Vertex_Before_PositionUpdated: string;
+
+    // normalUpdated
+    public Vertex_Before_NormalUpdated: string;
+}
+
+export class CustomMaterial extends StandardMaterial {
+    public static ShaderIndexer = 1;
+    public CustomParts: ShaderSpecialParts;
+    _isCreatedShader: boolean;
+    _createdShaderName: string;
+    _customUniform: string[];
+    _newUniforms: string[];
+    _newUniformInstances: any[];
+    _newSamplerInstances: Texture[];
+
+    public  FragmentShader : string ;
+    public  VertexShader : string ;
+
+    public AttachAfterBind(mesh: Mesh, effect: Effect) {
+        for (var el in this._newUniformInstances) {
+            var ea = el.toString().split('-');
+            if (ea[0] == 'vec2') {
+                effect.setVector2(ea[1], this._newUniformInstances[el]);
+            }
+            else if (ea[0] == 'vec3') {
+                effect.setVector3(ea[1], this._newUniformInstances[el]);
+            }
+            else if (ea[0] == 'vec4') {
+                effect.setVector4(ea[1], this._newUniformInstances[el]);
+            }
+            else if (ea[0] == 'mat4') {
+                effect.setMatrix(ea[1], this._newUniformInstances[el]);
+            }
+            else if (ea[0] == 'float') {
+                effect.setFloat(ea[1], this._newUniformInstances[el]);
+            }
+        }
+        for (var el in this._newSamplerInstances) {
+            var ea = el.toString().split('-');
+            if (ea[0] == 'sampler2D' && this._newSamplerInstances[el].isReady && this._newSamplerInstances[el].isReady()) {
+                effect.setTexture(ea[1], this._newSamplerInstances[el]);
+            }
+        }
+    }
+
+    public ReviewUniform(name: string, arr: string[]): string[] {
+        if (name == "uniform") {
+            for (var ind in this._newUniforms) {
+                if (this._customUniform[ind].indexOf('sampler') == -1) {
+                    arr.push(this._newUniforms[ind]);
+                }
+            }
+        }
+        if (name == "sampler") {
+            for (var ind in this._newUniforms) {
+                if (this._customUniform[ind].indexOf('sampler') != -1) {
+                    arr.push(this._newUniforms[ind]);
+                }
+            }
+        }
+        return arr;
+    }
+
+    public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string {
+
+        if (this._isCreatedShader) {
+            return this._createdShaderName;
+        }
+        this._isCreatedShader = false;
+
+        CustomMaterial.ShaderIndexer++;
+        var name: string = "custom_" + CustomMaterial.ShaderIndexer;
+
+        this.ReviewUniform("uniform", uniforms);
+        this.ReviewUniform("sampler", samplers);
+
+        var fn_afterBind = this._afterBind.bind(this);
+        this._afterBind = (m, e) => {
+            if (!e) {
+                return;
+            }
+            this.AttachAfterBind(m, e);
+            try { fn_afterBind(m, e); }
+            catch (e) { }
+        };
+
+        BABYLON.Effect.ShadersStore[name + "VertexShader"] = this.VertexShader
+            .replace('#define CUSTOM_VERTEX_BEGIN', (this.CustomParts.Vertex_Begin ? this.CustomParts.Vertex_Begin : ""))
+            .replace('#define CUSTOM_VERTEX_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Vertex_Definitions ? this.CustomParts.Vertex_Definitions : ""))
+            .replace('#define CUSTOM_VERTEX_MAIN_BEGIN', (this.CustomParts.Vertex_MainBegin ? this.CustomParts.Vertex_MainBegin : ""))
+            .replace('#define CUSTOM_VERTEX_UPDATE_POSITION', (this.CustomParts.Vertex_Before_PositionUpdated ? this.CustomParts.Vertex_Before_PositionUpdated : ""))
+            .replace('#define CUSTOM_VERTEX_UPDATE_NORMAL', (this.CustomParts.Vertex_Before_NormalUpdated ? this.CustomParts.Vertex_Before_NormalUpdated : ""));
+
+            // #define CUSTOM_VERTEX_MAIN_END
+
+        BABYLON.Effect.ShadersStore[name + "PixelShader"] = this.FragmentShader
+            .replace('#define CUSTOM_FRAGMENT_BEGIN', (this.CustomParts.Fragment_Begin ? this.CustomParts.Fragment_Begin : ""))
+            .replace('#define CUSTOM_FRAGMENT_MAIN_BEGIN', (this.CustomParts.Fragment_MainBegin ? this.CustomParts.Fragment_MainBegin : ""))
+            .replace('#define CUSTOM_FRAGMENT_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Fragment_Definitions ? this.CustomParts.Fragment_Definitions : ""))
+            .replace('#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE', (this.CustomParts.Fragment_Custom_Diffuse ? this.CustomParts.Fragment_Custom_Diffuse : ""))
+            .replace('#define CUSTOM_FRAGMENT_UPDATE_ALPHA', (this.CustomParts.Fragment_Custom_Alpha ? this.CustomParts.Fragment_Custom_Alpha : ""))
+            .replace('#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR', (this.CustomParts.Fragment_Before_FragColor ? this.CustomParts.Fragment_Before_FragColor : ""));
+
+            // #define CUSTOM_FRAGMENT_BEFORE_LIGHTS
+
+            // #define CUSTOM_FRAGMENT_BEFORE_FOG
+
+        this._isCreatedShader = true;
+        this._createdShaderName = name;
+
+        return name;
+    }
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+        this.CustomParts = new ShaderSpecialParts();
+        this.customShaderNameResolve = this.Builder;
+
+        this.FragmentShader = BABYLON.Effect.ShadersStore["defaultPixelShader"];
+        this.VertexShader = BABYLON.Effect.ShadersStore["defaultVertexShader"];
+    }
+
+    public AddUniform(name: string, kind: string, param: any): CustomMaterial {
+        if (!this._customUniform) {
+            this._customUniform = new Array();
+            this._newUniforms = new Array();
+            this._newSamplerInstances = new Array();
+            this._newUniformInstances = new Array();
+        }
+        if (param) {
+            if (kind.indexOf("sampler") == -1) {
+                (<any>this._newUniformInstances)[kind + "-" + name] = param;
+            }
+            else {
+                (<any>this._newUniformInstances)[kind + "-" + name] = param;
+            }
+        }
+        this._customUniform.push("uniform " + kind + " " + name + ";");
+        this._newUniforms.push(name);
+
+        return this;
+    }
+
+    public Fragment_Begin(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_Begin = shaderPart;
+        return this;
+    }
+
+    public Fragment_Definitions(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_Definitions = shaderPart;
+        return this;
+    }
+
+    public Fragment_MainBegin(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_MainBegin = shaderPart;
+        return this;
+    }
+
+    public Fragment_Custom_Diffuse(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_Custom_Diffuse = shaderPart.replace("result", "diffuseColor");
+        return this;
+    }
+
+    public Fragment_Custom_Alpha(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_Custom_Alpha = shaderPart.replace("result", "alpha");
+        return this;
+    }
+
+    public Fragment_Before_FragColor(shaderPart: string): CustomMaterial {
+        this.CustomParts.Fragment_Before_FragColor = shaderPart.replace("result", "color");
+        return this;
+    }
+
+    public Vertex_Begin(shaderPart: string): CustomMaterial {
+        this.CustomParts.Vertex_Begin = shaderPart;
+        return this;
+    }
+
+    public Vertex_Definitions(shaderPart: string): CustomMaterial {
+        this.CustomParts.Vertex_Definitions = shaderPart;
+        return this;
+    }
+
+    public Vertex_MainBegin(shaderPart: string): CustomMaterial {
+        this.CustomParts.Vertex_MainBegin = shaderPart;
+        return this;
+    }
+
+    public Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial {
+        this.CustomParts.Vertex_Before_PositionUpdated = shaderPart.replace("result", "positionUpdated");
+        return this;
+    }
+
+    public Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial {
+        this.CustomParts.Vertex_Before_NormalUpdated = shaderPart.replace("result", "normalUpdated");
+        return this;
+    }
+}

+ 1 - 0
materialsLibrary/src/custom/index.ts

@@ -0,0 +1 @@
+export * from "./customMaterial";

+ 0 - 382
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -1,382 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-
-    class FireMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public UV1 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public BonesPerMesh = 0;
-        public NUM_BONE_INFLUENCERS = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class FireMaterial extends PushMaterial {
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: Nullable<BaseTexture>;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: Nullable<BaseTexture>;
-
-        @serializeAsTexture("distortionTexture")
-        private _distortionTexture: Nullable<BaseTexture>;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public distortionTexture: Nullable<BaseTexture>;
-
-        @serializeAsTexture("opacityTexture")
-        private _opacityTexture: Nullable<BaseTexture>;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public opacityTexture: Nullable<BaseTexture>;
-
-        @serializeAsColor3("diffuse")
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize()
-        public speed = 1.0;
-
-        private _scaledDiffuse = new Color3();
-        private _renderId: number;
-        private _lastTime: number = 0;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return false;
-        }
-
-        public needAlphaTesting(): boolean {
-            return true;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new FireMaterialDefines();
-            }
-
-            var defines = <FireMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this._diffuseTexture.isReady()) {
-                        return false;
-                    } else {
-                        defines._needUVs = true;
-                        defines.DIFFUSE = true;
-                    }
-                }
-            }
-
-            defines.ALPHATEST = this._opacityTexture ? true : false;
-
-            // Misc.
-            if (defines._areMiscDirty) {
-                defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
-                defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
-            }
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "fire";
-
-                var join = defines.toString();
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    {
-                        attributes: attribs,
-                        uniformsNames: ["world", "view", "viewProjection", "vEyePosition",
-                            "vFogInfos", "vFogColor", "pointSize",
-                            "vDiffuseInfos",
-                            "mBones",
-                            "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
-                            // Fire
-                            "time", "speed"
-                        ],
-                        uniformBuffersNames: [],
-                        samplers: ["diffuseSampler",
-                            // Fire
-                            "distortionSampler", "opacitySampler"
-                        ],
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: null,
-                        maxSimultaneousLights: 4,
-                        transformFeedbackVaryings: null
-                    }, engine), defines);
-            }
-
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <FireMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
-
-                    this._activeEffect.setTexture("distortionSampler", this._distortionTexture);
-                    this._activeEffect.setTexture("opacitySampler", this._opacityTexture);
-                }
-
-                // Clip plane
-               MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            // Time
-            this._lastTime += scene.getEngine().getDeltaTime();
-            this._activeEffect.setFloat("time", this._lastTime);
-
-            // Speed
-            this._activeEffect.setFloat("speed", this.speed);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
-                results.push(this._diffuseTexture);
-            }
-            if (this._distortionTexture && this._distortionTexture.animations && this._distortionTexture.animations.length > 0) {
-                results.push(this._distortionTexture);
-            }
-            if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
-                results.push(this._opacityTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            if (this._distortionTexture) {
-                activeTextures.push(this._distortionTexture);
-            }
-
-            if (this._opacityTexture) {
-                activeTextures.push(this._opacityTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this._diffuseTexture === texture) {
-                return true;
-            }
-
-            if (this._distortionTexture === texture) {
-                return true;
-            }
-
-            if (this._opacityTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public getClassName(): string {
-            return "FireMaterial";
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this._diffuseTexture) {
-                this._diffuseTexture.dispose();
-            }
-            if (this._distortionTexture) {
-                this._distortionTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): FireMaterial {
-            return SerializationHelper.Clone<FireMaterial>(() => new FireMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-
-            var serializationObject = super.serialize();
-            serializationObject.customType = "BABYLON.FireMaterial";
-            serializationObject.diffuseColor = this.diffuseColor.asArray();
-            serializationObject.speed = this.speed;
-
-            if (this._diffuseTexture) {
-                serializationObject._diffuseTexture = this._diffuseTexture.serialize();
-            }
-
-            if (this._distortionTexture) {
-                serializationObject._distortionTexture = this._distortionTexture.serialize();
-            }
-
-            if (this._opacityTexture) {
-                serializationObject._opacityTexture = this._opacityTexture.serialize();
-            }
-
-            return serializationObject;
-        }
-
-        public static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial {
-            var material = new FireMaterial(source.name, scene);
-
-            material.diffuseColor = Color3.FromArray(source.diffuseColor);
-            material.speed = source.speed;
-
-            material.alpha = source.alpha;
-
-            material.id = source.id;
-
-            Tags.AddTagsTo(material, source.tags);
-            material.backFaceCulling = source.backFaceCulling;
-            material.wireframe = source.wireframe;
-
-            if (source._diffuseTexture) {
-                material._diffuseTexture = Texture.Parse(source._diffuseTexture, scene, rootUrl);
-            }
-
-            if (source._distortionTexture) {
-                material._distortionTexture = Texture.Parse(source._distortionTexture, scene, rootUrl);
-            }
-
-            if (source._opacityTexture) {
-                material._opacityTexture = Texture.Parse(source._opacityTexture, scene, rootUrl);
-            }
-
-            if (source.checkReadyOnlyOnce) {
-                material.checkReadyOnlyOnce = source.checkReadyOnlyOnce;
-            }
-
-            return material;
-        }
-    }
-}

+ 382 - 0
materialsLibrary/src/fire/fireMaterial.ts

@@ -0,0 +1,382 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, Nullable, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, Scene, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, Matrix, Mesh, IAnimatable, SerializationHelper, Tags, Texture, } from "babylonjs";
+
+Effect.ShadersStore["firePixelShader"] = require("./fire.fragment.fx");
+Effect.ShadersStore["fireVertexShader"] = require("./fire.vertex.fx");
+
+class FireMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public UV1 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public BonesPerMesh = 0;
+    public NUM_BONE_INFLUENCERS = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class FireMaterial extends PushMaterial {
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: Nullable<BaseTexture>;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: Nullable<BaseTexture>;
+
+    @serializeAsTexture("distortionTexture")
+    private _distortionTexture: Nullable<BaseTexture>;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public distortionTexture: Nullable<BaseTexture>;
+
+    @serializeAsTexture("opacityTexture")
+    private _opacityTexture: Nullable<BaseTexture>;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public opacityTexture: Nullable<BaseTexture>;
+
+    @serializeAsColor3("diffuse")
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize()
+    public speed = 1.0;
+
+    private _scaledDiffuse = new Color3();
+    private _renderId: number;
+    private _lastTime: number = 0;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return false;
+    }
+
+    public needAlphaTesting(): boolean {
+        return true;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new FireMaterialDefines();
+        }
+
+        var defines = <FireMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                if (!this._diffuseTexture.isReady()) {
+                    return false;
+                } else {
+                    defines._needUVs = true;
+                    defines.DIFFUSE = true;
+                }
+            }
+        }
+
+        defines.ALPHATEST = this._opacityTexture ? true : false;
+
+        // Misc.
+        if (defines._areMiscDirty) {
+            defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
+            defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
+        }
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "fire";
+
+            var join = defines.toString();
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                {
+                    attributes: attribs,
+                    uniformsNames: ["world", "view", "viewProjection", "vEyePosition",
+                        "vFogInfos", "vFogColor", "pointSize",
+                        "vDiffuseInfos",
+                        "mBones",
+                        "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
+                        // Fire
+                        "time", "speed"
+                    ],
+                    uniformBuffersNames: [],
+                    samplers: ["diffuseSampler",
+                        // Fire
+                        "distortionSampler", "opacitySampler"
+                    ],
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: null,
+                    maxSimultaneousLights: 4,
+                    transformFeedbackVaryings: null
+                }, engine), defines);
+        }
+
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <FireMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
+
+                this._activeEffect.setTexture("distortionSampler", this._distortionTexture);
+                this._activeEffect.setTexture("opacitySampler", this._opacityTexture);
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        // Time
+        this._lastTime += scene.getEngine().getDeltaTime();
+        this._activeEffect.setFloat("time", this._lastTime);
+
+        // Speed
+        this._activeEffect.setFloat("speed", this.speed);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
+            results.push(this._diffuseTexture);
+        }
+        if (this._distortionTexture && this._distortionTexture.animations && this._distortionTexture.animations.length > 0) {
+            results.push(this._distortionTexture);
+        }
+        if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
+            results.push(this._opacityTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        if (this._distortionTexture) {
+            activeTextures.push(this._distortionTexture);
+        }
+
+        if (this._opacityTexture) {
+            activeTextures.push(this._opacityTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this._diffuseTexture === texture) {
+            return true;
+        }
+
+        if (this._distortionTexture === texture) {
+            return true;
+        }
+
+        if (this._opacityTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public getClassName(): string {
+        return "FireMaterial";
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this._diffuseTexture) {
+            this._diffuseTexture.dispose();
+        }
+        if (this._distortionTexture) {
+            this._distortionTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): FireMaterial {
+        return SerializationHelper.Clone<FireMaterial>(() => new FireMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+
+        var serializationObject = super.serialize();
+        serializationObject.customType = "BABYLON.FireMaterial";
+        serializationObject.diffuseColor = this.diffuseColor.asArray();
+        serializationObject.speed = this.speed;
+
+        if (this._diffuseTexture) {
+            serializationObject._diffuseTexture = this._diffuseTexture.serialize();
+        }
+
+        if (this._distortionTexture) {
+            serializationObject._distortionTexture = this._distortionTexture.serialize();
+        }
+
+        if (this._opacityTexture) {
+            serializationObject._opacityTexture = this._opacityTexture.serialize();
+        }
+
+        return serializationObject;
+    }
+
+    public static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial {
+        var material = new FireMaterial(source.name, scene);
+
+        material.diffuseColor = Color3.FromArray(source.diffuseColor);
+        material.speed = source.speed;
+
+        material.alpha = source.alpha;
+
+        material.id = source.id;
+
+        Tags.AddTagsTo(material, source.tags);
+        material.backFaceCulling = source.backFaceCulling;
+        material.wireframe = source.wireframe;
+
+        if (source._diffuseTexture) {
+            material._diffuseTexture = Texture.Parse(source._diffuseTexture, scene, rootUrl);
+        }
+
+        if (source._distortionTexture) {
+            material._distortionTexture = Texture.Parse(source._distortionTexture, scene, rootUrl);
+        }
+
+        if (source._opacityTexture) {
+            material._opacityTexture = Texture.Parse(source._opacityTexture, scene, rootUrl);
+        }
+
+        if (source.checkReadyOnlyOnce) {
+            material.checkReadyOnlyOnce = source.checkReadyOnlyOnce;
+        }
+
+        return material;
+    }
+}

+ 1 - 0
materialsLibrary/src/fire/index.ts

@@ -0,0 +1 @@
+export * from "./fireMaterial";

+ 0 - 532
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -1,532 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class FurMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public HEIGHTMAP = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-        public HIGHLEVEL = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class FurMaterial extends PushMaterial {
-
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: BaseTexture;
-
-        @serializeAsTexture("heightTexture")
-        private _heightTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public heightTexture: BaseTexture;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize()
-        public furLength: number = 1;
-
-        @serialize()
-        public furAngle: number = 0;
-
-        @serializeAsColor3()
-        public furColor = new Color3(0.44, 0.21, 0.02);
-
-        @serialize()
-        public furOffset: number = 0.0;
-
-        @serialize()
-        public furSpacing: number = 12;
-
-        @serializeAsVector3()
-        public furGravity = new Vector3(0, 0, 0);
-
-        @serialize()
-        public furSpeed: number = 100;
-
-        @serialize()
-        public furDensity: number = 20;
-
-        @serialize()
-        public furOcclusion: number = 0.0;
-
-        public furTexture: DynamicTexture;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        @serialize()
-        public highLevelFur: boolean = true;
-
-        public _meshes: AbstractMesh[];
-
-        private _renderId: number;
-
-        private _furTime: number = 0;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        @serialize()
-        public get furTime() {
-            return this._furTime;
-        }
-
-        public set furTime(furTime: number) {
-            this._furTime = furTime;
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        public updateFur(): void {
-            for (var i = 1; i < this._meshes.length; i++) {
-                var offsetFur = <FurMaterial>this._meshes[i].material;
-
-                offsetFur.furLength = this.furLength;
-                offsetFur.furAngle = this.furAngle;
-                offsetFur.furGravity = this.furGravity;
-                offsetFur.furSpacing = this.furSpacing;
-                offsetFur.furSpeed = this.furSpeed;
-                offsetFur.furColor = this.furColor;
-                offsetFur.diffuseTexture = this.diffuseTexture;
-                offsetFur.furTexture = this.furTexture;
-                offsetFur.highLevelFur = this.highLevelFur;
-                offsetFur.furTime = this.furTime;
-                offsetFur.furDensity = this.furDensity;
-            }
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new FurMaterialDefines();
-            }
-
-            var defines = <FurMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                if (scene.texturesEnabled) {
-                    if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        if (!this.diffuseTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                    if (this.heightTexture && engine.getCaps().maxVertexTextureImageUnits) {
-                        if (!this.heightTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.HEIGHTMAP = true;
-                        }
-                    }
-                }
-            }
-
-            // High level
-            if (this.highLevelFur !== defines.HIGHLEVEL) {
-                defines.HIGHLEVEL = true;
-                defines.markAsUnprocessed();
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "fur";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
-                    "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity", "furOcclusion"
-                ];
-                var samplers = ["diffuseSampler",
-                    "heightTexture", "furTexture"
-                ];
-
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <FurMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (scene.getCachedMaterial() !== this) {
-                // Textures
-                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
-                }
-
-                if (this._heightTexture) {
-                    this._activeEffect.setTexture("heightTexture", this._heightTexture);
-                }
-
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._activeEffect.setFloat("furLength", this.furLength);
-            this._activeEffect.setFloat("furAngle", this.furAngle);
-            this._activeEffect.setColor4("furColor", this.furColor, 1.0);
-
-            if (this.highLevelFur) {
-                this._activeEffect.setVector3("furGravity", this.furGravity);
-                this._activeEffect.setFloat("furOffset", this.furOffset);
-                this._activeEffect.setFloat("furSpacing", this.furSpacing);
-                this._activeEffect.setFloat("furDensity", this.furDensity);
-                this._activeEffect.setFloat("furOcclusion", this.furOcclusion);
-
-                this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
-                this._activeEffect.setFloat("furTime", this._furTime);
-
-                this._activeEffect.setTexture("furTexture", this.furTexture);
-            }
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
-                results.push(this.diffuseTexture);
-            }
-
-            if (this.heightTexture && this.heightTexture.animations && this.heightTexture.animations.length > 0) {
-                results.push(this.heightTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            if (this._heightTexture) {
-                activeTextures.push(this._heightTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this.diffuseTexture === texture) {
-                return true;
-            }
-
-            if (this._heightTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.diffuseTexture) {
-                this.diffuseTexture.dispose();
-            }
-
-            if (this._meshes) {
-                for (var i = 1; i < this._meshes.length; i++) {
-                    let mat = this._meshes[i].material;
-
-                    if (mat) {
-                        mat.dispose(forceDisposeEffect);
-                    }
-                    this._meshes[i].dispose();
-                }
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): FurMaterial {
-            return SerializationHelper.Clone(() => new FurMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.FurMaterial";
-
-            if (this._meshes) {
-                serializationObject.sourceMeshName = this._meshes[0].name;
-                serializationObject.quality = this._meshes.length;
-            }
-
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "FurMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
-            var material = SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
-
-            if (source.sourceMeshName && material.highLevelFur) {
-                scene.executeWhenReady(() => {
-                    var sourceMesh = <Mesh>scene.getMeshByName(source.sourceMeshName);
-                    if (sourceMesh) {
-                        var furTexture = FurMaterial.GenerateTexture("Fur Texture", scene);
-                        material.furTexture = furTexture;
-                        FurMaterial.FurifyMesh(sourceMesh, source.quality);
-                    }
-                });
-            }
-
-            return material;
-        }
-
-        public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
-            // Generate fur textures
-            var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
-            var context = texture.getContext();
-
-            for (var i = 0; i < 20000; ++i) {
-                context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
-                context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
-            }
-
-            texture.update(false);
-            texture.wrapU = Texture.WRAP_ADDRESSMODE;
-            texture.wrapV = Texture.WRAP_ADDRESSMODE;
-
-            return texture;
-        }
-
-        // Creates and returns an array of meshes used as shells for the Fur Material
-        // that can be disposed later in your code
-        // The quality is in interval [0, 100]
-        public static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[] {
-            var meshes = [sourceMesh];
-            var mat: FurMaterial = <FurMaterial>sourceMesh.material;
-            var i;
-
-            if (!(mat instanceof FurMaterial)) {
-                throw "The material of the source mesh must be a Fur Material";
-            }
-
-            for (i = 1; i < quality; i++) {
-                var offsetFur = new BABYLON.FurMaterial(mat.name + i, sourceMesh.getScene());
-                sourceMesh.getScene().materials.pop();
-                Tags.EnableFor(offsetFur);
-                Tags.AddTagsTo(offsetFur, "furShellMaterial");
-
-                offsetFur.furLength = mat.furLength;
-                offsetFur.furAngle = mat.furAngle;
-                offsetFur.furGravity = mat.furGravity;
-                offsetFur.furSpacing = mat.furSpacing;
-                offsetFur.furSpeed = mat.furSpeed;
-                offsetFur.furColor = mat.furColor;
-                offsetFur.diffuseTexture = mat.diffuseTexture;
-                offsetFur.furOffset = i / quality;
-                offsetFur.furTexture = mat.furTexture;
-                offsetFur.highLevelFur = mat.highLevelFur;
-                offsetFur.furTime = mat.furTime;
-                offsetFur.furDensity = mat.furDensity;
-
-                var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
-
-                offsetMesh.material = offsetFur;
-                offsetMesh.skeleton = sourceMesh.skeleton;
-                offsetMesh.position = Vector3.Zero();
-                meshes.push(offsetMesh);
-            }
-
-            for (i = 1; i < meshes.length; i++) {
-                meshes[i].parent = sourceMesh;
-            }
-
-            (<FurMaterial>sourceMesh.material)._meshes = meshes;
-
-            return meshes;
-        }
-    }
-}

+ 533 - 0
materialsLibrary/src/fur/furMaterial.ts

@@ -0,0 +1,533 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, serializeAsVector3, Vector3, DynamicTexture, AbstractMesh, Scene, Nullable, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper, Texture, Tags } from "babylonjs";
+
+Effect.ShadersStore["furPixelShader"] = require("./fur.fragment.fx");
+Effect.ShadersStore["furVertexShader"] = require("./fur.vertex.fx");
+
+class FurMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public HEIGHTMAP = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public HIGHLEVEL = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class FurMaterial extends PushMaterial {
+
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: BaseTexture;
+
+    @serializeAsTexture("heightTexture")
+    private _heightTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public heightTexture: BaseTexture;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize()
+    public furLength: number = 1;
+
+    @serialize()
+    public furAngle: number = 0;
+
+    @serializeAsColor3()
+    public furColor = new Color3(0.44, 0.21, 0.02);
+
+    @serialize()
+    public furOffset: number = 0.0;
+
+    @serialize()
+    public furSpacing: number = 12;
+
+    @serializeAsVector3()
+    public furGravity = new Vector3(0, 0, 0);
+
+    @serialize()
+    public furSpeed: number = 100;
+
+    @serialize()
+    public furDensity: number = 20;
+
+    @serialize()
+    public furOcclusion: number = 0.0;
+
+    public furTexture: DynamicTexture;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    @serialize()
+    public highLevelFur: boolean = true;
+
+    public _meshes: AbstractMesh[];
+
+    private _renderId: number;
+
+    private _furTime: number = 0;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    @serialize()
+    public get furTime() {
+        return this._furTime;
+    }
+
+    public set furTime(furTime: number) {
+        this._furTime = furTime;
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    public updateFur(): void {
+        for (var i = 1; i < this._meshes.length; i++) {
+            var offsetFur = <FurMaterial>this._meshes[i].material;
+
+            offsetFur.furLength = this.furLength;
+            offsetFur.furAngle = this.furAngle;
+            offsetFur.furGravity = this.furGravity;
+            offsetFur.furSpacing = this.furSpacing;
+            offsetFur.furSpeed = this.furSpeed;
+            offsetFur.furColor = this.furColor;
+            offsetFur.diffuseTexture = this.diffuseTexture;
+            offsetFur.furTexture = this.furTexture;
+            offsetFur.highLevelFur = this.highLevelFur;
+            offsetFur.furTime = this.furTime;
+            offsetFur.furDensity = this.furDensity;
+        }
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new FurMaterialDefines();
+        }
+
+        var defines = <FurMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            if (scene.texturesEnabled) {
+                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this.diffuseTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+                if (this.heightTexture && engine.getCaps().maxVertexTextureImageUnits) {
+                    if (!this.heightTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.HEIGHTMAP = true;
+                    }
+                }
+            }
+        }
+
+        // High level
+        if (this.highLevelFur !== defines.HIGHLEVEL) {
+            defines.HIGHLEVEL = true;
+            defines.markAsUnprocessed();
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "fur";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
+                "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity", "furOcclusion"
+            ];
+            var samplers = ["diffuseSampler",
+                "heightTexture", "furTexture"
+            ];
+
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <FurMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (scene.getCachedMaterial() !== this) {
+            // Textures
+            if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
+            }
+
+            if (this._heightTexture) {
+                this._activeEffect.setTexture("heightTexture", this._heightTexture);
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._activeEffect.setFloat("furLength", this.furLength);
+        this._activeEffect.setFloat("furAngle", this.furAngle);
+        this._activeEffect.setColor4("furColor", this.furColor, 1.0);
+
+        if (this.highLevelFur) {
+            this._activeEffect.setVector3("furGravity", this.furGravity);
+            this._activeEffect.setFloat("furOffset", this.furOffset);
+            this._activeEffect.setFloat("furSpacing", this.furSpacing);
+            this._activeEffect.setFloat("furDensity", this.furDensity);
+            this._activeEffect.setFloat("furOcclusion", this.furOcclusion);
+
+            this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
+            this._activeEffect.setFloat("furTime", this._furTime);
+
+            this._activeEffect.setTexture("furTexture", this.furTexture);
+        }
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
+            results.push(this.diffuseTexture);
+        }
+
+        if (this.heightTexture && this.heightTexture.animations && this.heightTexture.animations.length > 0) {
+            results.push(this.heightTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        if (this._heightTexture) {
+            activeTextures.push(this._heightTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this.diffuseTexture === texture) {
+            return true;
+        }
+
+        if (this._heightTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.diffuseTexture) {
+            this.diffuseTexture.dispose();
+        }
+
+        if (this._meshes) {
+            for (var i = 1; i < this._meshes.length; i++) {
+                let mat = this._meshes[i].material;
+
+                if (mat) {
+                    mat.dispose(forceDisposeEffect);
+                }
+                this._meshes[i].dispose();
+            }
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): FurMaterial {
+        return SerializationHelper.Clone(() => new FurMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.FurMaterial";
+
+        if (this._meshes) {
+            serializationObject.sourceMeshName = this._meshes[0].name;
+            serializationObject.quality = this._meshes.length;
+        }
+
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "FurMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
+        var material = SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
+
+        if (source.sourceMeshName && material.highLevelFur) {
+            scene.executeWhenReady(() => {
+                var sourceMesh = <Mesh>scene.getMeshByName(source.sourceMeshName);
+                if (sourceMesh) {
+                    var furTexture = FurMaterial.GenerateTexture("Fur Texture", scene);
+                    material.furTexture = furTexture;
+                    FurMaterial.FurifyMesh(sourceMesh, source.quality);
+                }
+            });
+        }
+
+        return material;
+    }
+
+    public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
+        // Generate fur textures
+        var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
+        var context = texture.getContext();
+
+        for (var i = 0; i < 20000; ++i) {
+            context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
+            context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
+        }
+
+        texture.update(false);
+        texture.wrapU = Texture.WRAP_ADDRESSMODE;
+        texture.wrapV = Texture.WRAP_ADDRESSMODE;
+
+        return texture;
+    }
+
+    // Creates and returns an array of meshes used as shells for the Fur Material
+    // that can be disposed later in your code
+    // The quality is in interval [0, 100]
+    public static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[] {
+        var meshes = [sourceMesh];
+        var mat: FurMaterial = <FurMaterial>sourceMesh.material;
+        var i;
+
+        if (!(mat instanceof FurMaterial)) {
+            throw "The material of the source mesh must be a Fur Material";
+        }
+
+        for (i = 1; i < quality; i++) {
+            var offsetFur = new FurMaterial(mat.name + i, sourceMesh.getScene());
+            sourceMesh.getScene().materials.pop();
+            Tags.EnableFor(offsetFur);
+            Tags.AddTagsTo(offsetFur, "furShellMaterial");
+
+            offsetFur.furLength = mat.furLength;
+            offsetFur.furAngle = mat.furAngle;
+            offsetFur.furGravity = mat.furGravity;
+            offsetFur.furSpacing = mat.furSpacing;
+            offsetFur.furSpeed = mat.furSpeed;
+            offsetFur.furColor = mat.furColor;
+            offsetFur.diffuseTexture = mat.diffuseTexture;
+            offsetFur.furOffset = i / quality;
+            offsetFur.furTexture = mat.furTexture;
+            offsetFur.highLevelFur = mat.highLevelFur;
+            offsetFur.furTime = mat.furTime;
+            offsetFur.furDensity = mat.furDensity;
+
+            var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
+
+            offsetMesh.material = offsetFur;
+            offsetMesh.skeleton = sourceMesh.skeleton;
+            offsetMesh.position = Vector3.Zero();
+            meshes.push(offsetMesh);
+        }
+
+        for (i = 1; i < meshes.length; i++) {
+            meshes[i].parent = sourceMesh;
+        }
+
+        (<FurMaterial>sourceMesh.material)._meshes = meshes;
+
+        return meshes;
+    }
+}

+ 1 - 0
materialsLibrary/src/fur/index.ts

@@ -0,0 +1 @@
+export * from "./furMaterial";

+ 0 - 324
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -1,324 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class GradientMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWESM0 = false;
-        public SHADOWESM1 = false;
-        public SHADOWESM2 = false;
-        public SHADOWESM3 = false;
-        public SHADOWPOISSON0 = false;
-        public SHADOWPOISSON1 = false;
-        public SHADOWPOISSON2 = false;
-        public SHADOWPOISSON3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
-        public SHADOWPCSS0 = false;
-        public SHADOWPCSS1 = false;
-        public SHADOWPCSS2 = false;
-        public SHADOWPCSS3 = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class GradientMaterial extends PushMaterial {
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        // The gradient top color, red by default
-        @serializeAsColor3()
-        public topColor = new Color3(1, 0, 0);
-
-        @serialize()
-        public topColorAlpha = 1.0;
-
-        // The gradient top color, blue by default
-        @serializeAsColor3()
-        public bottomColor = new Color3(0, 0, 1);
-
-        @serialize()
-        public bottomColorAlpha = 1.0;
-
-        // Gradient offset
-        @serialize()
-        public offset = 0;
-
-        @serialize()
-        public scale = 1.0;
-
-        @serialize()
-        public smoothness = 1.0;
-
-        @serialize()
-        public disableLighting = false;
-        private _scaledDiffuse = new Color3();
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0 || this.topColorAlpha < 1.0 || this.bottomColorAlpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return true;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new GradientMaterialDefines();
-            }
-
-            var defines = <GradientMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "gradient";
-                var join = defines.toString();
-
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
-                    "topColor", "bottomColor", "offset", "smoothness", "scale"
-                ];
-                var samplers = ["diffuseSampler"];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: 4
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: 4 }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <GradientMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, effect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Clip plane
-                MaterialHelper.BindClipPlane(effect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._activeEffect.setColor4("topColor", this.topColor, this.topColorAlpha);
-            this._activeEffect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
-            this._activeEffect.setFloat("offset", this.offset);
-            this._activeEffect.setFloat("scale", this.scale);
-            this._activeEffect.setFloat("smoothness", this.smoothness);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            return [];
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): GradientMaterial {
-            return SerializationHelper.Clone(() => new GradientMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.GradientMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "GradientMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial {
-            return SerializationHelper.Parse(() => new GradientMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 325 - 0
materialsLibrary/src/gradient/gradientMaterial.ts

@@ -0,0 +1,325 @@
+import { Effect, MaterialDefines, PushMaterial, serialize, expandToProperty, serializeAsColor3, Color3, Scene, Nullable, BaseTexture, AbstractMesh, SubMesh, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["gradientPixelShader"] = require("./gradient.fragment.fx");
+Effect.ShadersStore["gradientVertexShader"] = require("./gradient.vertex.fx");
+
+class GradientMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public LIGHT0 = false;
+    public LIGHT1 = false;
+    public LIGHT2 = false;
+    public LIGHT3 = false;
+    public SPOTLIGHT0 = false;
+    public SPOTLIGHT1 = false;
+    public SPOTLIGHT2 = false;
+    public SPOTLIGHT3 = false;
+    public HEMILIGHT0 = false;
+    public HEMILIGHT1 = false;
+    public HEMILIGHT2 = false;
+    public HEMILIGHT3 = false;
+    public DIRLIGHT0 = false;
+    public DIRLIGHT1 = false;
+    public DIRLIGHT2 = false;
+    public DIRLIGHT3 = false;
+    public POINTLIGHT0 = false;
+    public POINTLIGHT1 = false;
+    public POINTLIGHT2 = false;
+    public POINTLIGHT3 = false;
+    public SHADOW0 = false;
+    public SHADOW1 = false;
+    public SHADOW2 = false;
+    public SHADOW3 = false;
+    public SHADOWS = false;
+    public SHADOWESM0 = false;
+    public SHADOWESM1 = false;
+    public SHADOWESM2 = false;
+    public SHADOWESM3 = false;
+    public SHADOWPOISSON0 = false;
+    public SHADOWPOISSON1 = false;
+    public SHADOWPOISSON2 = false;
+    public SHADOWPOISSON3 = false;
+    public SHADOWPCF0 = false;
+    public SHADOWPCF1 = false;
+    public SHADOWPCF2 = false;
+    public SHADOWPCF3 = false;
+    public SHADOWPCSS0 = false;
+    public SHADOWPCSS1 = false;
+    public SHADOWPCSS2 = false;
+    public SHADOWPCSS3 = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class GradientMaterial extends PushMaterial {
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    // The gradient top color, red by default
+    @serializeAsColor3()
+    public topColor = new Color3(1, 0, 0);
+
+    @serialize()
+    public topColorAlpha = 1.0;
+
+    // The gradient top color, blue by default
+    @serializeAsColor3()
+    public bottomColor = new Color3(0, 0, 1);
+
+    @serialize()
+    public bottomColorAlpha = 1.0;
+
+    // Gradient offset
+    @serialize()
+    public offset = 0;
+
+    @serialize()
+    public scale = 1.0;
+
+    @serialize()
+    public smoothness = 1.0;
+
+    @serialize()
+    public disableLighting = false;
+    private _scaledDiffuse = new Color3();
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0 || this.topColorAlpha < 1.0 || this.bottomColorAlpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return true;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new GradientMaterialDefines();
+        }
+
+        var defines = <GradientMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "gradient";
+            var join = defines.toString();
+
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
+                "topColor", "bottomColor", "offset", "smoothness", "scale"
+            ];
+            var samplers = ["diffuseSampler"];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: 4
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: 4 }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <GradientMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, effect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Clip plane
+            MaterialHelper.BindClipPlane(effect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._activeEffect.setColor4("topColor", this.topColor, this.topColorAlpha);
+        this._activeEffect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
+        this._activeEffect.setFloat("offset", this.offset);
+        this._activeEffect.setFloat("scale", this.scale);
+        this._activeEffect.setFloat("smoothness", this.smoothness);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        return [];
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): GradientMaterial {
+        return SerializationHelper.Clone(() => new GradientMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.GradientMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "GradientMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial {
+        return SerializationHelper.Parse(() => new GradientMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 1 - 0
materialsLibrary/src/gradient/index.ts

@@ -0,0 +1 @@
+export * from "./gradientMaterial";

+ 0 - 216
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -1,216 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class GridMaterialDefines extends MaterialDefines {
-        public TRANSPARENT = false;
-        public FOG = false;
-        public PREMULTIPLYALPHA = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    /**
-     * The grid materials allows you to wrap any shape with a grid.
-     * Colors are customizable.
-     */
-    export class GridMaterial extends BABYLON.PushMaterial {
-
-        /**
-         * Main color of the grid (e.g. between lines)
-         */
-        @serializeAsColor3()
-        public mainColor = Color3.Black();
-
-        /**
-         * Color of the grid lines.
-         */
-        @serializeAsColor3()
-        public lineColor = Color3.Teal();
-
-        /**
-         * The scale of the grid compared to unit.
-         */
-        @serialize()
-        public gridRatio = 1.0;
-
-        /**
-         * Allows setting an offset for the grid lines.
-         */
-        @serializeAsColor3()
-        public gridOffset = Vector3.Zero();
-
-        /**
-         * The frequency of thicker lines.
-         */
-        @serialize()
-        public majorUnitFrequency = 10;
-
-        /**
-         * The visibility of minor units in the grid.
-         */
-        @serialize()
-        public minorUnitVisibility = 0.33;
-
-        /**
-         * The grid opacity outside of the lines.
-         */
-        @serialize()
-        public opacity = 1.0;
-
-        /**
-         * Determine RBG output is premultiplied by alpha value.
-         */
-        @serialize()
-        public preMultiplyAlpha = false;
-
-        private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
-
-        private _renderId: number;
-
-        /**
-         * constructor
-         * @param name The name given to the material in order to identify it afterwards.
-         * @param scene The scene the material is used in.
-         */
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        /**
-         * Returns wehter or not the grid requires alpha blending.
-         */
-        public needAlphaBlending(): boolean {
-            return this.opacity < 1.0;
-        }
-
-        public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
-            return this.needAlphaBlending();
-        }
-
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new GridMaterialDefines();
-            }
-
-            var defines = <GridMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            if (defines.TRANSPARENT !== (this.opacity < 1.0)) {
-                defines.TRANSPARENT = !defines.TRANSPARENT;
-                defines.markAsUnprocessed();
-            }
-
-            if (defines.PREMULTIPLYALPHA != this.preMultiplyAlpha) {
-                defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
-                defines.markAsUnprocessed();
-            }
-
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Attributes
-                var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
-
-                // Defines
-                var join = defines.toString();
-                subMesh.setEffect(scene.getEngine().createEffect("grid",
-                    attribs,
-                    ["projection", "worldView", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view"],
-                    [],
-                    join,
-                    undefined,
-                    this.onCompiled,
-                    this.onError), defines);
-            }
-
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <GridMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("worldView", world.multiply(scene.getViewMatrix()));
-            this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            this._activeEffect.setMatrix("projection", scene.getProjectionMatrix());
-
-            // Uniforms
-            if (this._mustRebind(scene, effect)) {
-                this._activeEffect.setColor3("mainColor", this.mainColor);
-                this._activeEffect.setColor3("lineColor", this.lineColor);
-
-                this._activeEffect.setVector3("gridOffset", this.gridOffset);
-
-                this._gridControl.x = this.gridRatio;
-                this._gridControl.y = Math.round(this.majorUnitFrequency);
-                this._gridControl.z = this.minorUnitVisibility;
-                this._gridControl.w = this.opacity;
-                this._activeEffect.setVector4("gridControl", this._gridControl);
-            }
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): GridMaterial {
-            return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.GridMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "GridMaterial";
-        }
-
-        public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
-            return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 217 - 0
materialsLibrary/src/grid/gridmaterial.ts

@@ -0,0 +1,217 @@
+import { Effect, MaterialDefines, serializeAsColor3, Color3, serialize, Vector3, Vector4, Scene, AbstractMesh, SubMesh, MaterialHelper, VertexBuffer, Matrix, Mesh, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["gridPixelShader"] = require("./grid.fragment.fx");
+Effect.ShadersStore["gridVertexShader"] = require("./grid.vertex.fx");
+
+class GridMaterialDefines extends MaterialDefines {
+    public TRANSPARENT = false;
+    public FOG = false;
+    public PREMULTIPLYALPHA = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+/**
+ * The grid materials allows you to wrap any shape with a grid.
+ * Colors are customizable.
+ */
+export class GridMaterial extends BABYLON.PushMaterial {
+
+    /**
+     * Main color of the grid (e.g. between lines)
+     */
+    @serializeAsColor3()
+    public mainColor = Color3.Black();
+
+    /**
+     * Color of the grid lines.
+     */
+    @serializeAsColor3()
+    public lineColor = Color3.Teal();
+
+    /**
+     * The scale of the grid compared to unit.
+     */
+    @serialize()
+    public gridRatio = 1.0;
+
+    /**
+     * Allows setting an offset for the grid lines.
+     */
+    @serializeAsColor3()
+    public gridOffset = Vector3.Zero();
+
+    /**
+     * The frequency of thicker lines.
+     */
+    @serialize()
+    public majorUnitFrequency = 10;
+
+    /**
+     * The visibility of minor units in the grid.
+     */
+    @serialize()
+    public minorUnitVisibility = 0.33;
+
+    /**
+     * The grid opacity outside of the lines.
+     */
+    @serialize()
+    public opacity = 1.0;
+
+    /**
+     * Determine RBG output is premultiplied by alpha value.
+     */
+    @serialize()
+    public preMultiplyAlpha = false;
+
+    private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
+
+    private _renderId: number;
+
+    /**
+     * constructor
+     * @param name The name given to the material in order to identify it afterwards.
+     * @param scene The scene the material is used in.
+     */
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    /**
+     * Returns wehter or not the grid requires alpha blending.
+     */
+    public needAlphaBlending(): boolean {
+        return this.opacity < 1.0;
+    }
+
+    public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
+        return this.needAlphaBlending();
+    }
+
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new GridMaterialDefines();
+        }
+
+        var defines = <GridMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        if (defines.TRANSPARENT !== (this.opacity < 1.0)) {
+            defines.TRANSPARENT = !defines.TRANSPARENT;
+            defines.markAsUnprocessed();
+        }
+
+        if (defines.PREMULTIPLYALPHA != this.preMultiplyAlpha) {
+            defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
+            defines.markAsUnprocessed();
+        }
+
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Attributes
+            var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
+
+            // Defines
+            var join = defines.toString();
+            subMesh.setEffect(scene.getEngine().createEffect("grid",
+                attribs,
+                ["projection", "worldView", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view"],
+                [],
+                join,
+                undefined,
+                this.onCompiled,
+                this.onError), defines);
+        }
+
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <GridMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("worldView", world.multiply(scene.getViewMatrix()));
+        this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        this._activeEffect.setMatrix("projection", scene.getProjectionMatrix());
+
+        // Uniforms
+        if (this._mustRebind(scene, effect)) {
+            this._activeEffect.setColor3("mainColor", this.mainColor);
+            this._activeEffect.setColor3("lineColor", this.lineColor);
+
+            this._activeEffect.setVector3("gridOffset", this.gridOffset);
+
+            this._gridControl.x = this.gridRatio;
+            this._gridControl.y = Math.round(this.majorUnitFrequency);
+            this._gridControl.z = this.minorUnitVisibility;
+            this._gridControl.w = this.opacity;
+            this._activeEffect.setVector4("gridControl", this._gridControl);
+        }
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): GridMaterial {
+        return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.GridMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "GridMaterial";
+    }
+
+    public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
+        return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 1 - 0
materialsLibrary/src/grid/index.ts

@@ -0,0 +1 @@
+export * from "./gridMaterial";

+ 15 - 0
materialsLibrary/src/index.ts

@@ -0,0 +1,15 @@
+export * from "./cell";
+export * from "./custom";
+export * from "./fire";
+export * from "./fur";
+export * from "./gradient";
+export * from "./grid";
+export * from "./lava";
+export * from "./mix";
+export * from "./normal";
+export * from "./shadowOnly";
+export * from "./simple";
+export * from "./sky";
+export * from "./terrain";
+export * from "./triPlanar";
+export * from "./water";

+ 0 - 417
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -1,417 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class LavaMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWESM0 = false;
-        public SHADOWESM1 = false;
-        public SHADOWESM2 = false;
-        public SHADOWESM3 = false;
-        public SHADOWPOISSON0 = false;
-        public SHADOWPOISSON1 = false;
-        public SHADOWPOISSON2 = false;
-        public SHADOWPOISSON3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
-        public SHADOWPCSS0 = false;
-        public SHADOWPCSS1 = false;
-        public SHADOWPCSS2 = false;
-        public SHADOWPCSS3 = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-        public UNLIT = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class LavaMaterial extends PushMaterial {
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: BaseTexture;
-
-        @serializeAsTexture()
-        public noiseTexture: BaseTexture;
-
-        @serializeAsColor3()
-        public fogColor: Color3;
-
-        @serialize()
-        public speed: number = 1;
-
-        @serialize()
-        public movingSpeed: number = 1;
-
-        @serialize()
-        public lowFrequencySpeed: number = 1;
-
-        @serialize()
-        public fogDensity: number = 0.15;
-
-        private _lastTime: number = 0;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("unlit")
-        private _unlit = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public unlit: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _scaledDiffuse = new Color3();
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new LavaMaterialDefines();
-            }
-
-            var defines = <LavaMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (scene.texturesEnabled) {
-                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        if (!this._diffuseTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = true;
-
-            MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "lava";
-                var join = defines.toString();
-
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
-                    "time", "speed", "movingSpeed",
-                    "fogColor", "fogDensity", "lowFrequencySpeed"
-                ];
-
-                var samplers = ["diffuseSampler",
-                    "noiseTexture"
-                ];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <LavaMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            defines.UNLIT = this._unlit;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
-                }
-
-                if (this.noiseTexture) {
-                    this._activeEffect.setTexture("noiseTexture", this.noiseTexture);
-                }
-
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._lastTime += scene.getEngine().getDeltaTime();
-            this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
-
-            if (!this.fogColor) {
-                this.fogColor = Color3.Black();
-            }
-            this._activeEffect.setColor3("fogColor", this.fogColor);
-            this._activeEffect.setFloat("fogDensity", this.fogDensity);
-
-            this._activeEffect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
-            this._activeEffect.setFloat("movingSpeed", this.movingSpeed);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
-                results.push(this.diffuseTexture);
-            }
-
-            if (this.noiseTexture && this.noiseTexture.animations && this.noiseTexture.animations.length > 0) {
-                results.push(this.noiseTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this.diffuseTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.diffuseTexture) {
-                this.diffuseTexture.dispose();
-            }
-            if (this.noiseTexture) {
-                this.noiseTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): LavaMaterial {
-            return SerializationHelper.Clone(() => new LavaMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.LavaMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "LavaMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): LavaMaterial {
-            return SerializationHelper.Parse(() => new LavaMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/lava/index.ts

@@ -0,0 +1 @@
+export * from "./lavaMaterial";

+ 418 - 0
materialsLibrary/src/lava/lavaMaterial.ts

@@ -0,0 +1,418 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["lavaPixelShader"] = require("./lava.fragment.fx");
+Effect.ShadersStore["lavaVertexShader"] = require("./lava.vertex.fx");
+
+class LavaMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public LIGHT0 = false;
+    public LIGHT1 = false;
+    public LIGHT2 = false;
+    public LIGHT3 = false;
+    public SPOTLIGHT0 = false;
+    public SPOTLIGHT1 = false;
+    public SPOTLIGHT2 = false;
+    public SPOTLIGHT3 = false;
+    public HEMILIGHT0 = false;
+    public HEMILIGHT1 = false;
+    public HEMILIGHT2 = false;
+    public HEMILIGHT3 = false;
+    public DIRLIGHT0 = false;
+    public DIRLIGHT1 = false;
+    public DIRLIGHT2 = false;
+    public DIRLIGHT3 = false;
+    public POINTLIGHT0 = false;
+    public POINTLIGHT1 = false;
+    public POINTLIGHT2 = false;
+    public POINTLIGHT3 = false;
+    public SHADOW0 = false;
+    public SHADOW1 = false;
+    public SHADOW2 = false;
+    public SHADOW3 = false;
+    public SHADOWS = false;
+    public SHADOWESM0 = false;
+    public SHADOWESM1 = false;
+    public SHADOWESM2 = false;
+    public SHADOWESM3 = false;
+    public SHADOWPOISSON0 = false;
+    public SHADOWPOISSON1 = false;
+    public SHADOWPOISSON2 = false;
+    public SHADOWPOISSON3 = false;
+    public SHADOWPCF0 = false;
+    public SHADOWPCF1 = false;
+    public SHADOWPCF2 = false;
+    public SHADOWPCF3 = false;
+    public SHADOWPCSS0 = false;
+    public SHADOWPCSS1 = false;
+    public SHADOWPCSS2 = false;
+    public SHADOWPCSS3 = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public UNLIT = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class LavaMaterial extends PushMaterial {
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: BaseTexture;
+
+    @serializeAsTexture()
+    public noiseTexture: BaseTexture;
+
+    @serializeAsColor3()
+    public fogColor: Color3;
+
+    @serialize()
+    public speed: number = 1;
+
+    @serialize()
+    public movingSpeed: number = 1;
+
+    @serialize()
+    public lowFrequencySpeed: number = 1;
+
+    @serialize()
+    public fogDensity: number = 0.15;
+
+    private _lastTime: number = 0;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("unlit")
+    private _unlit = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public unlit: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _scaledDiffuse = new Color3();
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new LavaMaterialDefines();
+        }
+
+        var defines = <LavaMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (scene.texturesEnabled) {
+                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this._diffuseTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = true;
+
+        MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "lava";
+            var join = defines.toString();
+
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix",
+                "time", "speed", "movingSpeed",
+                "fogColor", "fogDensity", "lowFrequencySpeed"
+            ];
+
+            var samplers = ["diffuseSampler",
+                "noiseTexture"
+            ];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <LavaMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        defines.UNLIT = this._unlit;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+            }
+
+            if (this.noiseTexture) {
+                this._activeEffect.setTexture("noiseTexture", this.noiseTexture);
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._lastTime += scene.getEngine().getDeltaTime();
+        this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
+
+        if (!this.fogColor) {
+            this.fogColor = Color3.Black();
+        }
+        this._activeEffect.setColor3("fogColor", this.fogColor);
+        this._activeEffect.setFloat("fogDensity", this.fogDensity);
+
+        this._activeEffect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
+        this._activeEffect.setFloat("movingSpeed", this.movingSpeed);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
+            results.push(this.diffuseTexture);
+        }
+
+        if (this.noiseTexture && this.noiseTexture.animations && this.noiseTexture.animations.length > 0) {
+            results.push(this.noiseTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this.diffuseTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.diffuseTexture) {
+            this.diffuseTexture.dispose();
+        }
+        if (this.noiseTexture) {
+            this.noiseTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): LavaMaterial {
+        return SerializationHelper.Clone(() => new LavaMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.LavaMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "LavaMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): LavaMaterial {
+        return SerializationHelper.Parse(() => new LavaMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 19 - 0
materialsLibrary/src/legacy.ts

@@ -0,0 +1,19 @@
+import * as MatLib from "./index";
+
+/**
+ * Legacy support, defining window.BABYLON.GridMaterial... (global variable).
+ *
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};
+    for (var mat in MatLib) {
+        if (MatLib.hasOwnProperty(mat)) {
+            (<any>globalObject).BABYLON[mat] = (<any>MatLib)[mat];
+        }
+    }
+}
+
+export * from "./index";

+ 0 - 519
materialsLibrary/src/mix/babylon.mixMaterial.ts

@@ -1,519 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class MixMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public SPECULARTERM = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-        public MIXMAP2 = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class MixMaterial extends PushMaterial {
-        /**
-         * Mix textures
-         */
-
-        @serializeAsTexture("mixTexture1")
-        private _mixTexture1: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public mixTexture1: BaseTexture;
-
-        @serializeAsTexture("mixTexture2")
-        private _mixTexture2: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public mixTexture2: BaseTexture;
-
-        /**
-         * Diffuse textures
-         */
-
-        @serializeAsTexture("diffuseTexture1")
-        private _diffuseTexture1: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture1: Texture;
-
-        @serializeAsTexture("diffuseTexture2")
-        private _diffuseTexture2: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture2: Texture;
-
-        @serializeAsTexture("diffuseTexture3")
-        private _diffuseTexture3: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture3: Texture;
-
-        @serializeAsTexture("diffuseTexture4")
-        private _diffuseTexture4: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture4: Texture;
-
-        @serializeAsTexture("diffuseTexture1")
-        private _diffuseTexture5: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture5: Texture;
-
-        @serializeAsTexture("diffuseTexture2")
-        private _diffuseTexture6: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture6: Texture;
-
-        @serializeAsTexture("diffuseTexture3")
-        private _diffuseTexture7: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture7: Texture;
-
-        @serializeAsTexture("diffuseTexture4")
-        private _diffuseTexture8: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture8: Texture;
-
-        /**
-         * Uniforms
-         */
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serializeAsColor3()
-        public specularColor = new Color3(0, 0, 0);
-
-        @serialize()
-        public specularPower = 64;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new MixMaterialDefines();
-            }
-
-            var defines = <MixMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (scene.texturesEnabled) {
-                if (StandardMaterial.DiffuseTextureEnabled) {
-                    if (this._mixTexture1) {
-                        if (!this._mixTexture1.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                    if (this._mixTexture2) {
-                        if (!this._mixTexture2.isReady()) {
-                            return false;
-                        } else {
-                            defines.MIXMAP2 = true;
-                        }
-                    }
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "mix";
-                var join = defines.toString();
-                var uniforms = [
-                    "world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vTextureInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMatrix",
-                    "diffuse1Infos", "diffuse2Infos", "diffuse3Infos", "diffuse4Infos",
-                    "diffuse5Infos", "diffuse6Infos", "diffuse7Infos", "diffuse8Infos"
-                ];
-                var samplers = [
-                    "mixMap1Sampler", "mixMap2Sampler",
-                    "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler", "diffuse4Sampler",
-                    "diffuse5Sampler", "diffuse6Sampler", "diffuse7Sampler", "diffuse8Sampler"
-                ];
-
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <MixMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this._mixTexture1) {
-                    this._activeEffect.setTexture("mixMap1Sampler", this._mixTexture1);
-                    this._activeEffect.setFloat2("vTextureInfos", this._mixTexture1.coordinatesIndex, this._mixTexture1.level);
-                    this._activeEffect.setMatrix("textureMatrix", this._mixTexture1.getTextureMatrix());
-
-                    if (StandardMaterial.DiffuseTextureEnabled) {
-                        if (this._diffuseTexture1) {
-                            this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
-                            this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
-                        }
-                        if (this._diffuseTexture2) {
-                            this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
-                            this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
-                        }
-                        if (this._diffuseTexture3) {
-                            this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
-                            this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
-                        }
-                        if (this._diffuseTexture4) {
-                            this._activeEffect.setTexture("diffuse4Sampler", this._diffuseTexture4);
-                            this._activeEffect.setFloat2("diffuse4Infos", this._diffuseTexture4.uScale, this._diffuseTexture4.vScale);
-                        }
-                    }
-                }
-
-                if (this._mixTexture2) {
-                    this._activeEffect.setTexture("mixMap2Sampler", this._mixTexture2);
-
-                    if (StandardMaterial.DiffuseTextureEnabled) {
-                        if (this._diffuseTexture5) {
-                            this._activeEffect.setTexture("diffuse5Sampler", this._diffuseTexture5);
-                            this._activeEffect.setFloat2("diffuse5Infos", this._diffuseTexture5.uScale, this._diffuseTexture5.vScale);
-                        }
-                        if (this._diffuseTexture6) {
-                            this._activeEffect.setTexture("diffuse6Sampler", this._diffuseTexture6);
-                            this._activeEffect.setFloat2("diffuse6Infos", this._diffuseTexture6.uScale, this._diffuseTexture6.vScale);
-                        }
-                        if (this._diffuseTexture7) {
-                            this._activeEffect.setTexture("diffuse7Sampler", this._diffuseTexture7);
-                            this._activeEffect.setFloat2("diffuse7Infos", this._diffuseTexture7.uScale, this._diffuseTexture7.vScale);
-                        }
-                        if (this._diffuseTexture8) {
-                            this._activeEffect.setTexture("diffuse8Sampler", this._diffuseTexture8);
-                            this._activeEffect.setFloat2("diffuse8Infos", this._diffuseTexture8.uScale, this._diffuseTexture8.vScale);
-                        }
-                    }
-                }
-
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            if (defines.SPECULARTERM) {
-                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
-            }
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this._mixTexture1 && this._mixTexture1.animations && this._mixTexture1.animations.length > 0) {
-                results.push(this._mixTexture1);
-            }
-
-            if (this._mixTexture2 && this._mixTexture2.animations && this._mixTexture2.animations.length > 0) {
-                results.push(this._mixTexture2);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            // Mix map 1
-            if (this._mixTexture1) {
-                activeTextures.push(this._mixTexture1);
-            }
-
-            if (this._diffuseTexture1) {
-                activeTextures.push(this._diffuseTexture1);
-            }
-
-            if (this._diffuseTexture2) {
-                activeTextures.push(this._diffuseTexture2);
-            }
-
-            if (this._diffuseTexture3) {
-                activeTextures.push(this._diffuseTexture3);
-            }
-
-            if (this._diffuseTexture4) {
-                activeTextures.push(this._diffuseTexture4);
-            }
-
-            // Mix map 2
-            if (this._mixTexture2) {
-                activeTextures.push(this._mixTexture2);
-            }
-
-            if (this._diffuseTexture5) {
-                activeTextures.push(this._diffuseTexture5);
-            }
-
-            if (this._diffuseTexture6) {
-                activeTextures.push(this._diffuseTexture6);
-            }
-
-            if (this._diffuseTexture7) {
-                activeTextures.push(this._diffuseTexture7);
-            }
-
-            if (this._diffuseTexture8) {
-                activeTextures.push(this._diffuseTexture8);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            // Mix map 1
-            if (this._mixTexture1 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture1 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture2 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture3 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture4 === texture) {
-                return true;
-            }
-
-            // Mix map 2
-            if (this._mixTexture2 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture5 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture6 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture7 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture8 === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this._mixTexture1) {
-                this._mixTexture1.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): MixMaterial {
-            return SerializationHelper.Clone(() => new MixMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.MixMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "MixMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): MixMaterial {
-            return SerializationHelper.Parse(() => new MixMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/mix/index.ts

@@ -0,0 +1 @@
+export * from "./mixMaterial";

+ 520 - 0
materialsLibrary/src/mix/mixMaterial.ts

@@ -0,0 +1,520 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, Texture, serializeAsColor3, Color3, serialize, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["mixPixelShader"] = require("./mix.fragment.fx");
+Effect.ShadersStore["mixVertexShader"] = require("./mix.vertex.fx");
+
+class MixMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public SPECULARTERM = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public MIXMAP2 = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class MixMaterial extends PushMaterial {
+    /**
+     * Mix textures
+     */
+
+    @serializeAsTexture("mixTexture1")
+    private _mixTexture1: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public mixTexture1: BaseTexture;
+
+    @serializeAsTexture("mixTexture2")
+    private _mixTexture2: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public mixTexture2: BaseTexture;
+
+    /**
+     * Diffuse textures
+     */
+
+    @serializeAsTexture("diffuseTexture1")
+    private _diffuseTexture1: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture1: Texture;
+
+    @serializeAsTexture("diffuseTexture2")
+    private _diffuseTexture2: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture2: Texture;
+
+    @serializeAsTexture("diffuseTexture3")
+    private _diffuseTexture3: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture3: Texture;
+
+    @serializeAsTexture("diffuseTexture4")
+    private _diffuseTexture4: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture4: Texture;
+
+    @serializeAsTexture("diffuseTexture1")
+    private _diffuseTexture5: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture5: Texture;
+
+    @serializeAsTexture("diffuseTexture2")
+    private _diffuseTexture6: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture6: Texture;
+
+    @serializeAsTexture("diffuseTexture3")
+    private _diffuseTexture7: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture7: Texture;
+
+    @serializeAsTexture("diffuseTexture4")
+    private _diffuseTexture8: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture8: Texture;
+
+    /**
+     * Uniforms
+     */
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serializeAsColor3()
+    public specularColor = new Color3(0, 0, 0);
+
+    @serialize()
+    public specularPower = 64;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new MixMaterialDefines();
+        }
+
+        var defines = <MixMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (scene.texturesEnabled) {
+            if (StandardMaterial.DiffuseTextureEnabled) {
+                if (this._mixTexture1) {
+                    if (!this._mixTexture1.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+                if (this._mixTexture2) {
+                    if (!this._mixTexture2.isReady()) {
+                        return false;
+                    } else {
+                        defines.MIXMAP2 = true;
+                    }
+                }
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "mix";
+            var join = defines.toString();
+            var uniforms = [
+                "world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vTextureInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMatrix",
+                "diffuse1Infos", "diffuse2Infos", "diffuse3Infos", "diffuse4Infos",
+                "diffuse5Infos", "diffuse6Infos", "diffuse7Infos", "diffuse8Infos"
+            ];
+            var samplers = [
+                "mixMap1Sampler", "mixMap2Sampler",
+                "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler", "diffuse4Sampler",
+                "diffuse5Sampler", "diffuse6Sampler", "diffuse7Sampler", "diffuse8Sampler"
+            ];
+
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <MixMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this._mixTexture1) {
+                this._activeEffect.setTexture("mixMap1Sampler", this._mixTexture1);
+                this._activeEffect.setFloat2("vTextureInfos", this._mixTexture1.coordinatesIndex, this._mixTexture1.level);
+                this._activeEffect.setMatrix("textureMatrix", this._mixTexture1.getTextureMatrix());
+
+                if (StandardMaterial.DiffuseTextureEnabled) {
+                    if (this._diffuseTexture1) {
+                        this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
+                        this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
+                    }
+                    if (this._diffuseTexture2) {
+                        this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
+                        this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
+                    }
+                    if (this._diffuseTexture3) {
+                        this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
+                        this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
+                    }
+                    if (this._diffuseTexture4) {
+                        this._activeEffect.setTexture("diffuse4Sampler", this._diffuseTexture4);
+                        this._activeEffect.setFloat2("diffuse4Infos", this._diffuseTexture4.uScale, this._diffuseTexture4.vScale);
+                    }
+                }
+            }
+
+            if (this._mixTexture2) {
+                this._activeEffect.setTexture("mixMap2Sampler", this._mixTexture2);
+
+                if (StandardMaterial.DiffuseTextureEnabled) {
+                    if (this._diffuseTexture5) {
+                        this._activeEffect.setTexture("diffuse5Sampler", this._diffuseTexture5);
+                        this._activeEffect.setFloat2("diffuse5Infos", this._diffuseTexture5.uScale, this._diffuseTexture5.vScale);
+                    }
+                    if (this._diffuseTexture6) {
+                        this._activeEffect.setTexture("diffuse6Sampler", this._diffuseTexture6);
+                        this._activeEffect.setFloat2("diffuse6Infos", this._diffuseTexture6.uScale, this._diffuseTexture6.vScale);
+                    }
+                    if (this._diffuseTexture7) {
+                        this._activeEffect.setTexture("diffuse7Sampler", this._diffuseTexture7);
+                        this._activeEffect.setFloat2("diffuse7Infos", this._diffuseTexture7.uScale, this._diffuseTexture7.vScale);
+                    }
+                    if (this._diffuseTexture8) {
+                        this._activeEffect.setTexture("diffuse8Sampler", this._diffuseTexture8);
+                        this._activeEffect.setFloat2("diffuse8Infos", this._diffuseTexture8.uScale, this._diffuseTexture8.vScale);
+                    }
+                }
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        if (defines.SPECULARTERM) {
+            this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+        }
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this._mixTexture1 && this._mixTexture1.animations && this._mixTexture1.animations.length > 0) {
+            results.push(this._mixTexture1);
+        }
+
+        if (this._mixTexture2 && this._mixTexture2.animations && this._mixTexture2.animations.length > 0) {
+            results.push(this._mixTexture2);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        // Mix map 1
+        if (this._mixTexture1) {
+            activeTextures.push(this._mixTexture1);
+        }
+
+        if (this._diffuseTexture1) {
+            activeTextures.push(this._diffuseTexture1);
+        }
+
+        if (this._diffuseTexture2) {
+            activeTextures.push(this._diffuseTexture2);
+        }
+
+        if (this._diffuseTexture3) {
+            activeTextures.push(this._diffuseTexture3);
+        }
+
+        if (this._diffuseTexture4) {
+            activeTextures.push(this._diffuseTexture4);
+        }
+
+        // Mix map 2
+        if (this._mixTexture2) {
+            activeTextures.push(this._mixTexture2);
+        }
+
+        if (this._diffuseTexture5) {
+            activeTextures.push(this._diffuseTexture5);
+        }
+
+        if (this._diffuseTexture6) {
+            activeTextures.push(this._diffuseTexture6);
+        }
+
+        if (this._diffuseTexture7) {
+            activeTextures.push(this._diffuseTexture7);
+        }
+
+        if (this._diffuseTexture8) {
+            activeTextures.push(this._diffuseTexture8);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        // Mix map 1
+        if (this._mixTexture1 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture1 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture2 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture3 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture4 === texture) {
+            return true;
+        }
+
+        // Mix map 2
+        if (this._mixTexture2 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture5 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture6 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture7 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture8 === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this._mixTexture1) {
+            this._mixTexture1.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): MixMaterial {
+        return SerializationHelper.Clone(() => new MixMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.MixMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "MixMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): MixMaterial {
+        return SerializationHelper.Parse(() => new MixMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 357
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -1,357 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class NormalMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public LIGHT0 = false;
-        public LIGHT1 = false;
-        public LIGHT2 = false;
-        public LIGHT3 = false;
-        public SPOTLIGHT0 = false;
-        public SPOTLIGHT1 = false;
-        public SPOTLIGHT2 = false;
-        public SPOTLIGHT3 = false;
-        public HEMILIGHT0 = false;
-        public HEMILIGHT1 = false;
-        public HEMILIGHT2 = false;
-        public HEMILIGHT3 = false;
-        public DIRLIGHT0 = false;
-        public DIRLIGHT1 = false;
-        public DIRLIGHT2 = false;
-        public DIRLIGHT3 = false;
-        public POINTLIGHT0 = false;
-        public POINTLIGHT1 = false;
-        public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;
-        public SHADOW0 = false;
-        public SHADOW1 = false;
-        public SHADOW2 = false;
-        public SHADOW3 = false;
-        public SHADOWS = false;
-        public SHADOWESM0 = false;
-        public SHADOWESM1 = false;
-        public SHADOWESM2 = false;
-        public SHADOWESM3 = false;
-        public SHADOWPOISSON0 = false;
-        public SHADOWPOISSON1 = false;
-        public SHADOWPOISSON2 = false;
-        public SHADOWPOISSON3 = false;
-        public SHADOWPCF0 = false;
-        public SHADOWPCF1 = false;
-        public SHADOWPCF2 = false;
-        public SHADOWPCF3 = false;
-        public SHADOWPCSS0 = false;
-        public SHADOWPCSS1 = false;
-        public SHADOWPCSS2 = false;
-        public SHADOWPCSS3 = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class NormalMaterial extends PushMaterial {
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: BaseTexture;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new NormalMaterialDefines();
-            }
-
-            var defines = <NormalMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (scene.texturesEnabled) {
-                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        if (!this._diffuseTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                var shaderName = "normal";
-                var join = defines.toString();
-
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
-                ];
-                var samplers = ["diffuseSampler"];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: 4
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: 4 }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <NormalMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
-                }
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
-                results.push(this.diffuseTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this.diffuseTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.diffuseTexture) {
-                this.diffuseTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): NormalMaterial {
-            return SerializationHelper.Clone(() => new NormalMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.NormalMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "NormalMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial {
-            return SerializationHelper.Parse(() => new NormalMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/normal/index.ts

@@ -0,0 +1 @@
+export * from "./normalMaterial";

+ 358 - 0
materialsLibrary/src/normal/normalMaterial.ts

@@ -0,0 +1,358 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["normalPixelShader"] = require("./normal.fragment.fx");
+Effect.ShadersStore["normalVertexShader"] = require("./normal.vertex.fx");
+
+class NormalMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public LIGHT0 = false;
+    public LIGHT1 = false;
+    public LIGHT2 = false;
+    public LIGHT3 = false;
+    public SPOTLIGHT0 = false;
+    public SPOTLIGHT1 = false;
+    public SPOTLIGHT2 = false;
+    public SPOTLIGHT3 = false;
+    public HEMILIGHT0 = false;
+    public HEMILIGHT1 = false;
+    public HEMILIGHT2 = false;
+    public HEMILIGHT3 = false;
+    public DIRLIGHT0 = false;
+    public DIRLIGHT1 = false;
+    public DIRLIGHT2 = false;
+    public DIRLIGHT3 = false;
+    public POINTLIGHT0 = false;
+    public POINTLIGHT1 = false;
+    public POINTLIGHT2 = false;
+    public POINTLIGHT3 = false;
+    public SHADOW0 = false;
+    public SHADOW1 = false;
+    public SHADOW2 = false;
+    public SHADOW3 = false;
+    public SHADOWS = false;
+    public SHADOWESM0 = false;
+    public SHADOWESM1 = false;
+    public SHADOWESM2 = false;
+    public SHADOWESM3 = false;
+    public SHADOWPOISSON0 = false;
+    public SHADOWPOISSON1 = false;
+    public SHADOWPOISSON2 = false;
+    public SHADOWPOISSON3 = false;
+    public SHADOWPCF0 = false;
+    public SHADOWPCF1 = false;
+    public SHADOWPCF2 = false;
+    public SHADOWPCF3 = false;
+    public SHADOWPCSS0 = false;
+    public SHADOWPCSS1 = false;
+    public SHADOWPCSS2 = false;
+    public SHADOWPCSS3 = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class NormalMaterial extends PushMaterial {
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: BaseTexture;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new NormalMaterialDefines();
+        }
+
+        var defines = <NormalMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (scene.texturesEnabled) {
+                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this._diffuseTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            var shaderName = "normal";
+            var join = defines.toString();
+
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
+            ];
+            var samplers = ["diffuseSampler"];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: 4
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: 4 }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <NormalMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+            }
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        // Lights
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
+            results.push(this.diffuseTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this.diffuseTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.diffuseTexture) {
+            this.diffuseTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): NormalMaterial {
+        return SerializationHelper.Clone(() => new NormalMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.NormalMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "NormalMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial {
+        return SerializationHelper.Parse(() => new NormalMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 244
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -1,244 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class ShadowOnlyMaterialDefines extends MaterialDefines {
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public NORMAL = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class ShadowOnlyMaterial extends PushMaterial {
-        private _renderId: number;
-        private _activeLight: IShadowLight;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public shadowColor = BABYLON.Color3.Black();
-
-        public needAlphaBlending(): boolean {
-            return true;
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        public get activeLight(): IShadowLight {
-            return this._activeLight;
-        }
-
-        public set activeLight(light: IShadowLight) {
-            this._activeLight = light;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new ShadowOnlyMaterialDefines();
-            }
-
-            var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Ensure that active light is the first shadow light
-            if (this._activeLight) {
-                for (var light of mesh._lightSources) {
-                    if (light.shadowEnabled) {
-                        if (this._activeLight === light) {
-                            break; // We are good
-                        }
-
-                        var lightPosition = mesh._lightSources.indexOf(this._activeLight);
-
-                        if (lightPosition !== -1) {
-                            mesh._lightSources.splice(lightPosition, 1);
-                            mesh._lightSources.splice(0, 0, this._activeLight);
-                        }
-                        break;
-                    }
-                }
-            }
-
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                var shaderName = "shadowOnly";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
-                    "vFogInfos", "vFogColor", "pointSize", "alpha", "shadowColor",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4"
-                ];
-                var samplers = new Array<string>();
-
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: 1
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: 1 }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                this._activeEffect.setFloat("alpha", this.alpha);
-                this._activeEffect.setColor3("shadowColor", this.shadowColor);
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            // Lights
-            if (scene.lightsEnabled) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public clone(name: string): ShadowOnlyMaterial {
-            return SerializationHelper.Clone<ShadowOnlyMaterial>(() => new ShadowOnlyMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.ShadowOnlyMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "ShadowOnlyMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial {
-            return SerializationHelper.Parse(() => new ShadowOnlyMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/shadowOnly/index.ts

@@ -0,0 +1 @@
+export * from "./shadowOnlyMaterial";

+ 245 - 0
materialsLibrary/src/shadowOnly/shadowOnlyMaterial.ts

@@ -0,0 +1,245 @@
+import { Effect, MaterialDefines, PushMaterial, IShadowLight, Scene, Nullable, BaseTexture, AbstractMesh, SubMesh, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["shadowOnlyPixelShader"] = require("./shadowOnly.fragment.fx");
+Effect.ShadersStore["shadowOnlyVertexShader"] = require("./shadowOnly.vertex.fx");
+
+class ShadowOnlyMaterialDefines extends MaterialDefines {
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class ShadowOnlyMaterial extends PushMaterial {
+    private _renderId: number;
+    private _activeLight: IShadowLight;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public shadowColor = BABYLON.Color3.Black();
+
+    public needAlphaBlending(): boolean {
+        return true;
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    public get activeLight(): IShadowLight {
+        return this._activeLight;
+    }
+
+    public set activeLight(light: IShadowLight) {
+        this._activeLight = light;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new ShadowOnlyMaterialDefines();
+        }
+
+        var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Ensure that active light is the first shadow light
+        if (this._activeLight) {
+            for (var light of mesh._lightSources) {
+                if (light.shadowEnabled) {
+                    if (this._activeLight === light) {
+                        break; // We are good
+                    }
+
+                    var lightPosition = mesh._lightSources.indexOf(this._activeLight);
+
+                    if (lightPosition !== -1) {
+                        mesh._lightSources.splice(lightPosition, 1);
+                        mesh._lightSources.splice(0, 0, this._activeLight);
+                    }
+                    break;
+                }
+            }
+        }
+
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            var shaderName = "shadowOnly";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
+                "vFogInfos", "vFogColor", "pointSize", "alpha", "shadowColor",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4"
+            ];
+            var samplers = new Array<string>();
+
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: 1
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: 1 }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            this._activeEffect.setFloat("alpha", this.alpha);
+            this._activeEffect.setColor3("shadowColor", this.shadowColor);
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        // Lights
+        if (scene.lightsEnabled) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public clone(name: string): ShadowOnlyMaterial {
+        return SerializationHelper.Clone<ShadowOnlyMaterial>(() => new ShadowOnlyMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.ShadowOnlyMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "ShadowOnlyMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial {
+        return SerializationHelper.Parse(() => new ShadowOnlyMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 315
materialsLibrary/src/simple/babylon.simpleMaterial.ts

@@ -1,315 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class SimpleMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class SimpleMaterial extends PushMaterial {
-        @serializeAsTexture("diffuseTexture")
-        private _diffuseTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: BaseTexture;
-
-        @serializeAsColor3("diffuse")
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new SimpleMaterialDefines();
-            }
-
-            var defines = <SimpleMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (scene.texturesEnabled) {
-                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        if (!this._diffuseTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.DIFFUSE = true;
-                        }
-                    }
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                var shaderName = "simple";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
-                ];
-                var samplers = ["diffuseSampler"];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights - 1 }
-                    }, engine), defines);
-
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <SimpleMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
-
-                    this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                    this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
-                }
-
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
-                results.push(this._diffuseTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTexture) {
-                activeTextures.push(this._diffuseTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this.diffuseTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this._diffuseTexture) {
-                this._diffuseTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): SimpleMaterial {
-            return SerializationHelper.Clone<SimpleMaterial>(() => new SimpleMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.SimpleMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "SimpleMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial {
-            return SerializationHelper.Parse(() => new SimpleMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/simple/index.ts

@@ -0,0 +1 @@
+export * from "./simpleMaterial";

+ 316 - 0
materialsLibrary/src/simple/simpleMaterial.ts

@@ -0,0 +1,316 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["simplePixelShader"] = require("./simple.fragment.fx");
+Effect.ShadersStore["simpleVertexShader"] = require("./simple.vertex.fx");
+
+class SimpleMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class SimpleMaterial extends PushMaterial {
+    @serializeAsTexture("diffuseTexture")
+    private _diffuseTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture: BaseTexture;
+
+    @serializeAsColor3("diffuse")
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new SimpleMaterialDefines();
+        }
+
+        var defines = <SimpleMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (scene.texturesEnabled) {
+                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this._diffuseTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
+                    }
+                }
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            var shaderName = "simple";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vDiffuseInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix"
+            ];
+            var samplers = ["diffuseSampler"];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights - 1 }
+                }, engine), defines);
+
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <SimpleMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
+
+                this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
+            }
+
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        // Lights
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
+            results.push(this._diffuseTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTexture) {
+            activeTextures.push(this._diffuseTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this.diffuseTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this._diffuseTexture) {
+            this._diffuseTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): SimpleMaterial {
+        return SerializationHelper.Clone<SimpleMaterial>(() => new SimpleMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.SimpleMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "SimpleMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial {
+        return SerializationHelper.Parse(() => new SimpleMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 238
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -1,238 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class SkyMaterialDefines extends MaterialDefines {
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class SkyMaterial extends PushMaterial {
-        // Public members
-        @serialize()
-        public luminance: number = 1.0;
-
-        @serialize()
-        public turbidity: number = 10.0;
-
-        @serialize()
-        public rayleigh: number = 2.0;
-
-        @serialize()
-        public mieCoefficient: number = 0.005;
-
-        @serialize()
-        public mieDirectionalG: number = 0.8;
-
-        @serialize()
-        public distance: number = 500;
-
-        @serialize()
-        public inclination: number = 0.49;
-
-        @serialize()
-        public azimuth: number = 0.25;
-
-        @serializeAsVector3()
-        public sunPosition: Vector3 = new Vector3(0, 100, 0);
-
-        @serialize()
-        public useSunPosition: boolean = false;
-
-        // Private members
-        private _cameraPosition: Vector3 = Vector3.Zero();
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new SkyMaterialDefines();
-            }
-
-            var defines = <SkyMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                var shaderName = "sky";
-
-                var join = defines.toString();
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    attribs,
-                    ["world", "viewProjection", "view",
-                        "vFogInfos", "vFogColor", "pointSize", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4",
-                        "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
-                        "cameraPosition"
-                    ],
-                    [],
-                    join, fallbacks, this.onCompiled, this.onError), defines);
-            }
-
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <SkyMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            if (this._mustRebind(scene, effect)) {
-
-                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            // Sky
-            var camera = scene.activeCamera;
-            if (camera) {
-                var cameraWorldMatrix = camera.getWorldMatrix();
-                this._cameraPosition.x = cameraWorldMatrix.m[12];
-                this._cameraPosition.y = cameraWorldMatrix.m[13];
-                this._cameraPosition.z = cameraWorldMatrix.m[14];
-                this._activeEffect.setVector3("cameraPosition", this._cameraPosition);
-            }
-
-            if (this.luminance > 0) {
-                this._activeEffect.setFloat("luminance", this.luminance);
-            }
-
-            this._activeEffect.setFloat("turbidity", this.turbidity);
-            this._activeEffect.setFloat("rayleigh", this.rayleigh);
-            this._activeEffect.setFloat("mieCoefficient", this.mieCoefficient);
-            this._activeEffect.setFloat("mieDirectionalG", this.mieDirectionalG);
-
-            if (!this.useSunPosition) {
-                var theta = Math.PI * (this.inclination - 0.5);
-                var phi = 2 * Math.PI * (this.azimuth - 0.5);
-
-                this.sunPosition.x = this.distance * Math.cos(phi);
-                this.sunPosition.y = this.distance * Math.sin(phi) * Math.sin(theta);
-                this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
-            }
-
-            this._activeEffect.setVector3("sunPosition", this.sunPosition);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            return [];
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): SkyMaterial {
-            return SerializationHelper.Clone<SkyMaterial>(() => new SkyMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType  = "BABYLON.SkyMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "SkyMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): SkyMaterial {
-            return SerializationHelper.Parse(() => new SkyMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/sky/index.ts

@@ -0,0 +1 @@
+export * from "./skyMaterial";

+ 239 - 0
materialsLibrary/src/sky/skyMaterial.ts

@@ -0,0 +1,239 @@
+import { Effect, MaterialDefines, PushMaterial, serialize, serializeAsVector3, Vector3, Scene, Nullable, BaseTexture, AbstractMesh, SubMesh, MaterialHelper, EffectFallbacks, VertexBuffer, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["skyPixelShader"] = require("./sky.fragment.fx");
+Effect.ShadersStore["skyVertexShader"] = require("./sky.vertex.fx");
+
+class SkyMaterialDefines extends MaterialDefines {
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class SkyMaterial extends PushMaterial {
+    // Public members
+    @serialize()
+    public luminance: number = 1.0;
+
+    @serialize()
+    public turbidity: number = 10.0;
+
+    @serialize()
+    public rayleigh: number = 2.0;
+
+    @serialize()
+    public mieCoefficient: number = 0.005;
+
+    @serialize()
+    public mieDirectionalG: number = 0.8;
+
+    @serialize()
+    public distance: number = 500;
+
+    @serialize()
+    public inclination: number = 0.49;
+
+    @serialize()
+    public azimuth: number = 0.25;
+
+    @serializeAsVector3()
+    public sunPosition: Vector3 = new Vector3(0, 100, 0);
+
+    @serialize()
+    public useSunPosition: boolean = false;
+
+    // Private members
+    private _cameraPosition: Vector3 = Vector3.Zero();
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new SkyMaterialDefines();
+        }
+
+        var defines = <SkyMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            var shaderName = "sky";
+
+            var join = defines.toString();
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                attribs,
+                ["world", "viewProjection", "view",
+                    "vFogInfos", "vFogColor", "pointSize", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4",
+                    "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
+                    "cameraPosition"
+                ],
+                [],
+                join, fallbacks, this.onCompiled, this.onError), defines);
+        }
+
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <SkyMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        if (this._mustRebind(scene, effect)) {
+
+            BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        // Sky
+        var camera = scene.activeCamera;
+        if (camera) {
+            var cameraWorldMatrix = camera.getWorldMatrix();
+            this._cameraPosition.x = cameraWorldMatrix.m[12];
+            this._cameraPosition.y = cameraWorldMatrix.m[13];
+            this._cameraPosition.z = cameraWorldMatrix.m[14];
+            this._activeEffect.setVector3("cameraPosition", this._cameraPosition);
+        }
+
+        if (this.luminance > 0) {
+            this._activeEffect.setFloat("luminance", this.luminance);
+        }
+
+        this._activeEffect.setFloat("turbidity", this.turbidity);
+        this._activeEffect.setFloat("rayleigh", this.rayleigh);
+        this._activeEffect.setFloat("mieCoefficient", this.mieCoefficient);
+        this._activeEffect.setFloat("mieDirectionalG", this.mieDirectionalG);
+
+        if (!this.useSunPosition) {
+            var theta = Math.PI * (this.inclination - 0.5);
+            var phi = 2 * Math.PI * (this.azimuth - 0.5);
+
+            this.sunPosition.x = this.distance * Math.cos(phi);
+            this.sunPosition.y = this.distance * Math.sin(phi) * Math.sin(theta);
+            this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
+        }
+
+        this._activeEffect.setVector3("sunPosition", this.sunPosition);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        return [];
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): SkyMaterial {
+        return SerializationHelper.Clone<SkyMaterial>(() => new SkyMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType  = "BABYLON.SkyMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "SkyMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): SkyMaterial {
+        return SerializationHelper.Parse(() => new SkyMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 437
materialsLibrary/src/terrain/babylon.terrainMaterial.ts

@@ -1,437 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-
-    class TerrainMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
-        public BUMP = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public SPECULARTERM = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class TerrainMaterial extends PushMaterial {
-        @serializeAsTexture("mixTexture")
-        private _mixTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public mixTexture: BaseTexture;
-
-        @serializeAsTexture("diffuseTexture1")
-        private _diffuseTexture1: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture1: Texture;
-
-        @serializeAsTexture("diffuseTexture2")
-        private _diffuseTexture2: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture2: Texture;
-
-        @serializeAsTexture("diffuseTexture3")
-        private _diffuseTexture3: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture3: Texture;
-
-        @serializeAsTexture("bumpTexture1")
-        private _bumpTexture1: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture1: Texture;
-
-        @serializeAsTexture("bumpTexture2")
-        private _bumpTexture2: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture2: Texture;
-
-        @serializeAsTexture("bumpTexture3")
-        private _bumpTexture3: Texture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture3: Texture;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serializeAsColor3()
-        public specularColor = new Color3(0, 0, 0);
-
-        @serialize()
-        public specularPower = 64;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new TerrainMaterialDefines();
-            }
-
-            var defines = <TerrainMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.mixTexture.isReady()) {
-                        return false;
-                    } else {
-                        defines._needUVs = true;
-                        defines.DIFFUSE = true;
-                    }
-                }
-                if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
-                    defines._needUVs = true;
-                    defines._needNormals = true;
-                    defines.BUMP = true;
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "terrain";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vTextureInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMatrix",
-                    "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
-                ];
-                var samplers = ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
-                    "bump1Sampler", "bump2Sampler", "bump3Sampler"
-                ];
-
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <TerrainMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this.mixTexture) {
-                    this._activeEffect.setTexture("textureSampler", this._mixTexture);
-                    this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
-                    this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
-
-                    if (StandardMaterial.DiffuseTextureEnabled) {
-                        if (this._diffuseTexture1) {
-                            this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
-                            this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
-                        }
-                        if (this._diffuseTexture2) {
-                            this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
-                            this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
-                        }
-                        if (this._diffuseTexture3) {
-                            this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
-                            this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
-                        }
-                    }
-
-                    if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
-                        if (this._bumpTexture1) {
-                            this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
-                        }
-                        if (this._bumpTexture2) {
-                            this._activeEffect.setTexture("bump2Sampler", this._bumpTexture2);
-                        }
-                        if (this._bumpTexture3) {
-                            this._activeEffect.setTexture("bump3Sampler", this._bumpTexture3);
-                        }
-                    }
-                }
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            if (defines.SPECULARTERM) {
-                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
-            }
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.mixTexture && this.mixTexture.animations && this.mixTexture.animations.length > 0) {
-                results.push(this.mixTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._mixTexture) {
-                activeTextures.push(this._mixTexture);
-            }
-
-            if (this._diffuseTexture1) {
-                activeTextures.push(this._diffuseTexture1);
-            }
-
-            if (this._diffuseTexture2) {
-                activeTextures.push(this._diffuseTexture2);
-            }
-
-            if (this._diffuseTexture3) {
-                activeTextures.push(this._diffuseTexture3);
-            }
-
-            if (this._bumpTexture1) {
-                activeTextures.push(this._bumpTexture1);
-            }
-
-            if (this._bumpTexture2) {
-                activeTextures.push(this._bumpTexture2);
-            }
-
-            if (this._bumpTexture3) {
-                activeTextures.push(this._bumpTexture3);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this._mixTexture === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture1 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture2 === texture) {
-                return true;
-            }
-
-            if (this._diffuseTexture3 === texture) {
-                return true;
-            }
-
-            if (this._bumpTexture1 === texture) {
-                return true;
-            }
-
-            if (this._bumpTexture2 === texture) {
-                return true;
-            }
-
-            if (this._bumpTexture3 === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.mixTexture) {
-                this.mixTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): TerrainMaterial {
-            return SerializationHelper.Clone(() => new TerrainMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.TerrainMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "TerrainMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): TerrainMaterial {
-            return SerializationHelper.Parse(() => new TerrainMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/terrain/index.ts

@@ -0,0 +1 @@
+export * from "./terrainMaterial";

+ 437 - 0
materialsLibrary/src/terrain/terrainMaterial.ts

@@ -0,0 +1,437 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, Texture, serializeAsColor3, Color3, serialize, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["terrainPixelShader"] = require("./terrain.fragment.fx");
+Effect.ShadersStore["terrainVertexShader"] = require("./terrain.vertex.fx");
+
+class TerrainMaterialDefines extends MaterialDefines {
+    public DIFFUSE = false;
+    public BUMP = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public SPECULARTERM = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class TerrainMaterial extends PushMaterial {
+    @serializeAsTexture("mixTexture")
+    private _mixTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public mixTexture: BaseTexture;
+
+    @serializeAsTexture("diffuseTexture1")
+    private _diffuseTexture1: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture1: Texture;
+
+    @serializeAsTexture("diffuseTexture2")
+    private _diffuseTexture2: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture2: Texture;
+
+    @serializeAsTexture("diffuseTexture3")
+    private _diffuseTexture3: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTexture3: Texture;
+
+    @serializeAsTexture("bumpTexture1")
+    private _bumpTexture1: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public bumpTexture1: Texture;
+
+    @serializeAsTexture("bumpTexture2")
+    private _bumpTexture2: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public bumpTexture2: Texture;
+
+    @serializeAsTexture("bumpTexture3")
+    private _bumpTexture3: Texture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public bumpTexture3: Texture;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serializeAsColor3()
+    public specularColor = new Color3(0, 0, 0);
+
+    @serialize()
+    public specularPower = 64;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new TerrainMaterialDefines();
+        }
+
+        var defines = <TerrainMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (scene.texturesEnabled) {
+            if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
+                if (!this.mixTexture.isReady()) {
+                    return false;
+                } else {
+                    defines._needUVs = true;
+                    defines.DIFFUSE = true;
+                }
+            }
+            if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
+                defines._needUVs = true;
+                defines._needNormals = true;
+                defines.BUMP = true;
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "terrain";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vTextureInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMatrix",
+                "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
+            ];
+            var samplers = ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
+                "bump1Sampler", "bump2Sampler", "bump3Sampler"
+            ];
+
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <TerrainMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this.mixTexture) {
+                this._activeEffect.setTexture("textureSampler", this._mixTexture);
+                this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
+                this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
+
+                if (StandardMaterial.DiffuseTextureEnabled) {
+                    if (this._diffuseTexture1) {
+                        this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
+                        this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
+                    }
+                    if (this._diffuseTexture2) {
+                        this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
+                        this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
+                    }
+                    if (this._diffuseTexture3) {
+                        this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
+                        this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
+                    }
+                }
+
+                if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
+                    if (this._bumpTexture1) {
+                        this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
+                    }
+                    if (this._bumpTexture2) {
+                        this._activeEffect.setTexture("bump2Sampler", this._bumpTexture2);
+                    }
+                    if (this._bumpTexture3) {
+                        this._activeEffect.setTexture("bump3Sampler", this._bumpTexture3);
+                    }
+                }
+            }
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        if (defines.SPECULARTERM) {
+            this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+        }
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.mixTexture && this.mixTexture.animations && this.mixTexture.animations.length > 0) {
+            results.push(this.mixTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._mixTexture) {
+            activeTextures.push(this._mixTexture);
+        }
+
+        if (this._diffuseTexture1) {
+            activeTextures.push(this._diffuseTexture1);
+        }
+
+        if (this._diffuseTexture2) {
+            activeTextures.push(this._diffuseTexture2);
+        }
+
+        if (this._diffuseTexture3) {
+            activeTextures.push(this._diffuseTexture3);
+        }
+
+        if (this._bumpTexture1) {
+            activeTextures.push(this._bumpTexture1);
+        }
+
+        if (this._bumpTexture2) {
+            activeTextures.push(this._bumpTexture2);
+        }
+
+        if (this._bumpTexture3) {
+            activeTextures.push(this._bumpTexture3);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this._mixTexture === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture1 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture2 === texture) {
+            return true;
+        }
+
+        if (this._diffuseTexture3 === texture) {
+            return true;
+        }
+
+        if (this._bumpTexture1 === texture) {
+            return true;
+        }
+
+        if (this._bumpTexture2 === texture) {
+            return true;
+        }
+
+        if (this._bumpTexture3 === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.mixTexture) {
+            this.mixTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): TerrainMaterial {
+        return SerializationHelper.Clone(() => new TerrainMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.TerrainMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "TerrainMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): TerrainMaterial {
+        return SerializationHelper.Parse(() => new TerrainMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 428
materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts

@@ -1,428 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class TriPlanarMaterialDefines extends MaterialDefines {
-        public DIFFUSEX = false;
-        public DIFFUSEY = false;
-        public DIFFUSEZ = false;
-
-        public BUMPX = false;
-        public BUMPY = false;
-        public BUMPZ = false;
-
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public SPECULARTERM = false;
-        public NORMAL = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class TriPlanarMaterial extends PushMaterial {
-        @serializeAsTexture()
-        public mixTexture: BaseTexture;
-
-        @serializeAsTexture("diffuseTextureX")
-        private _diffuseTextureX: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTextureX: BaseTexture;
-
-        @serializeAsTexture("diffuseTexturY")
-        private _diffuseTextureY: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTextureY: BaseTexture;
-
-        @serializeAsTexture("diffuseTextureZ")
-        private _diffuseTextureZ: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTextureZ: BaseTexture;
-
-        @serializeAsTexture("normalTextureX")
-        private _normalTextureX: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureX: BaseTexture;
-
-        @serializeAsTexture("normalTextureY")
-        private _normalTextureY: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureY: BaseTexture;
-
-        @serializeAsTexture("normalTextureZ")
-        private _normalTextureZ: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureZ: BaseTexture;
-
-        @serialize()
-        public tileSize: number = 1;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serializeAsColor3()
-        public specularColor = new Color3(0.2, 0.2, 0.2);
-
-        @serialize()
-        public specularPower = 64;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        private _renderId: number;
-
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        // Methods
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new TriPlanarMaterialDefines();
-            }
-
-            var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                if (scene.texturesEnabled) {
-                    if (StandardMaterial.DiffuseTextureEnabled) {
-                        var textures = [this.diffuseTextureX, this.diffuseTextureY, this.diffuseTextureZ];
-                        var textureDefines = ["DIFFUSEX", "DIFFUSEY", "DIFFUSEZ"];
-
-                        for (var i = 0; i < textures.length; i++) {
-                            if (textures[i]) {
-                                if (!textures[i].isReady()) {
-                                    return false;
-                                } else {
-                                    (<any>defines)[textureDefines[i]] = true;
-                                }
-                            }
-                        }
-                    }
-                    if (StandardMaterial.BumpTextureEnabled) {
-                        var textures = [this.normalTextureX, this.normalTextureY, this.normalTextureZ];
-                        var textureDefines = ["BUMPX", "BUMPY", "BUMPZ"];
-
-                        for (var i = 0; i < textures.length; i++) {
-                            if (textures[i]) {
-                                if (!textures[i].isReady()) {
-                                    return false;
-                                } else {
-                                    (<any>defines)[textureDefines[i]] = true;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-
-            // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "triplanar";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4",
-                    "tileSize"
-                ];
-                var samplers = ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
-                    "normalSamplerX", "normalSamplerY", "normalSamplerZ"
-                ];
-
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
-                    }, engine), defines);
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            this._activeEffect.setFloat("tileSize", this.tileSize);
-
-            if (scene.getCachedMaterial() !== this) {
-                // Textures
-                if (this.diffuseTextureX) {
-                    this._activeEffect.setTexture("diffuseSamplerX", this.diffuseTextureX);
-                }
-                if (this.diffuseTextureY) {
-                    this._activeEffect.setTexture("diffuseSamplerY", this.diffuseTextureY);
-                }
-                if (this.diffuseTextureZ) {
-                    this._activeEffect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
-                }
-                if (this.normalTextureX) {
-                    this._activeEffect.setTexture("normalSamplerX", this.normalTextureX);
-                }
-                if (this.normalTextureY) {
-                    this._activeEffect.setTexture("normalSamplerY", this.normalTextureY);
-                }
-                if (this.normalTextureZ) {
-                    this._activeEffect.setTexture("normalSamplerZ", this.normalTextureZ);
-                }
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            if (defines.SPECULARTERM) {
-                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
-            }
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.mixTexture && this.mixTexture.animations && this.mixTexture.animations.length > 0) {
-                results.push(this.mixTexture);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._diffuseTextureX) {
-                activeTextures.push(this._diffuseTextureX);
-            }
-
-            if (this._diffuseTextureY) {
-                activeTextures.push(this._diffuseTextureY);
-            }
-
-            if (this._diffuseTextureZ) {
-                activeTextures.push(this._diffuseTextureZ);
-            }
-
-            if (this._normalTextureX) {
-                activeTextures.push(this._normalTextureX);
-            }
-
-            if (this._normalTextureY) {
-                activeTextures.push(this._normalTextureY);
-            }
-
-            if (this._normalTextureZ) {
-                activeTextures.push(this._normalTextureZ);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this._diffuseTextureX === texture) {
-                return true;
-            }
-
-            if (this._diffuseTextureY === texture) {
-                return true;
-            }
-
-            if (this._diffuseTextureZ === texture) {
-                return true;
-            }
-
-            if (this._normalTextureX === texture) {
-                return true;
-            }
-
-            if (this._normalTextureY === texture) {
-                return true;
-            }
-
-            if (this._normalTextureZ === texture) {
-                return true;
-            }
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.mixTexture) {
-                this.mixTexture.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): TriPlanarMaterial {
-            return SerializationHelper.Clone(() => new TriPlanarMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.TriPlanarMaterial";
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "TriPlanarMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial {
-            return SerializationHelper.Parse(() => new TriPlanarMaterial(source.name, scene), source, scene, rootUrl);
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/triPlanar/index.ts

@@ -0,0 +1 @@
+export * from "./triPlanarMaterial";

+ 429 - 0
materialsLibrary/src/triPlanar/triPlanarMaterial.ts

@@ -0,0 +1,429 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serialize, serializeAsColor3, Color3, Scene, Nullable, AbstractMesh, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Matrix, Mesh, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["triPlanarPixelShader"] = require("./triPlanar.fragment.fx");
+Effect.ShadersStore["triPlanarVertexShader"] = require("./triPlanar.vertex.fx");
+
+class TriPlanarMaterialDefines extends MaterialDefines {
+    public DIFFUSEX = false;
+    public DIFFUSEY = false;
+    public DIFFUSEZ = false;
+
+    public BUMPX = false;
+    public BUMPY = false;
+    public BUMPZ = false;
+
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public SPECULARTERM = false;
+    public NORMAL = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class TriPlanarMaterial extends PushMaterial {
+    @serializeAsTexture()
+    public mixTexture: BaseTexture;
+
+    @serializeAsTexture("diffuseTextureX")
+    private _diffuseTextureX: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTextureX: BaseTexture;
+
+    @serializeAsTexture("diffuseTexturY")
+    private _diffuseTextureY: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTextureY: BaseTexture;
+
+    @serializeAsTexture("diffuseTextureZ")
+    private _diffuseTextureZ: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public diffuseTextureZ: BaseTexture;
+
+    @serializeAsTexture("normalTextureX")
+    private _normalTextureX: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public normalTextureX: BaseTexture;
+
+    @serializeAsTexture("normalTextureY")
+    private _normalTextureY: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public normalTextureY: BaseTexture;
+
+    @serializeAsTexture("normalTextureZ")
+    private _normalTextureZ: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public normalTextureZ: BaseTexture;
+
+    @serialize()
+    public tileSize: number = 1;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serializeAsColor3()
+    public specularColor = new Color3(0.2, 0.2, 0.2);
+
+    @serialize()
+    public specularPower = 64;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    private _renderId: number;
+
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    // Methods
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new TriPlanarMaterialDefines();
+        }
+
+        var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            if (scene.texturesEnabled) {
+                if (StandardMaterial.DiffuseTextureEnabled) {
+                    var textures = [this.diffuseTextureX, this.diffuseTextureY, this.diffuseTextureZ];
+                    var textureDefines = ["DIFFUSEX", "DIFFUSEY", "DIFFUSEZ"];
+
+                    for (var i = 0; i < textures.length; i++) {
+                        if (textures[i]) {
+                            if (!textures[i].isReady()) {
+                                return false;
+                            } else {
+                                (<any>defines)[textureDefines[i]] = true;
+                            }
+                        }
+                    }
+                }
+                if (StandardMaterial.BumpTextureEnabled) {
+                    var textures = [this.normalTextureX, this.normalTextureY, this.normalTextureZ];
+                    var textureDefines = ["BUMPX", "BUMPY", "BUMPZ"];
+
+                    for (var i = 0; i < textures.length; i++) {
+                        if (textures[i]) {
+                            if (!textures[i].isReady()) {
+                                return false;
+                            } else {
+                                (<any>defines)[textureDefines[i]] = true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Misc.
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "triplanar";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4",
+                "tileSize"
+            ];
+            var samplers = ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
+                "normalSamplerX", "normalSamplerY", "normalSamplerZ"
+            ];
+
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights }
+                }, engine), defines);
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        this._activeEffect.setFloat("tileSize", this.tileSize);
+
+        if (scene.getCachedMaterial() !== this) {
+            // Textures
+            if (this.diffuseTextureX) {
+                this._activeEffect.setTexture("diffuseSamplerX", this.diffuseTextureX);
+            }
+            if (this.diffuseTextureY) {
+                this._activeEffect.setTexture("diffuseSamplerY", this.diffuseTextureY);
+            }
+            if (this.diffuseTextureZ) {
+                this._activeEffect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
+            }
+            if (this.normalTextureX) {
+                this._activeEffect.setTexture("normalSamplerX", this.normalTextureX);
+            }
+            if (this.normalTextureY) {
+                this._activeEffect.setTexture("normalSamplerY", this.normalTextureY);
+            }
+            if (this.normalTextureZ) {
+                this._activeEffect.setTexture("normalSamplerZ", this.normalTextureZ);
+            }
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        if (defines.SPECULARTERM) {
+            this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+        }
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.mixTexture && this.mixTexture.animations && this.mixTexture.animations.length > 0) {
+            results.push(this.mixTexture);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._diffuseTextureX) {
+            activeTextures.push(this._diffuseTextureX);
+        }
+
+        if (this._diffuseTextureY) {
+            activeTextures.push(this._diffuseTextureY);
+        }
+
+        if (this._diffuseTextureZ) {
+            activeTextures.push(this._diffuseTextureZ);
+        }
+
+        if (this._normalTextureX) {
+            activeTextures.push(this._normalTextureX);
+        }
+
+        if (this._normalTextureY) {
+            activeTextures.push(this._normalTextureY);
+        }
+
+        if (this._normalTextureZ) {
+            activeTextures.push(this._normalTextureZ);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this._diffuseTextureX === texture) {
+            return true;
+        }
+
+        if (this._diffuseTextureY === texture) {
+            return true;
+        }
+
+        if (this._diffuseTextureZ === texture) {
+            return true;
+        }
+
+        if (this._normalTextureX === texture) {
+            return true;
+        }
+
+        if (this._normalTextureY === texture) {
+            return true;
+        }
+
+        if (this._normalTextureZ === texture) {
+            return true;
+        }
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.mixTexture) {
+            this.mixTexture.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): TriPlanarMaterial {
+        return SerializationHelper.Clone(() => new TriPlanarMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.TriPlanarMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "TriPlanarMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial {
+        return SerializationHelper.Parse(() => new TriPlanarMaterial(source.name, scene), source, scene, rootUrl);
+    }
+}

+ 0 - 12
materialsLibrary/src/tsconfig.json

@@ -1,12 +0,0 @@
-{
-  "compilerOptions": {
-    "experimentalDecorators": true,
-    "module": "commonjs",
-    "target": "es5",
-    "noImplicitAny": true,
-    "noImplicitReturns": true,
-    "noImplicitThis": true,
-    "noUnusedLocals": true,
-    "strictNullChecks": true
-  }
-}

+ 0 - 673
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -1,673 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-    class WaterMaterialDefines extends MaterialDefines {
-        public BUMP = false;
-        public REFLECTION = false;
-        public CLIPPLANE = false;
-        public CLIPPLANE2 = false;
-        public CLIPPLANE3 = false;
-        public CLIPPLANE4 = false;
-        public ALPHATEST = false;
-        public DEPTHPREPASS = false;
-        public POINTSIZE = false;
-        public FOG = false;
-        public NORMAL = false;
-        public UV1 = false;
-        public UV2 = false;
-        public VERTEXCOLOR = false;
-        public VERTEXALPHA = false;
-        public NUM_BONE_INFLUENCERS = 0;
-        public BonesPerMesh = 0;
-        public INSTANCES = false;
-        public SPECULARTERM = false;
-        public LOGARITHMICDEPTH = false;
-        public FRESNELSEPARATE = false;
-        public BUMPSUPERIMPOSE = false;
-        public BUMPAFFECTSREFLECTION = false;
-
-        constructor() {
-            super();
-            this.rebuild();
-        }
-    }
-
-    export class WaterMaterial extends PushMaterial {
-        /*
-		* Public members
-		*/
-        @serializeAsTexture("bumpTexture")
-        private _bumpTexture: BaseTexture;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture: BaseTexture;
-
-        @serializeAsColor3()
-        public diffuseColor = new Color3(1, 1, 1);
-
-        @serializeAsColor3()
-        public specularColor = new Color3(0, 0, 0);
-
-        @serialize()
-        public specularPower = 64;
-
-        @serialize("disableLighting")
-        private _disableLighting = false;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;
-
-        @serialize("maxSimultaneousLights")
-        private _maxSimultaneousLights = 4;
-        @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;
-
-        /**
-        * @param {number}: Represents the wind force
-        */
-        @serialize()
-        public windForce: number = 6;
-        /**
-        * @param {Vector2}: The direction of the wind in the plane (X, Z)
-        */
-        @serializeAsVector2()
-        public windDirection: Vector2 = new Vector2(0, 1);
-        /**
-        * @param {number}: Wave height, represents the height of the waves
-        */
-        @serialize()
-        public waveHeight: number = 0.4;
-        /**
-        * @param {number}: Bump height, represents the bump height related to the bump map
-        */
-        @serialize()
-        public bumpHeight: number = 0.4;
-        /**
-         * @param {boolean}: Add a smaller moving bump to less steady waves.
-         */
-        @serialize("bumpSuperimpose")
-        private _bumpSuperimpose = false;
-        @expandToProperty("_markAllSubMeshesAsMiscDirty")
-        public bumpSuperimpose: boolean;
-
-        /**
-         * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
-         */
-        @serialize("fresnelSeparate")
-        private _fresnelSeparate = false;
-        @expandToProperty("_markAllSubMeshesAsMiscDirty")
-        public fresnelSeparate: boolean;
-
-        /**
-         * @param {boolean}: bump Waves modify the reflection.
-         */
-        @serialize("bumpAffectsReflection")
-        private _bumpAffectsReflection = false;
-        @expandToProperty("_markAllSubMeshesAsMiscDirty")
-        public bumpAffectsReflection: boolean;
-
-        /**
-        * @param {number}: The water color blended with the refraction (near)
-        */
-        @serializeAsColor3()
-        public waterColor: Color3 = new Color3(0.1, 0.1, 0.6);
-        /**
-        * @param {number}: The blend factor related to the water color
-        */
-        @serialize()
-        public colorBlendFactor: number = 0.2;
-        /**
-         * @param {number}: The water color blended with the reflection (far)
-         */
-        @serializeAsColor3()
-        public waterColor2: Color3 = new Color3(0.1, 0.1, 0.6);
-        /**
-         * @param {number}: The blend factor related to the water color (reflection, far)
-         */
-        @serialize()
-        public colorBlendFactor2: number = 0.2;
-        /**
-        * @param {number}: Represents the maximum length of a wave
-        */
-        @serialize()
-        public waveLength: number = 0.1;
-
-        /**
-        * @param {number}: Defines the waves speed
-        */
-        @serialize()
-        public waveSpeed: number = 1.0;
-
-        protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
-
-        /*
-		* Private members
-		*/
-        private _mesh: Nullable<AbstractMesh> = null;
-
-        private _refractionRTT: Nullable<RenderTargetTexture>;
-        private _reflectionRTT: Nullable<RenderTargetTexture>;
-
-        private _reflectionTransform: Matrix = Matrix.Zero();
-        private _lastTime: number = 0;
-        private _lastDeltaTime: number = 0;
-
-        private _renderId: number;
-
-        private _useLogarithmicDepth: boolean;
-
-        private _waitingRenderList: Nullable<string[]>;
-
-        /**
-         * Gets a boolean indicating that current material needs to register RTT
-         */
-        public get hasRenderTargetTextures(): boolean {
-            return true;
-        }
-
-        /**
-		* Constructor
-		*/
-        constructor(name: string, scene: Scene, public renderTargetSize: Vector2 = new Vector2(512, 512)) {
-            super(name, scene);
-
-            this._createRenderTargets(scene, renderTargetSize);
-
-            // Create render targets
-            this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
-                this._renderTargets.reset();
-                this._renderTargets.push(<RenderTargetTexture>this._reflectionRTT);
-                this._renderTargets.push(<RenderTargetTexture>this._refractionRTT);
-
-                return this._renderTargets;
-            };
-        }
-
-        @serialize()
-        public get useLogarithmicDepth(): boolean {
-            return this._useLogarithmicDepth;
-        }
-
-        public set useLogarithmicDepth(value: boolean) {
-            this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
-            this._markAllSubMeshesAsMiscDirty();
-        }
-
-        // Get / Set
-        public get refractionTexture(): Nullable<RenderTargetTexture> {
-            return this._refractionRTT;
-        }
-
-        public get reflectionTexture(): Nullable<RenderTargetTexture> {
-            return this._reflectionRTT;
-        }
-
-        // Methods
-        public addToRenderList(node: any): void {
-            if (this._refractionRTT && this._refractionRTT.renderList) {
-                this._refractionRTT.renderList.push(node);
-            }
-
-            if (this._reflectionRTT && this._reflectionRTT.renderList) {
-                this._reflectionRTT.renderList.push(node);
-            }
-        }
-
-        public enableRenderTargets(enable: boolean): void {
-            var refreshRate = enable ? 1 : 0;
-
-            if (this._refractionRTT) {
-                this._refractionRTT.refreshRate = refreshRate;
-            }
-
-            if (this._reflectionRTT) {
-                this._reflectionRTT.refreshRate = refreshRate;
-            }
-        }
-
-        public getRenderList(): Nullable<AbstractMesh[]> {
-            return this._refractionRTT ? this._refractionRTT.renderList : [];
-        }
-
-        public get renderTargetsEnabled(): boolean {
-            return !(this._refractionRTT && this._refractionRTT.refreshRate === 0);
-        }
-
-        public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0);
-        }
-
-        public needAlphaTesting(): boolean {
-            return false;
-        }
-
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        }
-
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
-
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new WaterMaterialDefines();
-            }
-
-            var defines = <WaterMaterialDefines>subMesh._materialDefines;
-            var scene = this.getScene();
-
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var engine = scene.getEngine();
-
-            // Textures
-            if (defines._areTexturesDirty) {
-                defines._needUVs = false;
-                if (scene.texturesEnabled) {
-                    if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
-                        if (!this.bumpTexture.isReady()) {
-                            return false;
-                        } else {
-                            defines._needUVs = true;
-                            defines.BUMP = true;
-                        }
-                    }
-
-                    if (StandardMaterial.ReflectionTextureEnabled) {
-                        defines.REFLECTION = true;
-                    }
-                }
-            }
-
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
-
-            if (defines._areMiscDirty) {
-                if (this._fresnelSeparate) {
-                    defines.FRESNELSEPARATE = true;
-                }
-
-                if (this._bumpSuperimpose) {
-                    defines.BUMPSUPERIMPOSE = true;
-                }
-
-                if (this._bumpAffectsReflection) {
-                    defines.BUMPAFFECTSREFLECTION = true;
-                }
-            }
-
-            // Lights
-            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
-
-            // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
-
-            // Configure this
-            this._mesh = mesh;
-
-            if (this._waitingRenderList) {
-                for (var i = 0; i < this._waitingRenderList.length; i++) {
-                    this.addToRenderList(scene.getNodeByID(this._waitingRenderList[i]));
-                }
-
-                this._waitingRenderList = null;
-            }
-
-            // Get correct effect
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
-
-                // Fallbacks
-                var fallbacks = new EffectFallbacks();
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
-                }
-
-                if (defines.LOGARITHMICDEPTH) {
-                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
-                }
-
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-
-                if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
-                }
-
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-
-                if (defines.NORMAL) {
-                    attribs.push(VertexBuffer.NormalKind);
-                }
-
-                if (defines.UV1) {
-                    attribs.push(VertexBuffer.UVKind);
-                }
-
-                if (defines.UV2) {
-                    attribs.push(VertexBuffer.UV2Kind);
-                }
-
-                if (defines.VERTEXCOLOR) {
-                    attribs.push(VertexBuffer.ColorKind);
-                }
-
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
-
-                // Legacy browser patch
-                var shaderName = "water";
-                var join = defines.toString();
-                var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
-                    "vFogInfos", "vFogColor", "pointSize",
-                    "vNormalInfos",
-                    "mBones",
-                    "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "normalMatrix",
-                    "logarithmicDepthConstant",
-
-                    // Water
-                    "worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
-                    "cameraPosition", "bumpHeight", "waveHeight", "waterColor", "waterColor2", "colorBlendFactor", "colorBlendFactor2", "waveSpeed"
-                ];
-                var samplers = ["normalSampler",
-                    // Water
-                    "refractionSampler", "reflectionSampler"
-                ];
-                var uniformBuffers = new Array<string>();
-
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: this.maxSimultaneousLights
-                });
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: fallbacks,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }
-                    }, engine), defines);
-
-            }
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
-            }
-
-            this._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
-
-            return true;
-        }
-
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
-
-            var defines = <WaterMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }
-
-            var effect = subMesh.effect;
-            if (!effect || !this._mesh) {
-                return;
-            }
-            this._activeEffect = effect;
-
-            // Matrices
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
-
-            // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-
-            if (this._mustRebind(scene, effect)) {
-                // Textures
-                if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
-                    this._activeEffect.setTexture("normalSampler", this.bumpTexture);
-
-                    this._activeEffect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
-                    this._activeEffect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
-                }
-                // Clip plane
-                MaterialHelper.BindClipPlane(this._activeEffect, scene);
-
-                // Point size
-                if (this.pointsCloud) {
-                    this._activeEffect.setFloat("pointSize", this.pointSize);
-                }
-
-                MaterialHelper.BindEyePosition(effect, scene);
-            }
-
-            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-
-            if (defines.SPECULARTERM) {
-                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
-            }
-
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
-            }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._activeEffect.setMatrix("view", scene.getViewMatrix());
-            }
-
-            // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-
-            // Log. depth
-            MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
-
-            // Water
-            if (StandardMaterial.ReflectionTextureEnabled) {
-                this._activeEffect.setTexture("refractionSampler", this._refractionRTT);
-                this._activeEffect.setTexture("reflectionSampler", this._reflectionRTT);
-            }
-
-            var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
-
-            // Add delta time. Prevent adding delta time if it hasn't changed.
-            let deltaTime = scene.getEngine().getDeltaTime();
-            if (deltaTime !== this._lastDeltaTime) {
-                this._lastDeltaTime = deltaTime;
-                this._lastTime += this._lastDeltaTime;
-            }
-
-            this._activeEffect.setMatrix("worldReflectionViewProjection", wrvp);
-            this._activeEffect.setVector2("windDirection", this.windDirection);
-            this._activeEffect.setFloat("waveLength", this.waveLength);
-            this._activeEffect.setFloat("time", this._lastTime / 100000);
-            this._activeEffect.setFloat("windForce", this.windForce);
-            this._activeEffect.setFloat("waveHeight", this.waveHeight);
-            this._activeEffect.setFloat("bumpHeight", this.bumpHeight);
-            this._activeEffect.setColor4("waterColor", this.waterColor, 1.0);
-            this._activeEffect.setFloat("colorBlendFactor", this.colorBlendFactor);
-            this._activeEffect.setColor4("waterColor2", this.waterColor2, 1.0);
-            this._activeEffect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
-            this._activeEffect.setFloat("waveSpeed", this.waveSpeed);
-
-            this._afterBind(mesh, this._activeEffect);
-        }
-
-        private _createRenderTargets(scene: Scene, renderTargetSize: Vector2): void {
-            // Render targets
-            this._refractionRTT = new RenderTargetTexture(name + "_refraction", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
-            this._refractionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
-            this._refractionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
-            this._refractionRTT.ignoreCameraViewport = true;
-
-            this._reflectionRTT = new RenderTargetTexture(name + "_reflection", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
-            this._reflectionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
-            this._reflectionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
-            this._reflectionRTT.ignoreCameraViewport = true;
-
-            var isVisible: boolean;
-            var clipPlane: Nullable<Plane> = null;
-            var savedViewMatrix: Matrix;
-            var mirrorMatrix = Matrix.Zero();
-
-            this._refractionRTT.onBeforeRender = () => {
-                if (this._mesh) {
-                    isVisible = this._mesh.isVisible;
-                    this._mesh.isVisible = false;
-                }
-            };
-
-            this._refractionRTT.onAfterRender = () => {
-                if (this._mesh) {
-                    this._mesh.isVisible = isVisible;
-                }
-            };
-
-            this._reflectionRTT.onBeforeRender = () => {
-                if (this._mesh) {
-                    isVisible = this._mesh.isVisible;
-                    this._mesh.isVisible = false;
-                }
-
-                // Clip plane
-                clipPlane = scene.clipPlane;
-
-                var positiony = this._mesh ? this._mesh.position.y : 0.0;
-                scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony - 0.05, 0), new Vector3(0, -1, 0));
-
-                // Transform
-                Matrix.ReflectionToRef(scene.clipPlane, mirrorMatrix);
-                savedViewMatrix = scene.getViewMatrix();
-
-                mirrorMatrix.multiplyToRef(savedViewMatrix, this._reflectionTransform);
-                scene.setTransformMatrix(this._reflectionTransform, scene.getProjectionMatrix());
-                scene.getEngine().cullBackFaces = false;
-                scene._mirroredCameraPosition = Vector3.TransformCoordinates((<Camera>scene.activeCamera).position, mirrorMatrix);
-            };
-
-            this._reflectionRTT.onAfterRender = () => {
-                if (this._mesh) {
-                    this._mesh.isVisible = isVisible;
-                }
-
-                // Clip plane
-                scene.clipPlane = clipPlane;
-
-                // Transform
-                scene.setTransformMatrix(savedViewMatrix, scene.getProjectionMatrix());
-                scene.getEngine().cullBackFaces = true;
-                scene._mirroredCameraPosition = null;
-            };
-        }
-
-        public getAnimatables(): IAnimatable[] {
-            var results = [];
-
-            if (this.bumpTexture && this.bumpTexture.animations && this.bumpTexture.animations.length > 0) {
-                results.push(this.bumpTexture);
-            }
-            if (this._reflectionRTT && this._reflectionRTT.animations && this._reflectionRTT.animations.length > 0) {
-                results.push(this._reflectionRTT);
-            }
-            if (this._refractionRTT && this._refractionRTT.animations && this._refractionRTT.animations.length > 0) {
-                results.push(this._refractionRTT);
-            }
-
-            return results;
-        }
-
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
-
-            if (this._bumpTexture) {
-                activeTextures.push(this._bumpTexture);
-            }
-
-            return activeTextures;
-        }
-
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
-            }
-
-            if (this._bumpTexture === texture) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public dispose(forceDisposeEffect?: boolean): void {
-            if (this.bumpTexture) {
-                this.bumpTexture.dispose();
-            }
-
-            var index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._refractionRTT);
-            if (index != -1) {
-                this.getScene().customRenderTargets.splice(index, 1);
-            }
-            index = -1;
-            index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._reflectionRTT);
-            if (index != -1) {
-                this.getScene().customRenderTargets.splice(index, 1);
-            }
-
-            if (this._reflectionRTT) {
-                this._reflectionRTT.dispose();
-            }
-            if (this._refractionRTT) {
-                this._refractionRTT.dispose();
-            }
-
-            super.dispose(forceDisposeEffect);
-        }
-
-        public clone(name: string): WaterMaterial {
-            return SerializationHelper.Clone(() => new WaterMaterial(name, this.getScene()), this);
-        }
-
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.WaterMaterial";
-
-            serializationObject.renderList = [];
-            if (this._refractionRTT && this._refractionRTT.renderList) {
-                for (var i = 0; i < this._refractionRTT.renderList.length; i++) {
-                    serializationObject.renderList.push(this._refractionRTT.renderList[i].id);
-                }
-            }
-
-            return serializationObject;
-        }
-
-        public getClassName(): string {
-            return "WaterMaterial";
-        }
-
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): WaterMaterial {
-            var mat = SerializationHelper.Parse(() => new WaterMaterial(source.name, scene), source, scene, rootUrl);
-            mat._waitingRenderList = source.renderList;
-
-            return mat;
-        }
-
-        public static CreateDefaultMesh(name: string, scene: Scene): Mesh {
-            var mesh = Mesh.CreateGround(name, 512, 512, 32, scene, false);
-            return mesh;
-        }
-    }
-}

+ 1 - 0
materialsLibrary/src/water/index.ts

@@ -0,0 +1 @@
+export * from "./waterMaterial";

+ 682 - 0
materialsLibrary/src/water/waterMaterial.ts

@@ -0,0 +1,682 @@
+import { Effect, MaterialDefines, PushMaterial, serializeAsTexture, BaseTexture, expandToProperty, serializeAsColor3, Color3, serialize, serializeAsVector2, Vector2, SmartArray, RenderTargetTexture, Nullable, AbstractMesh, Matrix, Scene, SubMesh, StandardMaterial, MaterialHelper, EffectFallbacks, VertexBuffer, EffectCreationOptions, Mesh, Plane, Vector3, Camera, IAnimatable, SerializationHelper } from "babylonjs";
+
+Effect.ShadersStore["waterPixelShader"] = require("./water.fragment.fx");
+Effect.ShadersStore["waterVertexShader"] = require("./water.vertex.fx");
+
+class WaterMaterialDefines extends MaterialDefines {
+    public BUMP = false;
+    public REFLECTION = false;
+    public CLIPPLANE = false;
+    public CLIPPLANE2 = false;
+    public CLIPPLANE3 = false;
+    public CLIPPLANE4 = false;
+    public ALPHATEST = false;
+    public DEPTHPREPASS = false;
+    public POINTSIZE = false;
+    public FOG = false;
+    public NORMAL = false;
+    public UV1 = false;
+    public UV2 = false;
+    public VERTEXCOLOR = false;
+    public VERTEXALPHA = false;
+    public NUM_BONE_INFLUENCERS = 0;
+    public BonesPerMesh = 0;
+    public INSTANCES = false;
+    public SPECULARTERM = false;
+    public LOGARITHMICDEPTH = false;
+    public FRESNELSEPARATE = false;
+    public BUMPSUPERIMPOSE = false;
+    public BUMPAFFECTSREFLECTION = false;
+
+    constructor() {
+        super();
+        this.rebuild();
+    }
+}
+
+export class WaterMaterial extends PushMaterial {
+    /*
+    * Public members
+    */
+    @serializeAsTexture("bumpTexture")
+    private _bumpTexture: BaseTexture;
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public bumpTexture: BaseTexture;
+
+    @serializeAsColor3()
+    public diffuseColor = new Color3(1, 1, 1);
+
+    @serializeAsColor3()
+    public specularColor = new Color3(0, 0, 0);
+
+    @serialize()
+    public specularPower = 64;
+
+    @serialize("disableLighting")
+    private _disableLighting = false;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public disableLighting: boolean;
+
+    @serialize("maxSimultaneousLights")
+    private _maxSimultaneousLights = 4;
+    @expandToProperty("_markAllSubMeshesAsLightsDirty")
+    public maxSimultaneousLights: number;
+
+    /**
+    * @param {number}: Represents the wind force
+    */
+    @serialize()
+    public windForce: number = 6;
+    /**
+    * @param {Vector2}: The direction of the wind in the plane (X, Z)
+    */
+    @serializeAsVector2()
+    public windDirection: Vector2 = new Vector2(0, 1);
+    /**
+    * @param {number}: Wave height, represents the height of the waves
+    */
+    @serialize()
+    public waveHeight: number = 0.4;
+    /**
+    * @param {number}: Bump height, represents the bump height related to the bump map
+    */
+    @serialize()
+    public bumpHeight: number = 0.4;
+    /**
+     * @param {boolean}: Add a smaller moving bump to less steady waves.
+     */
+    @serialize("bumpSuperimpose")
+    private _bumpSuperimpose = false;
+    @expandToProperty("_markAllSubMeshesAsMiscDirty")
+    public bumpSuperimpose: boolean;
+
+    /**
+     * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
+     */
+    @serialize("fresnelSeparate")
+    private _fresnelSeparate = false;
+    @expandToProperty("_markAllSubMeshesAsMiscDirty")
+    public fresnelSeparate: boolean;
+
+    /**
+     * @param {boolean}: bump Waves modify the reflection.
+     */
+    @serialize("bumpAffectsReflection")
+    private _bumpAffectsReflection = false;
+    @expandToProperty("_markAllSubMeshesAsMiscDirty")
+    public bumpAffectsReflection: boolean;
+
+    /**
+    * @param {number}: The water color blended with the refraction (near)
+    */
+    @serializeAsColor3()
+    public waterColor: Color3 = new Color3(0.1, 0.1, 0.6);
+    /**
+    * @param {number}: The blend factor related to the water color
+    */
+    @serialize()
+    public colorBlendFactor: number = 0.2;
+    /**
+     * @param {number}: The water color blended with the reflection (far)
+     */
+    @serializeAsColor3()
+    public waterColor2: Color3 = new Color3(0.1, 0.1, 0.6);
+    /**
+     * @param {number}: The blend factor related to the water color (reflection, far)
+     */
+    @serialize()
+    public colorBlendFactor2: number = 0.2;
+    /**
+    * @param {number}: Represents the maximum length of a wave
+    */
+    @serialize()
+    public waveLength: number = 0.1;
+
+    /**
+    * @param {number}: Defines the waves speed
+    */
+    @serialize()
+    public waveSpeed: number = 1.0;
+
+    protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
+
+    /*
+    * Private members
+    */
+    private _mesh: Nullable<AbstractMesh> = null;
+
+    private _refractionRTT: Nullable<RenderTargetTexture>;
+    private _reflectionRTT: Nullable<RenderTargetTexture>;
+
+    private _reflectionTransform: Matrix = Matrix.Zero();
+    private _lastTime: number = 0;
+    private _lastDeltaTime: number = 0;
+
+    private _renderId: number;
+
+    private _useLogarithmicDepth: boolean;
+
+    private _waitingRenderList: Nullable<string[]>;
+
+    /**
+     * Gets a boolean indicating that current material needs to register RTT
+     */
+    public get hasRenderTargetTextures(): boolean {
+        return true;
+        }
+
+    /**
+    * Constructor
+    */
+    constructor(name: string, scene: Scene, public renderTargetSize: Vector2 = new Vector2(512, 512)) {
+        super(name, scene);
+
+        this._createRenderTargets(scene, renderTargetSize);
+
+        // Create render targets
+        this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
+            this._renderTargets.reset();
+            this._renderTargets.push(<RenderTargetTexture>this._reflectionRTT);
+            this._renderTargets.push(<RenderTargetTexture>this._refractionRTT);
+
+            return this._renderTargets;
+        };
+    }
+
+    @serialize()
+    public get useLogarithmicDepth(): boolean {
+        return this._useLogarithmicDepth;
+    }
+
+    public set useLogarithmicDepth(value: boolean) {
+        this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+        this._markAllSubMeshesAsMiscDirty();
+    }
+
+    // Get / Set
+    public get refractionTexture(): Nullable<RenderTargetTexture> {
+        return this._refractionRTT;
+    }
+
+    public get reflectionTexture(): Nullable<RenderTargetTexture> {
+        return this._reflectionRTT;
+    }
+
+    // Methods
+    public addToRenderList(node: any): void {
+        if (this._refractionRTT && this._refractionRTT.renderList) {
+            this._refractionRTT.renderList.push(node);
+        }
+
+        if (this._reflectionRTT && this._reflectionRTT.renderList) {
+            this._reflectionRTT.renderList.push(node);
+        }
+    }
+
+    public enableRenderTargets(enable: boolean): void {
+        var refreshRate = enable ? 1 : 0;
+
+        if (this._refractionRTT) {
+            this._refractionRTT.refreshRate = refreshRate;
+        }
+
+        if (this._reflectionRTT) {
+            this._reflectionRTT.refreshRate = refreshRate;
+        }
+    }
+
+    public getRenderList(): Nullable<AbstractMesh[]> {
+        return this._refractionRTT ? this._refractionRTT.renderList : [];
+    }
+
+    public get renderTargetsEnabled(): boolean {
+        return !(this._refractionRTT && this._refractionRTT.refreshRate === 0);
+    }
+
+    public needAlphaBlending(): boolean {
+        return (this.alpha < 1.0);
+    }
+
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
+            }
+        }
+
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new WaterMaterialDefines();
+        }
+
+        var defines = <WaterMaterialDefines>subMesh._materialDefines;
+        var scene = this.getScene();
+
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (this._renderId === scene.getRenderId()) {
+                return true;
+            }
+        }
+
+        var engine = scene.getEngine();
+
+        // Textures
+        if (defines._areTexturesDirty) {
+            defines._needUVs = false;
+            if (scene.texturesEnabled) {
+                if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
+                    if (!this.bumpTexture.isReady()) {
+                        return false;
+                    } else {
+                        defines._needUVs = true;
+                        defines.BUMP = true;
+                    }
+                }
+
+                if (StandardMaterial.ReflectionTextureEnabled) {
+                    defines.REFLECTION = true;
+                }
+            }
+        }
+
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+
+        MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
+
+        if (defines._areMiscDirty) {
+            if (this._fresnelSeparate) {
+                defines.FRESNELSEPARATE = true;
+            }
+
+            if (this._bumpSuperimpose) {
+                defines.BUMPSUPERIMPOSE = true;
+            }
+
+            if (this._bumpAffectsReflection) {
+                defines.BUMPAFFECTSREFLECTION = true;
+            }
+        }
+
+        // Lights
+        defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
+
+        // Attribs
+        MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
+
+        // Configure this
+        this._mesh = mesh;
+
+        if (this._waitingRenderList) {
+            for (var i = 0; i < this._waitingRenderList.length; i++) {
+                this.addToRenderList(scene.getNodeByID(this._waitingRenderList[i]));
+            }
+
+            this._waitingRenderList = null;
+        }
+
+        // Get correct effect
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            // Fallbacks
+            var fallbacks = new EffectFallbacks();
+            if (defines.FOG) {
+                fallbacks.addFallback(1, "FOG");
+            }
+
+            if (defines.LOGARITHMICDEPTH) {
+                fallbacks.addFallback(0, "LOGARITHMICDEPTH");
+            }
+
+            MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+
+            if (defines.NUM_BONE_INFLUENCERS > 0) {
+                fallbacks.addCPUSkinningFallback(0, mesh);
+            }
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+
+            if (defines.NORMAL) {
+                attribs.push(VertexBuffer.NormalKind);
+            }
+
+            if (defines.UV1) {
+                attribs.push(VertexBuffer.UVKind);
+            }
+
+            if (defines.UV2) {
+                attribs.push(VertexBuffer.UV2Kind);
+            }
+
+            if (defines.VERTEXCOLOR) {
+                attribs.push(VertexBuffer.ColorKind);
+            }
+
+            MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
+            // Legacy browser patch
+            var shaderName = "water";
+            var join = defines.toString();
+            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                "vFogInfos", "vFogColor", "pointSize",
+                "vNormalInfos",
+                "mBones",
+                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "normalMatrix",
+                "logarithmicDepthConstant",
+
+                // Water
+                "worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
+                "cameraPosition", "bumpHeight", "waveHeight", "waterColor", "waterColor2", "colorBlendFactor", "colorBlendFactor2", "waveSpeed"
+            ];
+            var samplers = ["normalSampler",
+                // Water
+                "refractionSampler", "reflectionSampler"
+            ];
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: this.maxSimultaneousLights
+            });
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: fallbacks,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }
+                }, engine), defines);
+
+        }
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
+
+        this._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
+
+        return true;
+    }
+
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
+
+        var defines = <WaterMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
+
+        var effect = subMesh.effect;
+        if (!effect || !this._mesh) {
+            return;
+        }
+        this._activeEffect = effect;
+
+        // Matrices
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+        // Bones
+        MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+
+        if (this._mustRebind(scene, effect)) {
+            // Textures
+            if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
+                this._activeEffect.setTexture("normalSampler", this.bumpTexture);
+
+                this._activeEffect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
+                this._activeEffect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
+            }
+            // Clip plane
+            MaterialHelper.BindClipPlane(this._activeEffect, scene);
+
+            // Point size
+            if (this.pointsCloud) {
+                this._activeEffect.setFloat("pointSize", this.pointSize);
+            }
+
+            MaterialHelper.BindEyePosition(effect, scene);
+        }
+
+        this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+
+        if (defines.SPECULARTERM) {
+            this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+        }
+
+        if (scene.lightsEnabled && !this.disableLighting) {
+            MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
+        }
+
+        // View
+        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
+        }
+
+        // Fog
+        MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+
+        // Log. depth
+        MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
+
+        // Water
+        if (StandardMaterial.ReflectionTextureEnabled) {
+            this._activeEffect.setTexture("refractionSampler", this._refractionRTT);
+            this._activeEffect.setTexture("reflectionSampler", this._reflectionRTT);
+        }
+
+        var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
+
+        // Add delta time. Prevent adding delta time if it hasn't changed.
+        let deltaTime = scene.getEngine().getDeltaTime();
+        if (deltaTime !== this._lastDeltaTime) {
+            this._lastDeltaTime = deltaTime;
+            this._lastTime += this._lastDeltaTime;
+        }
+
+        this._activeEffect.setMatrix("worldReflectionViewProjection", wrvp);
+        this._activeEffect.setVector2("windDirection", this.windDirection);
+        this._activeEffect.setFloat("waveLength", this.waveLength);
+        this._activeEffect.setFloat("time", this._lastTime / 100000);
+        this._activeEffect.setFloat("windForce", this.windForce);
+        this._activeEffect.setFloat("waveHeight", this.waveHeight);
+        this._activeEffect.setFloat("bumpHeight", this.bumpHeight);
+        this._activeEffect.setColor4("waterColor", this.waterColor, 1.0);
+        this._activeEffect.setFloat("colorBlendFactor", this.colorBlendFactor);
+        this._activeEffect.setColor4("waterColor2", this.waterColor2, 1.0);
+        this._activeEffect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
+        this._activeEffect.setFloat("waveSpeed", this.waveSpeed);
+
+        this._afterBind(mesh, this._activeEffect);
+    }
+
+    private _createRenderTargets(scene: Scene, renderTargetSize: Vector2): void {
+        // Render targets
+        this._refractionRTT = new RenderTargetTexture(name + "_refraction", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
+        this._refractionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
+        this._refractionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
+        this._refractionRTT.ignoreCameraViewport = true;
+
+        this._reflectionRTT = new RenderTargetTexture(name + "_reflection", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
+        this._reflectionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
+        this._reflectionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
+        this._reflectionRTT.ignoreCameraViewport = true;
+
+        var isVisible: boolean;
+        var clipPlane: Nullable<Plane> = null;
+        var savedViewMatrix: Matrix;
+        var mirrorMatrix = Matrix.Zero();
+
+        this._refractionRTT.onBeforeRender = () => {
+            if (this._mesh) {
+                isVisible = this._mesh.isVisible;
+                this._mesh.isVisible = false;
+            }
+            // Clip plane
+            clipPlane = scene.clipPlane;
+
+            var positiony = this._mesh ? this._mesh.position.y : 0.0;
+            scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony + 0.05, 0), new Vector3(0, 1, 0));
+        };
+
+        this._refractionRTT.onAfterRender = () => {
+            if (this._mesh) {
+                this._mesh.isVisible = isVisible;
+            }
+
+            // Clip plane
+            scene.clipPlane = clipPlane;
+        };
+
+        this._reflectionRTT.onBeforeRender = () => {
+            if (this._mesh) {
+                isVisible = this._mesh.isVisible;
+                this._mesh.isVisible = false;
+            }
+
+            // Clip plane
+            clipPlane = scene.clipPlane;
+
+            var positiony = this._mesh ? this._mesh.position.y : 0.0;
+            scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony - 0.05, 0), new Vector3(0, -1, 0));
+
+            // Transform
+            Matrix.ReflectionToRef(scene.clipPlane, mirrorMatrix);
+            savedViewMatrix = scene.getViewMatrix();
+
+            mirrorMatrix.multiplyToRef(savedViewMatrix, this._reflectionTransform);
+            scene.setTransformMatrix(this._reflectionTransform, scene.getProjectionMatrix());
+            scene.getEngine().cullBackFaces = false;
+            scene._mirroredCameraPosition = Vector3.TransformCoordinates((<Camera>scene.activeCamera).position, mirrorMatrix);
+        };
+
+        this._reflectionRTT.onAfterRender = () => {
+            if (this._mesh) {
+                this._mesh.isVisible = isVisible;
+            }
+
+            // Clip plane
+            scene.clipPlane = clipPlane;
+
+            // Transform
+            scene.setTransformMatrix(savedViewMatrix, scene.getProjectionMatrix());
+            scene.getEngine().cullBackFaces = true;
+            scene._mirroredCameraPosition = null;
+        };
+    }
+
+    public getAnimatables(): IAnimatable[] {
+        var results = [];
+
+        if (this.bumpTexture && this.bumpTexture.animations && this.bumpTexture.animations.length > 0) {
+            results.push(this.bumpTexture);
+        }
+        if (this._reflectionRTT && this._reflectionRTT.animations && this._reflectionRTT.animations.length > 0) {
+            results.push(this._reflectionRTT);
+        }
+        if (this._refractionRTT && this._refractionRTT.animations && this._refractionRTT.animations.length > 0) {
+            results.push(this._refractionRTT);
+        }
+
+        return results;
+    }
+
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
+
+        if (this._bumpTexture) {
+            activeTextures.push(this._bumpTexture);
+        }
+
+        return activeTextures;
+    }
+
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
+        }
+
+        if (this._bumpTexture === texture) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        if (this.bumpTexture) {
+            this.bumpTexture.dispose();
+        }
+
+        var index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._refractionRTT);
+        if (index != -1) {
+            this.getScene().customRenderTargets.splice(index, 1);
+        }
+        index = -1;
+        index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._reflectionRTT);
+        if (index != -1) {
+            this.getScene().customRenderTargets.splice(index, 1);
+        }
+
+        if (this._reflectionRTT) {
+            this._reflectionRTT.dispose();
+        }
+        if (this._refractionRTT) {
+            this._refractionRTT.dispose();
+        }
+
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): WaterMaterial {
+        return SerializationHelper.Clone(() => new WaterMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.WaterMaterial";
+
+        serializationObject.renderList = [];
+        if (this._refractionRTT && this._refractionRTT.renderList) {
+            for (var i = 0; i < this._refractionRTT.renderList.length; i++) {
+                serializationObject.renderList.push(this._refractionRTT.renderList[i].id);
+            }
+        }
+
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "WaterMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): WaterMaterial {
+        var mat = SerializationHelper.Parse(() => new WaterMaterial(source.name, scene), source, scene, rootUrl);
+        mat._waitingRenderList = source.renderList;
+
+        return mat;
+    }
+
+    public static CreateDefaultMesh(name: string, scene: Scene): Mesh {
+        var mesh = Mesh.CreateGround(name, 512, 512, 32, scene, false);
+        return mesh;
+    }
+}

+ 31 - 0
materialsLibrary/tsconfig.json

@@ -0,0 +1,31 @@
+{
+  "compilerOptions": {
+      "experimentalDecorators": true,
+      "module": "commonjs",
+      "target": "es5",
+      "noImplicitAny": true,
+      "noImplicitReturns": true,
+      "noImplicitThis": true,
+      "noUnusedLocals": true,
+      "strictNullChecks": true,
+      "declaration": true,
+      "sourceMap": true,
+      "lib": [
+          "es5",
+          "dom",
+          "es2015.promise",
+          "es2015.collection",
+          "es2015.iterable"
+      ],
+      "skipDefaultLibCheck": true,
+      "skipLibCheck": true,
+      "baseUrl": "./src/",
+      "rootDir": "./src/",
+      "paths": {
+          "babylonjs": [
+              "../../dist/preview release/babylon.d.ts"
+          ]
+      },
+      "outDir": "./build"
+  }
+}

+ 76 - 0
materialsLibrary/webpack.config.js

@@ -0,0 +1,76 @@
+const path = require('path');
+const webpack = require('webpack');
+const DtsBundleWebpack = require('dts-bundle-webpack');
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+
+module.exports = {
+    context: __dirname,
+    entry: {
+        'babylonjs-materials': path.resolve(__dirname, './src/legacy.ts'),
+    },
+    output: {
+        path: path.resolve(__dirname, '../dist/preview release/gui'),
+        filename: 'babylon.materials.min.js',
+        libraryTarget: 'umd',
+        library: {
+            root: ["MATLIB"],
+            amd: "babylonjs-materials",
+            commonjs: "babylonjs-materials"
+        },
+        umdNamedDefine: true,
+        //devtoolModuleFilenameTemplate: "[absolute-resource-path]"
+    },
+    resolve: {
+        extensions: [".js", '.ts']
+    },
+    externals: {
+        babylonjs: {
+            root: "BABYLON",
+            commonjs: "babylonjs",
+            commonjs2: "babylonjs",
+            amd: "babylonjs"
+        }
+    },
+    devtool: "source-map",
+    module: {
+        rules: [{
+            test: /\.tsx?$/,
+            loader: "ts-loader",
+            exclude: /node_modules/
+        },
+        {
+            test: /\.fx$/,
+            use: [{
+                loader: path.resolve(__dirname, '../Tools/WebpackShaderLoader/index.js')
+            }]
+        }]
+    },
+    mode: "production",
+    devServer: {
+        contentBase: path.join(__dirname, "dist"),
+        compress: false,
+        //open: true,
+        port: 9000
+    },
+    plugins: [
+        new CleanWebpackPlugin([
+            path.resolve(__dirname, './src/**/*.js'),
+            path.resolve(__dirname, './src/**/*.map')
+        ]),
+        // moved out of here due to the way gulp works...
+        /*new DtsBundleWebpack({
+            name: "babylonjs-gui",
+            main: path.resolve(__dirname, '../dist/preview release/gui/build/index.d.ts'),
+            out: path.resolve(__dirname, '../dist/preview release/gui/babylon.gui.module.d.ts'),
+            baseDir: path.resolve(__dirname, '../dist/preview release/gui/build/'),
+            headerText: "BabylonJS GUI"
+        }),*/
+        new webpack.WatchIgnorePlugin([
+            /\.js$/,
+            /\.d\.ts$/
+        ])
+    ],
+    watchOptions: {
+        ignored: [path.resolve(__dirname, './dist/**/*.*'), 'node_modules']
+    }
+}