Jelajahi Sumber

New ```Texture.CreateFromBase64String``` function
New procedural textures

David Catuhe 10 tahun lalu
induk
melakukan
79abec7eb5
29 mengubah file dengan 1406 tambahan dan 79 penghapusan
  1. 13 0
      Babylon/Loading/Plugins/babylon.babylonFileLoader.js
  2. 13 0
      Babylon/Loading/Plugins/babylon.babylonFileLoader.ts
  3. 124 0
      Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.js
  4. 122 0
      Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.ts
  5. 4 0
      Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.js
  6. 5 0
      Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.ts
  7. 127 0
      Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.js
  8. 110 1
      Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.ts
  9. 8 0
      Babylon/Materials/textures/babylon.texture.js
  10. 5 0
      Babylon/Materials/textures/babylon.texture.ts
  11. 27 3
      Babylon/Math/babylon.math.js
  12. 24 3
      Babylon/Math/babylon.math.ts
  13. 16 0
      Babylon/Mesh/babylon.abstractMesh.js
  14. 16 0
      Babylon/Mesh/babylon.abstractMesh.ts
  15. 10 10
      Babylon/Mesh/babylon.csg.js
  16. 12 14
      Babylon/Mesh/babylon.csg.ts
  17. 2 0
      Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js
  18. 2 1
      Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPass.ts
  19. 82 0
      Babylon/Shaders/brick.fragment.fx
  20. 8 0
      Babylon/Shaders/empty.fragment.fx
  21. 13 18
      Babylon/Shaders/grass.fragment.fx
  22. 104 0
      Babylon/Shaders/marble.fragment.fx
  23. 37 0
      Babylon/Shaders/road.fragment.fx
  24. 120 0
      Babylon/Shaders/rock.fragment.fx
  25. 1 1
      Babylon/Tools/babylon.tools.js
  26. 1 1
      Babylon/Tools/babylon.tools.ts
  27. 337 15
      babylon.2.0-alpha.debug.js
  28. 11 11
      babylon.2.0-alpha.js
  29. 52 1
      babylon.2.0.d.ts

+ 13 - 0
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -335,6 +335,11 @@
                 light._excludedMeshesIds = parsedLight.excludedMeshesIds;
             }
 
+            // Parent
+            if (parsedLight.parentId) {
+                light._waitingParentId = parsedLight.parentId;
+            }
+
             if (parsedLight.includedOnlyMeshesIds) {
                 light._includedOnlyMeshesIds = parsedLight.includedOnlyMeshesIds;
             }
@@ -1196,6 +1201,14 @@
                     }
                 }
 
+                for (index = 0; index < scene.lights.length; index++) {
+                    var light = scene.lights[index];
+                    if (light._waitingParentId) {
+                        light.parent = scene.getLastEntryByID(light._waitingParentId);
+                        light._waitingParentId = undefined;
+                    }
+                }
+
                 for (index = 0; index < scene.meshes.length; index++) {
                     var mesh = scene.meshes[index];
                     if (mesh._waitingParentId) {

+ 13 - 0
Babylon/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -334,6 +334,11 @@
             light._excludedMeshesIds = parsedLight.excludedMeshesIds;
         }
 
+        // Parent
+        if (parsedLight.parentId) {
+            light._waitingParentId = parsedLight.parentId;
+        }
+
         if (parsedLight.includedOnlyMeshesIds) {
             light._includedOnlyMeshesIds = parsedLight.includedOnlyMeshesIds;
         }
@@ -1213,6 +1218,14 @@
                 }
             }
 
+            for (index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+                if (light._waitingParentId) {
+                    light.parent = scene.getLastEntryByID(light._waitingParentId);
+                    light._waitingParentId = undefined;
+                }
+            }
+
             for (index = 0; index < scene.meshes.length; index++) {
                 var mesh = scene.meshes[index];
                 if (mesh._waitingParentId) {

+ 124 - 0
Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.js

@@ -0,0 +1,124 @@
+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, "empty", scene, fallbackTexture, generateMipMaps);
+            this._generateTime = true;
+            this._time = 0;
+            this._shaderLoaded = false;
+
+            this._texturePath = texturePath;
+
+            //readJson
+            this.loadJson(texturePath);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        CustomProceduralTexture.prototype.loadJson = function (jsonUrl) {
+            var _this = this;
+            function noConfigFile() {
+                BABYLON.Tools.Log("No config file found in " + jsonUrl);
+            }
+
+            var that = this;
+            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  {
+                        that._config = JSON.parse(xhr.response);
+                        that.updateShaderUniforms();
+                        that.setFragment(jsonUrl + "/custom");
+                        that._generateTime = that._config.generateTime;
+                        if (that._generateTime)
+                            _this.refreshRate = 1;
+                        that._shaderLoaded = true;
+                        that.render();
+                    } catch (ex) {
+                        noConfigFile();
+                    }
+                } else {
+                    noConfigFile();
+                }
+            }, false);
+
+            xhr.addEventListener("error", function (event) {
+                noConfigFile();
+            }, false);
+
+            try  {
+                xhr.send();
+            } catch (ex) {
+                BABYLON.Tools.Error("Error on XHR send request.");
+            }
+        };
+
+        CustomProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            //if config and shader not loaded, do not render
+            if (!this._shaderLoaded)
+                return;
+
+            if (this._generateTime) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            _super.prototype.render.call(this, useCameraPostProcess);
+        };
+
+        CustomProceduralTexture.prototype.updateShaderUniforms = function () {
+            for (var i = 0; i < this._config.texture2Ds.length; i++) {
+                this.setTexture(this._config.texture2Ds[i].textureName, new BABYLON.Texture(this._texturePath + "/" + this._config.texture2Ds[i].textureRelativeUrl, this.getScene()));
+            }
+
+            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;
+                }
+            }
+        };
+
+        Object.defineProperty(CustomProceduralTexture.prototype, "generateTime", {
+            get: function () {
+                return this.generateTime;
+            },
+            set: function (value) {
+                this.generateTime = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return CustomProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.CustomProceduralTexture = CustomProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.customProceduralTexture.js.map

+ 122 - 0
Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.ts

@@ -0,0 +1,122 @@
+module BABYLON {
+    export class CustomProceduralTexture extends ProceduralTexture {
+
+        private _generateTime: boolean = true;
+        private _time: number = 0;
+        private _shaderLoaded: boolean = false;
+        private _config: any;
+        private _texturePath: string;
+
+        constructor(name: string, texturePath: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "empty", scene, fallbackTexture, generateMipMaps);
+
+            this._texturePath = texturePath;
+
+            //readJson
+            this.loadJson(texturePath);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+
+        private loadJson(jsonUrl: string) {
+
+            function noConfigFile() {
+                BABYLON.Tools.Log("No config file found in " + jsonUrl);
+            }
+
+            var that = this;
+            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 {
+                        that._config = JSON.parse(xhr.response);
+                        that.updateShaderUniforms();
+                        that.setFragment(jsonUrl + "/custom");
+                        that._generateTime = that._config.generateTime;
+                        if (that._generateTime)
+                            this.refreshRate = 1;
+                        that._shaderLoaded = true;
+                        that.render();
+                    }
+                    catch (ex) {
+                        noConfigFile();
+                    }
+                }
+                else {
+                    noConfigFile();
+                }
+            }, false);
+
+            xhr.addEventListener("error", event => {
+                noConfigFile();
+            }, false);
+
+            try {
+                xhr.send();
+            }
+            catch (ex) {
+                BABYLON.Tools.Error("Error on XHR send request.");
+            }
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+
+            //if config and shader not loaded, do not render
+            if (!this._shaderLoaded)
+                return;
+
+
+            if (this._generateTime) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            super.render(useCameraPostProcess);
+        }
+
+        public updateShaderUniforms() {
+
+            for (var i = 0; i < this._config.texture2Ds.length; i++) {
+                this.setTexture(this._config.texture2Ds[i].textureName, new BABYLON.Texture(this._texturePath + "/" + this._config.texture2Ds[i].textureRelativeUrl, this.getScene()));
+            }
+
+            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;
+                }
+            }
+        }
+
+        public get generateTime(): boolean {
+            return this.generateTime;
+        }
+
+        public set generateTime(value: boolean) {
+            this.generateTime = value;
+            this.updateShaderUniforms();
+        }
+
+    }
+}

+ 4 - 0
Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.js

@@ -77,6 +77,10 @@ var BABYLON;
             this._currentRefreshId = -1;
         };
 
+        ProceduralTexture.prototype.setFragment = function (fragment) {
+            this._fragment = fragment;
+        };
+
         Object.defineProperty(ProceduralTexture.prototype, "refreshRate", {
             get: function () {
                 return this._refreshRate;

+ 5 - 0
Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.ts

@@ -66,6 +66,7 @@
             this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
         }
 
+      
         public isReady(): boolean {
             var engine = this.getScene().getEngine();
 
@@ -87,6 +88,10 @@
             this._currentRefreshId = -1;
         }
 
+        public setFragment(fragment: any) {
+            this._fragment = fragment;
+        }
+
         public get refreshRate(): number {
             return this._refreshRate;
         }

+ 127 - 0
Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.js

@@ -226,8 +226,11 @@ var BABYLON;
             this._skyColor = new BABYLON.Color3(0.15, 0.68, 1.0);
             this._cloudColor = new BABYLON.Color3(1, 1, 1);
 
+            this.updateShaderUniforms();
+
             // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
+            // https://www.shadertoy.com/view/XsjSRt
         }
         CloudProceduralTexture.prototype.updateShaderUniforms = function () {
             this.setColor3("skyColor", this._skyColor);
@@ -274,5 +277,129 @@ var BABYLON;
         return GrassProceduralTexture;
     })(BABYLON.ProceduralTexture);
     BABYLON.GrassProceduralTexture = GrassProceduralTexture;
+
+    var RockProceduralTexture = (function (_super) {
+        __extends(RockProceduralTexture, _super);
+        function RockProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "rock", scene, fallbackTexture, generateMipMaps);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        return RockProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.RockProceduralTexture = RockProceduralTexture;
+
+    var RoadProceduralTexture = (function (_super) {
+        __extends(RoadProceduralTexture, _super);
+        function RoadProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "road", scene, fallbackTexture, generateMipMaps);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        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.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        BrickProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
+        };
+
+        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
+        });
+
+        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._numberOfBricksHeight = 3;
+            this._numberOfBricksWidth = 3;
+
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        MarbleProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
+        };
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfBricksHeight", {
+            get: function () {
+                return this._numberOfBricksHeight;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "cloudColor", {
+            set: function (value) {
+                this._numberOfBricksHeight = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfBricksWidth", {
+            get: function () {
+                return this._numberOfBricksWidth;
+            },
+            set: function (value) {
+                this._numberOfBricksHeight = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return MarbleProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.MarbleProceduralTexture = MarbleProceduralTexture;
 })(BABYLON || (BABYLON = {}));
 //# sourceMappingURL=babylon.standardProceduralTexture.js.map

+ 110 - 1
Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.ts

@@ -186,9 +186,11 @@
         constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
             super(name, size, "cloud", scene, fallbackTexture, generateMipMaps);
 
+            this.updateShaderUniforms();
+
             // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
-
+            // https://www.shadertoy.com/view/XsjSRt
         }
 
         public updateShaderUniforms() {
@@ -227,4 +229,111 @@
         }
     }
 
+
+    export class RockProceduralTexture extends ProceduralTexture {
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "rock", scene, fallbackTexture, generateMipMaps);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+    }
+
+    export class RoadProceduralTexture extends ProceduralTexture {
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "road", scene, fallbackTexture, generateMipMaps);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+    }
+
+
+    export class BrickProceduralTexture extends ProceduralTexture {
+
+        private _numberOfBricksHeight: number = 15;
+        private _numberOfBricksWidth: number = 5;
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "brick", scene, fallbackTexture, generateMipMaps);
+
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+
+        public updateShaderUniforms() {
+
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
+        }
+
+
+        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();
+        }
+    }
+
+
+    export class MarbleProceduralTexture extends ProceduralTexture {
+
+        private _numberOfBricksHeight: number = 3;
+        private _numberOfBricksWidth: number = 3;
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "marble", scene, fallbackTexture, generateMipMaps);
+
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+
+        public updateShaderUniforms() {
+
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
+        }
+
+        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();
+        }
+
+    }
+
 }

+ 8 - 0
Babylon/Materials/textures/babylon.texture.js

@@ -190,6 +190,14 @@ var BABYLON;
 
             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;

+ 5 - 0
Babylon/Materials/textures/babylon.texture.ts

@@ -224,5 +224,10 @@
 
             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);
+        }
     }
 } 

+ 27 - 3
Babylon/Math/babylon.math.js

@@ -2281,9 +2281,11 @@
     BABYLON.Frustum = Frustum;
 
     var Ray = (function () {
-        function Ray(origin, direction) {
+        function Ray(origin, direction, length) {
+            if (typeof length === "undefined") { length = Number.MAX_VALUE; }
             this.origin = origin;
             this.direction = direction;
+            this.length = length;
         }
         // Methods
         Ray.prototype.intersectsBoxMinMax = function (minimum, maximum) {
@@ -2422,7 +2424,13 @@
                 return null;
             }
 
-            return new BABYLON.IntersectionInfo(bu, bv, Vector3.Dot(this._edge2, this._qvec) * invdet);
+            //check if the distance is longer than the predefined length.
+            var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+            if (distance > this.length) {
+                return null;
+            }
+
+            return new BABYLON.IntersectionInfo(bu, bv, distance);
         };
 
         // Statics
@@ -2436,11 +2444,27 @@
             return new Ray(start, direction);
         };
 
+        /**
+        * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
+        * transformed to the given world matrix.
+        * @param origin The origin point
+        * @param end The end point
+        * @param world a matrix to transform the ray to. Default is the identity matrix.
+        */
+        Ray.CreateNewFromTo = function (origin, end, world) {
+            if (typeof world === "undefined") { world = BABYLON.Matrix.Identity(); }
+            var direction = end.subtract(origin);
+            var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
+            direction.normalize();
+
+            return Ray.Transform(new Ray(origin, direction, length), world);
+        };
+
         Ray.Transform = function (ray, matrix) {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         };
         return Ray;
     })();

+ 24 - 3
Babylon/Math/babylon.math.ts

@@ -2280,7 +2280,7 @@
         private _tvec: Vector3;
         private _qvec: Vector3;
 
-        constructor(public origin: Vector3, public direction: Vector3) {
+        constructor(public origin: Vector3, public direction: Vector3, public length: number = Number.MAX_VALUE) {
         }
 
         // Methods
@@ -2423,7 +2423,13 @@
                 return null;
             }
 
-            return new IntersectionInfo(bu, bv, Vector3.Dot(this._edge2, this._qvec) * invdet);
+            //check if the distance is longer than the predefined length.
+            var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+            if (distance > this.length) {
+                return null;
+            }
+
+            return new IntersectionInfo(bu, bv, distance);
         }
 
         // Statics
@@ -2437,11 +2443,26 @@
             return new Ray(start, direction);
         }
 
+        /**
+        * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be 
+        * transformed to the given world matrix.
+        * @param origin The origin point
+        * @param end The end point
+        * @param world a matrix to transform the ray to. Default is the identity matrix.
+        */
+        public static CreateNewFromTo(origin: BABYLON.Vector3, end: BABYLON.Vector3, world: Matrix = BABYLON.Matrix.Identity()): Ray {
+            var direction = end.subtract(origin);
+            var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
+            direction.normalize();
+
+            return Ray.Transform(new Ray(origin, direction, length), world);
+        }
+
         public static Transform(ray: Ray, matrix: Matrix): Ray {
             var newOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, matrix);
             var newDirection = BABYLON.Vector3.TransformNormal(ray.direction, matrix);
 
-            return new Ray(newOrigin, newDirection);
+            return new Ray(newOrigin, newDirection, ray.length);
         }
     }
 

+ 16 - 0
Babylon/Mesh/babylon.abstractMesh.js

@@ -547,6 +547,22 @@ var BABYLON;
             return this._physicRestitution;
         };
 
+        AbstractMesh.prototype.getPositionInCameraSpace = function (camera) {
+            if (!camera) {
+                camera = this.getScene().activeCamera;
+            }
+
+            return BABYLON.Vector3.TransformCoordinates(this.absolutePosition, camera.getViewMatrix());
+        };
+
+        AbstractMesh.prototype.getDistanceToCamera = function (camera) {
+            if (!camera) {
+                camera = this.getScene().activeCamera;
+            }
+
+            return this.absolutePosition.subtract(camera.position);
+        };
+
         AbstractMesh.prototype.applyImpulse = function (force, contactPoint) {
             if (!this._physicImpostor) {
                 return;

+ 16 - 0
Babylon/Mesh/babylon.abstractMesh.ts

@@ -540,6 +540,22 @@
             return this._physicRestitution;
         }
 
+        public getPositionInCameraSpace(camera?: Camera): Vector3 {
+            if (!camera) {
+                camera = this.getScene().activeCamera;
+            }
+
+            return Vector3.TransformCoordinates(this.absolutePosition, camera.getViewMatrix());
+        }
+
+        public getDistanceToCamera(camera?: Camera): Vector3 {
+            if (!camera) {
+                camera = this.getScene().activeCamera;
+            }
+
+            return this.absolutePosition.subtract(camera.position);
+        }
+
         public applyImpulse(force: Vector3, contactPoint: Vector3): void {
             if (!this._physicImpostor) {
                 return;

+ 10 - 10
Babylon/Mesh/babylon.csg.js

@@ -303,11 +303,11 @@
                 for (var i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3) {
                     vertices = [];
                     for (var j = 0; j < 3; j++) {
-                        normal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
+                        var sourceNormal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
                         uv = new BABYLON.Vector2(uvs[indices[i + j] * 2], uvs[indices[i + j] * 2 + 1]);
-                        position = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
-                        BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, position);
-                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
+                        var sourcePosition = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
+                        position = BABYLON.Vector3.TransformCoordinates(sourcePosition, matrix);
+                        normal = BABYLON.Vector3.TransformNormal(sourceNormal, matrix);
 
                         vertex = new Vertex(position, normal, uv);
                         vertices.push(vertex);
@@ -506,17 +506,17 @@
                         vertex.copyFrom(polygon.vertices[polygonIndices[k]].pos);
                         normal.copyFrom(polygon.vertices[polygonIndices[k]].normal);
                         uv.copyFrom(polygon.vertices[polygonIndices[k]].uv);
-                        BABYLON.Vector3.TransformCoordinatesToRef(vertex, matrix, vertex);
-                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
+                        var localVertex = BABYLON.Vector3.TransformCoordinates(vertex, matrix);
+                        var localNormal = BABYLON.Vector3.TransformNormal(normal, matrix);
 
-                        vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
+                        vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z];
 
                         // Check if 2 points can be merged
-                        if (!(typeof vertex_idx !== 'undefined' && normals[vertex_idx * 3] === normal.x && normals[vertex_idx * 3 + 1] === normal.y && normals[vertex_idx * 3 + 2] === normal.z && uvs[vertex_idx * 2] === uv.x && uvs[vertex_idx * 2 + 1] === uv.y)) {
-                            vertices.push(vertex.x, vertex.y, vertex.z);
+                        if (!(typeof vertex_idx !== 'undefined' && normals[vertex_idx * 3] === localNormal.x && normals[vertex_idx * 3 + 1] === localNormal.y && normals[vertex_idx * 3 + 2] === localNormal.z && uvs[vertex_idx * 2] === uv.x && uvs[vertex_idx * 2 + 1] === uv.y)) {
+                            vertices.push(localVertex.x, localVertex.y, localVertex.z);
                             uvs.push(uv.x, uv.y);
                             normals.push(normal.x, normal.y, normal.z);
-                            vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = (vertices.length / 3) - 1;
+                            vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z] = (vertices.length / 3) - 1;
                         }
 
                         indices.push(vertex_idx);

+ 12 - 14
Babylon/Mesh/babylon.csg.ts

@@ -306,11 +306,11 @@
                 for (var i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3) {
                     vertices = [];
                     for (var j = 0; j < 3; j++) {
-                        normal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
+                        var sourceNormal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
                         uv = new BABYLON.Vector2(uvs[indices[i + j] * 2], uvs[indices[i + j] * 2 + 1]);
-                        position = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
-                        BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, position);
-                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
+                        var sourcePosition = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
+                        position = BABYLON.Vector3.TransformCoordinates(sourcePosition, matrix);
+                        normal = BABYLON.Vector3.TransformNormal(sourceNormal, matrix);
 
                         vertex = new Vertex(position, normal, uv);
                         vertices.push(vertex);
@@ -522,24 +522,22 @@
                         vertex.copyFrom(polygon.vertices[polygonIndices[k]].pos);
                         normal.copyFrom(polygon.vertices[polygonIndices[k]].normal);
                         uv.copyFrom(polygon.vertices[polygonIndices[k]].uv);
-                        BABYLON.Vector3.TransformCoordinatesToRef(vertex, matrix, vertex);
-                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
+                        var localVertex = BABYLON.Vector3.TransformCoordinates(vertex, matrix);
+                        var localNormal = BABYLON.Vector3.TransformNormal(normal, matrix);
 
-
-
-                        vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
+                        vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z];
 
                         // Check if 2 points can be merged
                         if (!(typeof vertex_idx !== 'undefined' &&
-                            normals[vertex_idx * 3] === normal.x &&
-                            normals[vertex_idx * 3 + 1] === normal.y &&
-                            normals[vertex_idx * 3 + 2] === normal.z &&
+                            normals[vertex_idx * 3] === localNormal.x &&
+                            normals[vertex_idx * 3 + 1] === localNormal.y &&
+                            normals[vertex_idx * 3 + 2] === localNormal.z &&
                             uvs[vertex_idx * 2] === uv.x &&
                             uvs[vertex_idx * 2 + 1] === uv.y)) {
-                            vertices.push(vertex.x, vertex.y, vertex.z);
+                            vertices.push(localVertex.x, localVertex.y, localVertex.z);
                             uvs.push(uv.x, uv.y);
                             normals.push(normal.x, normal.y, normal.z);
-                            vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = (vertices.length / 3) - 1;
+                            vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z] = (vertices.length / 3) - 1;
                         }
 
                         indices.push(vertex_idx);

+ 2 - 0
Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js

@@ -13,6 +13,8 @@
             this._renderTexture.onAfterRender = afterRender;
 
             this._scene = scene;
+
+            this._renderList = renderList;
         }
         // private
         PostProcessRenderPass.prototype._incRefCount = function () {

+ 2 - 1
Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPass.ts

@@ -19,10 +19,11 @@
             this._renderTexture.onAfterRender = afterRender;
 
             this._scene = scene;
+
+            this._renderList = renderList;
         }
 
         // private
-
         public _incRefCount(): number {
             if (this._refCount === 0) {
                 this._scene.customRenderTargets.push(this._renderTexture);

+ 82 - 0
Babylon/Shaders/brick.fragment.fx

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

+ 8 - 0
Babylon/Shaders/empty.fragment.fx

@@ -0,0 +1,8 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+void main(void)
+{
+	
+}

+ 13 - 18
Babylon/Shaders/grass.fragment.fx

@@ -2,13 +2,8 @@
 precision highp float;
 #endif
 
-varying vec2 vPosition;              
-varying vec2 vUV;                    
-
-uniform float ampScale;
-uniform float ringScale;
-uniform vec3 woodColor1;
-uniform vec3 woodColor2;
+varying vec2 vPosition;
+varying vec2 vUV;
 
 
 float rand(vec2 n) {
@@ -33,17 +28,17 @@ float fbm(vec2 n) {
 
 void main(void) {
 
-	float amplifier = 100.0;
-
-	vec3 dirt = vec3(0.47, 0.27, 0.09);
-	vec3 herb = vec3(0.0, 0.39, 0.09);
-
-	float ratioy = mod(vUV.y * amplifier, 2.0 + fbm(vPosition * 2.0));
-	float ratiox = mod(vUV.x * amplifier, 2.0 + fbm(vUV * 2.0));
-		
-	dirt = dirt * ratioy;
-	herb = herb * ratiox;
-	vec3 ground = mix(dirt, herb, fbm(vUV * 2.0));
+	vec3 herb1 = vec3(0.29, 0.38, 0.02);
+	vec3 herb2 = vec3(0.36, 0.49, 0.09);
+	vec3 herb3 = vec3(0.51, 0.6, 0.28);
+	vec3 dirt = vec3(0.6, 0.46, 0.13);
+
+	vec3 ground = vec3(1,1,1);
+	
+	ground = mix(ground, herb1, rand(gl_FragCoord.xy * 4.0));
+	ground = mix(ground, herb2, rand(gl_FragCoord.xy * 8.0));
+	ground = mix(ground, herb3, rand(gl_FragCoord.xy));
+	ground = mix(ground, herb1, fbm(gl_FragCoord.xy * 16.0));
 
 	gl_FragColor = vec4(ground, 1.0);
 }

+ 104 - 0
Babylon/Shaders/marble.fragment.fx

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

+ 37 - 0
Babylon/Shaders/road.fragment.fx

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

+ 120 - 0
Babylon/Shaders/rock.fragment.fx

@@ -0,0 +1,120 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+varying vec2 vPosition;
+varying vec2 vUV;
+
+vec3 hash(vec3 x)
+{
+	x = vec3(dot(x, vec3(127.1, 311.7, 74.7)),
+		dot(x, vec3(269.5, 183.3, 246.1)),
+		dot(x, vec3(113.5, 271.9, 124.6)));
+
+	return fract(sin(x)*43758.5453123);
+}
+
+// returns closest, second closest, and cell id
+vec3 voronoi(in vec3 x)
+{
+	vec3 p = floor(x);
+	vec3 f = fract(x);
+
+	float id = 0.0;
+	vec2 res = vec2(100.0);
+	for (int k = -1; k <= 1; k++)
+		for (int j = -1; j <= 1; j++)
+			for (int i = -1; i <= 1; i++)
+			{
+		vec3 b = vec3(float(i), float(j), float(k));
+		vec3 r = vec3(b) - f + hash(p + b);
+		float d = dot(r, r);
+
+		if (d < res.x)
+		{
+			id = dot(p + b, vec3(1.0, 57.0, 113.0));
+			res = vec2(d, res.x);
+		}
+		else if (d < res.y)
+		{
+			res.y = d;
+		}
+			}
+
+	return vec3(sqrt(res), abs(id));
+}
+
+const mat3 m = mat3(0.00, 0.80, 0.60,
+	-0.80, 0.36, -0.48,
+	-0.60, -0.48, 0.64);
+
+void main(void)
+{
+	vec2 p = vUV;
+
+	// camera movement	
+	float an = 0.5*0.1;
+	vec3 ro = vec3(2.5*cos(an), 1.0, 2.5*sin(an));
+	vec3 ta = vec3(0.0, 1.0, 0.0);
+	// camera matrix
+	vec3 ww = normalize(ta - ro);
+	vec3 uu = normalize(cross(ww, vec3(0.0, 1.0, 0.0)));
+	vec3 vv = normalize(cross(uu, ww));
+	// create view ray
+	vec3 rd = normalize(p.x*uu + p.y*vv + 1.5*ww);
+
+	// sphere center	
+	vec3 sc = vec3(0.0, 1.0, 0.0);
+
+	// raytrace
+	float tmin = 10000.0;
+	vec3  nor = vec3(0.0);
+	float occ = 1.0;
+	vec3  pos = vec3(0.0);
+
+	// raytrace-plane
+	float h = (0.0 - ro.y) / rd.y;
+	if (h>0.0)
+	{
+		tmin = h;
+		nor = vec3(0.0, 1.0, 0.0);
+		pos = ro + h*rd;
+		vec3 di = sc - pos;
+		float l = length(di);
+		occ = 1.0 - dot(nor, di / l)*1.0*1.0 / (l*l);
+	}
+
+	// raytrace-sphere
+	vec3  ce = ro - sc;
+	float b = dot(rd, ce);
+	float c = dot(ce, ce) - 1.0;
+	h = b*b - c;
+	if (h>0.0)
+	{
+		h = -b - sqrt(h);
+		if (h<tmin)
+		{
+			tmin = h;
+			nor = normalize(ro + h*rd - sc);
+			occ = 0.5 + 0.5*nor.y;
+		}
+	}
+
+	// shading/lighting	
+	vec3 col = vec3(0.9);
+	if (tmin<100.0)
+	{
+		pos = ro + tmin*rd;
+
+		float f = voronoi(4.0*pos).x;
+
+		f *= occ;
+		col = vec3(f*1.2);
+		col = mix(col, vec3(0.9), 1.0 - exp(-0.003*tmin*tmin));
+	}
+
+	col = sqrt(col);
+
+
+	gl_FragColor = vec4(col, 1.0);
+}

+ 1 - 1
Babylon/Tools/babylon.tools.js

@@ -747,7 +747,7 @@
 
         Object.defineProperty(Tools, "Now", {
             get: function () {
-                if (window.performance.now) {
+                if (window.performance && window.performance.now) {
                     return window.performance.now();
                 }
 

+ 1 - 1
Babylon/Tools/babylon.tools.ts

@@ -775,7 +775,7 @@
         public static EndPerformanceCounter: (counterName: string, condition?: boolean) => void = Tools._EndPerformanceCounterDisabled;
 
         public static get Now(): number {
-            if (window.performance.now) {
+            if (window.performance && window.performance.now) {
                 return window.performance.now();
             }
 

File diff ditekan karena terlalu besar
+ 337 - 15
babylon.2.0-alpha.debug.js


File diff ditekan karena terlalu besar
+ 11 - 11
babylon.2.0-alpha.js


+ 52 - 1
babylon.2.0.d.ts

@@ -1896,6 +1896,7 @@ declare module BABYLON {
         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;
     }
 }
 declare module BABYLON {
@@ -1908,6 +1909,20 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    class CustomProceduralTexture extends ProceduralTexture {
+        private _generateTime;
+        private _time;
+        private _shaderLoaded;
+        private _config;
+        private _texturePath;
+        constructor(name: string, texturePath: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        private loadJson(jsonUrl);
+        public render(useCameraPostProcess?: boolean): void;
+        public updateShaderUniforms(): void;
+        public generateTime : boolean;
+    }
+}
+declare module BABYLON {
     class ProceduralTexture extends Texture {
         private _size;
         public _generateMipMaps: boolean;
@@ -1934,6 +1949,7 @@ declare module BABYLON {
         constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
         public isReady(): boolean;
         public resetRefreshCounter(): void;
+        public setFragment(fragment: any): void;
         public refreshRate : number;
         public _shouldRender(): boolean;
         public getRenderSize(): number;
@@ -1992,6 +2008,30 @@ declare module BABYLON {
     class GrassProceduralTexture extends ProceduralTexture {
         constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
     }
+    class RockProceduralTexture extends ProceduralTexture {
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+    }
+    class RoadProceduralTexture extends ProceduralTexture {
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+    }
+    class BrickProceduralTexture extends ProceduralTexture {
+        private _numberOfBricksHeight;
+        private _numberOfBricksWidth;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public numberOfBricksHeight : number;
+        public cloudColor : number;
+        public numberOfBricksWidth : number;
+    }
+    class MarbleProceduralTexture extends ProceduralTexture {
+        private _numberOfBricksHeight;
+        private _numberOfBricksWidth;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        public updateShaderUniforms(): void;
+        public numberOfBricksHeight : number;
+        public cloudColor : number;
+        public numberOfBricksWidth : number;
+    }
 }
 declare module BABYLON {
     class Color3 {
@@ -2324,17 +2364,26 @@ declare module BABYLON {
     class Ray {
         public origin: Vector3;
         public direction: Vector3;
+        public length: number;
         private _edge1;
         private _edge2;
         private _pvec;
         private _tvec;
         private _qvec;
-        constructor(origin: Vector3, direction: Vector3);
+        constructor(origin: Vector3, direction: Vector3, length?: number);
         public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3): boolean;
         public intersectsBox(box: BoundingBox): boolean;
         public intersectsSphere(sphere: any): boolean;
         public intersectsTriangle(vertex0: Vector3, vertex1: Vector3, vertex2: Vector3): IntersectionInfo;
         static CreateNew(x: number, y: number, viewportWidth: number, viewportHeight: number, world: Matrix, view: Matrix, projection: Matrix): Ray;
+        /**
+        * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
+        * transformed to the given world matrix.
+        * @param origin The origin point
+        * @param end The end point
+        * @param world a matrix to transform the ray to. Default is the identity matrix.
+        */
+        static CreateNewFromTo(origin: Vector3, end: Vector3, world?: Matrix): Ray;
         static Transform(ray: Ray, matrix: Matrix): Ray;
     }
     enum Space {
@@ -2453,6 +2502,8 @@ declare module BABYLON {
         public getPhysicsMass(): number;
         public getPhysicsFriction(): number;
         public getPhysicsRestitution(): number;
+        public getPositionInCameraSpace(camera?: Camera): Vector3;
+        public getDistanceToCamera(camera?: Camera): Vector3;
         public applyImpulse(force: Vector3, contactPoint: Vector3): void;
         public setPhysicsLinkWith(otherMesh: Mesh, pivot1: Vector3, pivot2: Vector3, options?: any): void;
         public updatePhysicsBodyPosition(): void;