Browse Source

Merge remote-tracking branch 'BabylonJS/master' into viewer-changes-new

Raanan Weber 7 years ago
parent
commit
d4a087a20a
88 changed files with 18369 additions and 17500 deletions
  1. 5167 5114
      Playground/babylon.d.txt
  2. 4856 4804
      dist/preview release/babylon.d.ts
  3. 50 50
      dist/preview release/babylon.js
  4. 320 167
      dist/preview release/babylon.max.js
  5. 51 51
      dist/preview release/babylon.worker.js
  6. 6384 6332
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 54 54
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 322 169
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 322 169
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  10. 320 167
      dist/preview release/es6.js
  11. 3 3
      dist/preview release/gui/babylon.gui.min.js
  12. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  14. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  15. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  16. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  17. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  18. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  19. 2 2
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.min.js
  21. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  22. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  23. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  25. 2 2
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  26. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  27. 2 2
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  29. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  31. 2 2
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  32. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  33. 2 2
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  34. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  35. 2 2
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  37. 2 2
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  39. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.min.js
  41. 2 2
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  42. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  43. 2 2
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  44. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  45. 2 2
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  46. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  47. 25 25
      dist/preview release/materialsLibrary/babylonjs.materials.js
  48. 6 6
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  49. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  50. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  51. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  52. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  53. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  54. 2 78
      dist/preview release/typedocValidationBaseline.json
  55. 62 62
      dist/preview release/viewer/babylon.viewer.js
  56. 2 0
      dist/preview release/what's new.md
  57. 2 2
      materialsLibrary/src/cell/babylon.cellMaterial.ts
  58. 2 2
      materialsLibrary/src/custom/babylon.customMaterial.ts
  59. 1 1
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  60. 2 2
      materialsLibrary/src/fur/babylon.furMaterial.ts
  61. 2 2
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  62. 1 1
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  63. 2 2
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  64. 2 2
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  65. 2 2
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  66. 2 2
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  67. 1 1
      materialsLibrary/src/sky/babylon.skyMaterial.ts
  68. 2 2
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts
  69. 2 2
      materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts
  70. 2 2
      materialsLibrary/src/water/babylon.waterMaterial.ts
  71. 13 2
      src/Engine/babylon.engine.ts
  72. 2 2
      src/Materials/Background/babylon.backgroundMaterial.ts
  73. 3 3
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  74. 4 4
      src/Materials/PBR/babylon.pbrMaterial.ts
  75. 1 1
      src/Materials/Textures/babylon.baseTexture.ts
  76. 109 108
      src/Materials/babylon.effect.ts
  77. 1 1
      src/Materials/babylon.fresnelParameters.ts
  78. 26 2
      src/Materials/babylon.material.ts
  79. 14 8
      src/Materials/babylon.materialHelper.ts
  80. 5 5
      src/Materials/babylon.standardMaterial.ts
  81. 19 1
      src/Mesh/babylon.abstractMesh.ts
  82. 15 2
      src/Particles/babylon.boxParticleEmitter.ts
  83. 13 1
      src/Particles/babylon.coneParticleEmitter.ts
  84. 6 0
      src/Particles/babylon.iParticleEmitterType.ts
  85. 27 3
      src/Particles/babylon.sphereParticleEmitter.ts
  86. 39 16
      src/Tools/babylon.promise.ts
  87. 11 0
      src/babylon.scene.ts
  88. 27 2
      tests/unit/babylon/promises/babylon.promises.tests.ts

File diff suppressed because it is too large
+ 5167 - 5114
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 4856 - 4804
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 50 - 50
dist/preview release/babylon.js


+ 320 - 167
dist/preview release/babylon.max.js

@@ -153,28 +153,31 @@ var __extends = (this && this.__extends) || (function () {
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -229,25 +232,23 @@ var __extends = (this && this.__extends) || (function () {
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -257,31 +258,28 @@ var __extends = (this && this.__extends) || (function () {
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -291,7 +289,7 @@ var __extends = (this && this.__extends) || (function () {
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -320,16 +318,14 @@ var __extends = (this && this.__extends) || (function () {
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -353,80 +349,86 @@ var __extends = (this && this.__extends) || (function () {
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
                         }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
+                            }
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8292,6 +8294,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8314,23 +8317,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8343,14 +8358,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8364,18 +8379,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
+                }
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
                 }
-                return returnedPromise;
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8389,12 +8427,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9846,7 +9885,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -11661,8 +11700,8 @@ var BABYLON;
             // establish the file extension, if possible
             var lastDot = url.lastIndexOf('.');
             var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
-            var isDDS = this.getCaps().s3tc && (extension === ".dds");
-            var isTGA = (extension === ".tga");
+            var isDDS = this.getCaps().s3tc && (extension.indexOf(".dds") === 0);
+            var isTGA = (extension.indexOf(".tga") === 0);
             // determine if a ktx file should be substituted
             var isKTX = false;
             if (this._textureFormatInUse && !isBase64 && !fallBack) {
@@ -13809,6 +13848,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -15638,7 +15688,7 @@ var BABYLON;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
             _this._isOcclusionQueryInProgress = false;
-            _this.visibility = 1.0;
+            _this._visibility = 1.0;
             _this.alphaIndex = Number.MAX_VALUE;
             _this.isVisible = true;
             _this.isPickable = true;
@@ -15873,6 +15923,26 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "visibility", {
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            get: function () {
+                return this._visibility;
+            },
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            set: function (value) {
+                if (this._visibility === value) {
+                    return;
+                }
+                this._visibility = value;
+                this._markSubMeshesAsMiscDirty();
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -15920,6 +15990,7 @@ var BABYLON;
                 }
                 this._hasVertexAlpha = value;
                 this._markSubMeshesAsAttributesDirty();
+                this._markSubMeshesAsMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -23547,6 +23618,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -24545,7 +24627,7 @@ var BABYLON;
                 }
                 this._hasAlpha = value;
                 if (this._scene) {
-                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag);
+                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag | BABYLON.Material.MiscDirtyFlag);
                 }
             },
             enumerable: true,
@@ -28872,7 +28954,7 @@ var BABYLON;
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnlyOnce = false;
             this.state = "";
-            this.alpha = 1.0;
+            this._alpha = 1.0;
             this._backFaceCulling = true;
             this.doNotSerialize = false;
             this.storeEffectOnSubMeshes = false;
@@ -29028,6 +29110,20 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(Material.prototype, "alpha", {
+            get: function () {
+                return this._alpha;
+            },
+            set: function (value) {
+                if (this._alpha === value) {
+                    return;
+                }
+                this._alpha = value;
+                this.markAsDirty(Material.MiscDirtyFlag);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Material.prototype, "backFaceCulling", {
             get: function () {
                 return this._backFaceCulling;
@@ -29366,6 +29462,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsFresnelDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsFresnelDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsFresnelAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsFresnelDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype._markAllSubMeshesAsLightsDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsLightDirty(); });
         };
@@ -29375,6 +29477,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsMiscDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsMiscDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsTexturesAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsTexturesDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -29488,8 +29596,8 @@ var BABYLON;
             BABYLON.serialize()
         ], Material.prototype, "state", void 0);
         __decorate([
-            BABYLON.serialize()
-        ], Material.prototype, "alpha", void 0);
+            BABYLON.serialize("alpha")
+        ], Material.prototype, "_alpha", void 0);
         __decorate([
             BABYLON.serialize("backFaceCulling")
         ], Material.prototype, "_backFaceCulling", void 0);
@@ -35825,32 +35933,39 @@ var BABYLON;
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
             }
         };
-        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, defines) {
+        /**
+         * Helper used to prepare the list of defines associated with misc. values for shader compilation
+         * @param mesh defines the current mesh
+         * @param scene defines the current scene
+         * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
+         * @param pointsCloud defines if point cloud rendering has to be turned on
+         * @param fogEnabled defines if fog has to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         * @param defines defines the current list of defines
+         */
+        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, alphaTest, defines) {
             if (defines._areMiscDirty) {
                 defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
                 defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
                 defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && fogEnabled);
                 defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
+                defines["ALPHATEST"] = alphaTest;
             }
         };
         /**
-         * Helper used to prepare the list of defines for shader compilation
+         * Helper used to prepare the list of defines associated with frame values for shader compilation
          * @param scene defines the current scene
          * @param engine defines the current engine
          * @param defines specifies the list of active defines
          * @param useInstances defines if instances have to be turned on
          * @param alphaTest defines if alpha testing has to be turned on
          */
-        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances, alphaTest) {
+        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances) {
             var changed = false;
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
                 defines["CLIPPLANE"] = !defines["CLIPPLANE"];
                 changed = true;
             }
-            if (defines["ALPHATEST"] !== alphaTest) {
-                defines["ALPHATEST"] = !defines["ALPHATEST"];
-                changed = true;
-            }
             if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
                 defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
                 changed = true;
@@ -36826,11 +36941,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -37482,7 +37597,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("diffuseTexture")
         ], StandardMaterial.prototype, "_diffuseTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "diffuseTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("ambientTexture")
@@ -37494,7 +37609,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("opacityTexture")
         ], StandardMaterial.prototype, "_opacityTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("reflectionTexture")
@@ -37626,7 +37741,7 @@ var BABYLON;
             BABYLON.serializeAsFresnelParameters("opacityFresnelParameters")
         ], StandardMaterial.prototype, "_opacityFresnelParameters", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty")
         ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
         __decorate([
             BABYLON.serializeAsFresnelParameters("reflectionFresnelParameters")
@@ -38096,7 +38211,7 @@ var BABYLON;
                 }
                 this._transparencyMode = value;
                 this._forceAlphaTest = (value === BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
-                this._markAllSubMeshesAsTexturesDirty();
+                this._markAllSubMeshesAsTexturesAndMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -38423,9 +38538,9 @@ var BABYLON;
             defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
             defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
                 var bufferMesh = null;
@@ -39658,7 +39773,7 @@ var BABYLON;
         ], PBRMaterial.prototype, "ambientTextureStrength", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
@@ -39742,15 +39857,15 @@ var BABYLON;
         ], PBRMaterial.prototype, "useLightmapAsShadowmap", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "useAlphaFromAlbedoTexture", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "forceAlphaTest", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "alphaCutOff", void 0);
         __decorate([
             BABYLON.serialize(),
@@ -48565,6 +48680,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        BoxParticleEmitter.prototype.clone = function () {
+            var newOne = new BoxParticleEmitter(this._particleSystem);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -48664,6 +48788,15 @@ var BABYLON;
             var randY = h;
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        ConeParticleEmitter.prototype.clone = function () {
+            var newOne = new ConeParticleEmitter(this.radius, this.angle, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -48729,6 +48862,15 @@ var BABYLON;
             var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -48771,6 +48913,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.direction1.z, this.direction2.z);
             BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereDirectedParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -48780,7 +48931,7 @@ var BABYLON;
 
 
 
-//# sourceMappingURL=babylon.iParticleEmitterType.js.map
+//# sourceMappingURL=babylon.IParticleEmitterType.js.map
 
 var BABYLON;
 (function (BABYLON) {
@@ -55035,9 +55186,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {
@@ -58993,7 +59143,7 @@ var BABYLON;
                     return;
                 }
                 this._isEnabled = value;
-                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag);
+                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag | BABYLON.Material.MiscDirtyFlag);
             },
             enumerable: true,
             configurable: true
@@ -77211,9 +77361,8 @@ var BABYLON;
                 if (this._teleportationInitialized && this._isTeleportationFloor(hit.pickedMesh) && hit.pickedPoint) {
                     // Moving the teleportation area to this targetted point
                     //Raise onSelectedMeshUnselected observable if ray collided floor mesh/meshes and a non floor mesh was previously selected
-                    if (this._currentMeshSelected &&
-                        !this._isTeleportationFloor(this._currentMeshSelected)) {
-                        this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+                    if (this._currentMeshSelected && !this._isTeleportationFloor(this._currentMeshSelected)) {
+                        this._notifySelectedMeshUnselected();
                     }
                     this._currentMeshSelected = null;
                     this._moveTeleportationSelectorTo(hit);
@@ -77244,9 +77393,7 @@ var BABYLON;
                         }
                     }
                     else {
-                        if (this._currentMeshSelected) {
-                            this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
-                        }
+                        this._notifySelectedMeshUnselected();
                         this._currentMeshSelected = null;
                         this.changeGazeColor(new BABYLON.Color3(0.7, 0.7, 0.7));
                         this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
@@ -77255,6 +77402,7 @@ var BABYLON;
             }
             else {
                 this._currentHit = null;
+                this._notifySelectedMeshUnselected();
                 this._currentMeshSelected = null;
                 this._teleportationAllowed = false;
                 this._hideTeleportationTarget();
@@ -77262,6 +77410,11 @@ var BABYLON;
                 this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
             }
         };
+        VRExperienceHelper.prototype._notifySelectedMeshUnselected = function () {
+            if (this._currentMeshSelected) {
+                this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+            }
+        };
         /**
          * Sets the color of the laser ray from the vr controllers.
          * @param color new color for the ray.
@@ -84129,9 +84282,9 @@ var BABYLON;
                 this._imageProcessingConfiguration.prepareDefines(defines);
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
                 if (mesh) {

File diff suppressed because it is too large
+ 51 - 51
dist/preview release/babylon.worker.js


File diff suppressed because it is too large
+ 6384 - 6332
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


File diff suppressed because it is too large
+ 54 - 54
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 322 - 169
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -153,28 +153,31 @@ var __extends = (this && this.__extends) || (function () {
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -229,25 +232,23 @@ var __extends = (this && this.__extends) || (function () {
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -257,31 +258,28 @@ var __extends = (this && this.__extends) || (function () {
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -291,7 +289,7 @@ var __extends = (this && this.__extends) || (function () {
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -320,16 +318,14 @@ var __extends = (this && this.__extends) || (function () {
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -353,80 +349,86 @@ var __extends = (this && this.__extends) || (function () {
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
-                        }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
+                        }
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
+                            }
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8292,6 +8294,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8314,23 +8317,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8343,14 +8358,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8364,18 +8379,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8389,12 +8427,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9846,7 +9885,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -11661,8 +11700,8 @@ var BABYLON;
             // establish the file extension, if possible
             var lastDot = url.lastIndexOf('.');
             var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
-            var isDDS = this.getCaps().s3tc && (extension === ".dds");
-            var isTGA = (extension === ".tga");
+            var isDDS = this.getCaps().s3tc && (extension.indexOf(".dds") === 0);
+            var isTGA = (extension.indexOf(".tga") === 0);
             // determine if a ktx file should be substituted
             var isKTX = false;
             if (this._textureFormatInUse && !isBase64 && !fallBack) {
@@ -13809,6 +13848,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -15638,7 +15688,7 @@ var BABYLON;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
             _this._isOcclusionQueryInProgress = false;
-            _this.visibility = 1.0;
+            _this._visibility = 1.0;
             _this.alphaIndex = Number.MAX_VALUE;
             _this.isVisible = true;
             _this.isPickable = true;
@@ -15873,6 +15923,26 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "visibility", {
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            get: function () {
+                return this._visibility;
+            },
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            set: function (value) {
+                if (this._visibility === value) {
+                    return;
+                }
+                this._visibility = value;
+                this._markSubMeshesAsMiscDirty();
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -15920,6 +15990,7 @@ var BABYLON;
                 }
                 this._hasVertexAlpha = value;
                 this._markSubMeshesAsAttributesDirty();
+                this._markSubMeshesAsMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -23547,6 +23618,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -24545,7 +24627,7 @@ var BABYLON;
                 }
                 this._hasAlpha = value;
                 if (this._scene) {
-                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag);
+                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag | BABYLON.Material.MiscDirtyFlag);
                 }
             },
             enumerable: true,
@@ -28872,7 +28954,7 @@ var BABYLON;
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnlyOnce = false;
             this.state = "";
-            this.alpha = 1.0;
+            this._alpha = 1.0;
             this._backFaceCulling = true;
             this.doNotSerialize = false;
             this.storeEffectOnSubMeshes = false;
@@ -29028,6 +29110,20 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(Material.prototype, "alpha", {
+            get: function () {
+                return this._alpha;
+            },
+            set: function (value) {
+                if (this._alpha === value) {
+                    return;
+                }
+                this._alpha = value;
+                this.markAsDirty(Material.MiscDirtyFlag);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Material.prototype, "backFaceCulling", {
             get: function () {
                 return this._backFaceCulling;
@@ -29366,6 +29462,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsFresnelDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsFresnelDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsFresnelAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsFresnelDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype._markAllSubMeshesAsLightsDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsLightDirty(); });
         };
@@ -29375,6 +29477,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsMiscDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsMiscDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsTexturesAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsTexturesDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -29488,8 +29596,8 @@ var BABYLON;
             BABYLON.serialize()
         ], Material.prototype, "state", void 0);
         __decorate([
-            BABYLON.serialize()
-        ], Material.prototype, "alpha", void 0);
+            BABYLON.serialize("alpha")
+        ], Material.prototype, "_alpha", void 0);
         __decorate([
             BABYLON.serialize("backFaceCulling")
         ], Material.prototype, "_backFaceCulling", void 0);
@@ -35825,32 +35933,39 @@ var BABYLON;
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
             }
         };
-        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, defines) {
+        /**
+         * Helper used to prepare the list of defines associated with misc. values for shader compilation
+         * @param mesh defines the current mesh
+         * @param scene defines the current scene
+         * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
+         * @param pointsCloud defines if point cloud rendering has to be turned on
+         * @param fogEnabled defines if fog has to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         * @param defines defines the current list of defines
+         */
+        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, alphaTest, defines) {
             if (defines._areMiscDirty) {
                 defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
                 defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
                 defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && fogEnabled);
                 defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
+                defines["ALPHATEST"] = alphaTest;
             }
         };
         /**
-         * Helper used to prepare the list of defines for shader compilation
+         * Helper used to prepare the list of defines associated with frame values for shader compilation
          * @param scene defines the current scene
          * @param engine defines the current engine
          * @param defines specifies the list of active defines
          * @param useInstances defines if instances have to be turned on
          * @param alphaTest defines if alpha testing has to be turned on
          */
-        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances, alphaTest) {
+        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances) {
             var changed = false;
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
                 defines["CLIPPLANE"] = !defines["CLIPPLANE"];
                 changed = true;
             }
-            if (defines["ALPHATEST"] !== alphaTest) {
-                defines["ALPHATEST"] = !defines["ALPHATEST"];
-                changed = true;
-            }
             if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
                 defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
                 changed = true;
@@ -36826,11 +36941,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -37482,7 +37597,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("diffuseTexture")
         ], StandardMaterial.prototype, "_diffuseTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "diffuseTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("ambientTexture")
@@ -37494,7 +37609,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("opacityTexture")
         ], StandardMaterial.prototype, "_opacityTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("reflectionTexture")
@@ -37626,7 +37741,7 @@ var BABYLON;
             BABYLON.serializeAsFresnelParameters("opacityFresnelParameters")
         ], StandardMaterial.prototype, "_opacityFresnelParameters", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty")
         ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
         __decorate([
             BABYLON.serializeAsFresnelParameters("reflectionFresnelParameters")
@@ -38096,7 +38211,7 @@ var BABYLON;
                 }
                 this._transparencyMode = value;
                 this._forceAlphaTest = (value === BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
-                this._markAllSubMeshesAsTexturesDirty();
+                this._markAllSubMeshesAsTexturesAndMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -38423,9 +38538,9 @@ var BABYLON;
             defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
             defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
                 var bufferMesh = null;
@@ -39658,7 +39773,7 @@ var BABYLON;
         ], PBRMaterial.prototype, "ambientTextureStrength", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
@@ -39742,15 +39857,15 @@ var BABYLON;
         ], PBRMaterial.prototype, "useLightmapAsShadowmap", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "useAlphaFromAlbedoTexture", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "forceAlphaTest", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "alphaCutOff", void 0);
         __decorate([
             BABYLON.serialize(),
@@ -48565,6 +48680,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        BoxParticleEmitter.prototype.clone = function () {
+            var newOne = new BoxParticleEmitter(this._particleSystem);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -48664,6 +48788,15 @@ var BABYLON;
             var randY = h;
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        ConeParticleEmitter.prototype.clone = function () {
+            var newOne = new ConeParticleEmitter(this.radius, this.angle, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -48729,6 +48862,15 @@ var BABYLON;
             var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -48771,6 +48913,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.direction1.z, this.direction2.z);
             BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereDirectedParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -48780,7 +48931,7 @@ var BABYLON;
 
 
 
-//# sourceMappingURL=babylon.iParticleEmitterType.js.map
+//# sourceMappingURL=babylon.IParticleEmitterType.js.map
 
 var BABYLON;
 (function (BABYLON) {
@@ -54829,9 +54980,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {
@@ -58787,7 +58937,7 @@ var BABYLON;
                     return;
                 }
                 this._isEnabled = value;
-                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag);
+                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag | BABYLON.Material.MiscDirtyFlag);
             },
             enumerable: true,
             configurable: true
@@ -77005,9 +77155,8 @@ var BABYLON;
                 if (this._teleportationInitialized && this._isTeleportationFloor(hit.pickedMesh) && hit.pickedPoint) {
                     // Moving the teleportation area to this targetted point
                     //Raise onSelectedMeshUnselected observable if ray collided floor mesh/meshes and a non floor mesh was previously selected
-                    if (this._currentMeshSelected &&
-                        !this._isTeleportationFloor(this._currentMeshSelected)) {
-                        this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+                    if (this._currentMeshSelected && !this._isTeleportationFloor(this._currentMeshSelected)) {
+                        this._notifySelectedMeshUnselected();
                     }
                     this._currentMeshSelected = null;
                     this._moveTeleportationSelectorTo(hit);
@@ -77038,9 +77187,7 @@ var BABYLON;
                         }
                     }
                     else {
-                        if (this._currentMeshSelected) {
-                            this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
-                        }
+                        this._notifySelectedMeshUnselected();
                         this._currentMeshSelected = null;
                         this.changeGazeColor(new BABYLON.Color3(0.7, 0.7, 0.7));
                         this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
@@ -77049,6 +77196,7 @@ var BABYLON;
             }
             else {
                 this._currentHit = null;
+                this._notifySelectedMeshUnselected();
                 this._currentMeshSelected = null;
                 this._teleportationAllowed = false;
                 this._hideTeleportationTarget();
@@ -77056,6 +77204,11 @@ var BABYLON;
                 this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
             }
         };
+        VRExperienceHelper.prototype._notifySelectedMeshUnselected = function () {
+            if (this._currentMeshSelected) {
+                this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+            }
+        };
         /**
          * Sets the color of the laser ray from the vr controllers.
          * @param color new color for the ray.
@@ -83573,9 +83726,9 @@ var BABYLON;
                 this._imageProcessingConfiguration.prepareDefines(defines);
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
                 if (mesh) {
@@ -84568,7 +84721,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

+ 322 - 169
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js

@@ -139,28 +139,31 @@ var BABYLON;
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -215,25 +218,23 @@ var BABYLON;
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -243,31 +244,28 @@ var BABYLON;
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -277,7 +275,7 @@ var BABYLON;
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -306,16 +304,14 @@ var BABYLON;
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -339,80 +335,86 @@ var BABYLON;
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
-                        }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
+                        }
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
+                            }
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8278,6 +8280,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8300,23 +8303,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8329,14 +8344,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8350,18 +8365,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8375,12 +8413,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9832,7 +9871,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -11647,8 +11686,8 @@ var BABYLON;
             // establish the file extension, if possible
             var lastDot = url.lastIndexOf('.');
             var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
-            var isDDS = this.getCaps().s3tc && (extension === ".dds");
-            var isTGA = (extension === ".tga");
+            var isDDS = this.getCaps().s3tc && (extension.indexOf(".dds") === 0);
+            var isTGA = (extension.indexOf(".tga") === 0);
             // determine if a ktx file should be substituted
             var isKTX = false;
             if (this._textureFormatInUse && !isBase64 && !fallBack) {
@@ -13795,6 +13834,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -15624,7 +15674,7 @@ var BABYLON;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
             _this._isOcclusionQueryInProgress = false;
-            _this.visibility = 1.0;
+            _this._visibility = 1.0;
             _this.alphaIndex = Number.MAX_VALUE;
             _this.isVisible = true;
             _this.isPickable = true;
@@ -15859,6 +15909,26 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "visibility", {
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            get: function () {
+                return this._visibility;
+            },
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            set: function (value) {
+                if (this._visibility === value) {
+                    return;
+                }
+                this._visibility = value;
+                this._markSubMeshesAsMiscDirty();
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -15906,6 +15976,7 @@ var BABYLON;
                 }
                 this._hasVertexAlpha = value;
                 this._markSubMeshesAsAttributesDirty();
+                this._markSubMeshesAsMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -23533,6 +23604,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -24531,7 +24613,7 @@ var BABYLON;
                 }
                 this._hasAlpha = value;
                 if (this._scene) {
-                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag);
+                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag | BABYLON.Material.MiscDirtyFlag);
                 }
             },
             enumerable: true,
@@ -28858,7 +28940,7 @@ var BABYLON;
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnlyOnce = false;
             this.state = "";
-            this.alpha = 1.0;
+            this._alpha = 1.0;
             this._backFaceCulling = true;
             this.doNotSerialize = false;
             this.storeEffectOnSubMeshes = false;
@@ -29014,6 +29096,20 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(Material.prototype, "alpha", {
+            get: function () {
+                return this._alpha;
+            },
+            set: function (value) {
+                if (this._alpha === value) {
+                    return;
+                }
+                this._alpha = value;
+                this.markAsDirty(Material.MiscDirtyFlag);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Material.prototype, "backFaceCulling", {
             get: function () {
                 return this._backFaceCulling;
@@ -29352,6 +29448,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsFresnelDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsFresnelDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsFresnelAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsFresnelDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype._markAllSubMeshesAsLightsDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsLightDirty(); });
         };
@@ -29361,6 +29463,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsMiscDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsMiscDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsTexturesAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsTexturesDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -29474,8 +29582,8 @@ var BABYLON;
             BABYLON.serialize()
         ], Material.prototype, "state", void 0);
         __decorate([
-            BABYLON.serialize()
-        ], Material.prototype, "alpha", void 0);
+            BABYLON.serialize("alpha")
+        ], Material.prototype, "_alpha", void 0);
         __decorate([
             BABYLON.serialize("backFaceCulling")
         ], Material.prototype, "_backFaceCulling", void 0);
@@ -35811,32 +35919,39 @@ var BABYLON;
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
             }
         };
-        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, defines) {
+        /**
+         * Helper used to prepare the list of defines associated with misc. values for shader compilation
+         * @param mesh defines the current mesh
+         * @param scene defines the current scene
+         * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
+         * @param pointsCloud defines if point cloud rendering has to be turned on
+         * @param fogEnabled defines if fog has to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         * @param defines defines the current list of defines
+         */
+        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, alphaTest, defines) {
             if (defines._areMiscDirty) {
                 defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
                 defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
                 defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && fogEnabled);
                 defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
+                defines["ALPHATEST"] = alphaTest;
             }
         };
         /**
-         * Helper used to prepare the list of defines for shader compilation
+         * Helper used to prepare the list of defines associated with frame values for shader compilation
          * @param scene defines the current scene
          * @param engine defines the current engine
          * @param defines specifies the list of active defines
          * @param useInstances defines if instances have to be turned on
          * @param alphaTest defines if alpha testing has to be turned on
          */
-        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances, alphaTest) {
+        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances) {
             var changed = false;
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
                 defines["CLIPPLANE"] = !defines["CLIPPLANE"];
                 changed = true;
             }
-            if (defines["ALPHATEST"] !== alphaTest) {
-                defines["ALPHATEST"] = !defines["ALPHATEST"];
-                changed = true;
-            }
             if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
                 defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
                 changed = true;
@@ -36812,11 +36927,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -37468,7 +37583,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("diffuseTexture")
         ], StandardMaterial.prototype, "_diffuseTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "diffuseTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("ambientTexture")
@@ -37480,7 +37595,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("opacityTexture")
         ], StandardMaterial.prototype, "_opacityTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("reflectionTexture")
@@ -37612,7 +37727,7 @@ var BABYLON;
             BABYLON.serializeAsFresnelParameters("opacityFresnelParameters")
         ], StandardMaterial.prototype, "_opacityFresnelParameters", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty")
         ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
         __decorate([
             BABYLON.serializeAsFresnelParameters("reflectionFresnelParameters")
@@ -38082,7 +38197,7 @@ var BABYLON;
                 }
                 this._transparencyMode = value;
                 this._forceAlphaTest = (value === BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
-                this._markAllSubMeshesAsTexturesDirty();
+                this._markAllSubMeshesAsTexturesAndMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -38409,9 +38524,9 @@ var BABYLON;
             defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
             defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
                 var bufferMesh = null;
@@ -39644,7 +39759,7 @@ var BABYLON;
         ], PBRMaterial.prototype, "ambientTextureStrength", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
@@ -39728,15 +39843,15 @@ var BABYLON;
         ], PBRMaterial.prototype, "useLightmapAsShadowmap", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "useAlphaFromAlbedoTexture", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "forceAlphaTest", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "alphaCutOff", void 0);
         __decorate([
             BABYLON.serialize(),
@@ -48551,6 +48666,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        BoxParticleEmitter.prototype.clone = function () {
+            var newOne = new BoxParticleEmitter(this._particleSystem);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -48650,6 +48774,15 @@ var BABYLON;
             var randY = h;
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        ConeParticleEmitter.prototype.clone = function () {
+            var newOne = new ConeParticleEmitter(this.radius, this.angle, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -48715,6 +48848,15 @@ var BABYLON;
             var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -48757,6 +48899,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.direction1.z, this.direction2.z);
             BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereDirectedParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -48766,7 +48917,7 @@ var BABYLON;
 
 
 
-//# sourceMappingURL=babylon.iParticleEmitterType.js.map
+//# sourceMappingURL=babylon.IParticleEmitterType.js.map
 
 var BABYLON;
 (function (BABYLON) {
@@ -54815,9 +54966,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {
@@ -58773,7 +58923,7 @@ var BABYLON;
                     return;
                 }
                 this._isEnabled = value;
-                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag);
+                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag | BABYLON.Material.MiscDirtyFlag);
             },
             enumerable: true,
             configurable: true
@@ -76991,9 +77141,8 @@ var BABYLON;
                 if (this._teleportationInitialized && this._isTeleportationFloor(hit.pickedMesh) && hit.pickedPoint) {
                     // Moving the teleportation area to this targetted point
                     //Raise onSelectedMeshUnselected observable if ray collided floor mesh/meshes and a non floor mesh was previously selected
-                    if (this._currentMeshSelected &&
-                        !this._isTeleportationFloor(this._currentMeshSelected)) {
-                        this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+                    if (this._currentMeshSelected && !this._isTeleportationFloor(this._currentMeshSelected)) {
+                        this._notifySelectedMeshUnselected();
                     }
                     this._currentMeshSelected = null;
                     this._moveTeleportationSelectorTo(hit);
@@ -77024,9 +77173,7 @@ var BABYLON;
                         }
                     }
                     else {
-                        if (this._currentMeshSelected) {
-                            this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
-                        }
+                        this._notifySelectedMeshUnselected();
                         this._currentMeshSelected = null;
                         this.changeGazeColor(new BABYLON.Color3(0.7, 0.7, 0.7));
                         this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
@@ -77035,6 +77182,7 @@ var BABYLON;
             }
             else {
                 this._currentHit = null;
+                this._notifySelectedMeshUnselected();
                 this._currentMeshSelected = null;
                 this._teleportationAllowed = false;
                 this._hideTeleportationTarget();
@@ -77042,6 +77190,11 @@ var BABYLON;
                 this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
             }
         };
+        VRExperienceHelper.prototype._notifySelectedMeshUnselected = function () {
+            if (this._currentMeshSelected) {
+                this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+            }
+        };
         /**
          * Sets the color of the laser ray from the vr controllers.
          * @param color new color for the ray.
@@ -83559,9 +83712,9 @@ var BABYLON;
                 this._imageProcessingConfiguration.prepareDefines(defines);
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
                 if (mesh) {
@@ -84554,7 +84707,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

+ 320 - 167
dist/preview release/es6.js

@@ -139,28 +139,31 @@ var BABYLON;
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -215,25 +218,23 @@ var BABYLON;
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -243,31 +244,28 @@ var BABYLON;
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -277,7 +275,7 @@ var BABYLON;
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -306,16 +304,14 @@ var BABYLON;
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -339,80 +335,86 @@ var BABYLON;
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
                         }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
+                            }
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8278,6 +8280,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8300,23 +8303,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8329,14 +8344,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8350,18 +8365,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
+                }
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
                 }
-                return returnedPromise;
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8375,12 +8413,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9832,7 +9871,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -11647,8 +11686,8 @@ var BABYLON;
             // establish the file extension, if possible
             var lastDot = url.lastIndexOf('.');
             var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
-            var isDDS = this.getCaps().s3tc && (extension === ".dds");
-            var isTGA = (extension === ".tga");
+            var isDDS = this.getCaps().s3tc && (extension.indexOf(".dds") === 0);
+            var isTGA = (extension.indexOf(".tga") === 0);
             // determine if a ktx file should be substituted
             var isKTX = false;
             if (this._textureFormatInUse && !isBase64 && !fallBack) {
@@ -13795,6 +13834,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -15624,7 +15674,7 @@ var BABYLON;
             _this._occlusionInternalRetryCounter = 0;
             _this._isOccluded = false;
             _this._isOcclusionQueryInProgress = false;
-            _this.visibility = 1.0;
+            _this._visibility = 1.0;
             _this.alphaIndex = Number.MAX_VALUE;
             _this.isVisible = true;
             _this.isPickable = true;
@@ -15859,6 +15909,26 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "visibility", {
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            get: function () {
+                return this._visibility;
+            },
+            /**
+             * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+             */
+            set: function (value) {
+                if (this._visibility === value) {
+                    return;
+                }
+                this._visibility = value;
+                this._markSubMeshesAsMiscDirty();
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(AbstractMesh.prototype, "material", {
             get: function () {
                 return this._material;
@@ -15906,6 +15976,7 @@ var BABYLON;
                 }
                 this._hasVertexAlpha = value;
                 this._markSubMeshesAsAttributesDirty();
+                this._markSubMeshesAsMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -23533,6 +23604,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -24531,7 +24613,7 @@ var BABYLON;
                 }
                 this._hasAlpha = value;
                 if (this._scene) {
-                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag);
+                    this._scene.markAllMaterialsAsDirty(BABYLON.Material.TextureDirtyFlag | BABYLON.Material.MiscDirtyFlag);
                 }
             },
             enumerable: true,
@@ -28858,7 +28940,7 @@ var BABYLON;
             this.checkReadyOnEveryCall = false;
             this.checkReadyOnlyOnce = false;
             this.state = "";
-            this.alpha = 1.0;
+            this._alpha = 1.0;
             this._backFaceCulling = true;
             this.doNotSerialize = false;
             this.storeEffectOnSubMeshes = false;
@@ -29014,6 +29096,20 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(Material.prototype, "alpha", {
+            get: function () {
+                return this._alpha;
+            },
+            set: function (value) {
+                if (this._alpha === value) {
+                    return;
+                }
+                this._alpha = value;
+                this.markAsDirty(Material.MiscDirtyFlag);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Material.prototype, "backFaceCulling", {
             get: function () {
                 return this._backFaceCulling;
@@ -29352,6 +29448,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsFresnelDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsFresnelDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsFresnelAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsFresnelDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype._markAllSubMeshesAsLightsDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsLightDirty(); });
         };
@@ -29361,6 +29463,12 @@ var BABYLON;
         Material.prototype._markAllSubMeshesAsMiscDirty = function () {
             this._markAllSubMeshesAsDirty(function (defines) { return defines.markAsMiscDirty(); });
         };
+        Material.prototype._markAllSubMeshesAsTexturesAndMiscDirty = function () {
+            this._markAllSubMeshesAsDirty(function (defines) {
+                defines.markAsTexturesDirty();
+                defines.markAsMiscDirty();
+            });
+        };
         Material.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -29474,8 +29582,8 @@ var BABYLON;
             BABYLON.serialize()
         ], Material.prototype, "state", void 0);
         __decorate([
-            BABYLON.serialize()
-        ], Material.prototype, "alpha", void 0);
+            BABYLON.serialize("alpha")
+        ], Material.prototype, "_alpha", void 0);
         __decorate([
             BABYLON.serialize("backFaceCulling")
         ], Material.prototype, "_backFaceCulling", void 0);
@@ -35811,32 +35919,39 @@ var BABYLON;
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
             }
         };
-        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, defines) {
+        /**
+         * Helper used to prepare the list of defines associated with misc. values for shader compilation
+         * @param mesh defines the current mesh
+         * @param scene defines the current scene
+         * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
+         * @param pointsCloud defines if point cloud rendering has to be turned on
+         * @param fogEnabled defines if fog has to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         * @param defines defines the current list of defines
+         */
+        MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, alphaTest, defines) {
             if (defines._areMiscDirty) {
                 defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
                 defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
                 defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && fogEnabled);
                 defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
+                defines["ALPHATEST"] = alphaTest;
             }
         };
         /**
-         * Helper used to prepare the list of defines for shader compilation
+         * Helper used to prepare the list of defines associated with frame values for shader compilation
          * @param scene defines the current scene
          * @param engine defines the current engine
          * @param defines specifies the list of active defines
          * @param useInstances defines if instances have to be turned on
          * @param alphaTest defines if alpha testing has to be turned on
          */
-        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances, alphaTest) {
+        MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances) {
             var changed = false;
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
                 defines["CLIPPLANE"] = !defines["CLIPPLANE"];
                 changed = true;
             }
-            if (defines["ALPHATEST"] !== alphaTest) {
-                defines["ALPHATEST"] = !defines["ALPHATEST"];
-                changed = true;
-            }
             if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
                 defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
                 changed = true;
@@ -36812,11 +36927,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -37468,7 +37583,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("diffuseTexture")
         ], StandardMaterial.prototype, "_diffuseTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "diffuseTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("ambientTexture")
@@ -37480,7 +37595,7 @@ var BABYLON;
             BABYLON.serializeAsTexture("opacityTexture")
         ], StandardMaterial.prototype, "_opacityTexture", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], StandardMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture("reflectionTexture")
@@ -37612,7 +37727,7 @@ var BABYLON;
             BABYLON.serializeAsFresnelParameters("opacityFresnelParameters")
         ], StandardMaterial.prototype, "_opacityFresnelParameters", void 0);
         __decorate([
-            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty")
         ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
         __decorate([
             BABYLON.serializeAsFresnelParameters("reflectionFresnelParameters")
@@ -38082,7 +38197,7 @@ var BABYLON;
                 }
                 this._transparencyMode = value;
                 this._forceAlphaTest = (value === BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
-                this._markAllSubMeshesAsTexturesDirty();
+                this._markAllSubMeshesAsTexturesAndMiscDirty();
             },
             enumerable: true,
             configurable: true
@@ -38409,9 +38524,9 @@ var BABYLON;
             defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
             defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
                 var bufferMesh = null;
@@ -39644,7 +39759,7 @@ var BABYLON;
         ], PBRMaterial.prototype, "ambientTextureStrength", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "opacityTexture", void 0);
         __decorate([
             BABYLON.serializeAsTexture(),
@@ -39728,15 +39843,15 @@ var BABYLON;
         ], PBRMaterial.prototype, "useLightmapAsShadowmap", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "useAlphaFromAlbedoTexture", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "forceAlphaTest", void 0);
         __decorate([
             BABYLON.serialize(),
-            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
+            BABYLON.expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         ], PBRMaterial.prototype, "alphaCutOff", void 0);
         __decorate([
             BABYLON.serialize(),
@@ -48551,6 +48666,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        BoxParticleEmitter.prototype.clone = function () {
+            var newOne = new BoxParticleEmitter(this._particleSystem);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -48650,6 +48774,15 @@ var BABYLON;
             var randY = h;
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        ConeParticleEmitter.prototype.clone = function () {
+            var newOne = new ConeParticleEmitter(this.radius, this.angle, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -48715,6 +48848,15 @@ var BABYLON;
             var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
             BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -48757,6 +48899,15 @@ var BABYLON;
             var randZ = BABYLON.Scalar.RandomRange(this.direction1.z, this.direction2.z);
             BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
         };
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        SphereDirectedParticleEmitter.prototype.clone = function () {
+            var newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
+            BABYLON.Tools.DeepCopy(this, newOne);
+            return newOne;
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -48766,7 +48917,7 @@ var BABYLON;
 
 
 
-//# sourceMappingURL=babylon.iParticleEmitterType.js.map
+//# sourceMappingURL=babylon.IParticleEmitterType.js.map
 
 var BABYLON;
 (function (BABYLON) {
@@ -55021,9 +55172,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {
@@ -58979,7 +59129,7 @@ var BABYLON;
                     return;
                 }
                 this._isEnabled = value;
-                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag);
+                BABYLON.Engine.MarkAllMaterialsAsDirty(BABYLON.Material.FresnelDirtyFlag | BABYLON.Material.MiscDirtyFlag);
             },
             enumerable: true,
             configurable: true
@@ -77197,9 +77347,8 @@ var BABYLON;
                 if (this._teleportationInitialized && this._isTeleportationFloor(hit.pickedMesh) && hit.pickedPoint) {
                     // Moving the teleportation area to this targetted point
                     //Raise onSelectedMeshUnselected observable if ray collided floor mesh/meshes and a non floor mesh was previously selected
-                    if (this._currentMeshSelected &&
-                        !this._isTeleportationFloor(this._currentMeshSelected)) {
-                        this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+                    if (this._currentMeshSelected && !this._isTeleportationFloor(this._currentMeshSelected)) {
+                        this._notifySelectedMeshUnselected();
                     }
                     this._currentMeshSelected = null;
                     this._moveTeleportationSelectorTo(hit);
@@ -77230,9 +77379,7 @@ var BABYLON;
                         }
                     }
                     else {
-                        if (this._currentMeshSelected) {
-                            this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
-                        }
+                        this._notifySelectedMeshUnselected();
                         this._currentMeshSelected = null;
                         this.changeGazeColor(new BABYLON.Color3(0.7, 0.7, 0.7));
                         this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
@@ -77241,6 +77388,7 @@ var BABYLON;
             }
             else {
                 this._currentHit = null;
+                this._notifySelectedMeshUnselected();
                 this._currentMeshSelected = null;
                 this._teleportationAllowed = false;
                 this._hideTeleportationTarget();
@@ -77248,6 +77396,11 @@ var BABYLON;
                 this.changeLaserColor(new BABYLON.Color3(0.7, 0.7, 0.7));
             }
         };
+        VRExperienceHelper.prototype._notifySelectedMeshUnselected = function () {
+            if (this._currentMeshSelected) {
+                this.onSelectedMeshUnselected.notifyObservers(this._currentMeshSelected);
+            }
+        };
         /**
          * Sets the color of the laser ray from the vr controllers.
          * @param color new color for the ray.
@@ -84115,9 +84268,9 @@ var BABYLON;
                 this._imageProcessingConfiguration.prepareDefines(defines);
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             if (BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
                 if (mesh) {

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


File diff suppressed because it is too large
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -98,11 +98,11 @@ var BABYLON;
             // High level
             defines.CELLBASIC = !this.computeHighLevel;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -563,11 +563,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -94,7 +94,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -143,11 +143,11 @@ var BABYLON;
                 defines.markAsUnprocessed();
             }
             // Misc.   
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -118,8 +118,8 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -110,7 +110,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -131,11 +131,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -125,11 +125,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -86,8 +86,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -92,11 +92,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -76,7 +76,7 @@ var BABYLON;
                     return true;
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -98,11 +98,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -117,11 +117,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -228,8 +228,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                     defines.FRESNELSEPARATE = true;

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 25 - 25
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -96,8 +96,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
@@ -326,8 +326,8 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
@@ -611,11 +611,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -922,11 +922,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1234,11 +1234,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1642,8 +1642,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                     defines.FRESNELSEPARATE = true;
@@ -2124,7 +2124,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
@@ -2494,11 +2494,11 @@ var BABYLON;
                 defines.markAsUnprocessed();
             }
             // Misc.   
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -2911,11 +2911,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -3317,11 +3317,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -3658,7 +3658,7 @@ var BABYLON;
                     return true;
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
             // Get correct effect      
@@ -3907,7 +3907,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -4559,11 +4559,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -6149,11 +6149,11 @@ var BABYLON;
             // High level
             defines.CELLBASIC = !this.computeHighLevel;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

File diff suppressed because it is too large
+ 6 - 6
dist/preview release/materialsLibrary/babylonjs.materials.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 2 - 78
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 8794,
+  "errors": 8780,
   "babylon.typedoc.json": {
-    "errors": 8794,
+    "errors": 8780,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -569,11 +569,6 @@
             "MissingText": true
           }
         },
-        "visibility": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "OCCLUSION_ALGORITHM_TYPE_ACCURATE": {
           "Comments": {
             "MissingText": true
@@ -10641,40 +10636,6 @@
             }
           }
         },
-        "_loadFragmentShader": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "fragment": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "callback": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "_loadVertexShader": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "vertex": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "callback": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "_prepareEffect": {
           "Comments": {
             "MissingText": true
@@ -19538,43 +19499,6 @@
             }
           }
         },
-        "PrepareDefinesForMisc": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "mesh": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "useLogarithmicDepth": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "pointsCloud": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "fogEnabled": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "defines": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "PrepareUniformsAndSamplersList": {
           "Comments": {
             "MissingText": true

File diff suppressed because it is too large
+ 62 - 62
dist/preview release/viewer/babylon.viewer.js


+ 2 - 0
dist/preview release/what's new.md

@@ -6,6 +6,7 @@
 - New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
 - `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
 - New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
+- Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
 
 ## Updates
 - Tons of functions and classes received the code comments they deserved (All the community)
@@ -32,6 +33,7 @@
    ([carloslanderas](https://github.com/carloslanderas))
 
 ## Bug fixes
+- Texture extension detection in `Engine.CreateTexture` ([sebavan](https://github.com/sebavan))
 
 ## Breaking changes
 

+ 2 - 2
materialsLibrary/src/cell/babylon.cellMaterial.ts

@@ -110,13 +110,13 @@ module BABYLON {
             defines.CELLBASIC = !this.computeHighLevel;
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -719,13 +719,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Get correct effect      
             if (defines.isDirty) {

+ 1 - 1
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -107,7 +107,7 @@ module BABYLON {
             }
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

+ 2 - 2
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -181,13 +181,13 @@ module BABYLON {
             }
 
             // Misc.   
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -128,9 +128,9 @@ module BABYLON {
 
             var engine = scene.getEngine();
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
 

+ 1 - 1
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -120,7 +120,7 @@ module BABYLON {
                 defines.markAsUnprocessed();
             }
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
 
             // Get correct effect      
             if (defines.isDirty) {

+ 2 - 2
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -153,13 +153,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -132,13 +132,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -86,9 +86,9 @@ module BABYLON {
                 }
             }
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
 

+ 2 - 2
materialsLibrary/src/simple/babylon.simpleMaterial.ts

@@ -99,13 +99,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 1 - 1
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -88,7 +88,7 @@ module BABYLON {
                 }
             }
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);

+ 2 - 2
materialsLibrary/src/terrain/babylon.terrainMaterial.ts

@@ -140,13 +140,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts

@@ -161,13 +161,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -275,9 +275,9 @@ module BABYLON {
                 }
             }
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {

+ 13 - 2
src/Engine/babylon.engine.ts

@@ -3136,8 +3136,8 @@
             // establish the file extension, if possible
             var lastDot = url.lastIndexOf('.');
             var extension = (lastDot > 0) ? url.substring(lastDot).toLowerCase() : "";
-            var isDDS = this.getCaps().s3tc && (extension === ".dds");
-            var isTGA = (extension === ".tga");
+            var isDDS = this.getCaps().s3tc && (extension.indexOf(".dds") === 0);
+            var isTGA = (extension.indexOf(".tga") === 0);
 
             // determine if a ktx file should be substituted
             var isKTX = false;
@@ -5754,6 +5754,17 @@
             return request;
         }
 
+        /** @ignore */
+        public _loadFileAsync(url: string, database?: Database, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {
+            return new Promise((resolve, reject) => {
+                this._loadFile(url, (data) => {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, (request, exception) => {
+                    reject(exception);
+                })
+            });
+        }
+
         private _partialLoadFile(url: string, index: number, loadedFiles: (string | ArrayBuffer)[], scene: Nullable<Scene>, onfinish: (files: (string | ArrayBuffer)[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null): void {
             var onload = (data: string | ArrayBuffer) => {
                 loadedFiles[index] = data;

+ 2 - 2
src/Materials/Background/babylon.backgroundMaterial.ts

@@ -696,10 +696,10 @@
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
 
             // Attribs
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {

+ 3 - 3
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -537,7 +537,7 @@
 
             this._forceAlphaTest = (value === PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
 
-            this._markAllSubMeshesAsTexturesDirty();
+            this._markAllSubMeshesAsTexturesAndMiscDirty();
         }
 
         /**
@@ -901,10 +901,10 @@
             defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {

+ 4 - 4
src/Materials/PBR/babylon.pbrMaterial.ts

@@ -101,7 +101,7 @@
         public ambientTextureStrength: number = 1.0;
 
         @serializeAsTexture()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public opacityTexture: BaseTexture;
 
         @serializeAsTexture()
@@ -225,21 +225,21 @@
          * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.
          */
         @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public useAlphaFromAlbedoTexture = false;
 
         /**
          * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
          */
         @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public forceAlphaTest = false;
 
         /**
          * Defines the alpha limits in alpha test mode.
          */
         @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public alphaCutOff = 0.4;
 
         /**

+ 1 - 1
src/Materials/Textures/babylon.baseTexture.ts

@@ -13,7 +13,7 @@
             }
             this._hasAlpha = value;
             if (this._scene) {
-                this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag);
+                this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag | Material.MiscDirtyFlag);
             }
         }
         public get hasAlpha(): boolean {

+ 109 - 108
src/Materials/babylon.effect.ts

@@ -183,28 +183,32 @@
                 fragmentSource = baseName.fragment || baseName;
             }
 
-            this._loadVertexShader(vertexSource, vertexCode => {
-                this._processIncludes(vertexCode, vertexCodeWithIncludes => {
-                    this._processShaderConversion(vertexCodeWithIncludes, false, migratedVertexCode => {
-                        this._loadFragmentShader(fragmentSource, (fragmentCode) => {
-                            this._processIncludes(fragmentCode, fragmentCodeWithIncludes => {
-                                this._processShaderConversion(fragmentCodeWithIncludes, true, migratedFragmentCode => {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-
-                                        this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    } else {
-                                        this._vertexSourceCode = migratedVertexCode;
-                                        this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            let finalVertexCode: string;
+
+            this._loadVertexShaderAsync(vertexSource)
+            .then((vertexCode) => {
+                return this._processIncludesAsync(vertexCode);
+            })
+            .then((vertexCodeWithIncludes) => {
+                finalVertexCode = this._processShaderConversion(vertexCodeWithIncludes, false);
+                return this._loadFragmentShaderAsync(fragmentSource);
+            })
+            .then((fragmentCode) => {
+                return this._processIncludesAsync(fragmentCode);
+            })
+            .then((fragmentCodeWithIncludes) => {
+                let migratedFragmentCode = this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+
+                    this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                } else {
+                    this._vertexSourceCode = finalVertexCode;
+                    this._fragmentSourceCode = migratedFragmentCode;
+                }
+                this._prepareEffect(); 
             });
         }
 
@@ -271,27 +275,25 @@
             });
         }
 
-        public _loadVertexShader(vertex: any, callback: (data: any) => void): void {
+        /** @ignore */
+        public _loadVertexShaderAsync(vertex: any): Promise<any> {
             if (Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
 
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
 
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
 
             var vertexShaderUrl;
@@ -303,35 +305,32 @@
             }
 
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         }
 
-        public _loadFragmentShader(fragment: any, callback: (data: any) => void): void {
+        /** @ignore */
+        public _loadFragmentShaderAsync(fragment: any): Promise<any>  {
             if (Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
 
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
 
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
 
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
 
             var fragmentShaderUrl;
@@ -343,7 +342,7 @@
             }
 
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         }
 
         private _dumpShadersSource(vertexCode: string, fragmentCode: string, defines: string): void {
@@ -375,19 +374,16 @@
             }
         };
 
-        private _processShaderConversion(sourceCode: string, isFragment: boolean, callback: (data: any) => void): void {
-
+        private _processShaderConversion(sourceCode: string, isFragment: boolean): any {
             var preparedSourceCode = this._processPrecision(sourceCode);
 
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
 
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
 
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
@@ -416,92 +412,97 @@
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
 
-            callback(result);
+            return result;
         }
 
-        private _processIncludes(sourceCode: string, callback: (data: any) => void): void {
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
+        private _processIncludesAsync(sourceCode: string): Promise<any> {
+            return new Promise((resolve, reject) => {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
 
-            var returnValue = new String(sourceCode);
+                var returnValue = sourceCode;
 
-            while (match != null) {
-                var includeFile = match[1];
+                while (match != null) {
+                    var includeFile = match[1];
 
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
+                        }
+                        includeFile = includeFile + "Declaration";
                     }
-                    includeFile = includeFile + "Declaration";
-                }
 
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
 
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
 
-                            includeContent = includeContent.replace(source, dest);
+                                includeContent = includeContent.replace(source, dest);
+                            }
                         }
-                    }
 
-                    if (match[4]) {
-                        var indexString = match[5];
+                        if (match[4]) {
+                            var indexString = match[5];
 
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
 
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
-                            }
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = this._indexParameters[indexSplits[1]];
+                                }
 
-                            for (var i = minIndex; i < maxIndex; i++) {
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, (str: string, p1: string) => {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
+                            } else {
                                 if (!this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, (str: string, p1: string) => {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, (str: string, p1: string) => {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
-                            }
-                        } else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, (str: string, p1: string) => {
-                                    return p1 + "{X}";
-                                });
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
                         }
-                    }
 
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                } else {
-                    var includeShaderUrl = Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
+                    } else {
+                        var includeShaderUrl = Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+
+                        this._engine._loadFileAsync(includeShaderUrl)
+                            .then((fileContent) => {
+                                Effect.IncludesShadersStore[includeFile] = fileContent as string;
+                                return this._processIncludesAsync(returnValue);
+                            })
+                            .then((returnValue) => {
+                                resolve(returnValue);
+                            });
+                        return;
+                    }
 
-                    this._engine._loadFile(includeShaderUrl, (fileContent) => {
-                        Effect.IncludesShadersStore[includeFile] = fileContent as string;
-                        this._processIncludes(<string>returnValue, callback);
-                    });
-                    return;
+                    match = regex.exec(sourceCode);
                 }
-
-                match = regex.exec(sourceCode);
-            }
-
-            callback(returnValue);
+                resolve(returnValue);
+            });            
         }
 
         private _processPrecision(source: string): string {

+ 1 - 1
src/Materials/babylon.fresnelParameters.ts

@@ -10,7 +10,7 @@
             }
 
             this._isEnabled = value;
-            Engine.MarkAllMaterialsAsDirty(Material.FresnelDirtyFlag);
+            Engine.MarkAllMaterialsAsDirty(Material.FresnelDirtyFlag | Material.MiscDirtyFlag);
         }   
 
         public leftColor = Color3.White();

+ 26 - 2
src/Materials/babylon.material.ts

@@ -251,8 +251,18 @@
         @serialize()
         public state = "";
 
-        @serialize()
-        public alpha = 1.0;
+        @serialize("alpha")
+        protected _alpha = 1.0;
+        public set alpha(value: number) {
+            if (this._alpha === value) {
+                return;
+            }
+            this._alpha = value;
+            this.markAsDirty(Material.MiscDirtyFlag);
+        }
+        public get alpha(): number {
+            return this._alpha;
+        }        
 
         @serialize("backFaceCulling")
         protected _backFaceCulling = true;
@@ -708,6 +718,13 @@
             this._markAllSubMeshesAsDirty(defines => defines.markAsFresnelDirty());
         }
 
+        protected _markAllSubMeshesAsFresnelAndMiscDirty() {
+            this._markAllSubMeshesAsDirty(defines => {
+                defines.markAsFresnelDirty();
+                defines.markAsMiscDirty();
+            });
+        }        
+
         protected _markAllSubMeshesAsLightsDirty() {
             this._markAllSubMeshesAsDirty(defines => defines.markAsLightDirty());
         }
@@ -720,6 +737,13 @@
             this._markAllSubMeshesAsDirty(defines => defines.markAsMiscDirty());
         }
 
+        protected _markAllSubMeshesAsTexturesAndMiscDirty() {
+            this._markAllSubMeshesAsDirty(defines => {
+                defines.markAsTexturesDirty();
+                defines.markAsMiscDirty();
+            });
+        }        
+
         public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
             // Animations
             this.getScene().stopAnimation(this);

+ 14 - 8
src/Materials/babylon.materialHelper.ts

@@ -32,24 +32,35 @@
             }
         }
 
-        public static PrepareDefinesForMisc(mesh: AbstractMesh, scene: Scene, useLogarithmicDepth: boolean, pointsCloud: boolean, fogEnabled: boolean, defines: any): void {
+        /**
+         * Helper used to prepare the list of defines associated with misc. values for shader compilation
+         * @param mesh defines the current mesh
+         * @param scene defines the current scene
+         * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
+         * @param pointsCloud defines if point cloud rendering has to be turned on
+         * @param fogEnabled defines if fog has to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         * @param defines defines the current list of defines
+         */
+        public static PrepareDefinesForMisc(mesh: AbstractMesh, scene: Scene, useLogarithmicDepth: boolean, pointsCloud: boolean, fogEnabled: boolean, alphaTest: boolean, defines: any): void {
             if (defines._areMiscDirty) {
                 defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
                 defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
                 defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && fogEnabled);
                 defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
+                defines["ALPHATEST"] = alphaTest;
             }
         }
 
         /**
-         * Helper used to prepare the list of defines for shader compilation
+         * Helper used to prepare the list of defines associated with frame values for shader compilation
          * @param scene defines the current scene
          * @param engine defines the current engine
          * @param defines specifies the list of active defines
          * @param useInstances defines if instances have to be turned on
          * @param alphaTest defines if alpha testing has to be turned on
          */
-        public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: any, useInstances: boolean, alphaTest: boolean): void {
+        public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: any, useInstances: boolean): void {
             var changed = false;
 
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
@@ -57,11 +68,6 @@
                 changed = true;
             }
 
-            if (defines["ALPHATEST"] !== alphaTest) {
-                defines["ALPHATEST"] = !defines["ALPHATEST"];
-                changed = true;
-            }
-
             if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
                 defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
                 changed = true;

+ 5 - 5
src/Materials/babylon.standardMaterial.ts

@@ -108,7 +108,7 @@ module BABYLON {
     export class StandardMaterial extends PushMaterial {
         @serializeAsTexture("diffuseTexture")
         private _diffuseTexture: Nullable<BaseTexture>;;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public diffuseTexture: Nullable<BaseTexture>;;
 
         @serializeAsTexture("ambientTexture")
@@ -118,7 +118,7 @@ module BABYLON {
 
         @serializeAsTexture("opacityTexture")
         private _opacityTexture: Nullable<BaseTexture>;;
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty")
         public opacityTexture: Nullable<BaseTexture>;;
 
         @serializeAsTexture("reflectionTexture")
@@ -233,7 +233,7 @@ module BABYLON {
 
         @serializeAsFresnelParameters("opacityFresnelParameters")
         private _opacityFresnelParameters: FresnelParameters;
-        @expandToProperty("_markAllSubMeshesAsFresnelDirty")
+        @expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty")
         public opacityFresnelParameters: FresnelParameters;
 
 
@@ -739,13 +739,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
 
             // Get correct effect      
             if (defines.isDirty) {

+ 19 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -205,7 +205,24 @@
 
         private _occlusionQuery: Nullable<WebGLQuery>;
 
-        public visibility = 1.0;
+        private _visibility = 1.0;
+        /**
+         * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+         */
+        public get visibility(): number {
+            return this._visibility;
+        }
+        /**
+         * Gets or sets mesh visibility between 0 and 1 (defult is 1)
+         */        
+        public set visibility(value: number) {
+            if (this._visibility === value) {
+                return;
+            }
+
+            this._visibility = value;
+            this._markSubMeshesAsMiscDirty();
+        }        
         public alphaIndex = Number.MAX_VALUE;
         public isVisible = true;
         public isPickable = true;
@@ -269,6 +286,7 @@
 
             this._hasVertexAlpha = value;
             this._markSubMeshesAsAttributesDirty();
+            this._markSubMeshesAsMiscDirty();
         }
 
         private _useVertexColors = true;

+ 15 - 2
src/Particles/babylon.boxParticleEmitter.ts

@@ -74,7 +74,7 @@ module BABYLON {
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
             var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
             var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
@@ -88,12 +88,25 @@ module BABYLON {
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+        public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
             var randX = Scalar.RandomRange(this.minEmitBox.x, this.maxEmitBox.x);
             var randY = Scalar.RandomRange(this.minEmitBox.y, this.maxEmitBox.y);
             var randZ = Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
 
             Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         }
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        public clone(): BoxParticleEmitter
+        {
+            let newOne = new BoxParticleEmitter(this._particleSystem);
+
+            Tools.DeepCopy(this, newOne);
+
+            return newOne;
+        }
     }
 }

+ 13 - 1
src/Particles/babylon.coneParticleEmitter.ts

@@ -53,7 +53,7 @@ module BABYLON {
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             if (this.angle === 0) {
                 Vector3.TransformNormalFromFloatsToRef(0, emitPower, 0, worldMatrix, directionToUpdate);
             }
@@ -92,5 +92,17 @@ module BABYLON {
 
             Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         }
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        public clone(): ConeParticleEmitter {
+            let newOne = new ConeParticleEmitter(this.radius, this.angle, this.directionRandomizer);
+
+            Tools.DeepCopy(this, newOne);
+
+            return newOne;
+        }          
     }
 }

+ 6 - 0
src/Particles/babylon.iParticleEmitterType.ts

@@ -20,5 +20,11 @@ module BABYLON {
          * @param particle is the particle we are computed the position for
          */
         startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        clone(): IParticleEmitterType;
     }
 }

+ 27 - 3
src/Particles/babylon.sphereParticleEmitter.ts

@@ -29,7 +29,7 @@ module BABYLON {
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
             var randX = Scalar.RandomRange(0, this.directionRandomizer);
             var randY = Scalar.RandomRange(0, this.directionRandomizer);
@@ -48,7 +48,7 @@ module BABYLON {
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+        public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
             var phi = Scalar.RandomRange(0, 2 * Math.PI);
             var theta = Scalar.RandomRange(0, Math.PI);
             var randX = this.radius * Math.cos(phi) * Math.sin(theta);
@@ -56,6 +56,18 @@ module BABYLON {
             var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
             Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         }
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        public clone(): SphereParticleEmitter {
+            let newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
+
+            Tools.DeepCopy(this, newOne);
+
+            return newOne;
+        }        
     }
 
     /**
@@ -89,11 +101,23 @@ module BABYLON {
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
          */
-        startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+        public startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
             var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
             var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
             Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, directionToUpdate);
         }
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        public clone(): SphereDirectedParticleEmitter {
+            let newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
+
+            Tools.DeepCopy(this, newOne);
+
+            return newOne;
+        }          
     }
 }

+ 39 - 16
src/Tools/babylon.promise.ts

@@ -17,7 +17,7 @@ module BABYLON {
         private _state = PromiseStates.Pending;
         private _result?: Nullable<T>;
         private _reason: any;
-        private _child: InternalPromise<T>;
+        private _children = new Array<InternalPromise<T>>();
         private _onFulfilled?: (fulfillment?: Nullable<T>) => Nullable<InternalPromise<T>> | T;
         private _onRejected?: (reason: any) => void;
         private _rejectWasConsumed = false;
@@ -26,27 +26,27 @@ module BABYLON {
             return this._state;
         }
 
-        public isFulfilled(): boolean {
+        public get isFulfilled(): boolean {
             return this._state === PromiseStates.Fulfilled;
         }            
 
-        public isRejected(): boolean {
+        public get isRejected(): boolean {
             return this._state === PromiseStates.Rejected;
         }
     
-        public isPending(): boolean {
+        public get isPending(): boolean {
             return this._state === PromiseStates.Pending;
         }
     
         public value(): Nullable<T> | undefined {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         }     
         
         public reason(): any {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -82,7 +82,7 @@ module BABYLON {
             newPromise._onRejected = onRejected;
 
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
 
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
@@ -91,7 +91,7 @@ module BABYLON {
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if ((<InternalPromise<T>>returnedValue)._state !== undefined) {
                             let returnedPromise = returnedValue as InternalPromise<T>;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         } else {
                             newPromise._result = (<T>returnedValue);
@@ -104,22 +104,45 @@ module BABYLON {
 
             return newPromise;
         }       
+
+        private _moveChildren(children: InternalPromise<T>[]): void {
+            this._children = children.splice(0, children.length);
+
+            if (this.isFulfilled) {
+                for (var child of this._children) {
+                    child._resolve(this._result);
+                } 
+            } else if (this.isRejected) {
+                for (var child of this._children) {
+                    child._reject(this._reason);
+                }                 
+            }
+        }
         
         private _resolve(value?: Nullable<T>): Nullable<InternalPromise<T>> | T {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                let returnedPromise: Nullable<InternalPromise<T>> | T = null;
+                let returnedValue: Nullable<InternalPromise<T>> | T = null;
 
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
+                }
+
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if ((<InternalPromise<T>>returnedValue)._state !== undefined) {
+                        // Transmit children
+                        let returnedPromise = returnedValue as InternalPromise<T>;
+                        
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
 
-                if (this._child) {
-                    this._child._resolve(value);
+                for (var child of this._children) {
+                    child._resolve(value);
                 }                
 
-                return returnedPromise;
+                return returnedValue;
             } catch(e) {
                 this._reject((<Error>e).message);
             }
@@ -136,11 +159,11 @@ module BABYLON {
                 this._rejectWasConsumed = true;
             }
 
-            if (this._child) {
+            for (var child of this._children) {
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 } else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }                
         }

+ 11 - 0
src/babylon.scene.ts

@@ -4814,5 +4814,16 @@
             });
             return request;
         }
+
+        /** @ignore */
+        public _loadFileAsync(url: string, useDatabase?: boolean, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {
+            return new Promise((resolve, reject) => {
+                this._loadFile(url, (data) => {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, (request, exception) => {
+                    reject(exception);
+                })
+            });
+        }
     }
 }

+ 27 - 2
tests/unit/babylon/promises/babylon.promises.tests.ts

@@ -147,7 +147,32 @@ describe('Babylon.Promise', () => {
             .then(number => { 
                 number.should.be.equal(3);
                 done();
-             })
+             });
         });
-    });      
+    });     
+    
+    describe('#Multiple children', () => {
+        it('should correctly handle multiple independant "then"', (done) => {
+            mocha.timeout(10000);
+            var promise1 = new Promise(function(resolve, reject) {
+                setTimeout(function() {
+                    resolve('Success!');
+                }, 500);
+            });
+            var sum = 0;
+            promise1.then(function(value) {
+                sum++;
+                if (sum === 2) {
+                    done();
+                }
+            });
+            
+            promise1.then(function(value) {
+                sum++;
+                if (sum === 2) {
+                    done();
+                }
+            });
+        });
+    });     
 });