Browse Source

Fixing folder issues
Adding support for instanced bones

David Catuhe 10 năm trước cách đây
mục cha
commit
235a42c75a
49 tập tin đã thay đổi với 4426 bổ sung30 xóa
  1. 14 0
      Babylon/Cameras/babylon.oculusCamera.d.ts
  2. 141 0
      Babylon/Cameras/babylon.oculusCamera.js
  3. 21 0
      Babylon/Cameras/babylon.oculusGamepadCamera.d.ts
  4. 175 0
      Babylon/Cameras/babylon.oculusGamepadCamera.js
  5. 9 0
      Babylon/Cameras/babylon.vrDeviceOrientationCamera.d.ts
  6. 37 0
      Babylon/Cameras/babylon.vrDeviceOrientationCamera.js
  7. 17 0
      Babylon/Cameras/babylon.webVRCamera.d.ts
  8. 80 0
      Babylon/Cameras/babylon.webVRCamera.js
  9. 15 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.d.ts
  10. 142 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.js
  11. 134 0
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.ts
  12. 48 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.d.ts
  13. 309 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.js
  14. 322 0
      Babylon/Materials/Textures/Procedurals/babylon.proceduralTexture.ts
  15. 81 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.d.ts
  16. 491 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js
  17. 378 0
      Babylon/Materials/Textures/Procedurals/babylon.standardProceduralTexture.ts
  18. 37 0
      Babylon/Materials/Textures/babylon.baseTexture.d.ts
  19. 156 0
      Babylon/Materials/Textures/babylon.baseTexture.js
  20. 157 0
      Babylon/Materials/Textures/babylon.baseTexture.ts
  21. 13 0
      Babylon/Materials/Textures/babylon.cubeTexture.d.ts
  22. 74 0
      Babylon/Materials/Textures/babylon.cubeTexture.js
  23. 70 0
      Babylon/Materials/Textures/babylon.cubeTexture.ts
  24. 14 0
      Babylon/Materials/Textures/babylon.dynamicTexture.d.ts
  25. 108 0
      Babylon/Materials/Textures/babylon.dynamicTexture.js
  26. 97 0
      Babylon/Materials/Textures/babylon.dynamicTexture.ts
  27. 10 0
      Babylon/Materials/Textures/babylon.mirrorTexture.d.ts
  28. 56 0
      Babylon/Materials/Textures/babylon.mirrorTexture.js
  29. 48 0
      Babylon/Materials/Textures/babylon.mirrorTexture.ts
  30. 10 0
      Babylon/Materials/Textures/babylon.rawTexture.d.ts
  31. 58 0
      Babylon/Materials/Textures/babylon.rawTexture.js
  32. 30 0
      Babylon/Materials/Textures/babylon.rawTexture.ts
  33. 30 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.d.ts
  34. 190 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.js
  35. 182 0
      Babylon/Materials/Textures/babylon.renderTargetTexture.ts
  36. 50 0
      Babylon/Materials/Textures/babylon.texture.d.ts
  37. 221 0
      Babylon/Materials/Textures/babylon.texture.js
  38. 235 0
      Babylon/Materials/Textures/babylon.texture.ts
  39. 9 0
      Babylon/Materials/Textures/babylon.videoTexture.d.ts
  40. 68 0
      Babylon/Materials/Textures/babylon.videoTexture.js
  41. 60 0
      Babylon/Materials/Textures/babylon.videoTexture.ts
  42. 1 1
      Babylon/Mesh/babylon.InstancedMesh.ts
  43. 2 2
      Babylon/Mesh/babylon.mesh.js
  44. 3 3
      Babylon/Mesh/babylon.mesh.ts
  45. 8 8
      Babylon/Shaders/default.vertex.fx
  46. 3 3
      Babylon/babylon.engine.js
  47. 2 3
      Babylon/babylon.engine.ts
  48. 6 6
      babylon.2.0-alpha.debug.js
  49. 4 4
      babylon.2.0-alpha.js

+ 14 - 0
Babylon/Cameras/babylon.oculusCamera.d.ts

@@ -0,0 +1,14 @@
+declare module BABYLON {
+    class OculusCamera extends FreeCamera {
+        private _leftCamera;
+        private _rightCamera;
+        private _offsetOrientation;
+        private _deviceOrientationHandler;
+        constructor(name: string, position: Vector3, scene: Scene);
+        public _update(): void;
+        public _updateCamera(camera: FreeCamera): void;
+        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        public detachControl(element: HTMLElement): void;
+    }
+}

+ 141 - 0
Babylon/Cameras/babylon.oculusCamera.js

@@ -0,0 +1,141 @@
+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 OculusRiftDevKit2013_Metric = {
+        HResolution: 1280,
+        VResolution: 800,
+        HScreenSize: 0.149759993,
+        VScreenSize: 0.0935999975,
+        VScreenCenter: 0.0467999987,
+        EyeToScreenDistance: 0.0410000011,
+        LensSeparationDistance: 0.0635000020,
+        InterpupillaryDistance: 0.0640000030,
+        DistortionK: [1.0, 0.219999999, 0.239999995, 0.0],
+        ChromaAbCorrection: [0.995999992, -0.00400000019, 1.01400006, 0.0],
+        PostProcessScaleFactor: 1.714605507808412,
+        LensCenterOffset: 0.151976421
+    };
+
+    var _OculusInnerCamera = (function (_super) {
+        __extends(_OculusInnerCamera, _super);
+        function _OculusInnerCamera(name, position, scene, isLeftEye) {
+            _super.call(this, name, position, scene);
+            this._workMatrix = new BABYLON.Matrix();
+            this._actualUp = new BABYLON.Vector3(0, 0, 0);
+
+            // Constants
+            this._aspectRatioAspectRatio = OculusRiftDevKit2013_Metric.HResolution / (2 * OculusRiftDevKit2013_Metric.VResolution);
+            this._aspectRatioFov = (2 * Math.atan((OculusRiftDevKit2013_Metric.PostProcessScaleFactor * OculusRiftDevKit2013_Metric.VScreenSize) / (2 * OculusRiftDevKit2013_Metric.EyeToScreenDistance)));
+
+            var hMeters = (OculusRiftDevKit2013_Metric.HScreenSize / 4) - (OculusRiftDevKit2013_Metric.LensSeparationDistance / 2);
+            var h = (4 * hMeters) / OculusRiftDevKit2013_Metric.HScreenSize;
+
+            this._hMatrix = BABYLON.Matrix.Translation(isLeftEye ? h : -h, 0, 0);
+
+            this.viewport = new BABYLON.Viewport(isLeftEye ? 0 : 0.5, 0, 0.5, 1.0);
+
+            this._preViewMatrix = BABYLON.Matrix.Translation(isLeftEye ? .5 * OculusRiftDevKit2013_Metric.InterpupillaryDistance : -.5 * OculusRiftDevKit2013_Metric.InterpupillaryDistance, 0, 0);
+
+            // Postprocess
+            var postProcess = new BABYLON.OculusDistortionCorrectionPostProcess("Oculus Distortion", this, !isLeftEye, OculusRiftDevKit2013_Metric);
+        }
+        _OculusInnerCamera.prototype.getProjectionMatrix = function () {
+            BABYLON.Matrix.PerspectiveFovLHToRef(this._aspectRatioFov, this._aspectRatioAspectRatio, this.minZ, this.maxZ, this._workMatrix);
+            this._workMatrix.multiplyToRef(this._hMatrix, this._projectionMatrix);
+            return this._projectionMatrix;
+        };
+
+        _OculusInnerCamera.prototype._getViewMatrix = function () {
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._cameraRotationMatrix);
+
+            BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
+            BABYLON.Vector3.TransformNormalToRef(this.upVector, this._cameraRotationMatrix, this._actualUp);
+
+            // Computing target and final matrix
+            this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
+
+            BABYLON.Matrix.LookAtLHToRef(this.position, this._currentTarget, this._actualUp, this._workMatrix);
+
+            this._workMatrix.multiplyToRef(this._preViewMatrix, this._viewMatrix);
+            return this._viewMatrix;
+        };
+        return _OculusInnerCamera;
+    })(BABYLON.FreeCamera);
+
+    var OculusCamera = (function (_super) {
+        __extends(OculusCamera, _super);
+        function OculusCamera(name, position, scene) {
+            _super.call(this, name, position, scene);
+
+            this._leftCamera = new _OculusInnerCamera(name + "_left", position.clone(), scene, true);
+            this._rightCamera = new _OculusInnerCamera(name + "_right", position.clone(), scene, false);
+
+            this.subCameras.push(this._leftCamera);
+            this.subCameras.push(this._rightCamera);
+
+            this._deviceOrientationHandler = this._onOrientationEvent.bind(this);
+        }
+        OculusCamera.prototype._update = function () {
+            this._leftCamera.position.copyFrom(this.position);
+            this._rightCamera.position.copyFrom(this.position);
+
+            this._updateCamera(this._leftCamera);
+            this._updateCamera(this._rightCamera);
+
+            _super.prototype._update.call(this);
+        };
+
+        OculusCamera.prototype._updateCamera = function (camera) {
+            camera.minZ = this.minZ;
+            camera.maxZ = this.maxZ;
+
+            camera.rotation.x = this.rotation.x;
+            camera.rotation.y = this.rotation.y;
+            camera.rotation.z = this.rotation.z;
+        };
+
+        // Oculus events
+        OculusCamera.prototype._onOrientationEvent = function (evt) {
+            var yaw = evt.alpha / 180 * Math.PI;
+            var pitch = evt.beta / 180 * Math.PI;
+            var roll = evt.gamma / 180 * Math.PI;
+
+            if (!this._offsetOrientation) {
+                this._offsetOrientation = {
+                    yaw: yaw,
+                    pitch: pitch,
+                    roll: roll
+                };
+                return;
+            } else {
+                this.rotation.y += yaw - this._offsetOrientation.yaw;
+                this.rotation.x += pitch - this._offsetOrientation.pitch;
+                this.rotation.z += this._offsetOrientation.roll - roll;
+
+                this._offsetOrientation.yaw = yaw;
+                this._offsetOrientation.pitch = pitch;
+                this._offsetOrientation.roll = roll;
+            }
+        };
+
+        OculusCamera.prototype.attachControl = function (element, noPreventDefault) {
+            _super.prototype.attachControl.call(this, element, noPreventDefault);
+
+            window.addEventListener("deviceorientation", this._deviceOrientationHandler);
+        };
+
+        OculusCamera.prototype.detachControl = function (element) {
+            _super.prototype.detachControl.call(this, element);
+
+            window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
+        };
+        return OculusCamera;
+    })(BABYLON.FreeCamera);
+    BABYLON.OculusCamera = OculusCamera;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.oculusCamera.js.map

+ 21 - 0
Babylon/Cameras/babylon.oculusGamepadCamera.d.ts

@@ -0,0 +1,21 @@
+declare module BABYLON {
+    class OculusGamepadCamera extends FreeCamera {
+        private _leftCamera;
+        private _rightCamera;
+        private _offsetOrientation;
+        private _deviceOrientationHandler;
+        private _gamepad;
+        private _gamepads;
+        public angularSensibility: number;
+        public moveSensibility: number;
+        constructor(name: string, position: Vector3, scene: Scene);
+        private _onNewGameConnected(gamepad);
+        public _update(): void;
+        public _checkInputs(): void;
+        public _updateCamera(camera: FreeCamera): void;
+        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        public detachControl(element: HTMLElement): void;
+        public dispose(): void;
+    }
+}

+ 175 - 0
Babylon/Cameras/babylon.oculusGamepadCamera.js

@@ -0,0 +1,175 @@
+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 OculusRiftDevKit2013_Metric = {
+        HResolution: 1280,
+        VResolution: 800,
+        HScreenSize: 0.149759993,
+        VScreenSize: 0.0935999975,
+        VScreenCenter: 0.0467999987,
+        EyeToScreenDistance: 0.0410000011,
+        LensSeparationDistance: 0.0635000020,
+        InterpupillaryDistance: 0.0640000030,
+        DistortionK: [1.0, 0.219999999, 0.239999995, 0.0],
+        ChromaAbCorrection: [0.995999992, -0.00400000019, 1.01400006, 0.0],
+        PostProcessScaleFactor: 1.714605507808412,
+        LensCenterOffset: 0.151976421
+    };
+
+    var _OculusInnerGamepadCamera = (function (_super) {
+        __extends(_OculusInnerGamepadCamera, _super);
+        function _OculusInnerGamepadCamera(name, position, scene, isLeftEye) {
+            _super.call(this, name, position, scene);
+            this._workMatrix = new BABYLON.Matrix();
+            this._actualUp = new BABYLON.Vector3(0, 0, 0);
+
+            // Constants
+            this._aspectRatioAspectRatio = OculusRiftDevKit2013_Metric.HResolution / (2 * OculusRiftDevKit2013_Metric.VResolution);
+            this._aspectRatioFov = (2 * Math.atan((OculusRiftDevKit2013_Metric.PostProcessScaleFactor * OculusRiftDevKit2013_Metric.VScreenSize) / (2 * OculusRiftDevKit2013_Metric.EyeToScreenDistance)));
+
+            var hMeters = (OculusRiftDevKit2013_Metric.HScreenSize / 4) - (OculusRiftDevKit2013_Metric.LensSeparationDistance / 2);
+            var h = (4 * hMeters) / OculusRiftDevKit2013_Metric.HScreenSize;
+
+            this._hMatrix = BABYLON.Matrix.Translation(isLeftEye ? h : -h, 0, 0);
+
+            this.viewport = new BABYLON.Viewport(isLeftEye ? 0 : 0.5, 0, 0.5, 1.0);
+
+            this._preViewMatrix = BABYLON.Matrix.Translation(isLeftEye ? .5 * OculusRiftDevKit2013_Metric.InterpupillaryDistance : -.5 * OculusRiftDevKit2013_Metric.InterpupillaryDistance, 0, 0);
+
+            // Postprocess
+            var postProcess = new BABYLON.OculusDistortionCorrectionPostProcess("Oculus Distortion", this, !isLeftEye, OculusRiftDevKit2013_Metric);
+        }
+        _OculusInnerGamepadCamera.prototype.getProjectionMatrix = function () {
+            BABYLON.Matrix.PerspectiveFovLHToRef(this._aspectRatioFov, this._aspectRatioAspectRatio, this.minZ, this.maxZ, this._workMatrix);
+            this._workMatrix.multiplyToRef(this._hMatrix, this._projectionMatrix);
+            return this._projectionMatrix;
+        };
+
+        _OculusInnerGamepadCamera.prototype._getViewMatrix = function () {
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._cameraRotationMatrix);
+
+            BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
+            BABYLON.Vector3.TransformNormalToRef(this.upVector, this._cameraRotationMatrix, this._actualUp);
+
+            // Computing target and final matrix
+            this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
+
+            BABYLON.Matrix.LookAtLHToRef(this.position, this._currentTarget, this._actualUp, this._workMatrix);
+
+            this._workMatrix.multiplyToRef(this._preViewMatrix, this._viewMatrix);
+            return this._viewMatrix;
+        };
+        return _OculusInnerGamepadCamera;
+    })(BABYLON.FreeCamera);
+
+    var OculusGamepadCamera = (function (_super) {
+        __extends(OculusGamepadCamera, _super);
+        function OculusGamepadCamera(name, position, scene) {
+            var _this = this;
+            _super.call(this, name, position, scene);
+            this.angularSensibility = 200;
+            this.moveSensibility = 75;
+
+            this._leftCamera = new _OculusInnerGamepadCamera(name + "_left", position.clone(), scene, true);
+            this._rightCamera = new _OculusInnerGamepadCamera(name + "_right", position.clone(), scene, false);
+
+            this.subCameras.push(this._leftCamera);
+            this.subCameras.push(this._rightCamera);
+
+            this._deviceOrientationHandler = this._onOrientationEvent.bind(this);
+            this._gamepads = new BABYLON.Gamepads(function (gamepad) {
+                _this._onNewGameConnected(gamepad);
+            });
+        }
+        OculusGamepadCamera.prototype._onNewGameConnected = function (gamepad) {
+            // Only the first gamepad can control the camera
+            if (gamepad.index === 0) {
+                this._gamepad = gamepad;
+            }
+        };
+
+        OculusGamepadCamera.prototype._update = function () {
+            this._leftCamera.position.copyFrom(this.position);
+            this._rightCamera.position.copyFrom(this.position);
+
+            this._updateCamera(this._leftCamera);
+            this._updateCamera(this._rightCamera);
+
+            _super.prototype._update.call(this);
+        };
+
+        OculusGamepadCamera.prototype._checkInputs = function () {
+            if (!this._gamepad) {
+                return;
+            }
+
+            var LSValues = this._gamepad.leftStick;
+            var normalizedLX = LSValues.x / this.moveSensibility;
+            var normalizedLY = LSValues.y / this.moveSensibility;
+            LSValues.x = Math.abs(normalizedLX) > 0.005 ? 0 + normalizedLX : 0;
+            LSValues.y = Math.abs(normalizedLY) > 0.005 ? 0 + normalizedLY : 0;
+
+            var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
+            var deltaTransform = BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(LSValues.x, 0, -LSValues.y), cameraTransform);
+            this.cameraDirection = this.cameraDirection.add(deltaTransform);
+        };
+
+        OculusGamepadCamera.prototype._updateCamera = function (camera) {
+            camera.minZ = this.minZ;
+            camera.maxZ = this.maxZ;
+
+            camera.rotation.x = this.rotation.x;
+            camera.rotation.y = this.rotation.y;
+            camera.rotation.z = this.rotation.z;
+        };
+
+        // Oculus events
+        OculusGamepadCamera.prototype._onOrientationEvent = function (evt) {
+            var yaw = evt.alpha / 180 * Math.PI;
+            var pitch = evt.beta / 180 * Math.PI;
+            var roll = evt.gamma / 180 * Math.PI;
+
+            if (!this._offsetOrientation) {
+                this._offsetOrientation = {
+                    yaw: yaw,
+                    pitch: pitch,
+                    roll: roll
+                };
+                return;
+            } else {
+                this.rotation.y += yaw - this._offsetOrientation.yaw;
+                this.rotation.x += pitch - this._offsetOrientation.pitch;
+                this.rotation.z += this._offsetOrientation.roll - roll;
+
+                this._offsetOrientation.yaw = yaw;
+                this._offsetOrientation.pitch = pitch;
+                this._offsetOrientation.roll = roll;
+            }
+        };
+
+        OculusGamepadCamera.prototype.attachControl = function (element, noPreventDefault) {
+            _super.prototype.attachControl.call(this, element, noPreventDefault);
+
+            window.addEventListener("deviceorientation", this._deviceOrientationHandler);
+        };
+
+        OculusGamepadCamera.prototype.detachControl = function (element) {
+            _super.prototype.detachControl.call(this, element);
+
+            window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
+        };
+
+        OculusGamepadCamera.prototype.dispose = function () {
+            this._gamepads.dispose();
+            _super.prototype.dispose.call(this);
+        };
+        return OculusGamepadCamera;
+    })(BABYLON.FreeCamera);
+    BABYLON.OculusGamepadCamera = OculusGamepadCamera;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.oculusGamepadCamera.js.map

+ 9 - 0
Babylon/Cameras/babylon.vrDeviceOrientationCamera.d.ts

@@ -0,0 +1,9 @@
+declare module BABYLON {
+    class VRDeviceOrientationCamera extends OculusCamera {
+        public _alpha: number;
+        public _beta: number;
+        public _gamma: number;
+        constructor(name: string, position: Vector3, scene: Scene);
+        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
+    }
+}

+ 37 - 0
Babylon/Cameras/babylon.vrDeviceOrientationCamera.js

@@ -0,0 +1,37 @@
+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 VRDeviceOrientationCamera = (function (_super) {
+        __extends(VRDeviceOrientationCamera, _super);
+        function VRDeviceOrientationCamera(name, position, scene) {
+            _super.call(this, name, position, scene);
+            this._alpha = 0;
+            this._beta = 0;
+            this._gamma = 0;
+        }
+        VRDeviceOrientationCamera.prototype._onOrientationEvent = function (evt) {
+            this._alpha = +evt.alpha | 0;
+            this._beta = +evt.beta | 0;
+            this._gamma = +evt.gamma | 0;
+
+            if (this._gamma < 0) {
+                this._gamma = 90 + this._gamma;
+            } else {
+                // Incline it in the correct angle.
+                this._gamma = 270 - this._gamma;
+            }
+
+            this.rotation.x = this._gamma / 180.0 * Math.PI;
+            this.rotation.y = -this._alpha / 180.0 * Math.PI;
+            this.rotation.z = this._beta / 180.0 * Math.PI;
+        };
+        return VRDeviceOrientationCamera;
+    })(BABYLON.OculusCamera);
+    BABYLON.VRDeviceOrientationCamera = VRDeviceOrientationCamera;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.vrDeviceOrientationCamera.js.map

+ 17 - 0
Babylon/Cameras/babylon.webVRCamera.d.ts

@@ -0,0 +1,17 @@
+declare var HMDVRDevice: any;
+declare var PositionSensorVRDevice: any;
+declare module BABYLON {
+    class WebVRCamera extends OculusCamera {
+        public _hmdDevice: any;
+        public _sensorDevice: any;
+        public _cacheState: any;
+        public _cacheQuaternion: Quaternion;
+        public _cacheRotation: Vector3;
+        public _vrEnabled: boolean;
+        constructor(name: string, position: Vector3, scene: Scene);
+        private _getWebVRDevices(devices);
+        public _update(): void;
+        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        public detachControl(element: HTMLElement): void;
+    }
+}

+ 80 - 0
Babylon/Cameras/babylon.webVRCamera.js

@@ -0,0 +1,80 @@
+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 WebVRCamera = (function (_super) {
+        __extends(WebVRCamera, _super);
+        function WebVRCamera(name, position, scene) {
+            _super.call(this, name, position, scene);
+            this._hmdDevice = null;
+            this._sensorDevice = null;
+            this._cacheState = null;
+            this._cacheQuaternion = new BABYLON.Quaternion();
+            this._cacheRotation = BABYLON.Vector3.Zero();
+            this._vrEnabled = false;
+            this._getWebVRDevices = this._getWebVRDevices.bind(this);
+        }
+        WebVRCamera.prototype._getWebVRDevices = function (devices) {
+            var size = devices.length;
+            var i = 0;
+
+            // Reset devices.
+            this._sensorDevice = null;
+            this._hmdDevice = null;
+
+            while (i < size && this._hmdDevice === null) {
+                if (devices[i] instanceof HMDVRDevice) {
+                    this._hmdDevice = devices[i];
+                }
+                i++;
+            }
+
+            i = 0;
+
+            while (i < size && this._sensorDevice === null) {
+                if (devices[i] instanceof PositionSensorVRDevice && (!this._hmdDevice || devices[i].hardwareUnitId === this._hmdDevice.hardwareUnitId)) {
+                    this._sensorDevice = devices[i];
+                }
+                i++;
+            }
+
+            this._vrEnabled = this._sensorDevice && this._hmdDevice ? true : false;
+        };
+
+        WebVRCamera.prototype._update = function () {
+            if (this._vrEnabled) {
+                this._cacheState = this._sensorDevice.getState();
+                this._cacheQuaternion.copyFromFloats(this._cacheState.orientation.x, this._cacheState.orientation.y, this._cacheState.orientation.z, this._cacheState.orientation.w);
+                this._cacheQuaternion.toEulerAnglesToRef(this._cacheRotation);
+
+                this.rotation.x = -this._cacheRotation.z;
+                this.rotation.y = -this._cacheRotation.y;
+                this.rotation.z = this._cacheRotation.x;
+            }
+
+            _super.prototype._update.call(this);
+        };
+
+        WebVRCamera.prototype.attachControl = function (element, noPreventDefault) {
+            _super.prototype.attachControl.call(this, element, noPreventDefault);
+
+            if (navigator.getVRDevices) {
+                navigator.getVRDevices().then(this._getWebVRDevices);
+            } else if (navigator.mozGetVRDevices) {
+                navigator.mozGetVRDevices(this._getWebVRDevices);
+            }
+        };
+
+        WebVRCamera.prototype.detachControl = function (element) {
+            _super.prototype.detachControl.call(this, element);
+            this._vrEnabled = false;
+        };
+        return WebVRCamera;
+    })(BABYLON.OculusCamera);
+    BABYLON.WebVRCamera = WebVRCamera;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.webVRCamera.js.map

+ 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

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 6
babylon.2.0-alpha.debug.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4 - 4
babylon.2.0-alpha.js