Browse Source

Fixing folder issues
Adding support for instanced bones

David Catuhe 10 years ago
parent
commit
cb1970c891
41 changed files with 3932 additions and 30 deletions
  1. 15 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.d.ts
  2. 142 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.js
  3. 134 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.ts
  4. 48 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.d.ts
  5. 309 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.js
  6. 322 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.ts
  7. 81 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.d.ts
  8. 491 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js
  9. 378 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.ts
  10. 37 0
      Babylon/Materials/Textures/babylon.baseTexture.d.ts
  11. 156 0
      Babylon/Materials/Textures/babylon.baseTexture.js
  12. 157 0
      Babylon/Materials/Textures/babylon.baseTexture.ts
  13. 13 0
      Babylon/Materials/Textures/babylon.cubeTexture.d.ts
  14. 74 0
      Babylon/Materials/Textures/babylon.cubeTexture.js
  15. 70 0
      Babylon/Materials/Textures/babylon.cubeTexture.ts
  16. 14 0
      Babylon/Materials/Textures/babylon.dynamicTexture.d.ts
  17. 108 0
      Babylon/Materials/Textures/babylon.dynamicTexture.js
  18. 97 0
      Babylon/Materials/Textures/babylon.dynamicTexture.ts
  19. 10 0
      Babylon/Materials/Textures/babylon.mirrorTexture.d.ts
  20. 56 0
      Babylon/Materials/Textures/babylon.mirrorTexture.js
  21. 48 0
      Babylon/Materials/Textures/babylon.mirrorTexture.ts
  22. 10 0
      Babylon/Materials/Textures/babylon.rawTexture.d.ts
  23. 58 0
      Babylon/Materials/Textures/babylon.rawTexture.js
  24. 30 0
      Babylon/Materials/Textures/babylon.rawTexture.ts
  25. 30 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.d.ts
  26. 190 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.js
  27. 182 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.ts
  28. 50 0
      Babylon/Materials/Textures/babylon.texture.d.ts
  29. 221 0
      Babylon/Materials/Textures/babylon.texture.js
  30. 235 0
      Babylon/Materials/Textures/babylon.texture.ts
  31. 9 0
      Babylon/Materials/Textures/babylon.videoTexture.d.ts
  32. 68 0
      Babylon/Materials/Textures/babylon.videoTexture.js
  33. 60 0
      Babylon/Materials/Textures/babylon.videoTexture.ts
  34. 1 1
      Babylon/Mesh/babylon.InstancedMesh.ts
  35. 2 2
      Babylon/Mesh/babylon.mesh.js
  36. 3 3
      Babylon/Mesh/babylon.mesh.ts
  37. 8 8
      Babylon/Shaders/default.vertex.fx
  38. 3 3
      Babylon/babylon.engine.js
  39. 2 3
      Babylon/babylon.engine.ts
  40. 6 6
      babylon.2.0-alpha.debug.js
  41. 4 4
      babylon.2.0-alpha.js

+ 15 - 0
Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.d.ts

@@ -0,0 +1,15 @@
+declare module BABYLON {
+    class CustomProceduralTexture extends ProceduralTexture {
+        private _animate;
+        private _time;
+        private _config;
+        private _texturePath;
+        constructor(name: string, texturePath: any, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        private loadJson(jsonUrl);
+        public isReady(): boolean;
+        public render(useCameraPostProcess?: boolean): void;
+        public updateTextures(): void;
+        public updateShaderUniforms(): void;
+        public animate : boolean;
+    }
+}

+ 142 - 0
Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.js

@@ -0,0 +1,142 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var CustomProceduralTexture = (function (_super) {
+        __extends(CustomProceduralTexture, _super);
+        function CustomProceduralTexture(name, texturePath, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, null, scene, fallbackTexture, generateMipMaps);
+            this._animate = true;
+            this._time = 0;
+            this._texturePath = texturePath;
+
+            //Try to load json
+            this.loadJson(texturePath);
+            this.refreshRate = 1;
+        }
+        CustomProceduralTexture.prototype.loadJson = function (jsonUrl) {
+            var _this = this;
+            var that = this;
+
+            function noConfigFile() {
+                BABYLON.Tools.Log("No config file found in " + jsonUrl + " trying to use ShaderStore or DOM element");
+                try  {
+                    that.setFragment(that._texturePath);
+                } catch (ex) {
+                    BABYLON.Tools.Error("No json or ShaderStore or DOM element found for CustomProceduralTexture");
+                }
+            }
+
+            var configFileUrl = jsonUrl + "/config.json";
+            var xhr = new XMLHttpRequest();
+
+            xhr.open("GET", configFileUrl, true);
+            xhr.addEventListener("load", function () {
+                if (xhr.status === 200 || BABYLON.Tools.ValidateXHRData(xhr, 1)) {
+                    try  {
+                        _this._config = JSON.parse(xhr.response);
+
+                        _this.updateShaderUniforms();
+                        _this.updateTextures();
+                        _this.setFragment(_this._texturePath + "/custom");
+
+                        _this._animate = _this._config.animate;
+                        _this.refreshRate = _this._config.refreshrate;
+                    } catch (ex) {
+                        noConfigFile();
+                    }
+                } else {
+                    noConfigFile();
+                }
+            }, false);
+
+            xhr.addEventListener("error", function (event) {
+                noConfigFile();
+            }, false);
+
+            try  {
+                xhr.send();
+            } catch (ex) {
+                BABYLON.Tools.Error("CustomProceduralTexture: Error on XHR send request.");
+            }
+        };
+
+        CustomProceduralTexture.prototype.isReady = function () {
+            if (!_super.prototype.isReady.call(this)) {
+                return false;
+            }
+
+            for (var name in this._textures) {
+                var texture = this._textures[name];
+
+                if (!texture.isReady()) {
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        CustomProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            if (this._animate) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            _super.prototype.render.call(this, useCameraPostProcess);
+        };
+
+        CustomProceduralTexture.prototype.updateTextures = function () {
+            for (var i = 0; i < this._config.sampler2Ds.length; i++) {
+                this.setTexture(this._config.sampler2Ds[i].sample2Dname, new BABYLON.Texture(this._texturePath + "/" + this._config.sampler2Ds[i].textureRelativeUrl, this.getScene()));
+            }
+        };
+
+        CustomProceduralTexture.prototype.updateShaderUniforms = function () {
+            if (this._config) {
+                for (var j = 0; j < this._config.uniforms.length; j++) {
+                    var uniform = this._config.uniforms[j];
+
+                    switch (uniform.type) {
+                        case "float":
+                            this.setFloat(uniform.name, uniform.value);
+                            break;
+                        case "color3":
+                            this.setColor3(uniform.name, new BABYLON.Color3(uniform.r, uniform.g, uniform.b));
+                            break;
+                        case "color4":
+                            this.setColor4(uniform.name, new BABYLON.Color4(uniform.r, uniform.g, uniform.b, uniform.a));
+                            break;
+                        case "vector2":
+                            this.setVector2(uniform.name, new BABYLON.Vector2(uniform.x, uniform.y));
+                            break;
+                        case "vector3":
+                            this.setVector3(uniform.name, new BABYLON.Vector3(uniform.x, uniform.y, uniform.z));
+                            break;
+                    }
+                }
+            }
+
+            this.setFloat("time", this._time);
+        };
+
+        Object.defineProperty(CustomProceduralTexture.prototype, "animate", {
+            get: function () {
+                return this._animate;
+            },
+            set: function (value) {
+                this._animate = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return CustomProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.CustomProceduralTexture = CustomProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.customProceduralTexture.js.map

+ 134 - 0
Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.ts

@@ -0,0 +1,134 @@
+module BABYLON {
+    export class CustomProceduralTexture extends ProceduralTexture {
+        private _animate: boolean = true;
+        private _time: number = 0;
+        private _config: any;
+        private _texturePath: any;
+
+        constructor(name: string, texturePath: any, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, null, scene, fallbackTexture, generateMipMaps);
+            this._texturePath = texturePath;
+
+            //Try to load json
+            this.loadJson(texturePath);
+            this.refreshRate = 1;
+        }
+
+        private loadJson(jsonUrl: string): void {
+            var that = this;
+
+            function noConfigFile() {
+                BABYLON.Tools.Log("No config file found in " + jsonUrl + " trying to use ShaderStore or DOM element");
+                try {
+                    that.setFragment(that._texturePath);
+                }
+                catch (ex) {
+                    BABYLON.Tools.Error("No json or ShaderStore or DOM element found for CustomProceduralTexture");
+                }
+            }
+
+            var configFileUrl = jsonUrl + "/config.json";
+            var xhr: XMLHttpRequest = new XMLHttpRequest();
+
+            xhr.open("GET", configFileUrl, true);
+            xhr.addEventListener("load", () => {
+                if (xhr.status === 200 || BABYLON.Tools.ValidateXHRData(xhr, 1)) {
+                    try {
+                        this._config = JSON.parse(xhr.response);
+
+                        this.updateShaderUniforms();
+                        this.updateTextures();
+                        this.setFragment(this._texturePath + "/custom");
+
+                        this._animate = this._config.animate;
+                        this.refreshRate = this._config.refreshrate;
+                    }
+                    catch (ex) {
+                        noConfigFile();
+                    }
+                }
+                else {
+                    noConfigFile();
+                }
+            }, false);
+
+            xhr.addEventListener("error", event => {
+                noConfigFile();
+            }, false);
+
+            try {
+                xhr.send();
+            }
+            catch (ex) {
+                BABYLON.Tools.Error("CustomProceduralTexture: Error on XHR send request.");
+            }
+        }
+
+        public isReady(): boolean {
+            if (!super.isReady()) {
+                return false;
+            }
+
+            for (var name in this._textures) {
+                var texture = this._textures[name];
+
+                if (!texture.isReady()) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public render(useCameraPostProcess?: boolean): void {
+            if (this._animate) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            super.render(useCameraPostProcess);
+        }
+
+        public updateTextures(): void {
+            for (var i = 0; i < this._config.sampler2Ds.length; i++) {
+                this.setTexture(this._config.sampler2Ds[i].sample2Dname, new Texture(this._texturePath + "/" + this._config.sampler2Ds[i].textureRelativeUrl, this.getScene()));
+            }
+        }
+
+        public updateShaderUniforms(): void {
+            if (this._config) {
+                for (var j = 0; j < this._config.uniforms.length; j++) {
+                    var uniform = this._config.uniforms[j];
+
+                    switch (uniform.type) {
+                        case "float":
+                            this.setFloat(uniform.name, uniform.value);
+                            break;
+                        case "color3":
+                            this.setColor3(uniform.name, new Color3(uniform.r, uniform.g, uniform.b));
+                            break;
+                        case "color4":
+                            this.setColor4(uniform.name, new Color4(uniform.r, uniform.g, uniform.b, uniform.a));
+                            break;
+                        case "vector2":
+                            this.setVector2(uniform.name, new Vector2(uniform.x, uniform.y));
+                            break;
+                        case "vector3":
+                            this.setVector3(uniform.name, new Vector3(uniform.x, uniform.y, uniform.z));
+                            break;
+                    }
+                }
+            }
+
+            this.setFloat("time", this._time);
+        }
+
+        public get animate(): boolean {
+            return this._animate;
+        }
+
+        public set animate(value: boolean) {
+            this._animate = value;
+        }
+    }
+}

+ 48 - 0
Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.d.ts

@@ -0,0 +1,48 @@
+declare module BABYLON {
+    class ProceduralTexture extends Texture {
+        private _size;
+        public _generateMipMaps: boolean;
+        private _doNotChangeAspectRatio;
+        private _currentRefreshId;
+        private _refreshRate;
+        private _vertexBuffer;
+        private _indexBuffer;
+        private _effect;
+        private _vertexDeclaration;
+        private _vertexStrideSize;
+        private _uniforms;
+        private _samplers;
+        private _fragment;
+        public _textures: Texture[];
+        private _floats;
+        private _floatsArrays;
+        private _colors3;
+        private _colors4;
+        private _vectors2;
+        private _vectors3;
+        private _matrices;
+        private _fallbackTexture;
+        private _fallbackTextureUsed;
+        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public reset(): void;
+        public isReady(): boolean;
+        public resetRefreshCounter(): void;
+        public setFragment(fragment: any): void;
+        public refreshRate : number;
+        public _shouldRender(): boolean;
+        public getRenderSize(): number;
+        public resize(size: any, generateMipMaps: any): void;
+        private _checkUniform(uniformName);
+        public setTexture(name: string, texture: Texture): ProceduralTexture;
+        public setFloat(name: string, value: number): ProceduralTexture;
+        public setFloats(name: string, value: number[]): ProceduralTexture;
+        public setColor3(name: string, value: Color3): ProceduralTexture;
+        public setColor4(name: string, value: Color4): ProceduralTexture;
+        public setVector2(name: string, value: Vector2): ProceduralTexture;
+        public setVector3(name: string, value: Vector3): ProceduralTexture;
+        public setMatrix(name: string, value: Matrix): ProceduralTexture;
+        public render(useCameraPostProcess?: boolean): void;
+        public clone(): ProceduralTexture;
+        public dispose(): void;
+    }
+}

+ 309 - 0
Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.js

@@ -0,0 +1,309 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var ProceduralTexture = (function (_super) {
+        __extends(ProceduralTexture, _super);
+        function ProceduralTexture(name, size, fragment, scene, fallbackTexture, generateMipMaps) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            _super.call(this, null, scene, !generateMipMaps);
+            this._currentRefreshId = -1;
+            this._refreshRate = 1;
+            this._vertexDeclaration = [2];
+            this._vertexStrideSize = 2 * 4;
+            this._uniforms = new Array();
+            this._samplers = new Array();
+            this._textures = new Array();
+            this._floats = new Array();
+            this._floatsArrays = {};
+            this._colors3 = new Array();
+            this._colors4 = new Array();
+            this._vectors2 = new Array();
+            this._vectors3 = new Array();
+            this._matrices = new Array();
+            this._fallbackTextureUsed = false;
+
+            scene._proceduralTextures.push(this);
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+
+            this.setFragment(fragment);
+
+            this._fallbackTexture = fallbackTexture;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // VBO
+            var vertices = [];
+            vertices.push(1, 1);
+            vertices.push(-1, 1);
+            vertices.push(-1, -1);
+            vertices.push(1, -1);
+
+            this._vertexBuffer = scene.getEngine().createVertexBuffer(vertices);
+
+            // Indices
+            var indices = [];
+            indices.push(0);
+            indices.push(1);
+            indices.push(2);
+
+            indices.push(0);
+            indices.push(2);
+            indices.push(3);
+
+            this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+        }
+        ProceduralTexture.prototype.reset = function () {
+            if (this._effect === undefined) {
+                return;
+            }
+            var engine = this.getScene().getEngine();
+            engine._releaseEffect(this._effect);
+        };
+
+        ProceduralTexture.prototype.isReady = function () {
+            var _this = this;
+            var engine = this.getScene().getEngine();
+            var shaders;
+
+            if (!this._fragment) {
+                return false;
+            }
+
+            if (this._fallbackTextureUsed) {
+                return true;
+            }
+
+            if (this._fragment.fragmentElement !== undefined) {
+                shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
+            } else {
+                shaders = { vertex: "procedural", fragment: this._fragment };
+            }
+
+            this._effect = engine.createEffect(shaders, ["position"], this._uniforms, this._samplers, "", null, null, function () {
+                _this.releaseInternalTexture();
+
+                if (_this._fallbackTexture) {
+                    _this._texture = _this._fallbackTexture._texture;
+                    _this._texture.references++;
+                }
+
+                _this._fallbackTextureUsed = true;
+            });
+
+            return this._effect.isReady();
+        };
+
+        ProceduralTexture.prototype.resetRefreshCounter = function () {
+            this._currentRefreshId = -1;
+        };
+
+        ProceduralTexture.prototype.setFragment = function (fragment) {
+            this._fragment = fragment;
+        };
+
+        Object.defineProperty(ProceduralTexture.prototype, "refreshRate", {
+            get: function () {
+                return this._refreshRate;
+            },
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            set: function (value) {
+                this._refreshRate = value;
+                this.resetRefreshCounter();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        ProceduralTexture.prototype._shouldRender = function () {
+            if (!this.isReady() || !this._texture) {
+                return false;
+            }
+
+            if (this._fallbackTextureUsed) {
+                return false;
+            }
+
+            if (this._currentRefreshId === -1) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate === this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        };
+
+        ProceduralTexture.prototype.getRenderSize = function () {
+            return this._size;
+        };
+
+        ProceduralTexture.prototype.resize = function (size, generateMipMaps) {
+            if (this._fallbackTextureUsed) {
+                return;
+            }
+
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        };
+
+        ProceduralTexture.prototype._checkUniform = function (uniformName) {
+            if (this._uniforms.indexOf(uniformName) === -1) {
+                this._uniforms.push(uniformName);
+            }
+        };
+
+        ProceduralTexture.prototype.setTexture = function (name, texture) {
+            if (this._samplers.indexOf(name) === -1) {
+                this._samplers.push(name);
+            }
+            this._textures[name] = texture;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setFloat = function (name, value) {
+            this._checkUniform(name);
+            this._floats[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setFloats = function (name, value) {
+            this._checkUniform(name);
+            this._floatsArrays[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setColor3 = function (name, value) {
+            this._checkUniform(name);
+            this._colors3[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setColor4 = function (name, value) {
+            this._checkUniform(name);
+            this._colors4[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setVector2 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors2[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setVector3 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors3[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setMatrix = function (name, value) {
+            this._checkUniform(name);
+            this._matrices[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            engine.bindFramebuffer(this._texture);
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            // Render
+            engine.enableEffect(this._effect);
+            engine.setState(false);
+
+            for (var name in this._textures) {
+                this._effect.setTexture(name, this._textures[name]);
+            }
+
+            for (name in this._floats) {
+                this._effect.setFloat(name, this._floats[name]);
+            }
+
+            for (name in this._floatsArrays) {
+                this._effect.setArray(name, this._floatsArrays[name]);
+            }
+
+            for (name in this._colors3) {
+                this._effect.setColor3(name, this._colors3[name]);
+            }
+
+            for (name in this._colors4) {
+                var color = this._colors4[name];
+                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+            }
+
+            for (name in this._vectors2) {
+                this._effect.setVector2(name, this._vectors2[name]);
+            }
+
+            for (name in this._vectors3) {
+                this._effect.setVector3(name, this._vectors3[name]);
+            }
+
+            for (name in this._matrices) {
+                this._effect.setMatrix(name, this._matrices[name]);
+            }
+
+            // VBOs
+            engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
+
+            // Draw order
+            engine.draw(true, 0, 6);
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+        };
+
+        ProceduralTexture.prototype.clone = function () {
+            var textureSize = this.getSize();
+            var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        };
+
+        ProceduralTexture.prototype.dispose = function () {
+            var index = this.getScene()._proceduralTextures.indexOf(this);
+
+            if (index >= 0) {
+                this.getScene()._proceduralTextures.splice(index, 1);
+            }
+            _super.prototype.dispose.call(this);
+        };
+        return ProceduralTexture;
+    })(BABYLON.Texture);
+    BABYLON.ProceduralTexture = ProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.proceduralTexture.js.map

+ 322 - 0
Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.ts

@@ -0,0 +1,322 @@
+module BABYLON {
+    export class ProceduralTexture extends Texture {
+        private _size: number;
+        public _generateMipMaps: boolean;
+        private _doNotChangeAspectRatio: boolean;
+        private _currentRefreshId = -1;
+        private _refreshRate = 1;
+
+        private _vertexBuffer: WebGLBuffer;
+        private _indexBuffer: WebGLBuffer;
+        private _effect: Effect;
+
+        private _vertexDeclaration = [2];
+        private _vertexStrideSize = 2 * 4;
+
+        private _uniforms = new Array<string>();
+        private _samplers = new Array<string>();
+        private _fragment: any;
+
+        public _textures = new Array<Texture>();
+        private _floats = new Array<number>();
+        private _floatsArrays = {};
+        private _colors3 = new Array<Color3>();
+        private _colors4 = new Array<Color4>();
+        private _vectors2 = new Array<Vector2>();
+        private _vectors3 = new Array<Vector3>();
+        private _matrices = new Array<Matrix>();
+
+        private _fallbackTexture: Texture;
+
+        private _fallbackTextureUsed = false;
+
+        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture?: Texture, generateMipMaps = true) {
+            super(null, scene, !generateMipMaps);
+
+            scene._proceduralTextures.push(this);
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+
+            this.setFragment(fragment);
+
+            this._fallbackTexture = fallbackTexture;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // VBO
+            var vertices = [];
+            vertices.push(1, 1);
+            vertices.push(-1, 1);
+            vertices.push(-1, -1);
+            vertices.push(1, -1);
+
+            this._vertexBuffer = scene.getEngine().createVertexBuffer(vertices);
+
+            // Indices
+            var indices = [];
+            indices.push(0);
+            indices.push(1);
+            indices.push(2);
+
+            indices.push(0);
+            indices.push(2);
+            indices.push(3);
+
+            this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+        }
+
+        public reset(): void {
+            if (this._effect === undefined) {
+                return;
+            }
+            var engine = this.getScene().getEngine();
+            engine._releaseEffect(this._effect);
+        }
+
+
+        public isReady(): boolean {
+            var engine = this.getScene().getEngine();
+            var shaders;
+
+            if (!this._fragment) {
+                return false;
+            }
+
+            if (this._fallbackTextureUsed) {
+                return true;
+            }
+
+            if (this._fragment.fragmentElement !== undefined) {
+                shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
+            }
+            else {
+                shaders = { vertex: "procedural", fragment: this._fragment };
+            }
+
+            this._effect = engine.createEffect(shaders,
+                ["position"],
+                this._uniforms,
+                this._samplers,
+                "", null, null, () => {
+                    this.releaseInternalTexture();
+
+                    if (this._fallbackTexture) {
+                        this._texture = this._fallbackTexture._texture;
+                        this._texture.references++;
+                    }
+
+                    this._fallbackTextureUsed = true;
+                });
+
+            return this._effect.isReady();
+        }
+
+        public resetRefreshCounter(): void {
+            this._currentRefreshId = -1;
+        }
+
+        public setFragment(fragment: any) {
+            this._fragment = fragment;
+        }
+
+        public get refreshRate(): number {
+            return this._refreshRate;
+        }
+
+        // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+        public set refreshRate(value: number) {
+            this._refreshRate = value;
+            this.resetRefreshCounter();
+        }
+
+        public _shouldRender(): boolean {
+            if (!this.isReady() || !this._texture) {
+                return false;
+            }
+
+            if (this._fallbackTextureUsed) {
+                return false;
+            }
+
+            if (this._currentRefreshId === -1) { // At least render once
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate === this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        }
+
+        public getRenderSize(): number {
+            return this._size;
+        }
+
+        public resize(size, generateMipMaps) {
+            if (this._fallbackTextureUsed) {
+                return;
+            }
+
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        }
+
+        private _checkUniform(uniformName): void {
+            if (this._uniforms.indexOf(uniformName) === -1) {
+                this._uniforms.push(uniformName);
+            }
+        }
+
+        public setTexture(name: string, texture: Texture): ProceduralTexture {
+            if (this._samplers.indexOf(name) === -1) {
+                this._samplers.push(name);
+            }
+            this._textures[name] = texture;
+
+            return this;
+        }
+
+        public setFloat(name: string, value: number): ProceduralTexture {
+            this._checkUniform(name);
+            this._floats[name] = value;
+
+            return this;
+        }
+
+        public setFloats(name: string, value: number[]): ProceduralTexture {
+            this._checkUniform(name);
+            this._floatsArrays[name] = value;
+
+            return this;
+        }
+
+        public setColor3(name: string, value: Color3): ProceduralTexture {
+            this._checkUniform(name);
+            this._colors3[name] = value;
+
+            return this;
+        }
+
+        public setColor4(name: string, value: Color4): ProceduralTexture {
+            this._checkUniform(name);
+            this._colors4[name] = value;
+
+            return this;
+        }
+
+        public setVector2(name: string, value: Vector2): ProceduralTexture {
+            this._checkUniform(name);
+            this._vectors2[name] = value;
+
+            return this;
+        }
+
+        public setVector3(name: string, value: Vector3): ProceduralTexture {
+            this._checkUniform(name);
+            this._vectors3[name] = value;
+
+            return this;
+        }
+
+        public setMatrix(name: string, value: Matrix): ProceduralTexture {
+            this._checkUniform(name);
+            this._matrices[name] = value;
+
+            return this;
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            engine.bindFramebuffer(this._texture);
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            // Render
+            engine.enableEffect(this._effect);
+            engine.setState(false);
+
+            // Texture
+            for (var name in this._textures) {
+                this._effect.setTexture(name, this._textures[name]);
+            }
+
+            // Float    
+            for (name in this._floats) {
+                this._effect.setFloat(name, this._floats[name]);
+            }
+
+            // Floats   
+            for (name in this._floatsArrays) {
+                this._effect.setArray(name, this._floatsArrays[name]);
+            }
+
+            // Color3        
+            for (name in this._colors3) {
+                this._effect.setColor3(name, this._colors3[name]);
+            }
+
+            // Color4      
+            for (name in this._colors4) {
+                var color = this._colors4[name];
+                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+            }
+
+            // Vector2        
+            for (name in this._vectors2) {
+                this._effect.setVector2(name, this._vectors2[name]);
+            }
+
+            // Vector3        
+            for (name in this._vectors3) {
+                this._effect.setVector3(name, this._vectors3[name]);
+            }
+
+            // Matrix      
+            for (name in this._matrices) {
+                this._effect.setMatrix(name, this._matrices[name]);
+            }
+
+            // VBOs
+            engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
+
+            // Draw order
+            engine.draw(true, 0, 6);
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+        }
+
+        public clone(): ProceduralTexture {
+            var textureSize = this.getSize();
+            var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        }
+
+        public dispose(): void {
+            var index = this.getScene()._proceduralTextures.indexOf(this);
+
+            if (index >= 0) {
+                this.getScene()._proceduralTextures.splice(index, 1);
+            }
+            super.dispose();
+        }
+    }
+} 

+ 81 - 0
Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.d.ts

@@ -0,0 +1,81 @@
+declare module BABYLON {
+    class WoodProceduralTexture extends ProceduralTexture {
+        private _ampScale;
+        private _woodColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public ampScale : number;
+        public woodColor : Color3;
+    }
+    class FireProceduralTexture extends ProceduralTexture {
+        private _time;
+        private _speed;
+        private _shift;
+        private _autoGenerateTime;
+        private _fireColors;
+        private _alphaThreshold;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public render(useCameraPostProcess?: boolean): void;
+        static PurpleFireColors : Color3[];
+        static GreenFireColors : Color3[];
+        static RedFireColors : Color3[];
+        static BlueFireColors : Color3[];
+        public fireColors : Color3[];
+        public time : number;
+        public speed : Vector2;
+        public shift : number;
+        public alphaThreshold : number;
+    }
+    class CloudProceduralTexture extends ProceduralTexture {
+        private _skyColor;
+        private _cloudColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public skyColor : Color3;
+        public cloudColor : Color3;
+    }
+    class GrassProceduralTexture extends ProceduralTexture {
+        private _grassColors;
+        private _herb1;
+        private _herb2;
+        private _herb3;
+        private _groundColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public grassColors : Color3[];
+        public groundColor : Color3;
+    }
+    class RoadProceduralTexture extends ProceduralTexture {
+        private _roadColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public roadColor : Color3;
+    }
+    class BrickProceduralTexture extends ProceduralTexture {
+        private _numberOfBricksHeight;
+        private _numberOfBricksWidth;
+        private _jointColor;
+        private _brickColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public numberOfBricksHeight : number;
+        public cloudColor : number;
+        public numberOfBricksWidth : number;
+        public jointColor : Color3;
+        public brickColor : Color3;
+    }
+    class MarbleProceduralTexture extends ProceduralTexture {
+        private _numberOfTilesHeight;
+        private _numberOfTilesWidth;
+        private _amplitude;
+        private _marbleColor;
+        private _jointColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public numberOfTilesHeight : number;
+        public numberOfTilesWidth : number;
+        public jointColor : Color3;
+        public marbleColor : Color3;
+    }
+}

+ 491 - 0
Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js

@@ -0,0 +1,491 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var WoodProceduralTexture = (function (_super) {
+        __extends(WoodProceduralTexture, _super);
+        function WoodProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "wood", scene, fallbackTexture, generateMipMaps);
+            this._ampScale = 100.0;
+            this._woodColor = new BABYLON.Color3(0.32, 0.17, 0.09);
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        WoodProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("ampScale", this._ampScale);
+            this.setColor3("woodColor", this._woodColor);
+        };
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "ampScale", {
+            get: function () {
+                return this._ampScale;
+            },
+            set: function (value) {
+                this._ampScale = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "woodColor", {
+            get: function () {
+                return this._woodColor;
+            },
+            set: function (value) {
+                this._woodColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return WoodProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.WoodProceduralTexture = WoodProceduralTexture;
+
+    var FireProceduralTexture = (function (_super) {
+        __extends(FireProceduralTexture, _super);
+        function FireProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "fire", scene, fallbackTexture, generateMipMaps);
+            this._time = 0.0;
+            this._speed = new BABYLON.Vector2(0.5, 0.3);
+            this._shift = 1.6;
+            this._autoGenerateTime = true;
+            this._alphaThreshold = 0.5;
+            this._fireColors = FireProceduralTexture.RedFireColors;
+            this.updateShaderUniforms();
+            this.refreshRate = 1;
+        }
+        FireProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("time", this._time);
+            this.setVector2("speed", this._speed);
+            this.setFloat("shift", this._shift);
+            this.setColor3("c1", this._fireColors[0]);
+            this.setColor3("c2", this._fireColors[1]);
+            this.setColor3("c3", this._fireColors[2]);
+            this.setColor3("c4", this._fireColors[3]);
+            this.setColor3("c5", this._fireColors[4]);
+            this.setColor3("c6", this._fireColors[5]);
+            this.setFloat("alphaThreshold", this._alphaThreshold);
+        };
+
+        FireProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            if (this._autoGenerateTime) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+            _super.prototype.render.call(this, useCameraPostProcess);
+        };
+
+        Object.defineProperty(FireProceduralTexture, "PurpleFireColors", {
+            get: function () {
+                return [
+                    new BABYLON.Color3(0.5, 0.0, 1.0),
+                    new BABYLON.Color3(0.9, 0.0, 1.0),
+                    new BABYLON.Color3(0.2, 0.0, 1.0),
+                    new BABYLON.Color3(1.0, 0.9, 1.0),
+                    new BABYLON.Color3(0.1, 0.1, 1.0),
+                    new BABYLON.Color3(0.9, 0.9, 1.0)
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "GreenFireColors", {
+            get: function () {
+                return [
+                    new BABYLON.Color3(0.5, 1.0, 0.0),
+                    new BABYLON.Color3(0.5, 1.0, 0.0),
+                    new BABYLON.Color3(0.3, 0.4, 0.0),
+                    new BABYLON.Color3(0.5, 1.0, 0.0),
+                    new BABYLON.Color3(0.2, 0.0, 0.0),
+                    new BABYLON.Color3(0.5, 1.0, 0.0)
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "RedFireColors", {
+            get: function () {
+                return [
+                    new BABYLON.Color3(0.5, 0.0, 0.1),
+                    new BABYLON.Color3(0.9, 0.0, 0.0),
+                    new BABYLON.Color3(0.2, 0.0, 0.0),
+                    new BABYLON.Color3(1.0, 0.9, 0.0),
+                    new BABYLON.Color3(0.1, 0.1, 0.1),
+                    new BABYLON.Color3(0.9, 0.9, 0.9)
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "BlueFireColors", {
+            get: function () {
+                return [
+                    new BABYLON.Color3(0.1, 0.0, 0.5),
+                    new BABYLON.Color3(0.0, 0.0, 0.5),
+                    new BABYLON.Color3(0.1, 0.0, 0.2),
+                    new BABYLON.Color3(0.0, 0.0, 1.0),
+                    new BABYLON.Color3(0.1, 0.2, 0.3),
+                    new BABYLON.Color3(0.0, 0.2, 0.9)
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture.prototype, "fireColors", {
+            get: function () {
+                return this._fireColors;
+            },
+            set: function (value) {
+                this._fireColors = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "time", {
+            get: function () {
+                return this._time;
+            },
+            set: function (value) {
+                this._time = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "speed", {
+            get: function () {
+                return this._speed;
+            },
+            set: function (value) {
+                this._speed = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "shift", {
+            get: function () {
+                return this._shift;
+            },
+            set: function (value) {
+                this._shift = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "alphaThreshold", {
+            get: function () {
+                return this._alphaThreshold;
+            },
+            set: function (value) {
+                this._alphaThreshold = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return FireProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.FireProceduralTexture = FireProceduralTexture;
+
+    var CloudProceduralTexture = (function (_super) {
+        __extends(CloudProceduralTexture, _super);
+        function CloudProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "cloud", scene, fallbackTexture, generateMipMaps);
+            this._skyColor = new BABYLON.Color3(0.15, 0.68, 1.0);
+            this._cloudColor = new BABYLON.Color3(1, 1, 1);
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        CloudProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setColor3("skyColor", this._skyColor);
+            this.setColor3("cloudColor", this._cloudColor);
+        };
+
+        Object.defineProperty(CloudProceduralTexture.prototype, "skyColor", {
+            get: function () {
+                return this._skyColor;
+            },
+            set: function (value) {
+                this._skyColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(CloudProceduralTexture.prototype, "cloudColor", {
+            get: function () {
+                return this._cloudColor;
+            },
+            set: function (value) {
+                this._cloudColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return CloudProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.CloudProceduralTexture = CloudProceduralTexture;
+
+    var GrassProceduralTexture = (function (_super) {
+        __extends(GrassProceduralTexture, _super);
+        function GrassProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "grass", scene, fallbackTexture, generateMipMaps);
+            this._herb1 = new BABYLON.Color3(0.29, 0.38, 0.02);
+            this._herb2 = new BABYLON.Color3(0.36, 0.49, 0.09);
+            this._herb3 = new BABYLON.Color3(0.51, 0.6, 0.28);
+            this._groundColor = new BABYLON.Color3(1, 1, 1);
+
+            this._grassColors = [
+                new BABYLON.Color3(0.29, 0.38, 0.02),
+                new BABYLON.Color3(0.36, 0.49, 0.09),
+                new BABYLON.Color3(0.51, 0.6, 0.28)
+            ];
+
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        GrassProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setColor3("herb1Color", this._grassColors[0]);
+            this.setColor3("herb2Color", this._grassColors[1]);
+            this.setColor3("herb3Color", this._grassColors[2]);
+            this.setColor3("groundColor", this._groundColor);
+        };
+
+        Object.defineProperty(GrassProceduralTexture.prototype, "grassColors", {
+            get: function () {
+                return this._grassColors;
+            },
+            set: function (value) {
+                this._grassColors = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(GrassProceduralTexture.prototype, "groundColor", {
+            get: function () {
+                return this._groundColor;
+            },
+            set: function (value) {
+                this.groundColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return GrassProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.GrassProceduralTexture = GrassProceduralTexture;
+
+    var RoadProceduralTexture = (function (_super) {
+        __extends(RoadProceduralTexture, _super);
+        function RoadProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "road", scene, fallbackTexture, generateMipMaps);
+            this._roadColor = new BABYLON.Color3(0.53, 0.53, 0.53);
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        RoadProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setColor3("roadColor", this._roadColor);
+        };
+
+        Object.defineProperty(RoadProceduralTexture.prototype, "roadColor", {
+            get: function () {
+                return this._roadColor;
+            },
+            set: function (value) {
+                this._roadColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return RoadProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.RoadProceduralTexture = RoadProceduralTexture;
+
+    var BrickProceduralTexture = (function (_super) {
+        __extends(BrickProceduralTexture, _super);
+        function BrickProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "brick", scene, fallbackTexture, generateMipMaps);
+            this._numberOfBricksHeight = 15;
+            this._numberOfBricksWidth = 5;
+            this._jointColor = new BABYLON.Color3(0.72, 0.72, 0.72);
+            this._brickColor = new BABYLON.Color3(0.77, 0.47, 0.40);
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        BrickProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
+            this.setColor3("brickColor", this._brickColor);
+            this.setColor3("jointColor", this._jointColor);
+        };
+
+        Object.defineProperty(BrickProceduralTexture.prototype, "numberOfBricksHeight", {
+            get: function () {
+                return this._numberOfBricksHeight;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(BrickProceduralTexture.prototype, "cloudColor", {
+            set: function (value) {
+                this._numberOfBricksHeight = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(BrickProceduralTexture.prototype, "numberOfBricksWidth", {
+            get: function () {
+                return this._numberOfBricksWidth;
+            },
+            set: function (value) {
+                this._numberOfBricksHeight = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(BrickProceduralTexture.prototype, "jointColor", {
+            get: function () {
+                return this._jointColor;
+            },
+            set: function (value) {
+                this._jointColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(BrickProceduralTexture.prototype, "brickColor", {
+            get: function () {
+                return this._brickColor;
+            },
+            set: function (value) {
+                this._brickColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return BrickProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.BrickProceduralTexture = BrickProceduralTexture;
+
+    var MarbleProceduralTexture = (function (_super) {
+        __extends(MarbleProceduralTexture, _super);
+        function MarbleProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "marble", scene, fallbackTexture, generateMipMaps);
+            this._numberOfTilesHeight = 3;
+            this._numberOfTilesWidth = 3;
+            this._amplitude = 9.0;
+            this._marbleColor = new BABYLON.Color3(0.77, 0.47, 0.40);
+            this._jointColor = new BABYLON.Color3(0.72, 0.72, 0.72);
+            this.updateShaderUniforms();
+            this.refreshRate = 0;
+        }
+        MarbleProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("numberOfTilesHeight", this._numberOfTilesHeight);
+            this.setFloat("numberOfTilesWidth", this._numberOfTilesWidth);
+            this.setFloat("amplitude", this._amplitude);
+            this.setColor3("marbleColor", this._marbleColor);
+            this.setColor3("jointColor", this._jointColor);
+        };
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfTilesHeight", {
+            get: function () {
+                return this._numberOfTilesHeight;
+            },
+            set: function (value) {
+                this._numberOfTilesHeight = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfTilesWidth", {
+            get: function () {
+                return this._numberOfTilesWidth;
+            },
+            set: function (value) {
+                this._numberOfTilesWidth = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "jointColor", {
+            get: function () {
+                return this._jointColor;
+            },
+            set: function (value) {
+                this._jointColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "marbleColor", {
+            get: function () {
+                return this._marbleColor;
+            },
+            set: function (value) {
+                this._marbleColor = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return MarbleProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.MarbleProceduralTexture = MarbleProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.standardProceduralTexture.js.map

+ 378 - 0
Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.ts

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

+ 37 - 0
Babylon/Materials/Textures/babylon.baseTexture.d.ts

@@ -0,0 +1,37 @@
+declare module BABYLON {
+    class BaseTexture {
+        public name: string;
+        public delayLoadState: number;
+        public hasAlpha: boolean;
+        public getAlphaFromRGB: boolean;
+        public level: number;
+        public isCube: boolean;
+        public isRenderTarget: boolean;
+        public animations: Animation[];
+        public onDispose: () => void;
+        public coordinatesIndex: number;
+        public coordinatesMode: number;
+        public wrapU: number;
+        public wrapV: number;
+        public anisotropicFilteringLevel: number;
+        public _cachedAnisotropicFilteringLevel: number;
+        private _scene;
+        public _texture: WebGLTexture;
+        constructor(scene: Scene);
+        public getScene(): Scene;
+        public getTextureMatrix(): Matrix;
+        public getReflectionTextureMatrix(): Matrix;
+        public getInternalTexture(): WebGLTexture;
+        public isReady(): boolean;
+        public getSize(): ISize;
+        public getBaseSize(): ISize;
+        public scale(ratio: number): void;
+        public canRescale : boolean;
+        public _removeFromCache(url: string, noMipmap: boolean): void;
+        public _getFromCache(url: string, noMipmap: boolean): WebGLTexture;
+        public delayLoad(): void;
+        public releaseInternalTexture(): void;
+        public clone(): BaseTexture;
+        public dispose(): void;
+    }
+}

+ 156 - 0
Babylon/Materials/Textures/babylon.baseTexture.js

@@ -0,0 +1,156 @@
+var BABYLON;
+(function (BABYLON) {
+    var BaseTexture = (function () {
+        function BaseTexture(scene) {
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NONE;
+            this.hasAlpha = false;
+            this.getAlphaFromRGB = false;
+            this.level = 1;
+            this.isCube = false;
+            this.isRenderTarget = false;
+            this.animations = new Array();
+            this.coordinatesIndex = 0;
+            this.coordinatesMode = BABYLON.Texture.EXPLICIT_MODE;
+            this.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this.anisotropicFilteringLevel = 4;
+            this._scene = scene;
+            this._scene.textures.push(this);
+        }
+        BaseTexture.prototype.getScene = function () {
+            return this._scene;
+        };
+
+        BaseTexture.prototype.getTextureMatrix = function () {
+            return null;
+        };
+
+        BaseTexture.prototype.getReflectionTextureMatrix = function () {
+            return null;
+        };
+
+        BaseTexture.prototype.getInternalTexture = function () {
+            return this._texture;
+        };
+
+        BaseTexture.prototype.isReady = function () {
+            if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
+                return true;
+            }
+
+            if (this._texture) {
+                return this._texture.isReady;
+            }
+
+            return false;
+        };
+
+        BaseTexture.prototype.getSize = function () {
+            if (this._texture._width) {
+                return { width: this._texture._width, height: this._texture._height };
+            }
+
+            if (this._texture._size) {
+                return { width: this._texture._size, height: this._texture._size };
+            }
+
+            return { width: 0, height: 0 };
+        };
+
+        BaseTexture.prototype.getBaseSize = function () {
+            if (!this.isReady())
+                return { width: 0, height: 0 };
+
+            if (this._texture._size) {
+                return { width: this._texture._size, height: this._texture._size };
+            }
+
+            return { width: this._texture._baseWidth, height: this._texture._baseHeight };
+        };
+
+        BaseTexture.prototype.scale = function (ratio) {
+        };
+
+        Object.defineProperty(BaseTexture.prototype, "canRescale", {
+            get: function () {
+                return false;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        BaseTexture.prototype._removeFromCache = function (url, noMipmap) {
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            for (var index = 0; index < texturesCache.length; index++) {
+                var texturesCacheEntry = texturesCache[index];
+
+                if (texturesCacheEntry.url === url && texturesCacheEntry.noMipmap === noMipmap) {
+                    texturesCache.splice(index, 1);
+                    return;
+                }
+            }
+        };
+
+        BaseTexture.prototype._getFromCache = function (url, noMipmap) {
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            for (var index = 0; index < texturesCache.length; index++) {
+                var texturesCacheEntry = texturesCache[index];
+
+                if (texturesCacheEntry.url === url && texturesCacheEntry.noMipmap === noMipmap) {
+                    texturesCacheEntry.references++;
+                    return texturesCacheEntry;
+                }
+            }
+
+            return null;
+        };
+
+        BaseTexture.prototype.delayLoad = function () {
+        };
+
+        BaseTexture.prototype.releaseInternalTexture = function () {
+            if (!this._texture) {
+                return;
+            }
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            this._texture.references--;
+
+            // Final reference ?
+            if (this._texture.references === 0) {
+                var index = texturesCache.indexOf(this._texture);
+                texturesCache.splice(index, 1);
+
+                this._scene.getEngine()._releaseTexture(this._texture);
+
+                delete this._texture;
+            }
+        };
+
+        BaseTexture.prototype.clone = function () {
+            return null;
+        };
+
+        BaseTexture.prototype.dispose = function () {
+            // Remove from scene
+            var index = this._scene.textures.indexOf(this);
+
+            if (index >= 0) {
+                this._scene.textures.splice(index, 1);
+            }
+
+            if (this._texture === undefined) {
+                return;
+            }
+
+            this.releaseInternalTexture();
+
+            // Callback
+            if (this.onDispose) {
+                this.onDispose();
+            }
+        };
+        return BaseTexture;
+    })();
+    BABYLON.BaseTexture = BaseTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.baseTexture.js.map

+ 157 - 0
Babylon/Materials/Textures/babylon.baseTexture.ts

@@ -0,0 +1,157 @@
+module BABYLON {
+    export class BaseTexture {
+        public name: string;
+        public delayLoadState = Engine.DELAYLOADSTATE_NONE;
+        public hasAlpha = false;
+        public getAlphaFromRGB = false;
+        public level = 1;
+        public isCube = false;
+        public isRenderTarget = false;
+        public animations = new Array<Animation>();
+        public onDispose: () => void;
+        public coordinatesIndex = 0;
+        public coordinatesMode = Texture.EXPLICIT_MODE;
+        public wrapU = Texture.WRAP_ADDRESSMODE;
+        public wrapV = Texture.WRAP_ADDRESSMODE;
+        public anisotropicFilteringLevel = 4;
+        public _cachedAnisotropicFilteringLevel: number;
+
+        private _scene: Scene;
+        public _texture: WebGLTexture;
+
+        constructor(scene: Scene) {
+            this._scene = scene;
+            this._scene.textures.push(this);
+        }
+
+        public getScene(): Scene {
+            return this._scene;
+        }
+
+        public getTextureMatrix(): Matrix {
+            return null;
+        }
+
+        public getReflectionTextureMatrix(): Matrix {
+            return null;
+        }
+
+        public getInternalTexture(): WebGLTexture {
+            return this._texture;
+        }
+
+        public isReady(): boolean {
+            if (this.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) {
+                return true;
+            }
+
+            if (this._texture) {
+                return this._texture.isReady;
+            }
+
+            return false;
+        }
+
+        public getSize(): ISize  {
+            if (this._texture._width) {
+                return { width: this._texture._width, height: this._texture._height };
+            }
+
+            if (this._texture._size) {
+                return { width: this._texture._size, height: this._texture._size };
+            }
+
+            return { width: 0, height: 0 };
+        }
+
+        public getBaseSize(): ISize {
+            if (!this.isReady())
+                return { width: 0, height: 0 };
+
+            if (this._texture._size) {
+                return { width: this._texture._size, height: this._texture._size };
+            }
+
+            return { width: this._texture._baseWidth, height: this._texture._baseHeight };
+        }
+
+        public scale(ratio: number): void {
+        }
+
+        public get canRescale(): boolean {
+            return false;
+        }
+
+        public _removeFromCache(url: string, noMipmap: boolean): void {
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            for (var index = 0; index < texturesCache.length; index++) {
+                var texturesCacheEntry = texturesCache[index];
+
+                if (texturesCacheEntry.url === url && texturesCacheEntry.noMipmap === noMipmap) {
+                    texturesCache.splice(index, 1);
+                    return;
+                }
+            }
+        }
+
+        public _getFromCache(url: string, noMipmap: boolean): WebGLTexture {
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            for (var index = 0; index < texturesCache.length; index++) {
+                var texturesCacheEntry = texturesCache[index];
+
+                if (texturesCacheEntry.url === url && texturesCacheEntry.noMipmap === noMipmap) {
+                    texturesCacheEntry.references++;
+                    return texturesCacheEntry;
+                }
+            }
+
+            return null;
+        }
+
+        public delayLoad(): void {
+        }
+
+        public releaseInternalTexture(): void {
+            if (!this._texture) {
+                return;
+            }
+            var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
+            this._texture.references--;
+
+            // Final reference ?
+            if (this._texture.references === 0) {
+                var index = texturesCache.indexOf(this._texture);
+                texturesCache.splice(index, 1);
+
+                this._scene.getEngine()._releaseTexture(this._texture);
+
+                delete this._texture;
+            }
+        }
+
+        public clone(): BaseTexture {
+            return null;
+        }
+
+        public dispose(): void {
+            // Remove from scene
+            var index = this._scene.textures.indexOf(this);
+
+            if (index >= 0) {
+                this._scene.textures.splice(index, 1);
+            }
+
+            if (this._texture === undefined) {
+                return;
+            }
+
+            this.releaseInternalTexture();
+
+
+            // Callback
+            if (this.onDispose) {
+                this.onDispose();
+            }
+        }
+    }
+} 

+ 13 - 0
Babylon/Materials/Textures/babylon.cubeTexture.d.ts

@@ -0,0 +1,13 @@
+declare module BABYLON {
+    class CubeTexture extends BaseTexture {
+        public url: string;
+        public coordinatesMode: number;
+        private _noMipmap;
+        private _extensions;
+        private _textureMatrix;
+        constructor(rootUrl: string, scene: Scene, extensions?: string[], noMipmap?: boolean);
+        public clone(): CubeTexture;
+        public delayLoad(): void;
+        public getReflectionTextureMatrix(): Matrix;
+    }
+}

+ 74 - 0
Babylon/Materials/Textures/babylon.cubeTexture.js

@@ -0,0 +1,74 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var CubeTexture = (function (_super) {
+        __extends(CubeTexture, _super);
+        function CubeTexture(rootUrl, scene, extensions, noMipmap) {
+            _super.call(this, scene);
+            this.coordinatesMode = BABYLON.Texture.CUBIC_MODE;
+
+            this.name = rootUrl;
+            this.url = rootUrl;
+            this._noMipmap = noMipmap;
+            this.hasAlpha = false;
+
+            this._texture = this._getFromCache(rootUrl, noMipmap);
+
+            if (!extensions) {
+                extensions = ["_px.jpg", "_py.jpg", "_pz.jpg", "_nx.jpg", "_ny.jpg", "_nz.jpg"];
+            }
+
+            this._extensions = extensions;
+
+            if (!this._texture) {
+                if (!scene.useDelayedTextureLoading) {
+                    this._texture = scene.getEngine().createCubeTexture(rootUrl, scene, extensions, noMipmap);
+                } else {
+                    this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+                }
+            }
+
+            this.isCube = true;
+
+            this._textureMatrix = BABYLON.Matrix.Identity();
+        }
+        CubeTexture.prototype.clone = function () {
+            var newTexture = new BABYLON.CubeTexture(this.url, this.getScene(), this._extensions, this._noMipmap);
+
+            // Base texture
+            newTexture.level = this.level;
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+            newTexture.coordinatesIndex = this.coordinatesIndex;
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        };
+
+        // Methods
+        CubeTexture.prototype.delayLoad = function () {
+            if (this.delayLoadState != BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
+                return;
+            }
+
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
+            this._texture = this._getFromCache(this.url, this._noMipmap);
+
+            if (!this._texture) {
+                this._texture = this.getScene().getEngine().createCubeTexture(this.url, this.getScene(), this._extensions);
+            }
+        };
+
+        CubeTexture.prototype.getReflectionTextureMatrix = function () {
+            return this._textureMatrix;
+        };
+        return CubeTexture;
+    })(BABYLON.BaseTexture);
+    BABYLON.CubeTexture = CubeTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.cubeTexture.js.map

+ 70 - 0
Babylon/Materials/Textures/babylon.cubeTexture.ts

@@ -0,0 +1,70 @@
+module BABYLON {
+    export class CubeTexture extends BaseTexture {
+        public url: string;
+        public coordinatesMode = BABYLON.Texture.CUBIC_MODE;
+
+        private _noMipmap: boolean;
+        private _extensions: string[];
+        private _textureMatrix: Matrix;
+
+        constructor(rootUrl: string, scene: Scene, extensions?: string[], noMipmap?: boolean) {
+            super(scene);
+
+            this.name = rootUrl;
+            this.url = rootUrl;
+            this._noMipmap = noMipmap;
+            this.hasAlpha = false;
+
+            this._texture = this._getFromCache(rootUrl, noMipmap);
+
+            if (!extensions) {
+                extensions = ["_px.jpg", "_py.jpg", "_pz.jpg", "_nx.jpg", "_ny.jpg", "_nz.jpg"];
+            }
+
+            this._extensions = extensions;
+
+            if (!this._texture) {
+                if (!scene.useDelayedTextureLoading) {
+                    this._texture = scene.getEngine().createCubeTexture(rootUrl, scene, extensions, noMipmap);
+                } else {
+                    this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+                }
+            }
+
+            this.isCube = true;
+
+            this._textureMatrix = BABYLON.Matrix.Identity();
+        }
+
+        public clone(): CubeTexture {
+            var newTexture = new BABYLON.CubeTexture(this.url, this.getScene(), this._extensions, this._noMipmap);
+
+            // Base texture
+            newTexture.level = this.level;
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+            newTexture.coordinatesIndex = this.coordinatesIndex;
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        }
+
+        // Methods
+        public delayLoad(): void {
+            if (this.delayLoadState != BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
+                return;
+            }
+
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
+            this._texture = this._getFromCache(this.url, this._noMipmap);
+
+            if (!this._texture) {
+                this._texture = this.getScene().getEngine().createCubeTexture(this.url, this.getScene(), this._extensions);
+            }
+        }
+
+        public getReflectionTextureMatrix(): Matrix {
+            return this._textureMatrix;
+        }
+    }
+} 

+ 14 - 0
Babylon/Materials/Textures/babylon.dynamicTexture.d.ts

@@ -0,0 +1,14 @@
+declare module BABYLON {
+    class DynamicTexture extends Texture {
+        private _generateMipMaps;
+        private _canvas;
+        private _context;
+        constructor(name: string, options: any, scene: Scene, generateMipMaps: boolean, samplingMode?: number);
+        public canRescale : boolean;
+        public scale(ratio: number): void;
+        public getContext(): CanvasRenderingContext2D;
+        public update(invertY?: boolean): void;
+        public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean): void;
+        public clone(): DynamicTexture;
+    }
+}

+ 108 - 0
Babylon/Materials/Textures/babylon.dynamicTexture.js

@@ -0,0 +1,108 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var DynamicTexture = (function (_super) {
+        __extends(DynamicTexture, _super);
+        function DynamicTexture(name, options, scene, generateMipMaps, samplingMode) {
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            _super.call(this, null, scene, !generateMipMaps);
+
+            this.name = name;
+
+            this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
+            this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
+
+            this._generateMipMaps = generateMipMaps;
+
+            if (options.getContext) {
+                this._canvas = options;
+                this._texture = scene.getEngine().createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+            } else {
+                this._canvas = document.createElement("canvas");
+
+                if (options.width) {
+                    this._texture = scene.getEngine().createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+                } else {
+                    this._texture = scene.getEngine().createDynamicTexture(options, options, generateMipMaps, samplingMode);
+                }
+            }
+
+            var textureSize = this.getSize();
+
+            this._canvas.width = textureSize.width;
+            this._canvas.height = textureSize.height;
+            this._context = this._canvas.getContext("2d");
+        }
+        Object.defineProperty(DynamicTexture.prototype, "canRescale", {
+            get: function () {
+                return true;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        DynamicTexture.prototype.scale = function (ratio) {
+            var textureSize = this.getSize();
+
+            textureSize.width *= ratio;
+            textureSize.height *= ratio;
+
+            this._canvas.width = textureSize.width;
+            this._canvas.height = textureSize.height;
+
+            this.releaseInternalTexture();
+
+            this._texture = this.getScene().getEngine().createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this._samplingMode);
+        };
+
+        DynamicTexture.prototype.getContext = function () {
+            return this._context;
+        };
+
+        DynamicTexture.prototype.update = function (invertY) {
+            this.getScene().getEngine().updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY);
+        };
+
+        DynamicTexture.prototype.drawText = function (text, x, y, font, color, clearColor, invertY) {
+            var size = this.getSize();
+            if (clearColor) {
+                this._context.fillStyle = clearColor;
+                this._context.fillRect(0, 0, size.width, size.height);
+            }
+
+            this._context.font = font;
+            if (x === null) {
+                var textSize = this._context.measureText(text);
+                x = (size.width - textSize.width) / 2;
+            }
+
+            this._context.fillStyle = color;
+            this._context.fillText(text, x, y);
+
+            this.update(invertY);
+        };
+
+        DynamicTexture.prototype.clone = function () {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.DynamicTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // Dynamic Texture
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+
+            return newTexture;
+        };
+        return DynamicTexture;
+    })(BABYLON.Texture);
+    BABYLON.DynamicTexture = DynamicTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.dynamicTexture.js.map

+ 97 - 0
Babylon/Materials/Textures/babylon.dynamicTexture.ts

@@ -0,0 +1,97 @@
+module BABYLON {
+    export class DynamicTexture extends Texture {
+        private _generateMipMaps: boolean;
+        private _canvas: HTMLCanvasElement;
+        private _context: CanvasRenderingContext2D;
+
+        constructor(name: string, options: any, scene: Scene, generateMipMaps: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
+            super(null, scene, !generateMipMaps);
+
+            this.name = name;
+
+            this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
+            this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
+
+            this._generateMipMaps = generateMipMaps;
+
+            if (options.getContext) {
+                this._canvas = options;
+                this._texture = scene.getEngine().createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+            } else {
+                this._canvas = document.createElement("canvas");
+
+                if (options.width) {
+                    this._texture = scene.getEngine().createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+                } else {
+                    this._texture = scene.getEngine().createDynamicTexture(options, options, generateMipMaps, samplingMode);
+                }
+            }
+
+            var textureSize = this.getSize();
+
+            this._canvas.width = textureSize.width;
+            this._canvas.height = textureSize.height;
+            this._context = this._canvas.getContext("2d");
+        }
+
+        public get canRescale(): boolean {
+            return true;
+        }
+
+        public scale(ratio: number): void {
+            var textureSize = this.getSize();
+
+            textureSize.width *= ratio;
+            textureSize.height *= ratio;
+
+            this._canvas.width = textureSize.width;
+            this._canvas.height = textureSize.height;
+
+            this.releaseInternalTexture();
+
+            this._texture = this.getScene().getEngine().createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this._samplingMode);
+        }
+
+        public getContext(): CanvasRenderingContext2D {
+            return this._context;
+        }
+
+        public update(invertY?: boolean): void {
+            this.getScene().getEngine().updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY);
+        }
+
+        public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean) {
+            var size = this.getSize();
+            if (clearColor) {
+                this._context.fillStyle = clearColor;
+                this._context.fillRect(0, 0, size.width, size.height);
+            }
+
+            this._context.font = font;
+            if (x === null) {
+                var textSize = this._context.measureText(text);
+                x = (size.width - textSize.width) / 2;
+            }
+
+            this._context.fillStyle = color;
+            this._context.fillText(text, x, y);
+
+            this.update(invertY);
+        }
+
+        public clone(): DynamicTexture {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.DynamicTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // Dynamic Texture
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+
+            return newTexture;
+        }
+    }
+} 

+ 10 - 0
Babylon/Materials/Textures/babylon.mirrorTexture.d.ts

@@ -0,0 +1,10 @@
+declare module BABYLON {
+    class MirrorTexture extends RenderTargetTexture {
+        public mirrorPlane: Plane;
+        private _transformMatrix;
+        private _mirrorMatrix;
+        private _savedViewMatrix;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        public clone(): MirrorTexture;
+    }
+}

+ 56 - 0
Babylon/Materials/Textures/babylon.mirrorTexture.js

@@ -0,0 +1,56 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var MirrorTexture = (function (_super) {
+        __extends(MirrorTexture, _super);
+        function MirrorTexture(name, size, scene, generateMipMaps) {
+            var _this = this;
+            _super.call(this, name, size, scene, generateMipMaps, true);
+            this.mirrorPlane = new BABYLON.Plane(0, 1, 0, 1);
+            this._transformMatrix = BABYLON.Matrix.Zero();
+            this._mirrorMatrix = BABYLON.Matrix.Zero();
+
+            this.onBeforeRender = function () {
+                BABYLON.Matrix.ReflectionToRef(_this.mirrorPlane, _this._mirrorMatrix);
+                _this._savedViewMatrix = scene.getViewMatrix();
+
+                _this._mirrorMatrix.multiplyToRef(_this._savedViewMatrix, _this._transformMatrix);
+
+                scene.setTransformMatrix(_this._transformMatrix, scene.getProjectionMatrix());
+
+                scene.clipPlane = _this.mirrorPlane;
+
+                scene.getEngine().cullBackFaces = false;
+            };
+
+            this.onAfterRender = function () {
+                scene.setTransformMatrix(_this._savedViewMatrix, scene.getProjectionMatrix());
+                scene.getEngine().cullBackFaces = true;
+
+                delete scene.clipPlane;
+            };
+        }
+        MirrorTexture.prototype.clone = function () {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.MirrorTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // Mirror Texture
+            newTexture.mirrorPlane = this.mirrorPlane.clone();
+            newTexture.renderList = this.renderList.slice(0);
+
+            return newTexture;
+        };
+        return MirrorTexture;
+    })(BABYLON.RenderTargetTexture);
+    BABYLON.MirrorTexture = MirrorTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.mirrorTexture.js.map

+ 48 - 0
Babylon/Materials/Textures/babylon.mirrorTexture.ts

@@ -0,0 +1,48 @@
+module BABYLON {
+    export class MirrorTexture extends RenderTargetTexture {
+        public mirrorPlane = new BABYLON.Plane(0, 1, 0, 1);
+
+        private _transformMatrix = BABYLON.Matrix.Zero();
+        private _mirrorMatrix = BABYLON.Matrix.Zero();
+        private _savedViewMatrix: Matrix;
+
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean) {
+            super(name, size, scene, generateMipMaps, true);
+
+            this.onBeforeRender = () => {
+                BABYLON.Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);
+                this._savedViewMatrix = scene.getViewMatrix();
+
+                this._mirrorMatrix.multiplyToRef(this._savedViewMatrix, this._transformMatrix);
+
+                scene.setTransformMatrix(this._transformMatrix, scene.getProjectionMatrix());
+
+                scene.clipPlane = this.mirrorPlane;
+
+                scene.getEngine().cullBackFaces = false;
+            }
+
+            this.onAfterRender = () => {
+                scene.setTransformMatrix(this._savedViewMatrix, scene.getProjectionMatrix());
+                scene.getEngine().cullBackFaces = true;
+
+                delete scene.clipPlane;
+            }
+        }
+
+        public clone(): MirrorTexture {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.MirrorTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // Mirror Texture
+            newTexture.mirrorPlane = this.mirrorPlane.clone();
+            newTexture.renderList = this.renderList.slice(0);
+
+            return newTexture;
+        }
+    }
+} 

+ 10 - 0
Babylon/Materials/Textures/babylon.rawTexture.d.ts

@@ -0,0 +1,10 @@
+declare module BABYLON {
+    class RawTexture extends Texture {
+        constructor(data: ArrayBufferView, width: number, height: number, format: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number);
+        static CreateLuminanceTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number): RawTexture;
+        static CreateLuminanceAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number): RawTexture;
+        static CreateAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number): RawTexture;
+        static CreateRGBTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number): RawTexture;
+        static CreateRGBATexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps?: boolean, invertY?: boolean, samplingMode?: number): RawTexture;
+    }
+}

+ 58 - 0
Babylon/Materials/Textures/babylon.rawTexture.js

@@ -0,0 +1,58 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var RawTexture = (function (_super) {
+        __extends(RawTexture, _super);
+        function RawTexture(data, width, height, format, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            _super.call(this, null, scene, !generateMipMaps, invertY);
+
+            this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode);
+        }
+        // Statics
+        RawTexture.CreateLuminanceTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            return new RawTexture(data, width, height, BABYLON.Engine.TEXTUREFORMAT_LUMINANCE, scene, generateMipMaps, invertY, samplingMode);
+        };
+
+        RawTexture.CreateLuminanceAlphaTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            return new RawTexture(data, width, height, BABYLON.Engine.TEXTUREFORMAT_LUMINANCE_ALPHA, scene, generateMipMaps, invertY, samplingMode);
+        };
+
+        RawTexture.CreateAlphaTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            return new RawTexture(data, width, height, BABYLON.Engine.TEXTUREFORMAT_ALPHA, scene, generateMipMaps, invertY, samplingMode);
+        };
+
+        RawTexture.CreateRGBTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            return new RawTexture(data, width, height, BABYLON.Engine.TEXTUREFORMAT_RGB, scene, generateMipMaps, invertY, samplingMode);
+        };
+
+        RawTexture.CreateRGBATexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
+            if (typeof invertY === "undefined") { invertY = false; }
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            return new RawTexture(data, width, height, BABYLON.Engine.TEXTUREFORMAT_RGBA, scene, generateMipMaps, invertY, samplingMode);
+        };
+        return RawTexture;
+    })(BABYLON.Texture);
+    BABYLON.RawTexture = RawTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.rawTexture.js.map

+ 30 - 0
Babylon/Materials/Textures/babylon.rawTexture.ts

@@ -0,0 +1,30 @@
+module BABYLON {
+    export class RawTexture extends Texture {
+        constructor(data: ArrayBufferView, width: number, height: number, format: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
+            super(null, scene, !generateMipMaps, invertY);
+
+            this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode);
+        }
+
+        // Statics
+        public static CreateLuminanceTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
+            return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_LUMINANCE, scene, generateMipMaps, invertY, samplingMode);
+        }
+
+        public static CreateLuminanceAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
+            return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_LUMINANCE_ALPHA, scene, generateMipMaps, invertY, samplingMode);
+        }
+
+        public static CreateAlphaTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
+            return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_ALPHA, scene, generateMipMaps, invertY, samplingMode);
+        }
+
+        public static CreateRGBTexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
+            return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_RGB, scene, generateMipMaps, invertY, samplingMode);
+        }
+
+        public static CreateRGBATexture(data: ArrayBufferView, width: number, height: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): RawTexture {
+            return new RawTexture(data, width, height, Engine.TEXTUREFORMAT_RGBA, scene, generateMipMaps, invertY, samplingMode);
+        }
+    }
+}

+ 30 - 0
Babylon/Materials/Textures/babylon.renderTargetTexture.d.ts

@@ -0,0 +1,30 @@
+declare module BABYLON {
+    class RenderTargetTexture extends Texture {
+        public renderList: AbstractMesh[];
+        public renderParticles: boolean;
+        public renderSprites: boolean;
+        public coordinatesMode: number;
+        public onBeforeRender: () => void;
+        public onAfterRender: () => void;
+        public activeCamera: Camera;
+        public customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, beforeTransparents?: () => void) => void;
+        private _size;
+        public _generateMipMaps: boolean;
+        private _renderingManager;
+        public _waitingRenderList: string[];
+        private _doNotChangeAspectRatio;
+        private _currentRefreshId;
+        private _refreshRate;
+        constructor(name: string, size: any, scene: Scene, generateMipMaps?: boolean, doNotChangeAspectRatio?: boolean);
+        public resetRefreshCounter(): void;
+        public refreshRate : number;
+        public _shouldRender(): boolean;
+        public isReady(): boolean;
+        public getRenderSize(): number;
+        public canRescale : boolean;
+        public scale(ratio: number): void;
+        public resize(size: any, generateMipMaps?: boolean): void;
+        public render(useCameraPostProcess?: boolean): void;
+        public clone(): RenderTargetTexture;
+    }
+}

+ 190 - 0
Babylon/Materials/Textures/babylon.renderTargetTexture.js

@@ -0,0 +1,190 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var RenderTargetTexture = (function (_super) {
+        __extends(RenderTargetTexture, _super);
+        function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio) {
+            if (typeof doNotChangeAspectRatio === "undefined") { doNotChangeAspectRatio = true; }
+            _super.call(this, null, scene, !generateMipMaps);
+            this.renderList = new Array();
+            this.renderParticles = true;
+            this.renderSprites = false;
+            this.coordinatesMode = BABYLON.Texture.PROJECTION_MODE;
+            this._currentRefreshId = -1;
+            this._refreshRate = 1;
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+            this._doNotChangeAspectRatio = doNotChangeAspectRatio;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // Rendering groups
+            this._renderingManager = new BABYLON.RenderingManager(scene);
+        }
+        RenderTargetTexture.prototype.resetRefreshCounter = function () {
+            this._currentRefreshId = -1;
+        };
+
+        Object.defineProperty(RenderTargetTexture.prototype, "refreshRate", {
+            get: function () {
+                return this._refreshRate;
+            },
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            set: function (value) {
+                this._refreshRate = value;
+                this.resetRefreshCounter();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        RenderTargetTexture.prototype._shouldRender = function () {
+            if (this._currentRefreshId === -1) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate == this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        };
+
+        RenderTargetTexture.prototype.isReady = function () {
+            if (!this.getScene().renderTargetsEnabled) {
+                return false;
+            }
+            return _super.prototype.isReady.call(this);
+        };
+
+        RenderTargetTexture.prototype.getRenderSize = function () {
+            return this._size;
+        };
+
+        Object.defineProperty(RenderTargetTexture.prototype, "canRescale", {
+            get: function () {
+                return true;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        RenderTargetTexture.prototype.scale = function (ratio) {
+            var newSize = this._size * ratio;
+
+            this.resize(newSize, this._generateMipMaps);
+        };
+
+        RenderTargetTexture.prototype.resize = function (size, generateMipMaps) {
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        };
+
+        RenderTargetTexture.prototype.render = function (useCameraPostProcess) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            if (this._waitingRenderList) {
+                this.renderList = [];
+                for (var index = 0; index < this._waitingRenderList.length; index++) {
+                    var id = this._waitingRenderList[index];
+                    this.renderList.push(scene.getMeshByID(id));
+                }
+
+                delete this._waitingRenderList;
+            }
+
+            if (!this.renderList) {
+                return;
+            }
+
+            // Bind
+            if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
+                engine.bindFramebuffer(this._texture);
+            }
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            this._renderingManager.reset();
+
+            for (var meshIndex = 0; meshIndex < this.renderList.length; meshIndex++) {
+                var mesh = this.renderList[meshIndex];
+
+                if (mesh) {
+                    if (!mesh.isReady() || (mesh.material && !mesh.material.isReady())) {
+                        // Reset _currentRefreshId
+                        this.resetRefreshCounter();
+                        continue;
+                    }
+
+                    if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && ((mesh.layerMask & scene.activeCamera.layerMask) != 0)) {
+                        mesh._activate(scene.getRenderId());
+
+                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                            var subMesh = mesh.subMeshes[subIndex];
+                            scene._activeVertices += subMesh.indexCount;
+                            this._renderingManager.dispatch(subMesh);
+                        }
+                    }
+                }
+            }
+
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
+
+            if (this.onBeforeRender) {
+                this.onBeforeRender();
+            }
+
+            // Render
+            this._renderingManager.render(this.customRenderFunction, this.renderList, this.renderParticles, this.renderSprites);
+
+            if (useCameraPostProcess) {
+                scene.postProcessManager._finalizeFrame(false, this._texture);
+            }
+
+            if (this.onAfterRender) {
+                this.onAfterRender();
+            }
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
+        };
+
+        RenderTargetTexture.prototype.clone = function () {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.RenderTargetTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+            newTexture.renderList = this.renderList.slice(0);
+
+            return newTexture;
+        };
+        return RenderTargetTexture;
+    })(BABYLON.Texture);
+    BABYLON.RenderTargetTexture = RenderTargetTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.renderTargetTexture.js.map

+ 182 - 0
Babylon/Materials/Textures/babylon.renderTargetTexture.ts

@@ -0,0 +1,182 @@
+module BABYLON {
+    export class RenderTargetTexture extends Texture {
+        public renderList = new Array<AbstractMesh>();
+        public renderParticles = true;
+        public renderSprites = false;
+        public coordinatesMode = BABYLON.Texture.PROJECTION_MODE;
+        public onBeforeRender: () => void;
+        public onAfterRender: () => void;
+        public activeCamera: Camera;
+        public customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, beforeTransparents?: () => void) => void;
+
+        private _size: number;
+        public _generateMipMaps: boolean;
+        private _renderingManager: RenderingManager;
+        public _waitingRenderList: string[];
+        private _doNotChangeAspectRatio: boolean;
+        private _currentRefreshId = -1;
+        private _refreshRate = 1;
+
+        constructor(name: string, size: any, scene: Scene, generateMipMaps?: boolean, doNotChangeAspectRatio: boolean = true) {
+            super(null, scene, !generateMipMaps);
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+            this._doNotChangeAspectRatio = doNotChangeAspectRatio;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // Rendering groups
+            this._renderingManager = new BABYLON.RenderingManager(scene);
+        }
+
+        public resetRefreshCounter(): void {
+            this._currentRefreshId = -1;
+        }
+
+        public get refreshRate(): number {
+            return this._refreshRate;
+        }
+
+        // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+        public set refreshRate(value: number) {
+            this._refreshRate = value;
+            this.resetRefreshCounter();
+        }
+
+        public _shouldRender(): boolean {
+            if (this._currentRefreshId === -1) { // At least render once
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate == this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        }
+
+        public isReady(): boolean {
+            if (!this.getScene().renderTargetsEnabled) {
+                return false;
+            }
+            return super.isReady();
+        }
+
+        public getRenderSize(): number {
+            return this._size;
+        }
+
+        public get canRescale(): boolean {
+            return true;
+        }
+
+        public scale(ratio: number): void {
+            var newSize = this._size * ratio;
+
+            this.resize(newSize, this._generateMipMaps);
+        }
+
+        public resize(size:any, generateMipMaps?: boolean) {
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            if (this._waitingRenderList) {
+                this.renderList = [];
+                for (var index = 0; index < this._waitingRenderList.length; index++) {
+                    var id = this._waitingRenderList[index];
+                    this.renderList.push(scene.getMeshByID(id));
+                }
+
+                delete this._waitingRenderList;
+            }
+
+            if (!this.renderList) {
+                return;
+            }
+
+            // Bind
+            if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
+                engine.bindFramebuffer(this._texture);
+            }
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            this._renderingManager.reset();
+
+            for (var meshIndex = 0; meshIndex < this.renderList.length; meshIndex++) {
+                var mesh = this.renderList[meshIndex];
+
+                if (mesh) {
+                    if (!mesh.isReady() || (mesh.material && !mesh.material.isReady())) {
+                        // Reset _currentRefreshId
+                        this.resetRefreshCounter();
+                        continue;
+                    }
+
+                    if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && ((mesh.layerMask & scene.activeCamera.layerMask) != 0)) {
+                        mesh._activate(scene.getRenderId());
+
+                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                            var subMesh = mesh.subMeshes[subIndex];
+                            scene._activeVertices += subMesh.indexCount;
+                            this._renderingManager.dispatch(subMesh);
+                        }
+                    }
+                }
+            }
+
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
+
+            if (this.onBeforeRender) {
+                this.onBeforeRender();
+            }
+
+            // Render
+            this._renderingManager.render(this.customRenderFunction, this.renderList, this.renderParticles, this.renderSprites);
+
+            if (useCameraPostProcess) {
+                scene.postProcessManager._finalizeFrame(false, this._texture);
+            }
+
+            if (this.onAfterRender) {
+                this.onAfterRender();
+            }
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
+        }
+
+        public clone(): RenderTargetTexture {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.RenderTargetTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+            newTexture.renderList = this.renderList.slice(0);
+
+            return newTexture;
+        }
+    }
+} 

+ 50 - 0
Babylon/Materials/Textures/babylon.texture.d.ts

@@ -0,0 +1,50 @@
+declare module BABYLON {
+    class Texture extends BaseTexture {
+        static NEAREST_SAMPLINGMODE: number;
+        static BILINEAR_SAMPLINGMODE: number;
+        static TRILINEAR_SAMPLINGMODE: number;
+        static EXPLICIT_MODE: number;
+        static SPHERICAL_MODE: number;
+        static PLANAR_MODE: number;
+        static CUBIC_MODE: number;
+        static PROJECTION_MODE: number;
+        static SKYBOX_MODE: number;
+        static CLAMP_ADDRESSMODE: number;
+        static WRAP_ADDRESSMODE: number;
+        static MIRROR_ADDRESSMODE: number;
+        public url: string;
+        public uOffset: number;
+        public vOffset: number;
+        public uScale: number;
+        public vScale: number;
+        public uAng: number;
+        public vAng: number;
+        public wAng: number;
+        private _noMipmap;
+        public _invertY: boolean;
+        private _rowGenerationMatrix;
+        private _cachedTextureMatrix;
+        private _projectionModeMatrix;
+        private _t0;
+        private _t1;
+        private _t2;
+        private _cachedUOffset;
+        private _cachedVOffset;
+        private _cachedUScale;
+        private _cachedVScale;
+        private _cachedUAng;
+        private _cachedVAng;
+        private _cachedWAng;
+        private _cachedCoordinatesMode;
+        public _samplingMode: number;
+        private _buffer;
+        private _deleteBuffer;
+        constructor(url: string, scene: Scene, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: () => void, onError?: () => void, buffer?: any, deleteBuffer?: boolean);
+        public delayLoad(): void;
+        private _prepareRowForTextureGeneration(x, y, z, t);
+        public getTextureMatrix(): Matrix;
+        public getReflectionTextureMatrix(): Matrix;
+        public clone(): Texture;
+        static CreateFromBase64String(data: string, name: string, scene: Scene, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: () => void, onError?: () => void): Texture;
+    }
+}

+ 221 - 0
Babylon/Materials/Textures/babylon.texture.js

@@ -0,0 +1,221 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var Texture = (function (_super) {
+        __extends(Texture, _super);
+        function Texture(url, scene, noMipmap, invertY, samplingMode, onLoad, onError, buffer, deleteBuffer) {
+            if (typeof samplingMode === "undefined") { samplingMode = Texture.TRILINEAR_SAMPLINGMODE; }
+            if (typeof onLoad === "undefined") { onLoad = null; }
+            if (typeof onError === "undefined") { onError = null; }
+            if (typeof buffer === "undefined") { buffer = null; }
+            if (typeof deleteBuffer === "undefined") { deleteBuffer = false; }
+            _super.call(this, scene);
+            this.uOffset = 0;
+            this.vOffset = 0;
+            this.uScale = 1.0;
+            this.vScale = 1.0;
+            this.uAng = 0;
+            this.vAng = 0;
+            this.wAng = 0;
+
+            this.name = url;
+            this.url = url;
+            this._noMipmap = noMipmap;
+            this._invertY = invertY;
+            this._samplingMode = samplingMode;
+            this._buffer = buffer;
+            this._deleteBuffer = deleteBuffer;
+
+            if (!url) {
+                return;
+            }
+
+            this._texture = this._getFromCache(url, noMipmap);
+
+            if (!this._texture) {
+                if (!scene.useDelayedTextureLoading) {
+                    this._texture = scene.getEngine().createTexture(url, noMipmap, invertY, scene, this._samplingMode, onLoad, onError, this._buffer);
+                    if (deleteBuffer) {
+                        delete this._buffer;
+                    }
+                } else {
+                    this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+                }
+            }
+        }
+        Texture.prototype.delayLoad = function () {
+            if (this.delayLoadState != BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
+                return;
+            }
+
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
+            this._texture = this._getFromCache(this.url, this._noMipmap);
+
+            if (!this._texture) {
+                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, null, null, this._buffer);
+                if (this._deleteBuffer) {
+                    delete this._buffer;
+                }
+            }
+        };
+
+        Texture.prototype._prepareRowForTextureGeneration = function (x, y, z, t) {
+            x -= this.uOffset + 0.5;
+            y -= this.vOffset + 0.5;
+            z -= 0.5;
+
+            BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix, t);
+
+            t.x *= this.uScale;
+            t.y *= this.vScale;
+
+            t.x += 0.5;
+            t.y += 0.5;
+            t.z += 0.5;
+        };
+
+        Texture.prototype.getTextureMatrix = function () {
+            if (this.uOffset === this._cachedUOffset && this.vOffset === this._cachedVOffset && this.uScale === this._cachedUScale && this.vScale === this._cachedVScale && this.uAng === this._cachedUAng && this.vAng === this._cachedVAng && this.wAng === this._cachedWAng) {
+                return this._cachedTextureMatrix;
+            }
+
+            this._cachedUOffset = this.uOffset;
+            this._cachedVOffset = this.vOffset;
+            this._cachedUScale = this.uScale;
+            this._cachedVScale = this.vScale;
+            this._cachedUAng = this.uAng;
+            this._cachedVAng = this.vAng;
+            this._cachedWAng = this.wAng;
+
+            if (!this._cachedTextureMatrix) {
+                this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+                this._rowGenerationMatrix = new BABYLON.Matrix();
+                this._t0 = BABYLON.Vector3.Zero();
+                this._t1 = BABYLON.Vector3.Zero();
+                this._t2 = BABYLON.Vector3.Zero();
+            }
+
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix);
+
+            this._prepareRowForTextureGeneration(0, 0, 0, this._t0);
+            this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1);
+            this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2);
+
+            this._t1.subtractInPlace(this._t0);
+            this._t2.subtractInPlace(this._t0);
+
+            BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+            this._cachedTextureMatrix.m[0] = this._t1.x;
+            this._cachedTextureMatrix.m[1] = this._t1.y;
+            this._cachedTextureMatrix.m[2] = this._t1.z;
+            this._cachedTextureMatrix.m[4] = this._t2.x;
+            this._cachedTextureMatrix.m[5] = this._t2.y;
+            this._cachedTextureMatrix.m[6] = this._t2.z;
+            this._cachedTextureMatrix.m[8] = this._t0.x;
+            this._cachedTextureMatrix.m[9] = this._t0.y;
+            this._cachedTextureMatrix.m[10] = this._t0.z;
+
+            return this._cachedTextureMatrix;
+        };
+
+        Texture.prototype.getReflectionTextureMatrix = function () {
+            if (this.uOffset === this._cachedUOffset && this.vOffset === this._cachedVOffset && this.uScale === this._cachedUScale && this.vScale === this._cachedVScale && this.coordinatesMode === this._cachedCoordinatesMode) {
+                return this._cachedTextureMatrix;
+            }
+
+            if (!this._cachedTextureMatrix) {
+                this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+                this._projectionModeMatrix = BABYLON.Matrix.Zero();
+            }
+
+            this._cachedCoordinatesMode = this.coordinatesMode;
+
+            switch (this.coordinatesMode) {
+                case BABYLON.Texture.SPHERICAL_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    this._cachedTextureMatrix[0] = -0.5 * this.uScale;
+                    this._cachedTextureMatrix[5] = -0.5 * this.vScale;
+                    this._cachedTextureMatrix[12] = 0.5 + this.uOffset;
+                    this._cachedTextureMatrix[13] = 0.5 + this.vOffset;
+                    break;
+                case BABYLON.Texture.PLANAR_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    this._cachedTextureMatrix[0] = this.uScale;
+                    this._cachedTextureMatrix[5] = this.vScale;
+                    this._cachedTextureMatrix[12] = this.uOffset;
+                    this._cachedTextureMatrix[13] = this.vOffset;
+                    break;
+                case BABYLON.Texture.PROJECTION_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._projectionModeMatrix);
+
+                    this._projectionModeMatrix.m[0] = 0.5;
+                    this._projectionModeMatrix.m[5] = -0.5;
+                    this._projectionModeMatrix.m[10] = 0.0;
+                    this._projectionModeMatrix.m[12] = 0.5;
+                    this._projectionModeMatrix.m[13] = 0.5;
+                    this._projectionModeMatrix.m[14] = 1.0;
+                    this._projectionModeMatrix.m[15] = 1.0;
+
+                    this.getScene().getProjectionMatrix().multiplyToRef(this._projectionModeMatrix, this._cachedTextureMatrix);
+                    break;
+                default:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    break;
+            }
+            return this._cachedTextureMatrix;
+        };
+
+        Texture.prototype.clone = function () {
+            var newTexture = new BABYLON.Texture(this._texture.url, this.getScene(), this._noMipmap, this._invertY);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+            newTexture.coordinatesIndex = this.coordinatesIndex;
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            // Texture
+            newTexture.uOffset = this.uOffset;
+            newTexture.vOffset = this.vOffset;
+            newTexture.uScale = this.uScale;
+            newTexture.vScale = this.vScale;
+            newTexture.uAng = this.uAng;
+            newTexture.vAng = this.vAng;
+            newTexture.wAng = this.wAng;
+
+            return newTexture;
+        };
+
+        // Statics
+        Texture.CreateFromBase64String = function (data, name, scene, noMipmap, invertY, samplingMode, onLoad, onError) {
+            if (typeof samplingMode === "undefined") { samplingMode = Texture.TRILINEAR_SAMPLINGMODE; }
+            if (typeof onLoad === "undefined") { onLoad = null; }
+            if (typeof onError === "undefined") { onError = null; }
+            return new Texture("data:" + name, scene, noMipmap, invertY, samplingMode, onLoad, onError, data);
+        };
+        Texture.NEAREST_SAMPLINGMODE = 1;
+        Texture.BILINEAR_SAMPLINGMODE = 2;
+        Texture.TRILINEAR_SAMPLINGMODE = 3;
+
+        Texture.EXPLICIT_MODE = 0;
+        Texture.SPHERICAL_MODE = 1;
+        Texture.PLANAR_MODE = 2;
+        Texture.CUBIC_MODE = 3;
+        Texture.PROJECTION_MODE = 4;
+        Texture.SKYBOX_MODE = 5;
+
+        Texture.CLAMP_ADDRESSMODE = 0;
+        Texture.WRAP_ADDRESSMODE = 1;
+        Texture.MIRROR_ADDRESSMODE = 2;
+        return Texture;
+    })(BABYLON.BaseTexture);
+    BABYLON.Texture = Texture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.texture.js.map

+ 235 - 0
Babylon/Materials/Textures/babylon.texture.ts

@@ -0,0 +1,235 @@
+module BABYLON {
+    export class Texture extends BaseTexture {
+        // Constants
+        public static NEAREST_SAMPLINGMODE = 1;
+        public static BILINEAR_SAMPLINGMODE = 2;
+        public static TRILINEAR_SAMPLINGMODE = 3;
+
+        public static EXPLICIT_MODE = 0;
+        public static SPHERICAL_MODE = 1;
+        public static PLANAR_MODE = 2;
+        public static CUBIC_MODE = 3;
+        public static PROJECTION_MODE = 4;
+        public static SKYBOX_MODE = 5;
+
+        public static CLAMP_ADDRESSMODE = 0;
+        public static WRAP_ADDRESSMODE = 1;
+        public static MIRROR_ADDRESSMODE = 2;
+
+        // Members
+        public url: string;
+        public uOffset = 0;
+        public vOffset = 0;
+        public uScale = 1.0;
+        public vScale = 1.0;
+        public uAng = 0;
+        public vAng = 0;
+        public wAng = 0;
+
+        private _noMipmap: boolean;
+        public _invertY: boolean;
+        private _rowGenerationMatrix: Matrix;
+        private _cachedTextureMatrix: Matrix;
+        private _projectionModeMatrix: Matrix;
+        private _t0: Vector3;
+        private _t1: Vector3;
+        private _t2: Vector3;
+
+        private _cachedUOffset: number;
+        private _cachedVOffset: number;
+        private _cachedUScale: number;
+        private _cachedVScale: number;
+        private _cachedUAng: number;
+        private _cachedVAng: number;
+        private _cachedWAng: number;
+        private _cachedCoordinatesMode: number;
+        public _samplingMode: number;
+        private _buffer: any;
+        private _deleteBuffer: boolean;
+
+        constructor(url: string, scene: Scene, noMipmap?: boolean, invertY?: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false) {
+            super(scene);
+
+            this.name = url;
+            this.url = url;
+            this._noMipmap = noMipmap;
+            this._invertY = invertY;
+            this._samplingMode = samplingMode;
+            this._buffer = buffer;
+            this._deleteBuffer = deleteBuffer;
+
+            if (!url) {
+                return;
+            }
+
+            this._texture = this._getFromCache(url, noMipmap);
+
+            if (!this._texture) {
+                if (!scene.useDelayedTextureLoading) {
+                    this._texture = scene.getEngine().createTexture(url, noMipmap, invertY, scene, this._samplingMode, onLoad, onError, this._buffer);
+                    if (deleteBuffer) {
+                        delete this._buffer;
+                    }
+                } else {
+                    this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+                }
+            }
+        }
+
+        public delayLoad(): void {
+            if (this.delayLoadState != BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
+                return;
+            }
+
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
+            this._texture = this._getFromCache(this.url, this._noMipmap);
+
+            if (!this._texture) {
+                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, null, null, this._buffer);
+                if (this._deleteBuffer) {
+                    delete this._buffer;
+                }
+            }
+        }
+
+        private _prepareRowForTextureGeneration(x: number, y: number, z: number, t: Vector3): void {
+            x -= this.uOffset + 0.5;
+            y -= this.vOffset + 0.5;
+            z -= 0.5;
+
+            Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix, t);
+
+            t.x *= this.uScale;
+            t.y *= this.vScale;
+
+            t.x += 0.5;
+            t.y += 0.5;
+            t.z += 0.5;
+        }
+
+        public getTextureMatrix(): Matrix {
+            if (
+                this.uOffset === this._cachedUOffset &&
+                this.vOffset === this._cachedVOffset &&
+                this.uScale === this._cachedUScale &&
+                this.vScale === this._cachedVScale &&
+                this.uAng === this._cachedUAng &&
+                this.vAng === this._cachedVAng &&
+                this.wAng === this._cachedWAng) {
+                return this._cachedTextureMatrix;
+            }
+
+            this._cachedUOffset = this.uOffset;
+            this._cachedVOffset = this.vOffset;
+            this._cachedUScale = this.uScale;
+            this._cachedVScale = this.vScale;
+            this._cachedUAng = this.uAng;
+            this._cachedVAng = this.vAng;
+            this._cachedWAng = this.wAng;
+
+            if (!this._cachedTextureMatrix) {
+                this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+                this._rowGenerationMatrix = new BABYLON.Matrix();
+                this._t0 = BABYLON.Vector3.Zero();
+                this._t1 = BABYLON.Vector3.Zero();
+                this._t2 = BABYLON.Vector3.Zero();
+            }
+
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix);
+
+            this._prepareRowForTextureGeneration(0, 0, 0, this._t0);
+            this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1);
+            this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2);
+
+            this._t1.subtractInPlace(this._t0);
+            this._t2.subtractInPlace(this._t0);
+
+            BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+            this._cachedTextureMatrix.m[0] = this._t1.x; this._cachedTextureMatrix.m[1] = this._t1.y; this._cachedTextureMatrix.m[2] = this._t1.z;
+            this._cachedTextureMatrix.m[4] = this._t2.x; this._cachedTextureMatrix.m[5] = this._t2.y; this._cachedTextureMatrix.m[6] = this._t2.z;
+            this._cachedTextureMatrix.m[8] = this._t0.x; this._cachedTextureMatrix.m[9] = this._t0.y; this._cachedTextureMatrix.m[10] = this._t0.z;
+
+            return this._cachedTextureMatrix;
+        }
+
+        public getReflectionTextureMatrix(): Matrix {
+            if (
+                this.uOffset === this._cachedUOffset &&
+                this.vOffset === this._cachedVOffset &&
+                this.uScale === this._cachedUScale &&
+                this.vScale === this._cachedVScale &&
+                this.coordinatesMode === this._cachedCoordinatesMode) {
+                return this._cachedTextureMatrix;
+            }
+
+            if (!this._cachedTextureMatrix) {
+                this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+                this._projectionModeMatrix = BABYLON.Matrix.Zero();
+            }
+
+            this._cachedCoordinatesMode = this.coordinatesMode;
+
+            switch (this.coordinatesMode) {
+                case BABYLON.Texture.SPHERICAL_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    this._cachedTextureMatrix[0] = -0.5 * this.uScale;
+                    this._cachedTextureMatrix[5] = -0.5 * this.vScale;
+                    this._cachedTextureMatrix[12] = 0.5 + this.uOffset;
+                    this._cachedTextureMatrix[13] = 0.5 + this.vOffset;
+                    break;
+                case BABYLON.Texture.PLANAR_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    this._cachedTextureMatrix[0] = this.uScale;
+                    this._cachedTextureMatrix[5] = this.vScale;
+                    this._cachedTextureMatrix[12] = this.uOffset;
+                    this._cachedTextureMatrix[13] = this.vOffset;
+                    break;
+                case BABYLON.Texture.PROJECTION_MODE:
+                    BABYLON.Matrix.IdentityToRef(this._projectionModeMatrix);
+
+                    this._projectionModeMatrix.m[0] = 0.5;
+                    this._projectionModeMatrix.m[5] = -0.5;
+                    this._projectionModeMatrix.m[10] = 0.0;
+                    this._projectionModeMatrix.m[12] = 0.5;
+                    this._projectionModeMatrix.m[13] = 0.5;
+                    this._projectionModeMatrix.m[14] = 1.0;
+                    this._projectionModeMatrix.m[15] = 1.0;
+
+                    this.getScene().getProjectionMatrix().multiplyToRef(this._projectionModeMatrix, this._cachedTextureMatrix);
+                    break;
+                default:
+                    BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                    break;
+            }
+            return this._cachedTextureMatrix;
+        }
+
+        public clone(): Texture {
+            var newTexture = new BABYLON.Texture(this._texture.url, this.getScene(), this._noMipmap, this._invertY);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+            newTexture.wrapU = this.wrapU;
+            newTexture.wrapV = this.wrapV;
+            newTexture.coordinatesIndex = this.coordinatesIndex;
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            // Texture
+            newTexture.uOffset = this.uOffset;
+            newTexture.vOffset = this.vOffset;
+            newTexture.uScale = this.uScale;
+            newTexture.vScale = this.vScale;
+            newTexture.uAng = this.uAng;
+            newTexture.vAng = this.vAng;
+            newTexture.wAng = this.wAng;
+
+            return newTexture;
+        }
+
+        // Statics
+        public static CreateFromBase64String(data: string, name: string, scene: Scene, noMipmap?: boolean, invertY?: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null): Texture {
+            return new Texture("data:" + name, scene, noMipmap, invertY, samplingMode, onLoad, onError, data);
+        }
+    }
+} 

+ 9 - 0
Babylon/Materials/Textures/babylon.videoTexture.d.ts

@@ -0,0 +1,9 @@
+declare module BABYLON {
+    class VideoTexture extends Texture {
+        public video: HTMLVideoElement;
+        private _autoLaunch;
+        private _lastUpdate;
+        constructor(name: string, urls: string[], size: any, scene: Scene, generateMipMaps: boolean, invertY: boolean, samplingMode?: number);
+        public update(): boolean;
+    }
+}

+ 68 - 0
Babylon/Materials/Textures/babylon.videoTexture.js

@@ -0,0 +1,68 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var VideoTexture = (function (_super) {
+        __extends(VideoTexture, _super);
+        function VideoTexture(name, urls, size, scene, generateMipMaps, invertY, samplingMode) {
+            if (typeof samplingMode === "undefined") { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
+            var _this = this;
+            _super.call(this, null, scene, !generateMipMaps, invertY);
+            this._autoLaunch = true;
+
+            this.name = name;
+
+            this.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+
+            var requiredWidth = size.width || size;
+            var requiredHeight = size.height || size;
+
+            this._texture = scene.getEngine().createDynamicTexture(requiredWidth, requiredHeight, generateMipMaps, samplingMode);
+            var textureSize = this.getSize();
+
+            this.video = document.createElement("video");
+            this.video.width = textureSize.width;
+            this.video.height = textureSize.height;
+            this.video.autoplay = false;
+            this.video.loop = true;
+
+            this.video.addEventListener("canplaythrough", function () {
+                if (_this._texture) {
+                    _this._texture.isReady = true;
+                }
+            });
+
+            urls.forEach(function (url) {
+                var source = document.createElement("source");
+                source.src = url;
+                _this.video.appendChild(source);
+            });
+
+            this._lastUpdate = BABYLON.Tools.Now;
+        }
+        VideoTexture.prototype.update = function () {
+            if (this._autoLaunch) {
+                this._autoLaunch = false;
+                this.video.play();
+            }
+
+            var now = BABYLON.Tools.Now;
+
+            if (now - this._lastUpdate < 15) {
+                return false;
+            }
+
+            this._lastUpdate = now;
+            this.getScene().getEngine().updateVideoTexture(this._texture, this.video, this._invertY);
+            return true;
+        };
+        return VideoTexture;
+    })(BABYLON.Texture);
+    BABYLON.VideoTexture = VideoTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.videoTexture.js.map

+ 60 - 0
Babylon/Materials/Textures/babylon.videoTexture.ts

@@ -0,0 +1,60 @@
+module BABYLON {
+    export class VideoTexture extends Texture {
+        public video: HTMLVideoElement;
+
+        private _autoLaunch = true;
+        private _lastUpdate: number;
+
+        constructor(name: string, urls: string[], size: any, scene: Scene, generateMipMaps: boolean, invertY: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
+            super(null, scene, !generateMipMaps, invertY);
+
+            this.name = name;
+
+            this.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+
+            var requiredWidth = size.width || size;
+            var requiredHeight = size.height || size;
+
+            this._texture = scene.getEngine().createDynamicTexture(requiredWidth, requiredHeight, generateMipMaps, samplingMode);
+            var textureSize = this.getSize();
+
+            this.video = document.createElement("video");
+            this.video.width = textureSize.width;
+            this.video.height = textureSize.height;
+            this.video.autoplay = false;
+            this.video.loop = true;
+
+            this.video.addEventListener("canplaythrough", () => {
+                if (this._texture) {
+                    this._texture.isReady = true;
+                }
+            });
+
+            urls.forEach(url => {
+                var source = document.createElement("source");
+                source.src = url;
+                this.video.appendChild(source);
+            });
+
+            this._lastUpdate = Tools.Now;
+        }
+
+        public update(): boolean {
+            if (this._autoLaunch) {
+                this._autoLaunch = false;
+                this.video.play();
+            }
+
+            var now = Tools.Now;
+
+            if (now - this._lastUpdate < 15) {
+                return false;
+            }
+
+            this._lastUpdate = now;
+            this.getScene().getEngine().updateVideoTexture(this._texture, this.video, this._invertY);
+            return true;
+        }
+    }
+} 

+ 1 - 1
Babylon/Mesh/babylon.InstancedMesh.ts

@@ -93,7 +93,7 @@
         public getLOD(camera: Camera): AbstractMesh {
             this._currentLOD = <Mesh>this.sourceMesh.getLOD(this.getScene().activeCamera, this.getBoundingInfo().boundingSphere);
 
-            return this._currentLOD
+            return this._currentLOD;
         }
 
         public _syncSubMeshes(): void {

+ 2 - 2
Babylon/Mesh/babylon.mesh.js

@@ -422,8 +422,8 @@ var BABYLON;
 
                 if (!this._batchCache.visibleInstances[subMeshId] && this._visibleInstances.defaultRenderId) {
                     this._batchCache.visibleInstances[subMeshId] = this._visibleInstances[this._visibleInstances.defaultRenderId];
-                    currentRenderId = this._visibleInstances.defaultRenderId;
-                    selfRenderId = this._visibleInstances.selfDefaultRenderId;
+                    currentRenderId = Math.max(this._visibleInstances.defaultRenderId, currentRenderId);
+                    selfRenderId = Math.max(this._visibleInstances.selfDefaultRenderId, currentRenderId);
                 }
 
                 if (this._batchCache.visibleInstances[subMeshId] && this._batchCache.visibleInstances[subMeshId].length) {

+ 3 - 3
Babylon/Mesh/babylon.mesh.ts

@@ -419,8 +419,8 @@
 
                 if (!this._batchCache.visibleInstances[subMeshId] && this._visibleInstances.defaultRenderId) {
                     this._batchCache.visibleInstances[subMeshId] = this._visibleInstances[this._visibleInstances.defaultRenderId];
-                    currentRenderId = this._visibleInstances.defaultRenderId;
-                    selfRenderId = this._visibleInstances.selfDefaultRenderId;
+                    currentRenderId = Math.max(this._visibleInstances.defaultRenderId, currentRenderId);
+                    selfRenderId = Math.max(this._visibleInstances.selfDefaultRenderId, currentRenderId);
                 }
 
                 if (this._batchCache.visibleInstances[subMeshId] && this._batchCache.visibleInstances[subMeshId].length) {
@@ -1155,7 +1155,7 @@
             var source = meshes[0];
             var material = source.material;
             var scene = source.getScene();
-            
+
             if (!allow32BitsIndices) {
                 var totalVertices = 0;
 

+ 8 - 8
Babylon/Shaders/default.vertex.fx

@@ -124,6 +124,12 @@ void main(void) {
 	vPositionUVW = position;
 #endif 
 
+#ifdef INSTANCES
+	finalWorld = mat4(world0, world1, world2, world3);
+#else
+	finalWorld = world;
+#endif
+
 #ifdef BONES
 	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
 	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
@@ -131,17 +137,11 @@ void main(void) {
 
 #ifdef BONES4
 	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = world * (m0 + m1 + m2 + m3);
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
 #else
-	finalWorld = world * (m0 + m1 + m2);
+	finalWorld = finalWorld * (m0 + m1 + m2);
 #endif 
 
-#else
-#ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
-#else
-	finalWorld = world;
-#endif
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 3 - 3
Babylon/babylon.engine.js

@@ -1006,6 +1006,8 @@
             // Apply states
             this.applyStates();
 
+            this._drawCalls++;
+
             // Render
             var indexFormat = this._uintIndicesCurrentlySet ? this._gl.UNSIGNED_INT : this._gl.UNSIGNED_SHORT;
             if (instancesCount) {
@@ -1014,13 +1016,12 @@
             }
 
             this._gl.drawElements(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, indexCount, indexFormat, indexStart * 2);
-
-            this._drawCalls++;
         };
 
         Engine.prototype.drawPointClouds = function (verticesStart, verticesCount, instancesCount) {
             // Apply states
             this.applyStates();
+            this._drawCalls++;
 
             if (instancesCount) {
                 this._caps.instancedArrays.drawArraysInstancedANGLE(this._gl.POINTS, verticesStart, verticesCount, instancesCount);
@@ -1028,7 +1029,6 @@
             }
 
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
-            this._drawCalls++;
         };
 
         // Shaders

+ 2 - 3
Babylon/babylon.engine.ts

@@ -1002,6 +1002,7 @@
             // Apply states
             this.applyStates();
 
+            this._drawCalls++;
             // Render
             var indexFormat = this._uintIndicesCurrentlySet ? this._gl.UNSIGNED_INT : this._gl.UNSIGNED_SHORT;
             if (instancesCount) {
@@ -1010,13 +1011,12 @@
             }
 
             this._gl.drawElements(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, indexCount, indexFormat, indexStart * 2);
-
-            this._drawCalls++;
         }
 
         public drawPointClouds(verticesStart: number, verticesCount: number, instancesCount?: number): void {
             // Apply states
             this.applyStates();
+            this._drawCalls++;
 
             if (instancesCount) {
                 this._caps.instancedArrays.drawArraysInstancedANGLE(this._gl.POINTS, verticesStart, verticesCount, instancesCount);
@@ -1024,7 +1024,6 @@
             }
 
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
-            this._drawCalls++;
         }
 
         // Shaders

File diff suppressed because it is too large
+ 6 - 6
babylon.2.0-alpha.debug.js


File diff suppressed because it is too large
+ 4 - 4
babylon.2.0-alpha.js