David Catuhe 7 gadi atpakaļ
vecāks
revīzija
a69fc1e14d
46 mainītis faili ar 38953 papildinājumiem un 41637 dzēšanām
  1. 9328 9268
      Playground/babylon.d.txt
  2. 10410 10349
      dist/preview release/babylon.d.ts
  3. 51 51
      dist/preview release/babylon.js
  4. 286 129
      dist/preview release/babylon.max.js
  5. 52 52
      dist/preview release/babylon.worker.js
  6. 16056 15995
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 53 53
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 350 180
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 350 180
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  10. 286 129
      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.d.ts
  15. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  16. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  17. 5 4
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  18. 70 54
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  19. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  20. 5 4
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  21. 70 54
      dist/preview release/loaders/babylon.glTFFileLoader.js
  22. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  23. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  24. 70 54
      dist/preview release/loaders/babylonjs.loaders.js
  25. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  26. 5 4
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  27. 4 282
      dist/preview release/materialsLibrary/babylon.customMaterial.d.ts
  28. 19 1908
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  29. 1 2
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  31. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  32. 22 1906
      dist/preview release/materialsLibrary/babylonjs.materials.js
  33. 4 6
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  34. 4 282
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  35. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  36. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  37. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  38. 86 29
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  39. 375 157
      dist/preview release/serializers/babylon.glTF2Serializer.js
  40. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  41. 375 157
      dist/preview release/serializers/babylonjs.serializers.js
  42. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  43. 86 29
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  44. 64 64
      dist/preview release/viewer/babylon.viewer.js
  45. 430 223
      dist/preview release/viewer/babylon.viewer.max.js
  46. 4 0
      src/Mesh/Compression/babylon.dracoCompression.ts

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 9328 - 9268
Playground/babylon.d.txt


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10410 - 10349
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 51 - 51
dist/preview release/babylon.js


+ 286 - 129
dist/preview release/babylon.max.js

@@ -15887,16 +15887,34 @@ var BABYLON;
             return BABYLON.Matrix.Identity();
         };
         /**
-         * Releases all associated resources
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        Node.prototype.dispose = function () {
+        Node.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
+            if (!doNotRecurse) {
+                var nodes = this.getDescendants(true);
+                for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                    var node = nodes_1[_i];
+                    node.dispose(doNotRecurse, disposeMaterialAndTextures);
+                }
+            }
+            else {
+                var transformNodes = this.getChildTransformNodes(true);
+                for (var _a = 0, transformNodes_1 = transformNodes; _a < transformNodes_1.length; _a++) {
+                    var transformNode = transformNodes_1[_a];
+                    transformNode.parent = null;
+                    transformNode.computeWorldMatrix(true);
+                }
+            }
             this.parent = null;
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
             // Behaviors
-            for (var _i = 0, _a = this._behaviors; _i < _a.length; _i++) {
-                var behavior = _a[_i];
+            for (var _b = 0, _c = this._behaviors; _b < _c.length; _b++) {
+                var behavior = _c[_b];
                 behavior.detach();
             }
             this._behaviors = [];
@@ -16323,6 +16341,13 @@ var BABYLON;
             }
             return _this;
         }
+        /**
+         * Gets a string idenfifying the name of the class
+         * @returns "TransformNode" string
+         */
+        TransformNode.prototype.getClassName = function () {
+            return "TransformNode";
+        };
         Object.defineProperty(TransformNode.prototype, "rotation", {
             /**
               * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
@@ -17145,32 +17170,18 @@ var BABYLON;
             return transformNode;
         };
         /**
-         * Disposes the TransformNode.
-         * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this transform node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        TransformNode.prototype.dispose = function (doNotRecurse) {
+        TransformNode.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Animations
             this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeTransformNode(this);
-            if (!doNotRecurse) {
-                // Children
-                var objects = this.getDescendants(true);
-                for (var index = 0; index < objects.length; index++) {
-                    objects[index].dispose();
-                }
-            }
-            else {
-                var childMeshes = this.getChildMeshes(true);
-                for (index = 0; index < childMeshes.length; index++) {
-                    var child = childMeshes[index];
-                    child.parent = null;
-                    child.computeWorldMatrix(true);
-                }
-            }
             this.onAfterWorldMatrixUpdateObservable.clear();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         // Statics
         TransformNode.BILLBOARDMODE_NONE = 0;
@@ -18459,9 +18470,9 @@ var BABYLON;
             return this;
         };
         /**
-         * Disposes the AbstractMesh.
-         * By default, all the mesh children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this abstract mesh.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
         AbstractMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
@@ -18557,7 +18568,7 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onCollideObservable.clear();
             this.onCollisionPositionChangeObservable.clear();
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         /**
          * Adds the passed mesh as a child to the current mesh.
@@ -19419,9 +19430,12 @@ var BABYLON;
             return b.renderPriority - a.renderPriority;
         };
         /**
-         * Disposes the light.
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        Light.prototype.dispose = function () {
+        Light.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             if (this._shadowGenerator) {
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
@@ -19436,7 +19450,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             // Remove from scene
             this.getScene().removeLight(this);
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         /**
          * Returns the light type ID (integer).
@@ -20226,7 +20240,13 @@ var BABYLON;
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             return new BABYLON.Ray(origin, direction, length);
         };
-        Camera.prototype.dispose = function () {
+        /**
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
+         */
+        Camera.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Observables
             this.onViewMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
@@ -20270,7 +20290,7 @@ var BABYLON;
             this.customRenderTargets = [];
             // Active Meshes
             this._activeMeshes.dispose();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         Object.defineProperty(Camera.prototype, "leftCamera", {
             // ---- Camera rigs section ----
@@ -28834,9 +28854,9 @@ var BABYLON;
             return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
         };
         /**
-         * Disposes the Mesh.
-         * By default, all the mesh children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this mesh.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
         Mesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
@@ -55553,11 +55573,12 @@ var BABYLON;
          * Disposes the InstancedMesh.
          * Returns nothing.
          */
-        InstancedMesh.prototype.dispose = function (doNotRecurse) {
+        InstancedMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Remove from mesh
             var index = this._sourceMesh.instances.indexOf(this);
             this._sourceMesh.instances.splice(index, 1);
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         return InstancedMesh;
     }(BABYLON.AbstractMesh));
@@ -59991,6 +60012,16 @@ var BABYLON;
             return this;
         };
         /**
+         * Reverses the effect of calling shareOutputWith and returns the post process back to its original state.
+         * This should be called if the post process that shares output with this post process is disabled/disposed.
+         */
+        PostProcess.prototype.useOwnOutput = function () {
+            if (this._textures.length == 0) {
+                this._textures = new BABYLON.SmartArray(2);
+            }
+            this._shareOutputWithPostProcess = null;
+        };
+        /**
          * Updates the effect with the current post process compile time values and recompiles the shader.
          * @param defines Define statements that should be added at the beginning of the shader. (default: null)
          * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
@@ -67204,7 +67235,7 @@ var BABYLON;
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             // Alpha test
-            if (material && material.needAlphaTesting()) {
+            if (material && material.needAlphaTesting() && material.getAlphaTestTexture()) {
                 defines.push("#define ALPHATEST");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
@@ -68859,7 +68890,7 @@ var BABYLON;
         /**
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * @param name The name of the effect.
-         * @param depthTexture The depth texture of the scene to compute the circle of confusion.
+         * @param depthTexture The depth texture of the scene to compute the circle of confusion. This must be set in order for this to function but may be set after initialization if needed.
          * @param options The required width/height ratio to downsize to before computing the render pass.
          * @param camera The camera to apply the render pass to.
          * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
@@ -68886,17 +68917,33 @@ var BABYLON;
              * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
              */
             _this.focalLength = 50;
+            _this._depthTexture = null;
+            _this._depthTexture = depthTexture;
             _this.onApplyObservable.add(function (effect) {
-                effect.setTexture("depthSampler", depthTexture);
+                if (!_this._depthTexture) {
+                    BABYLON.Tools.Warn("No depth texture set on CircleOfConfusionPostProcess");
+                    return;
+                }
+                effect.setTexture("depthSampler", _this._depthTexture);
                 // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html
                 var aperture = _this.lensSize / _this.fStop;
                 var cocPrecalculation = ((aperture * _this.focalLength) / ((_this.focusDistance - _this.focalLength))); // * ((this.focusDistance - pixelDistance)/pixelDistance) [This part is done in shader]
                 effect.setFloat('focusDistance', _this.focusDistance);
                 effect.setFloat('cocPrecalculation', cocPrecalculation);
-                effect.setFloat2('cameraMinMaxZ', depthTexture.activeCamera.minZ, depthTexture.activeCamera.maxZ);
+                effect.setFloat2('cameraMinMaxZ', _this._depthTexture.activeCamera.minZ, _this._depthTexture.activeCamera.maxZ);
             });
             return _this;
         }
+        Object.defineProperty(CircleOfConfusionPostProcess.prototype, "depthTexture", {
+            /**
+             * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
+             */
+            set: function (value) {
+                this._depthTexture = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         return CircleOfConfusionPostProcess;
     }(BABYLON.PostProcess));
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
@@ -68974,63 +69021,64 @@ var BABYLON;
         /**
          * Creates a new instance of @see DepthOfFieldEffect
          * @param scene The scene the effect belongs to.
-         * @param depthTexture The depth texture of the scene to compute the circle of confusion.
+         * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          */
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             var _this = _super.call(this, scene.getEngine(), "depth of field", function () {
-                // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-                _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", depthTexture, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                // Capture circle of confusion texture
-                _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                _this._depthOfFieldPass.autoClear = false;
-                // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)
-                // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
-                // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-                _this._depthOfFieldBlurY = [];
-                _this._depthOfFieldBlurX = [];
-                var blurCount = 1;
-                var kernelSize = 15;
-                switch (blurLevel) {
-                    case DepthOfFieldEffectBlurLevel.High: {
-                        blurCount = 3;
-                        kernelSize = 51;
-                        break;
-                    }
-                    case DepthOfFieldEffectBlurLevel.Medium: {
-                        blurCount = 2;
-                        kernelSize = 31;
-                        break;
-                    }
-                    default: {
-                        kernelSize = 15;
-                        blurCount = 1;
-                        break;
-                    }
-                }
-                var adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);
-                for (var i = 0; i < blurCount; i++) {
-                    var blurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, i == 0 ? _this._circleOfConfusion : null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                    blurY.autoClear = false;
-                    var blurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                    blurX.autoClear = false;
-                    _this._depthOfFieldBlurY.push(blurY);
-                    _this._depthOfFieldBlurX.push(blurX);
-                }
-                // Merge blurred images with original image based on circleOfConfusion
-                _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY.slice(1), 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                _this._depthOfFieldMerge.autoClear = false;
-                // Set all post processes on the effect.
-                var effects = [_this._circleOfConfusion, _this._depthOfFieldPass];
-                for (var i = 0; i < _this._depthOfFieldBlurX.length; i++) {
-                    effects.push(_this._depthOfFieldBlurY[i]);
-                    effects.push(_this._depthOfFieldBlurX[i]);
-                }
-                effects.push(_this._depthOfFieldMerge);
-                return effects;
+                return _this._effects;
             }, true) || this;
+            _this._effects = [];
+            // Circle of confusion value for each pixel is used to determine how much to blur that pixel
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", depthTexture, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            // Capture circle of confusion texture
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass.autoClear = false;
+            // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)
+            // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
+            // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
+            _this._depthOfFieldBlurY = [];
+            _this._depthOfFieldBlurX = [];
+            var blurCount = 1;
+            var kernelSize = 15;
+            switch (blurLevel) {
+                case DepthOfFieldEffectBlurLevel.High: {
+                    blurCount = 3;
+                    kernelSize = 51;
+                    break;
+                }
+                case DepthOfFieldEffectBlurLevel.Medium: {
+                    blurCount = 2;
+                    kernelSize = 31;
+                    break;
+                }
+                default: {
+                    kernelSize = 15;
+                    blurCount = 1;
+                    break;
+                }
+            }
+            var adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);
+            for (var i = 0; i < blurCount; i++) {
+                var blurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, i == 0 ? _this._circleOfConfusion : null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+                blurY.autoClear = false;
+                var blurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+                blurX.autoClear = false;
+                _this._depthOfFieldBlurY.push(blurY);
+                _this._depthOfFieldBlurX.push(blurX);
+            }
+            // Merge blurred images with original image based on circleOfConfusion
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY.slice(1), 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge.autoClear = false;
+            // Set all post processes on the effect.
+            _this._effects = [_this._circleOfConfusion, _this._depthOfFieldPass];
+            for (var i = 0; i < _this._depthOfFieldBlurX.length; i++) {
+                _this._effects.push(_this._depthOfFieldBlurY[i]);
+                _this._effects.push(_this._depthOfFieldBlurX[i]);
+            }
+            _this._effects.push(_this._depthOfFieldMerge);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
@@ -69085,6 +69133,16 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(DepthOfFieldEffect.prototype, "depthTexture", {
+            /**
+             * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
+             */
+            set: function (value) {
+                this._circleOfConfusion.depthTexture = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         /**
          * Disposes each of the internal effects for a given camera.
          * @param camera The camera to dispose the effect on.
@@ -69132,6 +69190,7 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            _this._originalCameras = [];
             /**
              * ID of the sharpen post process,
              */
@@ -69195,7 +69254,10 @@ var BABYLON;
              * Specifies the weight of the bloom in the final rendering
              */
             _this._bloomWeight = 0.15;
+            _this._prevPostProcess = null;
+            _this._prevPrevPostProcess = null;
             _this._cameras = cameras || [];
+            _this._originalCameras = _this._cameras.slice();
             _this._buildAllowed = automaticBuild;
             // Initialize
             _this._scene = scene;
@@ -69215,6 +69277,12 @@ var BABYLON;
             }
             // Attach
             scene.postProcessRenderPipelineManager.addPipeline(_this);
+            var engine = _this._scene.getEngine();
+            _this.sharpen = new BABYLON.SharpenPostProcess("sharpen", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType);
+            _this._sharpenEffect = new BABYLON.PostProcessRenderEffect(engine, _this.SharpenPostProcessId, function () { return _this.sharpen; }, true);
+            _this.depthOfField = new BABYLON.DepthOfFieldEffect(_this._scene, null, _this._depthOfFieldBlurLevel, _this._defaultPipelineTextureType);
+            _this.chromaticAberration = new BABYLON.ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType);
+            _this._chromaticAberrationEffect = new BABYLON.PostProcessRenderEffect(engine, _this.ChromaticAberrationPostProcessId, function () { return _this.chromaticAberration; }, true);
             _this._buildPipeline();
             return _this;
         }
@@ -69317,6 +69385,16 @@ var BABYLON;
                     return;
                 }
                 this._depthOfFieldBlurLevel = value;
+                // recreate dof and dispose old as this setting is not dynamic
+                var oldDof = this.depthOfField;
+                this.depthOfField = new BABYLON.DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
+                this.depthOfField.focalLength = oldDof.focalLength;
+                this.depthOfField.focusDistance = oldDof.focusDistance;
+                this.depthOfField.fStop = oldDof.fStop;
+                this.depthOfField.lensSize = oldDof.lensSize;
+                for (var i = 0; i < this._cameras.length; i++) {
+                    oldDof.disposeEffects(this._cameras[i]);
+                }
                 this._buildPipeline();
             },
             enumerable: true,
@@ -69399,6 +69477,27 @@ var BABYLON;
             this._buildPipeline();
             this._buildAllowed = previousState;
         };
+        DefaultRenderingPipeline.prototype._setAutoClearAndTextureSharing = function (postProcess, skipTextureSharing) {
+            if (skipTextureSharing === void 0) { skipTextureSharing = false; }
+            if (this._prevPostProcess && this._prevPostProcess.autoClear) {
+                postProcess.autoClear = false;
+            }
+            else {
+                postProcess.autoClear = true;
+            }
+            if (!skipTextureSharing) {
+                if (this._prevPrevPostProcess) {
+                    postProcess.shareOutputWith(this._prevPrevPostProcess);
+                }
+                else {
+                    postProcess.useOwnOutput();
+                }
+                if (this._prevPostProcess) {
+                    this._prevPrevPostProcess = this._prevPostProcess;
+                }
+                this._prevPostProcess = postProcess;
+            }
+        };
         DefaultRenderingPipeline.prototype._buildPipeline = function () {
             var _this = this;
             if (!this._buildAllowed) {
@@ -69406,19 +69505,32 @@ var BABYLON;
             }
             var engine = this._scene.getEngine();
             this._disposePostProcesses();
+            if (this._cameras !== null) {
+                this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
+                // get back cameras to be used to reattach pipeline
+                this._cameras = this._originalCameras.slice();
+            }
             this._reset();
+            this._prevPostProcess = null;
+            this._prevPrevPostProcess = null;
+            if (this.fxaaEnabled) {
+                this.fxaa = new BABYLON.FxaaPostProcess("fxaa", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FxaaPostProcessId, function () { return _this.fxaa; }, true));
+                this._setAutoClearAndTextureSharing(this.fxaa);
+            }
             if (this.sharpenEnabled) {
-                this.sharpen = new BABYLON.SharpenPostProcess("sharpen", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.SharpenPostProcessId, function () { return _this.sharpen; }, true));
+                this.addEffect(this._sharpenEffect);
+                this._setAutoClearAndTextureSharing(this.sharpen);
             }
             if (this.depthOfFieldEnabled) {
-                // Enable and get current depth map
                 var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
-                this.depthOfField = new BABYLON.DepthOfFieldEffect(this._scene, depthTexture, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
+                this.depthOfField.depthTexture = depthTexture;
                 this.addEffect(this.depthOfField);
+                this._setAutoClearAndTextureSharing(this.depthOfField._depthOfFieldMerge);
             }
             if (this.bloomEnabled) {
                 this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this._setAutoClearAndTextureSharing(this.pass, true);
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.PassPostProcessId, function () { return _this.pass; }, true));
                 if (!this._hdr) {
                     this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
@@ -69464,17 +69576,13 @@ var BABYLON;
                     this._scene.imageProcessingConfiguration.applyByPostProcess = false;
                 }
             }
-            if (this.fxaaEnabled) {
-                this.fxaa = new BABYLON.FxaaPostProcess("fxaa", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FxaaPostProcessId, function () { return _this.fxaa; }, true));
-                this.fxaa.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
-            }
-            else if (this._hdr && this.imageProcessing) {
+            if (this._hdr && this.imageProcessing) {
                 this.finalMerge = this.imageProcessing;
             }
             else {
                 this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FinalMergePostProcessId, function () { return _this.finalMerge; }, true));
+                this._setAutoClearAndTextureSharing(this.finalMerge, true);
                 this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
             }
             if (this.bloomEnabled) {
@@ -69484,25 +69592,17 @@ var BABYLON;
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.autoClear = false;
                     }
-                    else if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
                     else {
                         this.finalMerge.shareOutputWith(this.pass);
                     }
                 }
                 else {
-                    if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
-                    else {
-                        this.finalMerge.shareOutputWith(this.pass);
-                    }
+                    this.finalMerge.shareOutputWith(this.pass);
                 }
             }
             if (this.chromaticAberrationEnabled) {
-                this.chromaticAberration = new BABYLON.ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, function () { return _this.chromaticAberration; }, true));
+                this.addEffect(this._chromaticAberrationEffect);
+                this._setAutoClearAndTextureSharing(this.chromaticAberration);
             }
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
@@ -69513,12 +69613,10 @@ var BABYLON;
                 }
             }
         };
-        DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
+        DefaultRenderingPipeline.prototype._disposePostProcesses = function (disposeNonRecreated) {
+            if (disposeNonRecreated === void 0) { disposeNonRecreated = false; }
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
-                if (this.sharpen) {
-                    this.sharpen.dispose(camera);
-                }
                 if (this.pass) {
                     this.pass.dispose(camera);
                 }
@@ -69543,14 +69641,19 @@ var BABYLON;
                 if (this.finalMerge) {
                     this.finalMerge.dispose(camera);
                 }
-                if (this.depthOfField) {
-                    this.depthOfField.disposeEffects(camera);
-                }
-                if (this.chromaticAberration) {
-                    this.chromaticAberration.dispose(camera);
+                // These are created in the constructor and should not be disposed on every pipeline change
+                if (disposeNonRecreated) {
+                    if (this.sharpen) {
+                        this.sharpen.dispose(camera);
+                    }
+                    if (this.depthOfField) {
+                        this.depthOfField.disposeEffects(camera);
+                    }
+                    if (this.chromaticAberration) {
+                        this.chromaticAberration.dispose(camera);
+                    }
                 }
             }
-            this.sharpen = null;
             this.pass = null;
             this.highlights = null;
             this.blurX = null;
@@ -69559,14 +69662,17 @@ var BABYLON;
             this.imageProcessing = null;
             this.fxaa = null;
             this.finalMerge = null;
-            this.depthOfField = null;
-            this.chromaticAberration = null;
+            if (disposeNonRecreated) {
+                this.sharpen = null;
+                this.depthOfField = null;
+                this.chromaticAberration = null;
+            }
         };
         /**
          * Dispose of the pipeline and stop all post processes
          */
         DefaultRenderingPipeline.prototype.dispose = function () {
-            this._disposePostProcesses();
+            this._disposePostProcesses(true);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
@@ -70998,6 +71104,54 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainEnabled", {
+            /**
+             * Gets wether the grain effect is enabled.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainEnabled;
+            },
+            /**
+             * Sets wether the grain effect is enabled.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainEnabled = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainIntensity", {
+            /**
+             * Gets the grain effect's intensity.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainIntensity;
+            },
+            /**
+             * Sets the grain effect's intensity.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainIntensity = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainAnimated", {
+            /**
+             * Gets wether the grain effect is animated.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainAnimated;
+            },
+            /**
+             * Sets wether the grain effect is animated.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainAnimated = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(ImageProcessingPostProcess.prototype, "fromLinearSpace", {
             /**
              * Gets wether the input of the processing is in Gamma or Linear Space.
@@ -91494,13 +91648,16 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Releases all associated resources
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        VideoDome.prototype.dispose = function () {
-            _super.prototype.dispose.call(this);
+        VideoDome.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             this._videoTexture.dispose();
             this._mesh.dispose();
             this._material.dispose();
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         return VideoDome;
     }(BABYLON.Node));

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 52 - 52
dist/preview release/babylon.worker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 16056 - 15995
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 53 - 53
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 350 - 180
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 350 - 180
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


+ 286 - 129
dist/preview release/es6.js

@@ -15860,16 +15860,34 @@ var BABYLON;
             return BABYLON.Matrix.Identity();
         };
         /**
-         * Releases all associated resources
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        Node.prototype.dispose = function () {
+        Node.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
+            if (!doNotRecurse) {
+                var nodes = this.getDescendants(true);
+                for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                    var node = nodes_1[_i];
+                    node.dispose(doNotRecurse, disposeMaterialAndTextures);
+                }
+            }
+            else {
+                var transformNodes = this.getChildTransformNodes(true);
+                for (var _a = 0, transformNodes_1 = transformNodes; _a < transformNodes_1.length; _a++) {
+                    var transformNode = transformNodes_1[_a];
+                    transformNode.parent = null;
+                    transformNode.computeWorldMatrix(true);
+                }
+            }
             this.parent = null;
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
             // Behaviors
-            for (var _i = 0, _a = this._behaviors; _i < _a.length; _i++) {
-                var behavior = _a[_i];
+            for (var _b = 0, _c = this._behaviors; _b < _c.length; _b++) {
+                var behavior = _c[_b];
                 behavior.detach();
             }
             this._behaviors = [];
@@ -16296,6 +16314,13 @@ var BABYLON;
             }
             return _this;
         }
+        /**
+         * Gets a string idenfifying the name of the class
+         * @returns "TransformNode" string
+         */
+        TransformNode.prototype.getClassName = function () {
+            return "TransformNode";
+        };
         Object.defineProperty(TransformNode.prototype, "rotation", {
             /**
               * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
@@ -17118,32 +17143,18 @@ var BABYLON;
             return transformNode;
         };
         /**
-         * Disposes the TransformNode.
-         * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this transform node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        TransformNode.prototype.dispose = function (doNotRecurse) {
+        TransformNode.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Animations
             this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeTransformNode(this);
-            if (!doNotRecurse) {
-                // Children
-                var objects = this.getDescendants(true);
-                for (var index = 0; index < objects.length; index++) {
-                    objects[index].dispose();
-                }
-            }
-            else {
-                var childMeshes = this.getChildMeshes(true);
-                for (index = 0; index < childMeshes.length; index++) {
-                    var child = childMeshes[index];
-                    child.parent = null;
-                    child.computeWorldMatrix(true);
-                }
-            }
             this.onAfterWorldMatrixUpdateObservable.clear();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         // Statics
         TransformNode.BILLBOARDMODE_NONE = 0;
@@ -18432,9 +18443,9 @@ var BABYLON;
             return this;
         };
         /**
-         * Disposes the AbstractMesh.
-         * By default, all the mesh children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this abstract mesh.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
         AbstractMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
@@ -18530,7 +18541,7 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onCollideObservable.clear();
             this.onCollisionPositionChangeObservable.clear();
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         /**
          * Adds the passed mesh as a child to the current mesh.
@@ -19392,9 +19403,12 @@ var BABYLON;
             return b.renderPriority - a.renderPriority;
         };
         /**
-         * Disposes the light.
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        Light.prototype.dispose = function () {
+        Light.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             if (this._shadowGenerator) {
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
@@ -19409,7 +19423,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             // Remove from scene
             this.getScene().removeLight(this);
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         /**
          * Returns the light type ID (integer).
@@ -20199,7 +20213,13 @@ var BABYLON;
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             return new BABYLON.Ray(origin, direction, length);
         };
-        Camera.prototype.dispose = function () {
+        /**
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
+         */
+        Camera.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Observables
             this.onViewMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
@@ -20243,7 +20263,7 @@ var BABYLON;
             this.customRenderTargets = [];
             // Active Meshes
             this._activeMeshes.dispose();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         Object.defineProperty(Camera.prototype, "leftCamera", {
             // ---- Camera rigs section ----
@@ -28807,9 +28827,9 @@ var BABYLON;
             return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
         };
         /**
-         * Disposes the Mesh.
-         * By default, all the mesh children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-         * Returns nothing.
+         * Releases resources associated with this mesh.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
         Mesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
@@ -55526,11 +55546,12 @@ var BABYLON;
          * Disposes the InstancedMesh.
          * Returns nothing.
          */
-        InstancedMesh.prototype.dispose = function (doNotRecurse) {
+        InstancedMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Remove from mesh
             var index = this._sourceMesh.instances.indexOf(this);
             this._sourceMesh.instances.splice(index, 1);
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         return InstancedMesh;
     }(BABYLON.AbstractMesh));
@@ -59964,6 +59985,16 @@ var BABYLON;
             return this;
         };
         /**
+         * Reverses the effect of calling shareOutputWith and returns the post process back to its original state.
+         * This should be called if the post process that shares output with this post process is disabled/disposed.
+         */
+        PostProcess.prototype.useOwnOutput = function () {
+            if (this._textures.length == 0) {
+                this._textures = new BABYLON.SmartArray(2);
+            }
+            this._shareOutputWithPostProcess = null;
+        };
+        /**
          * Updates the effect with the current post process compile time values and recompiles the shader.
          * @param defines Define statements that should be added at the beginning of the shader. (default: null)
          * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
@@ -67177,7 +67208,7 @@ var BABYLON;
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             // Alpha test
-            if (material && material.needAlphaTesting()) {
+            if (material && material.needAlphaTesting() && material.getAlphaTestTexture()) {
                 defines.push("#define ALPHATEST");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
@@ -68832,7 +68863,7 @@ var BABYLON;
         /**
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * @param name The name of the effect.
-         * @param depthTexture The depth texture of the scene to compute the circle of confusion.
+         * @param depthTexture The depth texture of the scene to compute the circle of confusion. This must be set in order for this to function but may be set after initialization if needed.
          * @param options The required width/height ratio to downsize to before computing the render pass.
          * @param camera The camera to apply the render pass to.
          * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
@@ -68859,17 +68890,33 @@ var BABYLON;
              * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
              */
             _this.focalLength = 50;
+            _this._depthTexture = null;
+            _this._depthTexture = depthTexture;
             _this.onApplyObservable.add(function (effect) {
-                effect.setTexture("depthSampler", depthTexture);
+                if (!_this._depthTexture) {
+                    BABYLON.Tools.Warn("No depth texture set on CircleOfConfusionPostProcess");
+                    return;
+                }
+                effect.setTexture("depthSampler", _this._depthTexture);
                 // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html
                 var aperture = _this.lensSize / _this.fStop;
                 var cocPrecalculation = ((aperture * _this.focalLength) / ((_this.focusDistance - _this.focalLength))); // * ((this.focusDistance - pixelDistance)/pixelDistance) [This part is done in shader]
                 effect.setFloat('focusDistance', _this.focusDistance);
                 effect.setFloat('cocPrecalculation', cocPrecalculation);
-                effect.setFloat2('cameraMinMaxZ', depthTexture.activeCamera.minZ, depthTexture.activeCamera.maxZ);
+                effect.setFloat2('cameraMinMaxZ', _this._depthTexture.activeCamera.minZ, _this._depthTexture.activeCamera.maxZ);
             });
             return _this;
         }
+        Object.defineProperty(CircleOfConfusionPostProcess.prototype, "depthTexture", {
+            /**
+             * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
+             */
+            set: function (value) {
+                this._depthTexture = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         return CircleOfConfusionPostProcess;
     }(BABYLON.PostProcess));
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
@@ -68947,63 +68994,64 @@ var BABYLON;
         /**
          * Creates a new instance of @see DepthOfFieldEffect
          * @param scene The scene the effect belongs to.
-         * @param depthTexture The depth texture of the scene to compute the circle of confusion.
+         * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          */
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             var _this = _super.call(this, scene.getEngine(), "depth of field", function () {
-                // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-                _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", depthTexture, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                // Capture circle of confusion texture
-                _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                _this._depthOfFieldPass.autoClear = false;
-                // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)
-                // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
-                // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-                _this._depthOfFieldBlurY = [];
-                _this._depthOfFieldBlurX = [];
-                var blurCount = 1;
-                var kernelSize = 15;
-                switch (blurLevel) {
-                    case DepthOfFieldEffectBlurLevel.High: {
-                        blurCount = 3;
-                        kernelSize = 51;
-                        break;
-                    }
-                    case DepthOfFieldEffectBlurLevel.Medium: {
-                        blurCount = 2;
-                        kernelSize = 31;
-                        break;
-                    }
-                    default: {
-                        kernelSize = 15;
-                        blurCount = 1;
-                        break;
-                    }
-                }
-                var adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);
-                for (var i = 0; i < blurCount; i++) {
-                    var blurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, i == 0 ? _this._circleOfConfusion : null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                    blurY.autoClear = false;
-                    var blurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                    blurX.autoClear = false;
-                    _this._depthOfFieldBlurY.push(blurY);
-                    _this._depthOfFieldBlurX.push(blurX);
-                }
-                // Merge blurred images with original image based on circleOfConfusion
-                _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY.slice(1), 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-                _this._depthOfFieldMerge.autoClear = false;
-                // Set all post processes on the effect.
-                var effects = [_this._circleOfConfusion, _this._depthOfFieldPass];
-                for (var i = 0; i < _this._depthOfFieldBlurX.length; i++) {
-                    effects.push(_this._depthOfFieldBlurY[i]);
-                    effects.push(_this._depthOfFieldBlurX[i]);
-                }
-                effects.push(_this._depthOfFieldMerge);
-                return effects;
+                return _this._effects;
             }, true) || this;
+            _this._effects = [];
+            // Circle of confusion value for each pixel is used to determine how much to blur that pixel
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", depthTexture, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            // Capture circle of confusion texture
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass.autoClear = false;
+            // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)
+            // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
+            // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
+            _this._depthOfFieldBlurY = [];
+            _this._depthOfFieldBlurX = [];
+            var blurCount = 1;
+            var kernelSize = 15;
+            switch (blurLevel) {
+                case DepthOfFieldEffectBlurLevel.High: {
+                    blurCount = 3;
+                    kernelSize = 51;
+                    break;
+                }
+                case DepthOfFieldEffectBlurLevel.Medium: {
+                    blurCount = 2;
+                    kernelSize = 31;
+                    break;
+                }
+                default: {
+                    kernelSize = 15;
+                    blurCount = 1;
+                    break;
+                }
+            }
+            var adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);
+            for (var i = 0; i < blurCount; i++) {
+                var blurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, i == 0 ? _this._circleOfConfusion : null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+                blurY.autoClear = false;
+                var blurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), adjustedKernelSize, 1.0 / Math.pow(2, i), null, _this._depthOfFieldPass, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+                blurX.autoClear = false;
+                _this._depthOfFieldBlurY.push(blurY);
+                _this._depthOfFieldBlurX.push(blurX);
+            }
+            // Merge blurred images with original image based on circleOfConfusion
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY.slice(1), 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge.autoClear = false;
+            // Set all post processes on the effect.
+            _this._effects = [_this._circleOfConfusion, _this._depthOfFieldPass];
+            for (var i = 0; i < _this._depthOfFieldBlurX.length; i++) {
+                _this._effects.push(_this._depthOfFieldBlurY[i]);
+                _this._effects.push(_this._depthOfFieldBlurX[i]);
+            }
+            _this._effects.push(_this._depthOfFieldMerge);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
@@ -69058,6 +69106,16 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(DepthOfFieldEffect.prototype, "depthTexture", {
+            /**
+             * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
+             */
+            set: function (value) {
+                this._circleOfConfusion.depthTexture = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         /**
          * Disposes each of the internal effects for a given camera.
          * @param camera The camera to dispose the effect on.
@@ -69105,6 +69163,7 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            _this._originalCameras = [];
             /**
              * ID of the sharpen post process,
              */
@@ -69168,7 +69227,10 @@ var BABYLON;
              * Specifies the weight of the bloom in the final rendering
              */
             _this._bloomWeight = 0.15;
+            _this._prevPostProcess = null;
+            _this._prevPrevPostProcess = null;
             _this._cameras = cameras || [];
+            _this._originalCameras = _this._cameras.slice();
             _this._buildAllowed = automaticBuild;
             // Initialize
             _this._scene = scene;
@@ -69188,6 +69250,12 @@ var BABYLON;
             }
             // Attach
             scene.postProcessRenderPipelineManager.addPipeline(_this);
+            var engine = _this._scene.getEngine();
+            _this.sharpen = new BABYLON.SharpenPostProcess("sharpen", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType);
+            _this._sharpenEffect = new BABYLON.PostProcessRenderEffect(engine, _this.SharpenPostProcessId, function () { return _this.sharpen; }, true);
+            _this.depthOfField = new BABYLON.DepthOfFieldEffect(_this._scene, null, _this._depthOfFieldBlurLevel, _this._defaultPipelineTextureType);
+            _this.chromaticAberration = new BABYLON.ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType);
+            _this._chromaticAberrationEffect = new BABYLON.PostProcessRenderEffect(engine, _this.ChromaticAberrationPostProcessId, function () { return _this.chromaticAberration; }, true);
             _this._buildPipeline();
             return _this;
         }
@@ -69290,6 +69358,16 @@ var BABYLON;
                     return;
                 }
                 this._depthOfFieldBlurLevel = value;
+                // recreate dof and dispose old as this setting is not dynamic
+                var oldDof = this.depthOfField;
+                this.depthOfField = new BABYLON.DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
+                this.depthOfField.focalLength = oldDof.focalLength;
+                this.depthOfField.focusDistance = oldDof.focusDistance;
+                this.depthOfField.fStop = oldDof.fStop;
+                this.depthOfField.lensSize = oldDof.lensSize;
+                for (var i = 0; i < this._cameras.length; i++) {
+                    oldDof.disposeEffects(this._cameras[i]);
+                }
                 this._buildPipeline();
             },
             enumerable: true,
@@ -69372,6 +69450,27 @@ var BABYLON;
             this._buildPipeline();
             this._buildAllowed = previousState;
         };
+        DefaultRenderingPipeline.prototype._setAutoClearAndTextureSharing = function (postProcess, skipTextureSharing) {
+            if (skipTextureSharing === void 0) { skipTextureSharing = false; }
+            if (this._prevPostProcess && this._prevPostProcess.autoClear) {
+                postProcess.autoClear = false;
+            }
+            else {
+                postProcess.autoClear = true;
+            }
+            if (!skipTextureSharing) {
+                if (this._prevPrevPostProcess) {
+                    postProcess.shareOutputWith(this._prevPrevPostProcess);
+                }
+                else {
+                    postProcess.useOwnOutput();
+                }
+                if (this._prevPostProcess) {
+                    this._prevPrevPostProcess = this._prevPostProcess;
+                }
+                this._prevPostProcess = postProcess;
+            }
+        };
         DefaultRenderingPipeline.prototype._buildPipeline = function () {
             var _this = this;
             if (!this._buildAllowed) {
@@ -69379,19 +69478,32 @@ var BABYLON;
             }
             var engine = this._scene.getEngine();
             this._disposePostProcesses();
+            if (this._cameras !== null) {
+                this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
+                // get back cameras to be used to reattach pipeline
+                this._cameras = this._originalCameras.slice();
+            }
             this._reset();
+            this._prevPostProcess = null;
+            this._prevPrevPostProcess = null;
+            if (this.fxaaEnabled) {
+                this.fxaa = new BABYLON.FxaaPostProcess("fxaa", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FxaaPostProcessId, function () { return _this.fxaa; }, true));
+                this._setAutoClearAndTextureSharing(this.fxaa);
+            }
             if (this.sharpenEnabled) {
-                this.sharpen = new BABYLON.SharpenPostProcess("sharpen", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.SharpenPostProcessId, function () { return _this.sharpen; }, true));
+                this.addEffect(this._sharpenEffect);
+                this._setAutoClearAndTextureSharing(this.sharpen);
             }
             if (this.depthOfFieldEnabled) {
-                // Enable and get current depth map
                 var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
-                this.depthOfField = new BABYLON.DepthOfFieldEffect(this._scene, depthTexture, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
+                this.depthOfField.depthTexture = depthTexture;
                 this.addEffect(this.depthOfField);
+                this._setAutoClearAndTextureSharing(this.depthOfField._depthOfFieldMerge);
             }
             if (this.bloomEnabled) {
                 this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this._setAutoClearAndTextureSharing(this.pass, true);
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.PassPostProcessId, function () { return _this.pass; }, true));
                 if (!this._hdr) {
                     this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
@@ -69437,17 +69549,13 @@ var BABYLON;
                     this._scene.imageProcessingConfiguration.applyByPostProcess = false;
                 }
             }
-            if (this.fxaaEnabled) {
-                this.fxaa = new BABYLON.FxaaPostProcess("fxaa", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FxaaPostProcessId, function () { return _this.fxaa; }, true));
-                this.fxaa.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
-            }
-            else if (this._hdr && this.imageProcessing) {
+            if (this._hdr && this.imageProcessing) {
                 this.finalMerge = this.imageProcessing;
             }
             else {
                 this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.FinalMergePostProcessId, function () { return _this.finalMerge; }, true));
+                this._setAutoClearAndTextureSharing(this.finalMerge, true);
                 this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
             }
             if (this.bloomEnabled) {
@@ -69457,25 +69565,17 @@ var BABYLON;
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.autoClear = false;
                     }
-                    else if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
                     else {
                         this.finalMerge.shareOutputWith(this.pass);
                     }
                 }
                 else {
-                    if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
-                    else {
-                        this.finalMerge.shareOutputWith(this.pass);
-                    }
+                    this.finalMerge.shareOutputWith(this.pass);
                 }
             }
             if (this.chromaticAberrationEnabled) {
-                this.chromaticAberration = new BABYLON.ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, function () { return _this.chromaticAberration; }, true));
+                this.addEffect(this._chromaticAberrationEffect);
+                this._setAutoClearAndTextureSharing(this.chromaticAberration);
             }
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
@@ -69486,12 +69586,10 @@ var BABYLON;
                 }
             }
         };
-        DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
+        DefaultRenderingPipeline.prototype._disposePostProcesses = function (disposeNonRecreated) {
+            if (disposeNonRecreated === void 0) { disposeNonRecreated = false; }
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
-                if (this.sharpen) {
-                    this.sharpen.dispose(camera);
-                }
                 if (this.pass) {
                     this.pass.dispose(camera);
                 }
@@ -69516,14 +69614,19 @@ var BABYLON;
                 if (this.finalMerge) {
                     this.finalMerge.dispose(camera);
                 }
-                if (this.depthOfField) {
-                    this.depthOfField.disposeEffects(camera);
-                }
-                if (this.chromaticAberration) {
-                    this.chromaticAberration.dispose(camera);
+                // These are created in the constructor and should not be disposed on every pipeline change
+                if (disposeNonRecreated) {
+                    if (this.sharpen) {
+                        this.sharpen.dispose(camera);
+                    }
+                    if (this.depthOfField) {
+                        this.depthOfField.disposeEffects(camera);
+                    }
+                    if (this.chromaticAberration) {
+                        this.chromaticAberration.dispose(camera);
+                    }
                 }
             }
-            this.sharpen = null;
             this.pass = null;
             this.highlights = null;
             this.blurX = null;
@@ -69532,14 +69635,17 @@ var BABYLON;
             this.imageProcessing = null;
             this.fxaa = null;
             this.finalMerge = null;
-            this.depthOfField = null;
-            this.chromaticAberration = null;
+            if (disposeNonRecreated) {
+                this.sharpen = null;
+                this.depthOfField = null;
+                this.chromaticAberration = null;
+            }
         };
         /**
          * Dispose of the pipeline and stop all post processes
          */
         DefaultRenderingPipeline.prototype.dispose = function () {
-            this._disposePostProcesses();
+            this._disposePostProcesses(true);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
@@ -70971,6 +71077,54 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainEnabled", {
+            /**
+             * Gets wether the grain effect is enabled.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainEnabled;
+            },
+            /**
+             * Sets wether the grain effect is enabled.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainEnabled = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainIntensity", {
+            /**
+             * Gets the grain effect's intensity.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainIntensity;
+            },
+            /**
+             * Sets the grain effect's intensity.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainIntensity = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(ImageProcessingPostProcess.prototype, "grainAnimated", {
+            /**
+             * Gets wether the grain effect is animated.
+             */
+            get: function () {
+                return this.imageProcessingConfiguration.grainAnimated;
+            },
+            /**
+             * Sets wether the grain effect is animated.
+             */
+            set: function (value) {
+                this.imageProcessingConfiguration.grainAnimated = value;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(ImageProcessingPostProcess.prototype, "fromLinearSpace", {
             /**
              * Gets wether the input of the processing is in Gamma or Linear Space.
@@ -91467,13 +91621,16 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Releases all associated resources
+         * Releases resources associated with this node.
+         * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
+         * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
          */
-        VideoDome.prototype.dispose = function () {
-            _super.prototype.dispose.call(this);
+        VideoDome.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             this._videoTexture.dispose();
             this._mesh.dispose();
             this._material.dispose();
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         return VideoDome;
     }(BABYLON.Node));

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -116,7 +116,7 @@ declare module BABYLON {
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         /**
-         * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+         * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
          */
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         whenCompleteAsync(): Promise<void>;

+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -77,7 +77,7 @@ var BABYLON;
              */
             this.onMaterialLoadedObservable = new BABYLON.Observable();
             /**
-             * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+             * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
              */
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 5 - 4
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -116,7 +116,7 @@ declare module BABYLON {
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         /**
-         * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+         * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
          */
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         whenCompleteAsync(): Promise<void>;
@@ -321,12 +321,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
-        private _loadMeshAsync(context, node, mesh);
-        private _loadPrimitiveAsync(context, node, mesh, primitive);
+        private _loadMeshAsync(context, node, mesh, babylonMesh);
+        private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);

+ 70 - 54
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -77,7 +77,7 @@ var BABYLON;
              */
             this.onMaterialLoadedObservable = new BABYLON.Observable();
             /**
-             * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+             * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
              */
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
@@ -572,7 +572,7 @@ var BABYLON;
                         nodes = names.map(function (name) {
                             var node = nodeMap_1[name];
                             if (!node) {
-                                throw new Error("Failed to find node " + name);
+                                throw new Error("Failed to find node '" + name + "'");
                             }
                             return node;
                         });
@@ -728,7 +728,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error("Invalid coordinate system mode " + this.coordinateSystemMode);
+                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
                     }
                 }
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
@@ -757,6 +757,17 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            GLTFLoader.prototype._forEachNodeMesh = function (node, callback) {
+                if (node._babylonMesh) {
+                    callback(node._babylonMesh);
+                }
+                if (node._primitiveBabylonMeshes) {
+                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
+                        var babylonMesh = _a[_i];
+                        callback(babylonMesh);
+                    }
+                }
+            };
             GLTFLoader.prototype._getMeshes = function () {
                 var meshes = new Array();
                 // Root mesh is always first.
@@ -765,15 +776,9 @@ var BABYLON;
                 if (nodes) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                         var node = nodes_2[_i];
-                        if (node._babylonMesh) {
-                            meshes.push(node._babylonMesh);
-                        }
-                        if (node._primitiveBabylonMeshes) {
-                            for (var _a = 0, _b = node._primitiveBabylonMeshes; _a < _b.length; _a++) {
-                                var babylonMesh = _b[_a];
-                                meshes.push(babylonMesh);
-                            }
-                        }
+                        this._forEachNodeMesh(node, function (mesh) {
+                            meshes.push(mesh);
+                        });
                     }
                 }
                 return meshes;
@@ -814,7 +819,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode " + this.animationStartMode);
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
                         return;
                     }
                 }
@@ -835,7 +840,7 @@ var BABYLON;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
                     var mesh = GLTFLoader._GetProperty(context + "/mesh", this._gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh));
+                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh, babylonMesh));
                 }
                 if (node.children) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
@@ -847,37 +852,42 @@ var BABYLON;
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh) {
+            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 // TODO: instancing
+                var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 GLTF2.ArrayItem.Assign(primitives);
-                for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
-                    var primitive = primitives_1[_i];
-                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive));
+                if (primitives.length === 1) {
+                    var primitive = primitives[0];
+                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
+                }
+                else {
+                    node._primitiveBabylonMeshes = [];
+                    for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
+                        var primitive = primitives_1[_i];
+                        var primitiveBabylonMesh = new BABYLON.Mesh((mesh.name || babylonMesh.name) + "_" + primitive._index, this._babylonScene, babylonMesh);
+                        node._primitiveBabylonMeshes.push(babylonMesh);
+                        promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, primitiveBabylonMesh));
+                        this.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                    }
                 }
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
                 return Promise.all(promises).then(function () {
-                    if (node._primitiveBabylonMeshes) {
-                        for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                            var primitiveBabylonMesh = _a[_i];
-                            primitiveBabylonMesh._refreshBoundingInfo(true);
-                        }
-                    }
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
+                        babylonMesh._refreshBoundingInfo(true);
+                    });
                 });
             };
-            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive) {
+            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive, babylonMesh) {
                 var _this = this;
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh((mesh.name || node._babylonMesh.name) + "_" + primitive._index, this._babylonScene, node._babylonMesh);
-                node._primitiveBabylonMeshes = node._primitiveBabylonMeshes || [];
-                node._primitiveBabylonMeshes[primitive._index] = babylonMesh;
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
@@ -887,12 +897,11 @@ var BABYLON;
                     babylonMesh.material = this._getDefaultMaterial();
                 }
                 else {
-                    var material = GLTFLoader._GetProperty(context + "/material", this._gltf.materials, primitive.material);
+                    var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
                     promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -907,7 +916,7 @@ var BABYLON;
                 }
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                     // TODO: handle other primitive modes
-                    throw new Error(context + ": Mode " + primitive.mode + " is not currently supported");
+                    throw new Error(context + ": Mode (" + primitive.mode + ") is not currently supported");
                 }
                 var promises = new Array();
                 var babylonVertexData = new BABYLON.VertexData();
@@ -1049,7 +1058,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid component type " + accessor.componentType);
+                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                         }
                     }
                 }
@@ -1095,10 +1104,9 @@ var BABYLON;
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
                 var assignSkeleton = function () {
-                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                        var babylonMesh = _a[_i];
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
                         babylonMesh.skeleton = skin._babylonSkeleton;
-                    }
+                    });
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
@@ -1194,6 +1202,7 @@ var BABYLON;
                 });
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
+                var _this = this;
                 var targetNode = GLTFLoader._GetProperty(context + "/target/node", this._gltf.nodes, channel.target.node);
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                     return Promise.resolve();
@@ -1224,7 +1233,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid target path " + channel.target.path);
+                            throw new Error(context + ": Invalid target path (" + channel.target.path + ")");
                         }
                     }
                     var outputBufferOffset = 0;
@@ -1316,11 +1325,10 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            for (var _i = 0, _a = targetNode._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                                var babylonMesh = _a[_i];
+                            _this._forEachNodeMesh(targetNode, function (babylonMesh) {
                                 var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
-                            }
+                            });
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -1351,7 +1359,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid interpolation " + sampler.interpolation);
+                        throw new Error(context + ": Invalid interpolation (" + sampler.interpolation + ")");
                     }
                 }
                 var inputData;
@@ -1436,12 +1444,12 @@ var BABYLON;
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type " + accessor.componentType);
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e);
+                        throw new Error(context + ": " + e.messsage);
                     }
                 });
                 return accessor._data;
@@ -1605,7 +1613,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid alpha mode " + material.alphaMode);
+                        throw new Error(context + ": Invalid alpha mode (" + material.alphaMode + ")");
                     }
                 }
             };
@@ -1623,7 +1631,7 @@ var BABYLON;
                     }
                 }, function (message, exception) {
                     if (!_this._disposed) {
-                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                        deferred.reject(new Error(context + ": " + ((exception && exception.message) ? exception.message : message || "Failed to load texture")));
                     }
                 });
                 promises.push(deferred.promise);
@@ -1727,7 +1735,7 @@ var BABYLON;
             };
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
-                    throw new Error(context + ": Failed to find index " + index);
+                    throw new Error(context + ": Failed to find index (" + index + ")");
                 }
                 return array[index];
             };
@@ -1739,7 +1747,7 @@ var BABYLON;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     default:
-                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode " + mode);
+                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode (" + mode + ")");
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                 }
             };
@@ -1756,13 +1764,13 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                     }
                 }
                 else {
                     if (magFilter !== 9728 /* NEAREST */) {
-                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter " + magFilter);
+                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter (" + magFilter + ")");
                     }
                     switch (minFilter) {
                         case 9728 /* NEAREST */: return BABYLON.Texture.NEAREST_NEAREST;
@@ -1772,7 +1780,7 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.NEAREST_NEAREST_MIPNEAREST;
                     }
                 }
@@ -1787,7 +1795,7 @@ var BABYLON;
                     case "MAT3": return 9;
                     case "MAT4": return 16;
                 }
-                throw new Error(context + ": Invalid type " + type);
+                throw new Error(context + ": Invalid type (" + type + ")");
             };
             GLTFLoader._ValidateUri = function (uri) {
                 return (BABYLON.Tools.IsBase64(uri) || uri.indexOf("..") === -1);
@@ -2001,7 +2009,10 @@ var BABYLON;
                             var promise = _this._loader._loadNodeAsync("#/nodes/" + nodeLOD._index, nodeLOD).then(function () {
                                 if (indexLOD !== 0) {
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
-                                    previousNodeLOD._babylonMesh.setEnabled(false);
+                                    if (previousNodeLOD._babylonMesh) {
+                                        previousNodeLOD._babylonMesh.dispose();
+                                        delete previousNodeLOD._babylonMesh;
+                                    }
                                 }
                                 if (indexLOD !== nodeLODs.length - 1) {
                                     var nodeIndex = nodeLODs[indexLOD + 1]._index;
@@ -2045,6 +2056,11 @@ var BABYLON;
                             var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     assign(materialLOD._babylonMaterial);
+                                    var previousMaterialLOD = materialLODs[indexLOD - 1];
+                                    if (previousMaterialLOD._babylonMaterial) {
+                                        previousMaterialLOD._babylonMaterial.dispose();
+                                        delete previousMaterialLOD._babylonMaterial;
+                                    }
                                 }
                                 if (indexLOD !== materialLODs.length - 1) {
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
@@ -2360,7 +2376,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type " + light.type);
+                                throw new Error(context + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();
@@ -2373,7 +2389,7 @@ var BABYLON;
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: " + this.name + " not found");
+                            throw new Error("#/extensions: '" + this.name + "' not found");
                         }
                         var extension = extensions[this.name];
                         return extension.lights;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 5 - 4
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -116,7 +116,7 @@ declare module BABYLON {
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         /**
-         * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+         * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
          */
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         whenCompleteAsync(): Promise<void>;
@@ -877,12 +877,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
-        private _loadMeshAsync(context, node, mesh);
-        private _loadPrimitiveAsync(context, node, mesh, primitive);
+        private _loadMeshAsync(context, node, mesh, babylonMesh);
+        private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);

+ 70 - 54
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -77,7 +77,7 @@ var BABYLON;
              */
             this.onMaterialLoadedObservable = new BABYLON.Observable();
             /**
-             * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+             * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
              */
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
@@ -2749,7 +2749,7 @@ var BABYLON;
                         nodes = names.map(function (name) {
                             var node = nodeMap_1[name];
                             if (!node) {
-                                throw new Error("Failed to find node " + name);
+                                throw new Error("Failed to find node '" + name + "'");
                             }
                             return node;
                         });
@@ -2905,7 +2905,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error("Invalid coordinate system mode " + this.coordinateSystemMode);
+                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
                     }
                 }
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
@@ -2934,6 +2934,17 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            GLTFLoader.prototype._forEachNodeMesh = function (node, callback) {
+                if (node._babylonMesh) {
+                    callback(node._babylonMesh);
+                }
+                if (node._primitiveBabylonMeshes) {
+                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
+                        var babylonMesh = _a[_i];
+                        callback(babylonMesh);
+                    }
+                }
+            };
             GLTFLoader.prototype._getMeshes = function () {
                 var meshes = new Array();
                 // Root mesh is always first.
@@ -2942,15 +2953,9 @@ var BABYLON;
                 if (nodes) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                         var node = nodes_2[_i];
-                        if (node._babylonMesh) {
-                            meshes.push(node._babylonMesh);
-                        }
-                        if (node._primitiveBabylonMeshes) {
-                            for (var _a = 0, _b = node._primitiveBabylonMeshes; _a < _b.length; _a++) {
-                                var babylonMesh = _b[_a];
-                                meshes.push(babylonMesh);
-                            }
-                        }
+                        this._forEachNodeMesh(node, function (mesh) {
+                            meshes.push(mesh);
+                        });
                     }
                 }
                 return meshes;
@@ -2991,7 +2996,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode " + this.animationStartMode);
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
                         return;
                     }
                 }
@@ -3012,7 +3017,7 @@ var BABYLON;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
                     var mesh = GLTFLoader._GetProperty(context + "/mesh", this._gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh));
+                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh, babylonMesh));
                 }
                 if (node.children) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
@@ -3024,37 +3029,42 @@ var BABYLON;
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh) {
+            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 // TODO: instancing
+                var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 GLTF2.ArrayItem.Assign(primitives);
-                for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
-                    var primitive = primitives_1[_i];
-                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive));
+                if (primitives.length === 1) {
+                    var primitive = primitives[0];
+                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
+                }
+                else {
+                    node._primitiveBabylonMeshes = [];
+                    for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
+                        var primitive = primitives_1[_i];
+                        var primitiveBabylonMesh = new BABYLON.Mesh((mesh.name || babylonMesh.name) + "_" + primitive._index, this._babylonScene, babylonMesh);
+                        node._primitiveBabylonMeshes.push(babylonMesh);
+                        promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, primitiveBabylonMesh));
+                        this.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                    }
                 }
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
                 return Promise.all(promises).then(function () {
-                    if (node._primitiveBabylonMeshes) {
-                        for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                            var primitiveBabylonMesh = _a[_i];
-                            primitiveBabylonMesh._refreshBoundingInfo(true);
-                        }
-                    }
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
+                        babylonMesh._refreshBoundingInfo(true);
+                    });
                 });
             };
-            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive) {
+            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive, babylonMesh) {
                 var _this = this;
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh((mesh.name || node._babylonMesh.name) + "_" + primitive._index, this._babylonScene, node._babylonMesh);
-                node._primitiveBabylonMeshes = node._primitiveBabylonMeshes || [];
-                node._primitiveBabylonMeshes[primitive._index] = babylonMesh;
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
@@ -3064,12 +3074,11 @@ var BABYLON;
                     babylonMesh.material = this._getDefaultMaterial();
                 }
                 else {
-                    var material = GLTFLoader._GetProperty(context + "/material", this._gltf.materials, primitive.material);
+                    var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
                     promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -3084,7 +3093,7 @@ var BABYLON;
                 }
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                     // TODO: handle other primitive modes
-                    throw new Error(context + ": Mode " + primitive.mode + " is not currently supported");
+                    throw new Error(context + ": Mode (" + primitive.mode + ") is not currently supported");
                 }
                 var promises = new Array();
                 var babylonVertexData = new BABYLON.VertexData();
@@ -3226,7 +3235,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid component type " + accessor.componentType);
+                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                         }
                     }
                 }
@@ -3272,10 +3281,9 @@ var BABYLON;
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
                 var assignSkeleton = function () {
-                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                        var babylonMesh = _a[_i];
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
                         babylonMesh.skeleton = skin._babylonSkeleton;
-                    }
+                    });
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
@@ -3371,6 +3379,7 @@ var BABYLON;
                 });
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
+                var _this = this;
                 var targetNode = GLTFLoader._GetProperty(context + "/target/node", this._gltf.nodes, channel.target.node);
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                     return Promise.resolve();
@@ -3401,7 +3410,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid target path " + channel.target.path);
+                            throw new Error(context + ": Invalid target path (" + channel.target.path + ")");
                         }
                     }
                     var outputBufferOffset = 0;
@@ -3493,11 +3502,10 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            for (var _i = 0, _a = targetNode._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                                var babylonMesh = _a[_i];
+                            _this._forEachNodeMesh(targetNode, function (babylonMesh) {
                                 var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
-                            }
+                            });
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -3528,7 +3536,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid interpolation " + sampler.interpolation);
+                        throw new Error(context + ": Invalid interpolation (" + sampler.interpolation + ")");
                     }
                 }
                 var inputData;
@@ -3613,12 +3621,12 @@ var BABYLON;
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type " + accessor.componentType);
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e);
+                        throw new Error(context + ": " + e.messsage);
                     }
                 });
                 return accessor._data;
@@ -3782,7 +3790,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid alpha mode " + material.alphaMode);
+                        throw new Error(context + ": Invalid alpha mode (" + material.alphaMode + ")");
                     }
                 }
             };
@@ -3800,7 +3808,7 @@ var BABYLON;
                     }
                 }, function (message, exception) {
                     if (!_this._disposed) {
-                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                        deferred.reject(new Error(context + ": " + ((exception && exception.message) ? exception.message : message || "Failed to load texture")));
                     }
                 });
                 promises.push(deferred.promise);
@@ -3904,7 +3912,7 @@ var BABYLON;
             };
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
-                    throw new Error(context + ": Failed to find index " + index);
+                    throw new Error(context + ": Failed to find index (" + index + ")");
                 }
                 return array[index];
             };
@@ -3916,7 +3924,7 @@ var BABYLON;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     default:
-                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode " + mode);
+                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode (" + mode + ")");
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                 }
             };
@@ -3933,13 +3941,13 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                     }
                 }
                 else {
                     if (magFilter !== 9728 /* NEAREST */) {
-                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter " + magFilter);
+                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter (" + magFilter + ")");
                     }
                     switch (minFilter) {
                         case 9728 /* NEAREST */: return BABYLON.Texture.NEAREST_NEAREST;
@@ -3949,7 +3957,7 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.NEAREST_NEAREST_MIPNEAREST;
                     }
                 }
@@ -3964,7 +3972,7 @@ var BABYLON;
                     case "MAT3": return 9;
                     case "MAT4": return 16;
                 }
-                throw new Error(context + ": Invalid type " + type);
+                throw new Error(context + ": Invalid type (" + type + ")");
             };
             GLTFLoader._ValidateUri = function (uri) {
                 return (BABYLON.Tools.IsBase64(uri) || uri.indexOf("..") === -1);
@@ -4178,7 +4186,10 @@ var BABYLON;
                             var promise = _this._loader._loadNodeAsync("#/nodes/" + nodeLOD._index, nodeLOD).then(function () {
                                 if (indexLOD !== 0) {
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
-                                    previousNodeLOD._babylonMesh.setEnabled(false);
+                                    if (previousNodeLOD._babylonMesh) {
+                                        previousNodeLOD._babylonMesh.dispose();
+                                        delete previousNodeLOD._babylonMesh;
+                                    }
                                 }
                                 if (indexLOD !== nodeLODs.length - 1) {
                                     var nodeIndex = nodeLODs[indexLOD + 1]._index;
@@ -4222,6 +4233,11 @@ var BABYLON;
                             var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     assign(materialLOD._babylonMaterial);
+                                    var previousMaterialLOD = materialLODs[indexLOD - 1];
+                                    if (previousMaterialLOD._babylonMaterial) {
+                                        previousMaterialLOD._babylonMaterial.dispose();
+                                        delete previousMaterialLOD._babylonMaterial;
+                                    }
                                 }
                                 if (indexLOD !== materialLODs.length - 1) {
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
@@ -4537,7 +4553,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type " + light.type);
+                                throw new Error(context + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();
@@ -4550,7 +4566,7 @@ var BABYLON;
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: " + this.name + " not found");
+                            throw new Error("#/extensions: '" + this.name + "' not found");
                         }
                         var extension = extensions[this.name];
                         return extension.lights;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 70 - 54
dist/preview release/loaders/babylonjs.loaders.js

@@ -1073,7 +1073,7 @@ var BABYLON;
              */
             this.onMaterialLoadedObservable = new BABYLON.Observable();
             /**
-             * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+             * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
              */
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
@@ -1180,7 +1180,7 @@ var BABYLON;
             configurable: true
         });
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
@@ -3727,7 +3727,7 @@ var BABYLON;
                         nodes = names.map(function (name) {
                             var node = nodeMap_1[name];
                             if (!node) {
-                                throw new Error("Failed to find node " + name);
+                                throw new Error("Failed to find node '" + name + "'");
                             }
                             return node;
                         });
@@ -3883,7 +3883,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error("Invalid coordinate system mode " + this.coordinateSystemMode);
+                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
                     }
                 }
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
@@ -3912,6 +3912,17 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            GLTFLoader.prototype._forEachNodeMesh = function (node, callback) {
+                if (node._babylonMesh) {
+                    callback(node._babylonMesh);
+                }
+                if (node._primitiveBabylonMeshes) {
+                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
+                        var babylonMesh = _a[_i];
+                        callback(babylonMesh);
+                    }
+                }
+            };
             GLTFLoader.prototype._getMeshes = function () {
                 var meshes = new Array();
                 // Root mesh is always first.
@@ -3920,15 +3931,9 @@ var BABYLON;
                 if (nodes) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                         var node = nodes_2[_i];
-                        if (node._babylonMesh) {
-                            meshes.push(node._babylonMesh);
-                        }
-                        if (node._primitiveBabylonMeshes) {
-                            for (var _a = 0, _b = node._primitiveBabylonMeshes; _a < _b.length; _a++) {
-                                var babylonMesh = _b[_a];
-                                meshes.push(babylonMesh);
-                            }
-                        }
+                        this._forEachNodeMesh(node, function (mesh) {
+                            meshes.push(mesh);
+                        });
                     }
                 }
                 return meshes;
@@ -3969,7 +3974,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode " + this.animationStartMode);
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
                         return;
                     }
                 }
@@ -3990,7 +3995,7 @@ var BABYLON;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
                     var mesh = GLTFLoader._GetProperty(context + "/mesh", this._gltf.meshes, node.mesh);
-                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh));
+                    promises.push(this._loadMeshAsync("#/meshes/" + mesh._index, node, mesh, babylonMesh));
                 }
                 if (node.children) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
@@ -4002,37 +4007,42 @@ var BABYLON;
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh) {
+            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 // TODO: instancing
+                var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 GLTF2.ArrayItem.Assign(primitives);
-                for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
-                    var primitive = primitives_1[_i];
-                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive));
+                if (primitives.length === 1) {
+                    var primitive = primitives[0];
+                    promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, babylonMesh));
+                }
+                else {
+                    node._primitiveBabylonMeshes = [];
+                    for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
+                        var primitive = primitives_1[_i];
+                        var primitiveBabylonMesh = new BABYLON.Mesh((mesh.name || babylonMesh.name) + "_" + primitive._index, this._babylonScene, babylonMesh);
+                        node._primitiveBabylonMeshes.push(babylonMesh);
+                        promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, primitiveBabylonMesh));
+                        this.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                    }
                 }
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
                 return Promise.all(promises).then(function () {
-                    if (node._primitiveBabylonMeshes) {
-                        for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                            var primitiveBabylonMesh = _a[_i];
-                            primitiveBabylonMesh._refreshBoundingInfo(true);
-                        }
-                    }
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
+                        babylonMesh._refreshBoundingInfo(true);
+                    });
                 });
             };
-            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive) {
+            GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive, babylonMesh) {
                 var _this = this;
                 var promises = new Array();
-                var babylonMesh = new BABYLON.Mesh((mesh.name || node._babylonMesh.name) + "_" + primitive._index, this._babylonScene, node._babylonMesh);
-                node._primitiveBabylonMeshes = node._primitiveBabylonMeshes || [];
-                node._primitiveBabylonMeshes[primitive._index] = babylonMesh;
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
@@ -4042,12 +4052,11 @@ var BABYLON;
                     babylonMesh.material = this._getDefaultMaterial();
                 }
                 else {
-                    var material = GLTFLoader._GetProperty(context + "/material", this._gltf.materials, primitive.material);
+                    var material = GLTFLoader._GetProperty(context + "/material}", this._gltf.materials, primitive.material);
                     promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -4062,7 +4071,7 @@ var BABYLON;
                 }
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                     // TODO: handle other primitive modes
-                    throw new Error(context + ": Mode " + primitive.mode + " is not currently supported");
+                    throw new Error(context + ": Mode (" + primitive.mode + ") is not currently supported");
                 }
                 var promises = new Array();
                 var babylonVertexData = new BABYLON.VertexData();
@@ -4204,7 +4213,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid component type " + accessor.componentType);
+                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                         }
                     }
                 }
@@ -4250,10 +4259,9 @@ var BABYLON;
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
                 var assignSkeleton = function () {
-                    for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                        var babylonMesh = _a[_i];
+                    _this._forEachNodeMesh(node, function (babylonMesh) {
                         babylonMesh.skeleton = skin._babylonSkeleton;
-                    }
+                    });
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
@@ -4349,6 +4357,7 @@ var BABYLON;
                 });
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
+                var _this = this;
                 var targetNode = GLTFLoader._GetProperty(context + "/target/node", this._gltf.nodes, channel.target.node);
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                     return Promise.resolve();
@@ -4379,7 +4388,7 @@ var BABYLON;
                             break;
                         }
                         default: {
-                            throw new Error(context + ": Invalid target path " + channel.target.path);
+                            throw new Error(context + ": Invalid target path (" + channel.target.path + ")");
                         }
                     }
                     var outputBufferOffset = 0;
@@ -4471,11 +4480,10 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            for (var _i = 0, _a = targetNode._primitiveBabylonMeshes; _i < _a.length; _i++) {
-                                var babylonMesh = _a[_i];
+                            _this._forEachNodeMesh(targetNode, function (babylonMesh) {
                                 var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
-                            }
+                            });
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -4506,7 +4514,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid interpolation " + sampler.interpolation);
+                        throw new Error(context + ": Invalid interpolation (" + sampler.interpolation + ")");
                     }
                 }
                 var inputData;
@@ -4591,12 +4599,12 @@ var BABYLON;
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type " + accessor.componentType);
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e);
+                        throw new Error(context + ": " + e.messsage);
                     }
                 });
                 return accessor._data;
@@ -4760,7 +4768,7 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error(context + ": Invalid alpha mode " + material.alphaMode);
+                        throw new Error(context + ": Invalid alpha mode (" + material.alphaMode + ")");
                     }
                 }
             };
@@ -4778,7 +4786,7 @@ var BABYLON;
                     }
                 }, function (message, exception) {
                     if (!_this._disposed) {
-                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                        deferred.reject(new Error(context + ": " + ((exception && exception.message) ? exception.message : message || "Failed to load texture")));
                     }
                 });
                 promises.push(deferred.promise);
@@ -4882,7 +4890,7 @@ var BABYLON;
             };
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
-                    throw new Error(context + ": Failed to find index " + index);
+                    throw new Error(context + ": Failed to find index (" + index + ")");
                 }
                 return array[index];
             };
@@ -4894,7 +4902,7 @@ var BABYLON;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     default:
-                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode " + mode);
+                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode (" + mode + ")");
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                 }
             };
@@ -4911,13 +4919,13 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                     }
                 }
                 else {
                     if (magFilter !== 9728 /* NEAREST */) {
-                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter " + magFilter);
+                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter (" + magFilter + ")");
                     }
                     switch (minFilter) {
                         case 9728 /* NEAREST */: return BABYLON.Texture.NEAREST_NEAREST;
@@ -4927,7 +4935,7 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         default:
-                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter " + minFilter);
+                            BABYLON.Tools.Warn(context + ": Invalid texture minification filter (" + minFilter + ")");
                             return BABYLON.Texture.NEAREST_NEAREST_MIPNEAREST;
                     }
                 }
@@ -4942,7 +4950,7 @@ var BABYLON;
                     case "MAT3": return 9;
                     case "MAT4": return 16;
                 }
-                throw new Error(context + ": Invalid type " + type);
+                throw new Error(context + ": Invalid type (" + type + ")");
             };
             GLTFLoader._ValidateUri = function (uri) {
                 return (BABYLON.Tools.IsBase64(uri) || uri.indexOf("..") === -1);
@@ -5147,7 +5155,10 @@ var BABYLON;
                             var promise = _this._loader._loadNodeAsync("#/nodes/" + nodeLOD._index, nodeLOD).then(function () {
                                 if (indexLOD !== 0) {
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
-                                    previousNodeLOD._babylonMesh.setEnabled(false);
+                                    if (previousNodeLOD._babylonMesh) {
+                                        previousNodeLOD._babylonMesh.dispose();
+                                        delete previousNodeLOD._babylonMesh;
+                                    }
                                 }
                                 if (indexLOD !== nodeLODs.length - 1) {
                                     var nodeIndex = nodeLODs[indexLOD + 1]._index;
@@ -5191,6 +5202,11 @@ var BABYLON;
                             var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                     assign(materialLOD._babylonMaterial);
+                                    var previousMaterialLOD = materialLODs[indexLOD - 1];
+                                    if (previousMaterialLOD._babylonMaterial) {
+                                        previousMaterialLOD._babylonMaterial.dispose();
+                                        delete previousMaterialLOD._babylonMaterial;
+                                    }
                                 }
                                 if (indexLOD !== materialLODs.length - 1) {
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
@@ -5479,7 +5495,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type " + light.type);
+                                throw new Error(context + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();
@@ -5492,7 +5508,7 @@ var BABYLON;
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: " + this.name + " not found");
+                            throw new Error("#/extensions: '" + this.name + "' not found");
                         }
                         var extension = extensions[this.name];
                         return extension.lights;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 5 - 4
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -218,7 +218,7 @@ declare module BABYLON {
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         /**
-         * Raised when the loader creates an animation group after parsing the glTF properties of the material.
+         * Raised when the loader creates an animation group after parsing the glTF properties of the animation.
          */
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
@@ -245,7 +245,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
-         * Gets a promise that resolves when the asset to be completely loaded.
+         * Gets a promise that resolves when the asset is completely loaded.
          * @returns A promise that resolves when the asset is completely loaded.
          */
         whenCompleteAsync(): Promise<void>;
@@ -979,12 +979,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
-        private _loadMeshAsync(context, node, mesh);
-        private _loadPrimitiveAsync(context, node, mesh, primitive);
+        private _loadMeshAsync(context, node, mesh, babylonMesh);
+        private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);

+ 4 - 282
dist/preview release/materialsLibrary/babylon.customMaterial.d.ts

@@ -1,277 +1,5 @@
 
 declare module BABYLON {
-    class StandardMaterialDefines_OldVer extends MaterialDefines implements IImageProcessingConfigurationDefines {
-        DIFFUSE: boolean;
-        AMBIENT: boolean;
-        OPACITY: boolean;
-        OPACITYRGB: boolean;
-        REFLECTION: boolean;
-        EMISSIVE: boolean;
-        SPECULAR: boolean;
-        BUMP: boolean;
-        PARALLAX: boolean;
-        PARALLAXOCCLUSION: boolean;
-        SPECULAROVERALPHA: boolean;
-        CLIPPLANE: boolean;
-        ALPHATEST: boolean;
-        ALPHAFROMDIFFUSE: boolean;
-        POINTSIZE: boolean;
-        FOG: boolean;
-        SPECULARTERM: boolean;
-        DIFFUSEFRESNEL: boolean;
-        OPACITYFRESNEL: boolean;
-        REFLECTIONFRESNEL: boolean;
-        REFRACTIONFRESNEL: boolean;
-        EMISSIVEFRESNEL: boolean;
-        FRESNEL: boolean;
-        NORMAL: boolean;
-        UV1: boolean;
-        UV2: boolean;
-        VERTEXCOLOR: boolean;
-        VERTEXALPHA: boolean;
-        NUM_BONE_INFLUENCERS: number;
-        BonesPerMesh: number;
-        INSTANCES: boolean;
-        GLOSSINESS: boolean;
-        ROUGHNESS: boolean;
-        EMISSIVEASILLUMINATION: boolean;
-        LINKEMISSIVEWITHDIFFUSE: boolean;
-        REFLECTIONFRESNELFROMSPECULAR: boolean;
-        LIGHTMAP: boolean;
-        USELIGHTMAPASSHADOWMAP: boolean;
-        REFLECTIONMAP_3D: boolean;
-        REFLECTIONMAP_SPHERICAL: boolean;
-        REFLECTIONMAP_PLANAR: boolean;
-        REFLECTIONMAP_CUBIC: boolean;
-        REFLECTIONMAP_PROJECTION: boolean;
-        REFLECTIONMAP_SKYBOX: boolean;
-        REFLECTIONMAP_EXPLICIT: boolean;
-        REFLECTIONMAP_EQUIRECTANGULAR: boolean;
-        REFLECTIONMAP_EQUIRECTANGULAR_FIXED: boolean;
-        REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED: boolean;
-        INVERTCUBICMAP: boolean;
-        LOGARITHMICDEPTH: boolean;
-        REFRACTION: boolean;
-        REFRACTIONMAP_3D: boolean;
-        REFLECTIONOVERALPHA: boolean;
-        TWOSIDEDLIGHTING: boolean;
-        SHADOWFLOAT: boolean;
-        MORPHTARGETS: boolean;
-        MORPHTARGETS_NORMAL: boolean;
-        MORPHTARGETS_TANGENT: boolean;
-        NUM_MORPH_INFLUENCERS: number;
-        IMAGEPROCESSING: boolean;
-        VIGNETTE: boolean;
-        VIGNETTEBLENDMODEMULTIPLY: boolean;
-        VIGNETTEBLENDMODEOPAQUE: boolean;
-        TONEMAPPING: boolean;
-        CONTRAST: boolean;
-        COLORCURVES: boolean;
-        COLORGRADING: boolean;
-        COLORGRADING3D: boolean;
-        SAMPLER3DGREENDEPTH: boolean;
-        SAMPLER3DBGRMAP: boolean;
-        IMAGEPROCESSINGPOSTPROCESS: boolean;
-        EXPOSURE: boolean;
-        GRAIN: boolean;
-        constructor();
-        setReflectionMode(modeToEnable: string): void;
-    }
-    class StandardMaterial_OldVer extends PushMaterial {
-        private _diffuseTexture;
-        diffuseTexture: BaseTexture;
-        private _ambientTexture;
-        ambientTexture: BaseTexture;
-        private _opacityTexture;
-        opacityTexture: BaseTexture;
-        private _reflectionTexture;
-        reflectionTexture: BaseTexture;
-        private _emissiveTexture;
-        emissiveTexture: BaseTexture;
-        private _specularTexture;
-        specularTexture: BaseTexture;
-        private _bumpTexture;
-        bumpTexture: BaseTexture;
-        private _lightmapTexture;
-        lightmapTexture: BaseTexture;
-        private _refractionTexture;
-        refractionTexture: BaseTexture;
-        ambientColor: Color3;
-        diffuseColor: Color3;
-        specularColor: Color3;
-        emissiveColor: Color3;
-        specularPower: number;
-        private _useAlphaFromDiffuseTexture;
-        useAlphaFromDiffuseTexture: boolean;
-        private _useEmissiveAsIllumination;
-        useEmissiveAsIllumination: boolean;
-        private _linkEmissiveWithDiffuse;
-        linkEmissiveWithDiffuse: boolean;
-        private _useSpecularOverAlpha;
-        useSpecularOverAlpha: boolean;
-        private _useReflectionOverAlpha;
-        useReflectionOverAlpha: boolean;
-        private _disableLighting;
-        disableLighting: boolean;
-        private _useParallax;
-        useParallax: boolean;
-        private _useParallaxOcclusion;
-        useParallaxOcclusion: boolean;
-        parallaxScaleBias: number;
-        private _roughness;
-        roughness: number;
-        indexOfRefraction: number;
-        invertRefractionY: boolean;
-        private _useLightmapAsShadowmap;
-        useLightmapAsShadowmap: boolean;
-        private _diffuseFresnelParameters;
-        diffuseFresnelParameters: FresnelParameters;
-        private _opacityFresnelParameters;
-        opacityFresnelParameters: FresnelParameters;
-        private _reflectionFresnelParameters;
-        reflectionFresnelParameters: FresnelParameters;
-        private _refractionFresnelParameters;
-        refractionFresnelParameters: FresnelParameters;
-        private _emissiveFresnelParameters;
-        emissiveFresnelParameters: FresnelParameters;
-        private _useReflectionFresnelFromSpecular;
-        useReflectionFresnelFromSpecular: boolean;
-        private _useGlossinessFromSpecularMapAlpha;
-        useGlossinessFromSpecularMapAlpha: boolean;
-        private _maxSimultaneousLights;
-        maxSimultaneousLights: number;
-        /**
-         * If sets to true, x component of normal map value will invert (x = 1.0 - x).
-         */
-        private _invertNormalMapX;
-        invertNormalMapX: boolean;
-        /**
-         * If sets to true, y component of normal map value will invert (y = 1.0 - y).
-         */
-        private _invertNormalMapY;
-        invertNormalMapY: boolean;
-        /**
-         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
-         */
-        private _twoSidedLighting;
-        twoSidedLighting: boolean;
-        /**
-         * Default configuration related to image processing available in the standard Material.
-         */
-        protected _imageProcessingConfiguration: ImageProcessingConfiguration;
-        /**
-         * Gets the image processing configuration used either in this material.
-         */
-        /**
-         * Sets the Default image processing configuration used either in the this material.
-         *
-         * If sets to null, the scene one is in use.
-         */
-        imageProcessingConfiguration: ImageProcessingConfiguration;
-        /**
-         * Keep track of the image processing observer to allow dispose and replace.
-         */
-        private _imageProcessingObserver;
-        /**
-         * Attaches a new image processing configuration to the Standard Material.
-         * @param configuration
-         */
-        protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void;
-        /**
-         * Gets wether the color curves effect is enabled.
-         */
-        /**
-         * Sets wether the color curves effect is enabled.
-         */
-        cameraColorCurvesEnabled: boolean;
-        /**
-         * Gets wether the color grading effect is enabled.
-         */
-        /**
-         * Gets wether the color grading effect is enabled.
-         */
-        cameraColorGradingEnabled: boolean;
-        /**
-         * Gets wether tonemapping is enabled or not.
-         */
-        /**
-         * Sets wether tonemapping is enabled or not
-         */
-        cameraToneMappingEnabled: boolean;
-        /**
-         * The camera exposure used on this material.
-         * This property is here and not in the camera to allow controlling exposure without full screen post process.
-         * This corresponds to a photographic exposure.
-         */
-        /**
-         * The camera exposure used on this material.
-         * This property is here and not in the camera to allow controlling exposure without full screen post process.
-         * This corresponds to a photographic exposure.
-         */
-        cameraExposure: number;
-        /**
-         * Gets The camera contrast used on this material.
-         */
-        /**
-         * Sets The camera contrast used on this material.
-         */
-        cameraContrast: number;
-        /**
-         * Gets the Color Grading 2D Lookup Texture.
-         */
-        /**
-         * Sets the Color Grading 2D Lookup Texture.
-         */
-        cameraColorGradingTexture: Nullable<BaseTexture>;
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
-        protected _renderTargets: SmartArray<RenderTargetTexture>;
-        protected _worldViewProjectionMatrix: Matrix;
-        protected _globalAmbientColor: Color3;
-        protected _useLogarithmicDepth: boolean;
-        constructor(name: string, scene: Scene);
-        getClassName(): string;
-        useLogarithmicDepth: boolean;
-        needAlphaBlending(): boolean;
-        needAlphaTesting(): boolean;
-        protected _shouldUseAlphaFromDiffuseTexture(): boolean;
-        getAlphaTestTexture(): BaseTexture;
-        /**
-         * Child classes can use it to update shaders
-         */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
-        buildUniformLayout(): void;
-        unbind(): void;
-        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
-        getAnimatables(): IAnimatable[];
-        getActiveTextures(): BaseTexture[];
-        dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
-        clone(name: string): StandardMaterial_OldVer;
-        serialize(): any;
-        static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial_OldVer;
-        static _DiffuseTextureEnabled: boolean;
-        static DiffuseTextureEnabled: boolean;
-        static _AmbientTextureEnabled: boolean;
-        static AmbientTextureEnabled: boolean;
-        static _OpacityTextureEnabled: boolean;
-        static OpacityTextureEnabled: boolean;
-        static _ReflectionTextureEnabled: boolean;
-        static ReflectionTextureEnabled: boolean;
-        static _EmissiveTextureEnabled: boolean;
-        static EmissiveTextureEnabled: boolean;
-        static _SpecularTextureEnabled: boolean;
-        static SpecularTextureEnabled: boolean;
-        static _BumpTextureEnabled: boolean;
-        static BumpTextureEnabled: boolean;
-        static _LightmapTextureEnabled: boolean;
-        static LightmapTextureEnabled: boolean;
-        static _RefractionTextureEnabled: boolean;
-        static RefractionTextureEnabled: boolean;
-        static _ColorGradingTextureEnabled: boolean;
-        static ColorGradingTextureEnabled: boolean;
-        static _FresnelEnabled: boolean;
-        static FresnelEnabled: boolean;
-    }
     class CustomShaderStructure {
         FragmentStore: string;
         VertexStore: string;
@@ -291,26 +19,20 @@ declare module BABYLON {
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
     }
-    class ShaderForVer3_0 extends CustomShaderStructure {
-        constructor();
-    }
-    class StandardShaderVersions {
-        static Ver3_0: string;
-    }
-    class CustomMaterial extends StandardMaterial_OldVer {
+    class CustomMaterial extends StandardMaterial {
         static ShaderIndexer: number;
         CustomParts: ShaderSpecialParts;
-        ShaderVersion: CustomShaderStructure;
         _isCreatedShader: boolean;
         _createdShaderName: string;
         _customUniform: string[];
         _newUniforms: string[];
         _newUniformInstances: any[];
         _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer): string;
-        SelectVersion(ver: string): void;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string;
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19 - 1908
dist/preview release/materialsLibrary/babylon.customMaterial.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 22 - 1906
dist/preview release/materialsLibrary/babylonjs.materials.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 6
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 4 - 282
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -506,278 +506,6 @@ declare module BABYLON {
 
 
 declare module BABYLON {
-    class StandardMaterialDefines_OldVer extends MaterialDefines implements IImageProcessingConfigurationDefines {
-        DIFFUSE: boolean;
-        AMBIENT: boolean;
-        OPACITY: boolean;
-        OPACITYRGB: boolean;
-        REFLECTION: boolean;
-        EMISSIVE: boolean;
-        SPECULAR: boolean;
-        BUMP: boolean;
-        PARALLAX: boolean;
-        PARALLAXOCCLUSION: boolean;
-        SPECULAROVERALPHA: boolean;
-        CLIPPLANE: boolean;
-        ALPHATEST: boolean;
-        ALPHAFROMDIFFUSE: boolean;
-        POINTSIZE: boolean;
-        FOG: boolean;
-        SPECULARTERM: boolean;
-        DIFFUSEFRESNEL: boolean;
-        OPACITYFRESNEL: boolean;
-        REFLECTIONFRESNEL: boolean;
-        REFRACTIONFRESNEL: boolean;
-        EMISSIVEFRESNEL: boolean;
-        FRESNEL: boolean;
-        NORMAL: boolean;
-        UV1: boolean;
-        UV2: boolean;
-        VERTEXCOLOR: boolean;
-        VERTEXALPHA: boolean;
-        NUM_BONE_INFLUENCERS: number;
-        BonesPerMesh: number;
-        INSTANCES: boolean;
-        GLOSSINESS: boolean;
-        ROUGHNESS: boolean;
-        EMISSIVEASILLUMINATION: boolean;
-        LINKEMISSIVEWITHDIFFUSE: boolean;
-        REFLECTIONFRESNELFROMSPECULAR: boolean;
-        LIGHTMAP: boolean;
-        USELIGHTMAPASSHADOWMAP: boolean;
-        REFLECTIONMAP_3D: boolean;
-        REFLECTIONMAP_SPHERICAL: boolean;
-        REFLECTIONMAP_PLANAR: boolean;
-        REFLECTIONMAP_CUBIC: boolean;
-        REFLECTIONMAP_PROJECTION: boolean;
-        REFLECTIONMAP_SKYBOX: boolean;
-        REFLECTIONMAP_EXPLICIT: boolean;
-        REFLECTIONMAP_EQUIRECTANGULAR: boolean;
-        REFLECTIONMAP_EQUIRECTANGULAR_FIXED: boolean;
-        REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED: boolean;
-        INVERTCUBICMAP: boolean;
-        LOGARITHMICDEPTH: boolean;
-        REFRACTION: boolean;
-        REFRACTIONMAP_3D: boolean;
-        REFLECTIONOVERALPHA: boolean;
-        TWOSIDEDLIGHTING: boolean;
-        SHADOWFLOAT: boolean;
-        MORPHTARGETS: boolean;
-        MORPHTARGETS_NORMAL: boolean;
-        MORPHTARGETS_TANGENT: boolean;
-        NUM_MORPH_INFLUENCERS: number;
-        IMAGEPROCESSING: boolean;
-        VIGNETTE: boolean;
-        VIGNETTEBLENDMODEMULTIPLY: boolean;
-        VIGNETTEBLENDMODEOPAQUE: boolean;
-        TONEMAPPING: boolean;
-        CONTRAST: boolean;
-        COLORCURVES: boolean;
-        COLORGRADING: boolean;
-        COLORGRADING3D: boolean;
-        SAMPLER3DGREENDEPTH: boolean;
-        SAMPLER3DBGRMAP: boolean;
-        IMAGEPROCESSINGPOSTPROCESS: boolean;
-        EXPOSURE: boolean;
-        GRAIN: boolean;
-        constructor();
-        setReflectionMode(modeToEnable: string): void;
-    }
-    class StandardMaterial_OldVer extends PushMaterial {
-        private _diffuseTexture;
-        diffuseTexture: BaseTexture;
-        private _ambientTexture;
-        ambientTexture: BaseTexture;
-        private _opacityTexture;
-        opacityTexture: BaseTexture;
-        private _reflectionTexture;
-        reflectionTexture: BaseTexture;
-        private _emissiveTexture;
-        emissiveTexture: BaseTexture;
-        private _specularTexture;
-        specularTexture: BaseTexture;
-        private _bumpTexture;
-        bumpTexture: BaseTexture;
-        private _lightmapTexture;
-        lightmapTexture: BaseTexture;
-        private _refractionTexture;
-        refractionTexture: BaseTexture;
-        ambientColor: Color3;
-        diffuseColor: Color3;
-        specularColor: Color3;
-        emissiveColor: Color3;
-        specularPower: number;
-        private _useAlphaFromDiffuseTexture;
-        useAlphaFromDiffuseTexture: boolean;
-        private _useEmissiveAsIllumination;
-        useEmissiveAsIllumination: boolean;
-        private _linkEmissiveWithDiffuse;
-        linkEmissiveWithDiffuse: boolean;
-        private _useSpecularOverAlpha;
-        useSpecularOverAlpha: boolean;
-        private _useReflectionOverAlpha;
-        useReflectionOverAlpha: boolean;
-        private _disableLighting;
-        disableLighting: boolean;
-        private _useParallax;
-        useParallax: boolean;
-        private _useParallaxOcclusion;
-        useParallaxOcclusion: boolean;
-        parallaxScaleBias: number;
-        private _roughness;
-        roughness: number;
-        indexOfRefraction: number;
-        invertRefractionY: boolean;
-        private _useLightmapAsShadowmap;
-        useLightmapAsShadowmap: boolean;
-        private _diffuseFresnelParameters;
-        diffuseFresnelParameters: FresnelParameters;
-        private _opacityFresnelParameters;
-        opacityFresnelParameters: FresnelParameters;
-        private _reflectionFresnelParameters;
-        reflectionFresnelParameters: FresnelParameters;
-        private _refractionFresnelParameters;
-        refractionFresnelParameters: FresnelParameters;
-        private _emissiveFresnelParameters;
-        emissiveFresnelParameters: FresnelParameters;
-        private _useReflectionFresnelFromSpecular;
-        useReflectionFresnelFromSpecular: boolean;
-        private _useGlossinessFromSpecularMapAlpha;
-        useGlossinessFromSpecularMapAlpha: boolean;
-        private _maxSimultaneousLights;
-        maxSimultaneousLights: number;
-        /**
-         * If sets to true, x component of normal map value will invert (x = 1.0 - x).
-         */
-        private _invertNormalMapX;
-        invertNormalMapX: boolean;
-        /**
-         * If sets to true, y component of normal map value will invert (y = 1.0 - y).
-         */
-        private _invertNormalMapY;
-        invertNormalMapY: boolean;
-        /**
-         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
-         */
-        private _twoSidedLighting;
-        twoSidedLighting: boolean;
-        /**
-         * Default configuration related to image processing available in the standard Material.
-         */
-        protected _imageProcessingConfiguration: ImageProcessingConfiguration;
-        /**
-         * Gets the image processing configuration used either in this material.
-         */
-        /**
-         * Sets the Default image processing configuration used either in the this material.
-         *
-         * If sets to null, the scene one is in use.
-         */
-        imageProcessingConfiguration: ImageProcessingConfiguration;
-        /**
-         * Keep track of the image processing observer to allow dispose and replace.
-         */
-        private _imageProcessingObserver;
-        /**
-         * Attaches a new image processing configuration to the Standard Material.
-         * @param configuration
-         */
-        protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void;
-        /**
-         * Gets wether the color curves effect is enabled.
-         */
-        /**
-         * Sets wether the color curves effect is enabled.
-         */
-        cameraColorCurvesEnabled: boolean;
-        /**
-         * Gets wether the color grading effect is enabled.
-         */
-        /**
-         * Gets wether the color grading effect is enabled.
-         */
-        cameraColorGradingEnabled: boolean;
-        /**
-         * Gets wether tonemapping is enabled or not.
-         */
-        /**
-         * Sets wether tonemapping is enabled or not
-         */
-        cameraToneMappingEnabled: boolean;
-        /**
-         * The camera exposure used on this material.
-         * This property is here and not in the camera to allow controlling exposure without full screen post process.
-         * This corresponds to a photographic exposure.
-         */
-        /**
-         * The camera exposure used on this material.
-         * This property is here and not in the camera to allow controlling exposure without full screen post process.
-         * This corresponds to a photographic exposure.
-         */
-        cameraExposure: number;
-        /**
-         * Gets The camera contrast used on this material.
-         */
-        /**
-         * Sets The camera contrast used on this material.
-         */
-        cameraContrast: number;
-        /**
-         * Gets the Color Grading 2D Lookup Texture.
-         */
-        /**
-         * Sets the Color Grading 2D Lookup Texture.
-         */
-        cameraColorGradingTexture: Nullable<BaseTexture>;
-        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
-        protected _renderTargets: SmartArray<RenderTargetTexture>;
-        protected _worldViewProjectionMatrix: Matrix;
-        protected _globalAmbientColor: Color3;
-        protected _useLogarithmicDepth: boolean;
-        constructor(name: string, scene: Scene);
-        getClassName(): string;
-        useLogarithmicDepth: boolean;
-        needAlphaBlending(): boolean;
-        needAlphaTesting(): boolean;
-        protected _shouldUseAlphaFromDiffuseTexture(): boolean;
-        getAlphaTestTexture(): BaseTexture;
-        /**
-         * Child classes can use it to update shaders
-         */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
-        buildUniformLayout(): void;
-        unbind(): void;
-        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
-        getAnimatables(): IAnimatable[];
-        getActiveTextures(): BaseTexture[];
-        dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void;
-        clone(name: string): StandardMaterial_OldVer;
-        serialize(): any;
-        static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial_OldVer;
-        static _DiffuseTextureEnabled: boolean;
-        static DiffuseTextureEnabled: boolean;
-        static _AmbientTextureEnabled: boolean;
-        static AmbientTextureEnabled: boolean;
-        static _OpacityTextureEnabled: boolean;
-        static OpacityTextureEnabled: boolean;
-        static _ReflectionTextureEnabled: boolean;
-        static ReflectionTextureEnabled: boolean;
-        static _EmissiveTextureEnabled: boolean;
-        static EmissiveTextureEnabled: boolean;
-        static _SpecularTextureEnabled: boolean;
-        static SpecularTextureEnabled: boolean;
-        static _BumpTextureEnabled: boolean;
-        static BumpTextureEnabled: boolean;
-        static _LightmapTextureEnabled: boolean;
-        static LightmapTextureEnabled: boolean;
-        static _RefractionTextureEnabled: boolean;
-        static RefractionTextureEnabled: boolean;
-        static _ColorGradingTextureEnabled: boolean;
-        static ColorGradingTextureEnabled: boolean;
-        static _FresnelEnabled: boolean;
-        static FresnelEnabled: boolean;
-    }
     class CustomShaderStructure {
         FragmentStore: string;
         VertexStore: string;
@@ -797,26 +525,20 @@ declare module BABYLON {
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
     }
-    class ShaderForVer3_0 extends CustomShaderStructure {
-        constructor();
-    }
-    class StandardShaderVersions {
-        static Ver3_0: string;
-    }
-    class CustomMaterial extends StandardMaterial_OldVer {
+    class CustomMaterial extends StandardMaterial {
         static ShaderIndexer: number;
         CustomParts: ShaderSpecialParts;
-        ShaderVersion: CustomShaderStructure;
         _isCreatedShader: boolean;
         _createdShaderName: string;
         _customUniform: string[];
         _newUniforms: string[];
         _newUniformInstances: any[];
         _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer): string;
-        SelectVersion(ver: string): void;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string;
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


+ 86 - 29
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -290,23 +290,33 @@ declare module BABYLON.GLTF2 {
         /**
          * Represents the dielectric specular values for R, G and B.
          */
-        private static readonly dielectricSpecular;
+        private static readonly _dielectricSpecular;
         /**
          * Allows the maximum specular power to be defined for material calculations.
          */
-        private static maxSpecularPower;
-        private static epsilon;
+        private static _maxSpecularPower;
+        /**
+         * Numeric tolerance value
+         */
+        private static _epsilon;
+        /**
+         * Specifies if two colors are approximately equal in value.
+         * @param color1 - first color to compare to.
+         * @param color2 - second color to compare to.
+         * @param epsilon - threshold value
+         */
+        private static FuzzyEquals(color1, color2, epsilon);
         /**
          * Gets the materials from a Babylon scene and converts them to glTF materials.
-         * @param scene
-         * @param mimeType
-         * @param images
-         * @param textures
-         * @param materials
-         * @param imageData
-         * @param hasTextureCoords
-         */
-        static ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+         * @param scene - babylonjs scene.
+         * @param mimeType - texture mime type.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param materials - array of materials.
+         * @param imageData - mapping of texture names to base64 textures
+         * @param hasTextureCoords - specifies if texture coordinates are present on the material.
+         */
+        static _ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -317,19 +327,19 @@ declare module BABYLON.GLTF2 {
          * @param originalMaterial - original glTF material.
          * @returns glTF material without texture parameters
          */
-        static StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        static _StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
         /**
          * Specifies if the material has any texture parameters present.
          * @param material - glTF Material.
          * @returns boolean specifying if texture parameters are present
          */
-        static HasTexturesPresent(material: IMaterial): boolean;
+        static _HasTexturesPresent(material: IMaterial): boolean;
         /**
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
          */
-        static ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
         /**
          * Computes the metallic factor
          * @param diffuse - diffused value
@@ -337,13 +347,13 @@ declare module BABYLON.GLTF2 {
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @returns - metallic value
          */
-        static SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
+        static _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
         /**
          * Gets the glTF alpha mode from the Babylon Material
          * @param babylonMaterial - Babylon Material
          * @returns - The Babylon alpha mode value
          */
-        static GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
         /**
          * Converts a Babylon Standard Material to a glTF Material.
          * @param babylonStandardMaterial - BJS Standard Material.
@@ -354,7 +364,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -370,25 +380,66 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * Converts an image typed array buffer to a base64 image.
+         * @param buffer - typed array buffer.
+         * @param width - width of the image.
+         * @param height - height of the image.
+         * @param mimeType - mimetype of the image.
+         * @returns - base64 image string.
+         */
+        private static _CreateBase64FromCanvas(buffer, width, height, mimeType);
+        /**
+         * Generates a white texture based on the specified width and height.
+         * @param width - width of the texture in pixels.
+         * @param height - height of the texture in pixels.
+         * @param scene - babylonjs scene.
+         * @returns - white texture.
+         */
+        private static _CreateWhiteTexture(width, height, scene);
+        /**
+         * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+         * @param texture1 - first texture to resize.
+         * @param texture2 - second texture to resize.
+         * @param scene - babylonjs scene.
+         * @returns resized textures or null.
+         */
+        private static _ResizeTexturesToSameDimensions(texture1, texture2, scene);
+        /**
+         * Convert Specular Glossiness Textures to Metallic Roughness.
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param diffuseTexture - texture used to store diffuse information.
+         * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+         * @param factors - specular glossiness material factors.
+         * @param mimeType - the mime type to use for the texture.
+         * @returns pbr metallic roughness interface or null.
+         */
+        private static _ConvertSpecularGlossinessTexturesToMetallicRoughness(diffuseTexture, specularGlossinessTexture, factors, mimeType);
+        /**
+         * Converts specular glossiness material properties to metallic roughness.
+         * @param specularGlossiness - interface with specular glossiness material properties.
+         * @returns - interface with metallic roughness material properties.
+         */
+        private static _ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+        /**
+         * Calculates the surface reflectance, independent of lighting conditions.
          * @param color - Color source to calculate brightness from.
          * @returns number representing the perceived brightness, or zero if color is undefined.
          */
-        static GetPerceivedBrightness(color: Color3): number;
+        private static _GetPerceivedBrightness(color);
         /**
          * Returns the maximum color component value.
          * @param color
          * @returns maximum color component value, or zero if color is null or undefined.
          */
-        static GetMaxComponent(color: Color3): number;
+        private static _GetMaxComponent(color);
         /**
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
          * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
@@ -399,7 +450,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -412,13 +463,19 @@ declare module BABYLON.GLTF2 {
          * @param images - Array of glTF images.
          * @param textures - Array of glTF textures.
          * @param imageData - map of image file name and data.
-         * @return - glTF texture, or null if the texture format is not supported.
+         * @return - glTF texture info, or null if the texture format is not supported.
          */
-        static ExportTexture(babylonTexture: BaseTexture, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], imageData: {
-            [fileName: string]: {
-                data: Uint8Array;
-                mimeType: ImageMimeType;
-            };
-        }): Nullable<ITextureInfo>;
+        private static _ExportTexture(babylonTexture, mimeType, images, textures, imageData);
+        /**
+         * Builds a texture from base64 string.
+         * @param base64Texture - base64 texture string.
+         * @param textureName - Name to use for the texture.
+         * @param mimeType - image mime type for the texture.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param imageData - map of image data.
+         * @returns - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _GetTextureInfoFromBase64(base64Texture, textureName, mimeType, images, textures, imageData);
     }
 }

+ 375 - 157
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -613,13 +613,13 @@ var BABYLON;
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                 }
-                                if (materialIndex != null) {
-                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial.HasTexturesPresent(this.materials[materialIndex])) {
+                                if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
+                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
                                         meshPrimitive.material = materialIndex;
                                     }
                                     else {
                                         // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
-                                        var newMat = GLTF2._GLTFMaterial.StripTexturesFromMaterial(this.materials[materialIndex]);
+                                        var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
                                         this.materials.push(newMat);
                                         meshPrimitive.material = this.materials.length - 1;
                                     }
@@ -642,7 +642,7 @@ var BABYLON;
                 if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
-                    GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
+                    GLTF2._GLTFMaterial._ConvertMaterialsToGLTF(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.materials, this.imageData, true);
                     var result = this.createNodeMap(babylonScene, byteOffset);
                     this.nodeMap = result.nodeMap;
                     this.totalByteLength = result.byteOffset;
@@ -799,29 +799,40 @@ var BABYLON;
             function _GLTFMaterial() {
             }
             /**
+             * Specifies if two colors are approximately equal in value.
+             * @param color1 - first color to compare to.
+             * @param color2 - second color to compare to.
+             * @param epsilon - threshold value
+             */
+            _GLTFMaterial.FuzzyEquals = function (color1, color2, epsilon) {
+                return BABYLON.Scalar.WithinEpsilon(color1.r, color2.r, epsilon) &&
+                    BABYLON.Scalar.WithinEpsilon(color1.g, color2.g, epsilon) &&
+                    BABYLON.Scalar.WithinEpsilon(color1.b, color2.b, epsilon);
+            };
+            /**
              * Gets the materials from a Babylon scene and converts them to glTF materials.
-             * @param scene
-             * @param mimeType
-             * @param images
-             * @param textures
-             * @param materials
-             * @param imageData
-             * @param hasTextureCoords
+             * @param scene - babylonjs scene.
+             * @param mimeType - texture mime type.
+             * @param images - array of images.
+             * @param textures - array of textures.
+             * @param materials - array of materials.
+             * @param imageData - mapping of texture names to base64 textures
+             * @param hasTextureCoords - specifies if texture coordinates are present on the material.
              */
-            _GLTFMaterial.ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 for (var i = 0; i < babylonMaterials.length; ++i) {
                     var babylonMaterial = babylonMaterials[i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                        _GLTFMaterial.ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                        _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                        _GLTFMaterial.ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else {
-                        BABYLON.Tools.Error("Unsupported material type: " + babylonMaterial.name);
+                        throw new Error("Unsupported material type: " + babylonMaterial.name);
                     }
                 }
             };
@@ -830,7 +841,7 @@ var BABYLON;
              * @param originalMaterial - original glTF material.
              * @returns glTF material without texture parameters
              */
-            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+            _GLTFMaterial._StripTexturesFromMaterial = function (originalMaterial) {
                 var newMaterial = {};
                 if (originalMaterial) {
                     newMaterial.name = originalMaterial.name;
@@ -853,7 +864,7 @@ var BABYLON;
              * @param material - glTF Material.
              * @returns boolean specifying if texture parameters are present
              */
-            _GLTFMaterial.HasTexturesPresent = function (material) {
+            _GLTFMaterial._HasTexturesPresent = function (material) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                     return true;
                 }
@@ -870,7 +881,7 @@ var BABYLON;
              * @param babylonStandardMaterial
              * @returns - glTF Metallic Roughness Material representation
              */
-            _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
+            _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P2 = new BABYLON.Vector2(0, 0.1);
@@ -884,7 +895,7 @@ var BABYLON;
                  * @param p3 - fourth control point.
                  * @returns - number result of cubic bezier curve at the specified t.
                  */
-                function cubicBezierCurve(t, p0, p1, p2, p3) {
+                function _cubicBezierCurve(t, p0, p1, p2, p3) {
                     return ((1 - t) * (1 - t) * (1 - t) * p0 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * t * t * p2 +
@@ -897,14 +908,14 @@ var BABYLON;
                  * @param specularPower - specular power of standard material.
                  * @returns - Number representing the roughness value.
                  */
-                function solveForRoughness(specularPower) {
+                function _solveForRoughness(specularPower) {
                     var t = Math.pow(specularPower / P3.x, 0.333333);
-                    return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
+                    return _cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
                 }
                 var diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
                 var opacity = babylonStandardMaterial.alpha;
-                var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this.maxSpecularPower);
-                var roughness = solveForRoughness(specularPower);
+                var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this._maxSpecularPower);
+                var roughness = _solveForRoughness(specularPower);
                 var glTFPbrMetallicRoughness = {
                     baseColorFactor: [
                         diffuse.r,
@@ -924,14 +935,14 @@ var BABYLON;
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @returns - metallic value
              */
-            _GLTFMaterial.SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
-                if (specular < _GLTFMaterial.dielectricSpecular.r) {
-                    _GLTFMaterial.dielectricSpecular;
+            _GLTFMaterial._SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
+                if (specular < _GLTFMaterial._dielectricSpecular.r) {
+                    _GLTFMaterial._dielectricSpecular;
                     return 0;
                 }
-                var a = _GLTFMaterial.dielectricSpecular.r;
-                var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial.dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial.dielectricSpecular.r;
-                var c = _GLTFMaterial.dielectricSpecular.r - specular;
+                var a = _GLTFMaterial._dielectricSpecular.r;
+                var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial._dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial._dielectricSpecular.r;
+                var c = _GLTFMaterial._dielectricSpecular.r - specular;
                 var D = b * b - 4.0 * a * c;
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
             };
@@ -940,7 +951,7 @@ var BABYLON;
              * @param babylonMaterial - Babylon Material
              * @returns - The Babylon alpha mode value
              */
-            _GLTFMaterial.GetAlphaMode = function (babylonMaterial) {
+            _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     var babylonStandardMaterial = babylonMaterial;
                     if ((babylonStandardMaterial.alpha != 1.0) ||
@@ -1008,11 +1019,11 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Standard Material is currently not fully supported/implemented in glTF serializer");
-                var glTFPbrMetallicRoughness = _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                var glTFPbrMetallicRoughness = _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
                 var glTFMaterial = { name: babylonStandardMaterial.name };
-                if (babylonStandardMaterial.backFaceCulling) {
+                if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                     }
@@ -1020,26 +1031,26 @@ var BABYLON;
                 }
                 if (hasTextureCoords) {
                     if (babylonStandardMaterial.diffuseTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                     }
                     if (babylonStandardMaterial.bumpTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                     }
                     if (babylonStandardMaterial.emissiveTexture) {
-                        var glTFEmissiveTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        var glTFEmissiveTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
                         if (glTFEmissiveTexture) {
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                         }
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     if (babylonStandardMaterial.ambientTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             var occlusionTexture = {
                                 index: glTFTexture.index
@@ -1057,7 +1068,7 @@ var BABYLON;
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
                     }
                 }
-                if (babylonStandardMaterial.emissiveColor) {
+                if (babylonStandardMaterial.emissiveColor && !this.FuzzyEquals(babylonStandardMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
                     glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
@@ -1073,7 +1084,7 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                     glTFPbrMetallicRoughness.baseColorFactor = [
@@ -1083,10 +1094,10 @@ var BABYLON;
                         babylonPBRMetalRoughMaterial.alpha
                     ];
                 }
-                if (babylonPBRMetalRoughMaterial.metallic != null) {
+                if (babylonPBRMetalRoughMaterial.metallic != null && babylonPBRMetalRoughMaterial.metallic !== 1) {
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                 }
-                if (babylonPBRMetalRoughMaterial.roughness != null) {
+                if (babylonPBRMetalRoughMaterial.roughness != null && babylonPBRMetalRoughMaterial.roughness !== 1) {
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                 }
                 var glTFMaterial = {
@@ -1097,19 +1108,19 @@ var BABYLON;
                 }
                 if (hasTextureCoords) {
                     if (babylonPBRMetalRoughMaterial.baseTexture != null) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.normalTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.occlusionTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.occlusionTexture = glTFTexture;
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
@@ -1118,17 +1129,17 @@ var BABYLON;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.emissiveTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFMaterial.emissiveTexture = glTFTexture;
                         }
                     }
                 }
-                if (babylonPBRMetalRoughMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
+                if (this.FuzzyEquals(babylonPBRMetalRoughMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
                     glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
                 }
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
-                    var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMetalRoughMaterial);
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMetalRoughMaterial);
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                         glTFMaterial.alphaMode = alphaMode;
                         if (alphaMode === "BLEND" /* BLEND */) {
@@ -1140,12 +1151,213 @@ var BABYLON;
                 materials.push(glTFMaterial);
             };
             /**
+             * Converts an image typed array buffer to a base64 image.
+             * @param buffer - typed array buffer.
+             * @param width - width of the image.
+             * @param height - height of the image.
+             * @param mimeType - mimetype of the image.
+             * @returns - base64 image string.
+             */
+            _GLTFMaterial._CreateBase64FromCanvas = function (buffer, width, height, mimeType) {
+                var imageCanvas = document.createElement('canvas');
+                imageCanvas.id = "WriteCanvas";
+                var ctx = imageCanvas.getContext('2d');
+                imageCanvas.width = width;
+                imageCanvas.height = height;
+                var imgData = ctx.createImageData(width, height);
+                imgData.data.set(buffer);
+                ctx.putImageData(imgData, 0, 0);
+                return imageCanvas.toDataURL(mimeType);
+            };
+            /**
+             * Generates a white texture based on the specified width and height.
+             * @param width - width of the texture in pixels.
+             * @param height - height of the texture in pixels.
+             * @param scene - babylonjs scene.
+             * @returns - white texture.
+             */
+            _GLTFMaterial._CreateWhiteTexture = function (width, height, scene) {
+                var data = new Uint8Array(width * height * 4);
+                for (var i = 0; i < data.length; ++i) {
+                    data[i] = 255;
+                }
+                var rawTexture = BABYLON.RawTexture.CreateRGBATexture(data, width, height, scene);
+                return rawTexture;
+            };
+            /**
+             * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+             * @param texture1 - first texture to resize.
+             * @param texture2 - second texture to resize.
+             * @param scene - babylonjs scene.
+             * @returns resized textures or null.
+             */
+            _GLTFMaterial._ResizeTexturesToSameDimensions = function (texture1, texture2, scene) {
+                var texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };
+                var texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };
+                var resizedTexture1;
+                var resizedTexture2;
+                if (texture1Size.width < texture2Size.width) {
+                    if (texture1) {
+                        resizedTexture1 = BABYLON.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
+                    }
+                    else {
+                        resizedTexture1 = this._CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);
+                    }
+                    resizedTexture2 = texture2;
+                }
+                else if (texture1Size.width > texture2Size.width) {
+                    if (texture2) {
+                        resizedTexture2 = BABYLON.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
+                    }
+                    else {
+                        resizedTexture2 = this._CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);
+                    }
+                    resizedTexture1 = texture1;
+                }
+                else {
+                    resizedTexture1 = texture1;
+                    resizedTexture2 = texture2;
+                }
+                return {
+                    "texture1": resizedTexture1,
+                    "texture2": resizedTexture2
+                };
+            };
+            /**
+             * Convert Specular Glossiness Textures to Metallic Roughness.
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+             * @param diffuseTexture - texture used to store diffuse information.
+             * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+             * @param factors - specular glossiness material factors.
+             * @param mimeType - the mime type to use for the texture.
+             * @returns pbr metallic roughness interface or null.
+             */
+            _GLTFMaterial._ConvertSpecularGlossinessTexturesToMetallicRoughness = function (diffuseTexture, specularGlossinessTexture, factors, mimeType) {
+                if (!(diffuseTexture || specularGlossinessTexture)) {
+                    return null;
+                }
+                var scene = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture.getScene();
+                if (!scene) {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
+                }
+                var resizedTextures = this._ResizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);
+                var diffuseSize = resizedTextures.texture1.getSize();
+                var diffuseBuffer;
+                var specularGlossinessBuffer;
+                var width = diffuseSize.width;
+                var height = diffuseSize.height;
+                var pixels = (resizedTextures.texture1.readPixels());
+                if (pixels instanceof Uint8Array) {
+                    diffuseBuffer = (resizedTextures.texture1.readPixels());
+                }
+                else {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture1.name);
+                }
+                pixels = resizedTextures.texture2.readPixels();
+                if (pixels instanceof Uint8Array) {
+                    specularGlossinessBuffer = (resizedTextures.texture2.readPixels());
+                }
+                else {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture2.name);
+                }
+                var byteLength = specularGlossinessBuffer.byteLength;
+                var metallicRoughnessBuffer = new Uint8Array(byteLength);
+                var baseColorBuffer = new Uint8Array(byteLength);
+                var strideSize = 4;
+                var maxBaseColor = BABYLON.Color3.Black();
+                var maxMetallic = 0;
+                var maxRoughness = 0;
+                for (var h = 0; h < height; ++h) {
+                    for (var w = 0; w < width; ++w) {
+                        var offset = (width * h + w) * strideSize;
+                        var diffuseColor = BABYLON.Color3.FromInts(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).multiply(factors.diffuseColor);
+                        var specularColor = BABYLON.Color3.FromInts(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).multiply(factors.specularColor);
+                        var glossiness = (specularGlossinessBuffer[offset + 3] / 255) * factors.glossiness;
+                        var specularGlossiness = {
+                            diffuseColor: diffuseColor,
+                            specularColor: specularColor,
+                            glossiness: glossiness
+                        };
+                        var metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+                        maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
+                        maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
+                        maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
+                        maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
+                        maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
+                        baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
+                        baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
+                        baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
+                        baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] : 255;
+                        metallicRoughnessBuffer[offset] = 255;
+                        metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
+                        metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
+                        metallicRoughnessBuffer[offset + 3] = 255;
+                    }
+                }
+                // Retrieves the metallic roughness factors from the maximum texture values.
+                var metallicRoughnessFactors = {
+                    baseColor: maxBaseColor,
+                    metallic: maxMetallic,
+                    roughness: maxRoughness
+                };
+                var writeOutMetallicRoughnessTexture = false;
+                var writeOutBaseColorTexture = false;
+                for (var h = 0; h < height; ++h) {
+                    for (var w = 0; w < width; ++w) {
+                        var destinationOffset = (width * h + w) * strideSize;
+                        baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > this._epsilon ? metallicRoughnessFactors.baseColor.r : 1;
+                        baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > this._epsilon ? metallicRoughnessFactors.baseColor.g : 1;
+                        baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > this._epsilon ? metallicRoughnessFactors.baseColor.b : 1;
+                        var baseColorPixel = BABYLON.Color3.FromArray([baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]]);
+                        if (!this.FuzzyEquals(baseColorPixel, BABYLON.Color3.White(), this._epsilon)) {
+                            writeOutBaseColorTexture = true;
+                        }
+                        metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness > this._epsilon ? metallicRoughnessFactors.roughness : 1;
+                        metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic > this._epsilon ? metallicRoughnessFactors.metallic : 1;
+                        var metallicRoughnessPixel = BABYLON.Color3.FromArray([metallicRoughnessBuffer[destinationOffset], metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]]);
+                        if (!this.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), this._epsilon)) {
+                            writeOutMetallicRoughnessTexture = true;
+                        }
+                    }
+                }
+                if (writeOutMetallicRoughnessTexture) {
+                    var metallicRoughnessBase64 = this._CreateBase64FromCanvas(metallicRoughnessBuffer, width, height, mimeType);
+                    metallicRoughnessFactors.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
+                }
+                if (writeOutBaseColorTexture) {
+                    var baseColorBase64 = this._CreateBase64FromCanvas(baseColorBuffer, width, height, mimeType);
+                    metallicRoughnessFactors.baseColorTextureBase64 = baseColorBase64;
+                }
+                return metallicRoughnessFactors;
+            };
+            /**
+             * Converts specular glossiness material properties to metallic roughness.
+             * @param specularGlossiness - interface with specular glossiness material properties.
+             * @returns - interface with metallic roughness material properties.
+             */
+            _GLTFMaterial._ConvertSpecularGlossinessToMetallicRoughness = function (specularGlossiness) {
+                var diffusePerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.diffuseColor);
+                var specularPerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.specularColor);
+                var oneMinusSpecularStrength = 1 - _GLTFMaterial._GetMaxComponent(specularGlossiness.specularColor);
+                var metallic = _GLTFMaterial._SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
+                var baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this._dielectricSpecular.r) / Math.max(1 - metallic, this._epsilon));
+                var baseColorFromSpecular = specularGlossiness.specularColor.subtract(this._dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this._epsilon));
+                var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
+                baseColor = baseColor.clampToRef(0, 1, baseColor);
+                var metallicRoughness = {
+                    baseColor: baseColor,
+                    metallic: metallic,
+                    roughness: 1 - specularGlossiness.glossiness
+                };
+                return metallicRoughness;
+            };
+            /**
+             * Calculates the surface reflectance, independent of lighting conditions.
              * @param color - Color source to calculate brightness from.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              */
-            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+            _GLTFMaterial._GetPerceivedBrightness = function (color) {
                 if (color) {
                     return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
                 }
@@ -1156,7 +1368,7 @@ var BABYLON;
              * @param color
              * @returns maximum color component value, or zero if color is null or undefined.
              */
-            _GLTFMaterial.GetMaxComponent = function (color) {
+            _GLTFMaterial._GetMaxComponent = function (color) {
                 if (color) {
                     return Math.max(color.r, Math.max(color.g, color.b));
                 }
@@ -1172,110 +1384,108 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
+                var metallicRoughness;
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                 };
                 var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
-                if (babylonPBRMaterial) {
-                    if (useMetallicRoughness) {
-                        glTFPbrMetallicRoughness.baseColorFactor = [
-                            babylonPBRMaterial.albedoColor.r,
-                            babylonPBRMaterial.albedoColor.g,
-                            babylonPBRMaterial.albedoColor.b,
-                            babylonPBRMaterial.alpha
-                        ];
-                        if (babylonPBRMaterial.metallic != null) {
-                            if (babylonPBRMaterial.metallic !== 1) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                if (!useMetallicRoughness) {
+                    var specGloss = {
+                        diffuseColor: babylonPBRMaterial.albedoColor || BABYLON.Color3.White(),
+                        specularColor: babylonPBRMaterial.reflectivityColor || BABYLON.Color3.White(),
+                        glossiness: babylonPBRMaterial.microSurface || 1,
+                    };
+                    if (babylonPBRMaterial.reflectivityTexture && !babylonPBRMaterial.useMicroSurfaceFromReflectivityMapAlpha) {
+                        throw new Error("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture currently not supported");
+                    }
+                    metallicRoughness = this._ConvertSpecularGlossinessTexturesToMetallicRoughness(babylonPBRMaterial.albedoTexture, babylonPBRMaterial.reflectivityTexture, specGloss, mimeType);
+                    if (!metallicRoughness) {
+                        metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specGloss);
+                    }
+                    else {
+                        if (metallicRoughness.baseColorTextureBase64) {
+                            var glTFBaseColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.baseColorTextureBase64, "bjsBaseColorTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
+                            if (glTFBaseColorTexture != null) {
+                                glTFPbrMetallicRoughness.baseColorTexture = glTFBaseColorTexture;
                             }
                         }
-                        if (babylonPBRMaterial.roughness != null) {
-                            if (babylonPBRMaterial.roughness !== 1) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                        if (metallicRoughness.metallicRoughnessTextureBase64) {
+                            var glTFMRColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.metallicRoughnessTextureBase64, "bjsMetallicRoughnessTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
+                            if (glTFMRColorTexture != null) {
+                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;
                             }
                         }
                     }
-                    else {
-                        var diffuseColor = babylonPBRMaterial.albedoColor || BABYLON.Color3.Black();
-                        var specularColor = babylonPBRMaterial.reflectionColor || BABYLON.Color3.Black();
-                        var diffusePerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(diffuseColor);
-                        var specularPerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(specularColor);
-                        var oneMinusSpecularStrength = 1 - _GLTFMaterial.GetMaxComponent(babylonPBRMaterial.reflectionColor);
-                        var metallic = _GLTFMaterial.SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
-                        var glossiness = babylonPBRMaterial.microSurface || 0;
-                        var baseColorFromDiffuse = diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this.dielectricSpecular.r) / Math.max(1 - metallic, this.epsilon));
-                        var baseColorFromSpecular = specularColor.subtract(this.dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this.epsilon));
-                        var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
-                        baseColor = baseColor.clampToRef(0, 1, baseColor);
-                        glTFPbrMetallicRoughness.baseColorFactor = [
-                            baseColor.r,
-                            baseColor.g,
-                            baseColor.b,
-                            babylonPBRMaterial.alpha
-                        ];
-                        if (metallic !== 1) {
-                            glTFPbrMetallicRoughness.metallicFactor = metallic;
-                        }
-                        if (glossiness) {
-                            glTFPbrMetallicRoughness.roughnessFactor = 1 - glossiness;
-                        }
+                }
+                if (!(this.FuzzyEquals(babylonPBRMaterial.albedoColor, BABYLON.Color3.White(), this._epsilon) && babylonPBRMaterial.alpha >= this._epsilon)) {
+                    glTFPbrMetallicRoughness.baseColorFactor = [
+                        babylonPBRMaterial.albedoColor.r,
+                        babylonPBRMaterial.albedoColor.g,
+                        babylonPBRMaterial.albedoColor.b,
+                        babylonPBRMaterial.alpha
+                    ];
+                }
+                if (babylonPBRMaterial.metallic != null && babylonPBRMaterial.metallic !== 1) {
+                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                }
+                if (babylonPBRMaterial.roughness != null && babylonPBRMaterial.roughness !== 1) {
+                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                }
+                if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {
+                    if (!babylonPBRMaterial.twoSidedLighting) {
+                        BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                     }
-                    if (babylonPBRMaterial.backFaceCulling) {
-                        if (!babylonPBRMaterial.twoSidedLighting) {
-                            BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
+                    glTFMaterial.doubleSided = true;
+                }
+                if (hasTextureCoords) {
+                    if (useMetallicRoughness && babylonPBRMaterial.albedoTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
-                        glTFMaterial.doubleSided = true;
                     }
-                    if (hasTextureCoords) {
-                        if (babylonPBRMaterial.albedoTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                            }
-                        }
-                        if (babylonPBRMaterial.bumpTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                glTFMaterial.normalTexture = glTFTexture;
-                            }
-                        }
-                        if (babylonPBRMaterial.ambientTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                var occlusionTexture = {
-                                    index: glTFTexture.index
-                                };
-                                glTFMaterial.occlusionTexture = occlusionTexture;
-                                if (babylonPBRMaterial.ambientTextureStrength) {
-                                    occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
-                                }
-                            }
+                    if (babylonPBRMaterial.bumpTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            glTFMaterial.normalTexture = glTFTexture;
                         }
-                        if (babylonPBRMaterial.emissiveTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture != null) {
-                                glTFMaterial.emissiveTexture = glTFTexture;
+                    }
+                    if (babylonPBRMaterial.ambientTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            var occlusionTexture = {
+                                index: glTFTexture.index
+                            };
+                            glTFMaterial.occlusionTexture = occlusionTexture;
+                            if (babylonPBRMaterial.ambientTextureStrength) {
+                                occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
                             }
                         }
-                        if (babylonPBRMaterial.metallicTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture != null) {
-                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
-                            }
+                    }
+                    if (babylonPBRMaterial.emissiveTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture != null) {
+                            glTFMaterial.emissiveTexture = glTFTexture;
                         }
                     }
-                    if (!babylonPBRMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
-                        glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                    if (babylonPBRMaterial.metallicTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture != null) {
+                            glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
+                        }
                     }
-                    if (babylonPBRMaterial.transparencyMode != null) {
-                        var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                        if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                            glTFMaterial.alphaMode = alphaMode;
-                            if (alphaMode === "BLEND" /* BLEND */) {
-                                glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
-                            }
+                }
+                if (!this.FuzzyEquals(babylonPBRMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
+                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                }
+                if (babylonPBRMaterial.transparencyMode != null) {
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMaterial);
+                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                        glTFMaterial.alphaMode = alphaMode;
+                        if (alphaMode === "BLEND" /* BLEND */) {
+                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
                         }
                     }
                 }
@@ -1289,17 +1499,13 @@ var BABYLON;
              * @param images - Array of glTF images.
              * @param textures - Array of glTF textures.
              * @param imageData - map of image file name and data.
-             * @return - glTF texture, or null if the texture format is not supported.
+             * @return - glTF texture info, or null if the texture format is not supported.
              */
-            _GLTFMaterial.ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
-                var textureInfo = null;
-                var glTFTexture = {
-                    source: images.length
-                };
+            _GLTFMaterial._ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
                 var textureName = "texture_" + (textures.length - 1).toString();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
-                    textureName = textureData.url;
+                    textureName = textureData.url || textureName;
                 }
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 var baseFile = textureName.split('.')[0];
@@ -1311,28 +1517,37 @@ var BABYLON;
                     extension = ".png";
                 }
                 else {
-                    BABYLON.Tools.Error("Unsupported mime type " + mimeType);
+                    throw new Error("Unsupported mime type " + mimeType);
                 }
                 textureName = baseFile + extension;
                 var pixels = babylonTexture.readPixels();
-                var imageCanvas = document.createElement('canvas');
-                imageCanvas.id = "ImageCanvas";
-                var ctx = imageCanvas.getContext('2d');
                 var size = babylonTexture.getSize();
-                imageCanvas.width = size.width;
-                imageCanvas.height = size.height;
-                var imgData = ctx.createImageData(size.width, size.height);
-                imgData.data.set(pixels);
-                ctx.putImageData(imgData, 0, 0);
-                var base64Data = imageCanvas.toDataURL(mimeType);
-                var binStr = atob(base64Data.split(',')[1]);
+                var base64Data = this._CreateBase64FromCanvas(pixels, size.width, size.height, mimeType);
+                return this._GetTextureInfoFromBase64(base64Data, textureName, mimeType, images, textures, imageData);
+            };
+            /**
+             * Builds a texture from base64 string.
+             * @param base64Texture - base64 texture string.
+             * @param textureName - Name to use for the texture.
+             * @param mimeType - image mime type for the texture.
+             * @param images - array of images.
+             * @param textures - array of textures.
+             * @param imageData - map of image data.
+             * @returns - glTF texture info, or null if the texture format is not supported.
+             */
+            _GLTFMaterial._GetTextureInfoFromBase64 = function (base64Texture, textureName, mimeType, images, textures, imageData) {
+                var textureInfo = null;
+                var glTFTexture = {
+                    source: images.length
+                };
+                var binStr = atob(base64Texture.split(',')[1]);
                 var arr = new Uint8Array(binStr.length);
                 for (var i = 0; i < binStr.length; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 imageData[textureName] = imageValues;
-                if (mimeType === "image/jpeg" /* JPEG */) {
+                if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */) {
                     var glTFImage = {
                         uri: textureName
                     };
@@ -1365,12 +1580,15 @@ var BABYLON;
             /**
              * Represents the dielectric specular values for R, G and B.
              */
-            _GLTFMaterial.dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
+            _GLTFMaterial._dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
             /**
              * Allows the maximum specular power to be defined for material calculations.
              */
-            _GLTFMaterial.maxSpecularPower = 1024;
-            _GLTFMaterial.epsilon = 1e-6;
+            _GLTFMaterial._maxSpecularPower = 1024;
+            /**
+             * Numeric tolerance value
+             */
+            _GLTFMaterial._epsilon = 1e-6;
             return _GLTFMaterial;
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 375 - 157
dist/preview release/serializers/babylonjs.serializers.js

@@ -767,13 +767,13 @@ var BABYLON;
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                 }
-                                if (materialIndex != null) {
-                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial.HasTexturesPresent(this.materials[materialIndex])) {
+                                if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
+                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
                                         meshPrimitive.material = materialIndex;
                                     }
                                     else {
                                         // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
-                                        var newMat = GLTF2._GLTFMaterial.StripTexturesFromMaterial(this.materials[materialIndex]);
+                                        var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
                                         this.materials.push(newMat);
                                         meshPrimitive.material = this.materials.length - 1;
                                     }
@@ -796,7 +796,7 @@ var BABYLON;
                 if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
-                    GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
+                    GLTF2._GLTFMaterial._ConvertMaterialsToGLTF(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.materials, this.imageData, true);
                     var result = this.createNodeMap(babylonScene, byteOffset);
                     this.nodeMap = result.nodeMap;
                     this.totalByteLength = result.byteOffset;
@@ -953,29 +953,40 @@ var BABYLON;
             function _GLTFMaterial() {
             }
             /**
+             * Specifies if two colors are approximately equal in value.
+             * @param color1 - first color to compare to.
+             * @param color2 - second color to compare to.
+             * @param epsilon - threshold value
+             */
+            _GLTFMaterial.FuzzyEquals = function (color1, color2, epsilon) {
+                return BABYLON.Scalar.WithinEpsilon(color1.r, color2.r, epsilon) &&
+                    BABYLON.Scalar.WithinEpsilon(color1.g, color2.g, epsilon) &&
+                    BABYLON.Scalar.WithinEpsilon(color1.b, color2.b, epsilon);
+            };
+            /**
              * Gets the materials from a Babylon scene and converts them to glTF materials.
-             * @param scene
-             * @param mimeType
-             * @param images
-             * @param textures
-             * @param materials
-             * @param imageData
-             * @param hasTextureCoords
+             * @param scene - babylonjs scene.
+             * @param mimeType - texture mime type.
+             * @param images - array of images.
+             * @param textures - array of textures.
+             * @param materials - array of materials.
+             * @param imageData - mapping of texture names to base64 textures
+             * @param hasTextureCoords - specifies if texture coordinates are present on the material.
              */
-            _GLTFMaterial.ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 for (var i = 0; i < babylonMaterials.length; ++i) {
                     var babylonMaterial = babylonMaterials[i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                        _GLTFMaterial.ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                        _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                        _GLTFMaterial.ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                        _GLTFMaterial._ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
                     else {
-                        BABYLON.Tools.Error("Unsupported material type: " + babylonMaterial.name);
+                        throw new Error("Unsupported material type: " + babylonMaterial.name);
                     }
                 }
             };
@@ -984,7 +995,7 @@ var BABYLON;
              * @param originalMaterial - original glTF material.
              * @returns glTF material without texture parameters
              */
-            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+            _GLTFMaterial._StripTexturesFromMaterial = function (originalMaterial) {
                 var newMaterial = {};
                 if (originalMaterial) {
                     newMaterial.name = originalMaterial.name;
@@ -1007,7 +1018,7 @@ var BABYLON;
              * @param material - glTF Material.
              * @returns boolean specifying if texture parameters are present
              */
-            _GLTFMaterial.HasTexturesPresent = function (material) {
+            _GLTFMaterial._HasTexturesPresent = function (material) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                     return true;
                 }
@@ -1024,7 +1035,7 @@ var BABYLON;
              * @param babylonStandardMaterial
              * @returns - glTF Metallic Roughness Material representation
              */
-            _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
+            _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P2 = new BABYLON.Vector2(0, 0.1);
@@ -1038,7 +1049,7 @@ var BABYLON;
                  * @param p3 - fourth control point.
                  * @returns - number result of cubic bezier curve at the specified t.
                  */
-                function cubicBezierCurve(t, p0, p1, p2, p3) {
+                function _cubicBezierCurve(t, p0, p1, p2, p3) {
                     return ((1 - t) * (1 - t) * (1 - t) * p0 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * t * t * p2 +
@@ -1051,14 +1062,14 @@ var BABYLON;
                  * @param specularPower - specular power of standard material.
                  * @returns - Number representing the roughness value.
                  */
-                function solveForRoughness(specularPower) {
+                function _solveForRoughness(specularPower) {
                     var t = Math.pow(specularPower / P3.x, 0.333333);
-                    return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
+                    return _cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
                 }
                 var diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
                 var opacity = babylonStandardMaterial.alpha;
-                var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this.maxSpecularPower);
-                var roughness = solveForRoughness(specularPower);
+                var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this._maxSpecularPower);
+                var roughness = _solveForRoughness(specularPower);
                 var glTFPbrMetallicRoughness = {
                     baseColorFactor: [
                         diffuse.r,
@@ -1078,14 +1089,14 @@ var BABYLON;
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @returns - metallic value
              */
-            _GLTFMaterial.SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
-                if (specular < _GLTFMaterial.dielectricSpecular.r) {
-                    _GLTFMaterial.dielectricSpecular;
+            _GLTFMaterial._SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
+                if (specular < _GLTFMaterial._dielectricSpecular.r) {
+                    _GLTFMaterial._dielectricSpecular;
                     return 0;
                 }
-                var a = _GLTFMaterial.dielectricSpecular.r;
-                var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial.dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial.dielectricSpecular.r;
-                var c = _GLTFMaterial.dielectricSpecular.r - specular;
+                var a = _GLTFMaterial._dielectricSpecular.r;
+                var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial._dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial._dielectricSpecular.r;
+                var c = _GLTFMaterial._dielectricSpecular.r - specular;
                 var D = b * b - 4.0 * a * c;
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
             };
@@ -1094,7 +1105,7 @@ var BABYLON;
              * @param babylonMaterial - Babylon Material
              * @returns - The Babylon alpha mode value
              */
-            _GLTFMaterial.GetAlphaMode = function (babylonMaterial) {
+            _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     var babylonStandardMaterial = babylonMaterial;
                     if ((babylonStandardMaterial.alpha != 1.0) ||
@@ -1162,11 +1173,11 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Standard Material is currently not fully supported/implemented in glTF serializer");
-                var glTFPbrMetallicRoughness = _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                var glTFPbrMetallicRoughness = _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
                 var glTFMaterial = { name: babylonStandardMaterial.name };
-                if (babylonStandardMaterial.backFaceCulling) {
+                if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                     }
@@ -1174,26 +1185,26 @@ var BABYLON;
                 }
                 if (hasTextureCoords) {
                     if (babylonStandardMaterial.diffuseTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                     }
                     if (babylonStandardMaterial.bumpTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                     }
                     if (babylonStandardMaterial.emissiveTexture) {
-                        var glTFEmissiveTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        var glTFEmissiveTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
                         if (glTFEmissiveTexture) {
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                         }
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     if (babylonStandardMaterial.ambientTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             var occlusionTexture = {
                                 index: glTFTexture.index
@@ -1211,7 +1222,7 @@ var BABYLON;
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
                     }
                 }
-                if (babylonStandardMaterial.emissiveColor) {
+                if (babylonStandardMaterial.emissiveColor && !this.FuzzyEquals(babylonStandardMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
                     glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
@@ -1227,7 +1238,7 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                     glTFPbrMetallicRoughness.baseColorFactor = [
@@ -1237,10 +1248,10 @@ var BABYLON;
                         babylonPBRMetalRoughMaterial.alpha
                     ];
                 }
-                if (babylonPBRMetalRoughMaterial.metallic != null) {
+                if (babylonPBRMetalRoughMaterial.metallic != null && babylonPBRMetalRoughMaterial.metallic !== 1) {
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                 }
-                if (babylonPBRMetalRoughMaterial.roughness != null) {
+                if (babylonPBRMetalRoughMaterial.roughness != null && babylonPBRMetalRoughMaterial.roughness !== 1) {
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                 }
                 var glTFMaterial = {
@@ -1251,19 +1262,19 @@ var BABYLON;
                 }
                 if (hasTextureCoords) {
                     if (babylonPBRMetalRoughMaterial.baseTexture != null) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.normalTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.occlusionTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
                         if (glTFTexture) {
                             glTFMaterial.occlusionTexture = glTFTexture;
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
@@ -1272,17 +1283,17 @@ var BABYLON;
                         }
                     }
                     if (babylonPBRMetalRoughMaterial.emissiveTexture) {
-                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
                         if (glTFTexture != null) {
                             glTFMaterial.emissiveTexture = glTFTexture;
                         }
                     }
                 }
-                if (babylonPBRMetalRoughMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
+                if (this.FuzzyEquals(babylonPBRMetalRoughMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
                     glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
                 }
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
-                    var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMetalRoughMaterial);
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMetalRoughMaterial);
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                         glTFMaterial.alphaMode = alphaMode;
                         if (alphaMode === "BLEND" /* BLEND */) {
@@ -1294,12 +1305,213 @@ var BABYLON;
                 materials.push(glTFMaterial);
             };
             /**
+             * Converts an image typed array buffer to a base64 image.
+             * @param buffer - typed array buffer.
+             * @param width - width of the image.
+             * @param height - height of the image.
+             * @param mimeType - mimetype of the image.
+             * @returns - base64 image string.
+             */
+            _GLTFMaterial._CreateBase64FromCanvas = function (buffer, width, height, mimeType) {
+                var imageCanvas = document.createElement('canvas');
+                imageCanvas.id = "WriteCanvas";
+                var ctx = imageCanvas.getContext('2d');
+                imageCanvas.width = width;
+                imageCanvas.height = height;
+                var imgData = ctx.createImageData(width, height);
+                imgData.data.set(buffer);
+                ctx.putImageData(imgData, 0, 0);
+                return imageCanvas.toDataURL(mimeType);
+            };
+            /**
+             * Generates a white texture based on the specified width and height.
+             * @param width - width of the texture in pixels.
+             * @param height - height of the texture in pixels.
+             * @param scene - babylonjs scene.
+             * @returns - white texture.
+             */
+            _GLTFMaterial._CreateWhiteTexture = function (width, height, scene) {
+                var data = new Uint8Array(width * height * 4);
+                for (var i = 0; i < data.length; ++i) {
+                    data[i] = 255;
+                }
+                var rawTexture = BABYLON.RawTexture.CreateRGBATexture(data, width, height, scene);
+                return rawTexture;
+            };
+            /**
+             * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+             * @param texture1 - first texture to resize.
+             * @param texture2 - second texture to resize.
+             * @param scene - babylonjs scene.
+             * @returns resized textures or null.
+             */
+            _GLTFMaterial._ResizeTexturesToSameDimensions = function (texture1, texture2, scene) {
+                var texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };
+                var texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };
+                var resizedTexture1;
+                var resizedTexture2;
+                if (texture1Size.width < texture2Size.width) {
+                    if (texture1) {
+                        resizedTexture1 = BABYLON.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
+                    }
+                    else {
+                        resizedTexture1 = this._CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);
+                    }
+                    resizedTexture2 = texture2;
+                }
+                else if (texture1Size.width > texture2Size.width) {
+                    if (texture2) {
+                        resizedTexture2 = BABYLON.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
+                    }
+                    else {
+                        resizedTexture2 = this._CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);
+                    }
+                    resizedTexture1 = texture1;
+                }
+                else {
+                    resizedTexture1 = texture1;
+                    resizedTexture2 = texture2;
+                }
+                return {
+                    "texture1": resizedTexture1,
+                    "texture2": resizedTexture2
+                };
+            };
+            /**
+             * Convert Specular Glossiness Textures to Metallic Roughness.
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+             * @param diffuseTexture - texture used to store diffuse information.
+             * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+             * @param factors - specular glossiness material factors.
+             * @param mimeType - the mime type to use for the texture.
+             * @returns pbr metallic roughness interface or null.
+             */
+            _GLTFMaterial._ConvertSpecularGlossinessTexturesToMetallicRoughness = function (diffuseTexture, specularGlossinessTexture, factors, mimeType) {
+                if (!(diffuseTexture || specularGlossinessTexture)) {
+                    return null;
+                }
+                var scene = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture.getScene();
+                if (!scene) {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
+                }
+                var resizedTextures = this._ResizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);
+                var diffuseSize = resizedTextures.texture1.getSize();
+                var diffuseBuffer;
+                var specularGlossinessBuffer;
+                var width = diffuseSize.width;
+                var height = diffuseSize.height;
+                var pixels = (resizedTextures.texture1.readPixels());
+                if (pixels instanceof Uint8Array) {
+                    diffuseBuffer = (resizedTextures.texture1.readPixels());
+                }
+                else {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture1.name);
+                }
+                pixels = resizedTextures.texture2.readPixels();
+                if (pixels instanceof Uint8Array) {
+                    specularGlossinessBuffer = (resizedTextures.texture2.readPixels());
+                }
+                else {
+                    throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture2.name);
+                }
+                var byteLength = specularGlossinessBuffer.byteLength;
+                var metallicRoughnessBuffer = new Uint8Array(byteLength);
+                var baseColorBuffer = new Uint8Array(byteLength);
+                var strideSize = 4;
+                var maxBaseColor = BABYLON.Color3.Black();
+                var maxMetallic = 0;
+                var maxRoughness = 0;
+                for (var h = 0; h < height; ++h) {
+                    for (var w = 0; w < width; ++w) {
+                        var offset = (width * h + w) * strideSize;
+                        var diffuseColor = BABYLON.Color3.FromInts(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).multiply(factors.diffuseColor);
+                        var specularColor = BABYLON.Color3.FromInts(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).multiply(factors.specularColor);
+                        var glossiness = (specularGlossinessBuffer[offset + 3] / 255) * factors.glossiness;
+                        var specularGlossiness = {
+                            diffuseColor: diffuseColor,
+                            specularColor: specularColor,
+                            glossiness: glossiness
+                        };
+                        var metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+                        maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
+                        maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
+                        maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
+                        maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
+                        maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
+                        baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
+                        baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
+                        baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
+                        baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] : 255;
+                        metallicRoughnessBuffer[offset] = 255;
+                        metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
+                        metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
+                        metallicRoughnessBuffer[offset + 3] = 255;
+                    }
+                }
+                // Retrieves the metallic roughness factors from the maximum texture values.
+                var metallicRoughnessFactors = {
+                    baseColor: maxBaseColor,
+                    metallic: maxMetallic,
+                    roughness: maxRoughness
+                };
+                var writeOutMetallicRoughnessTexture = false;
+                var writeOutBaseColorTexture = false;
+                for (var h = 0; h < height; ++h) {
+                    for (var w = 0; w < width; ++w) {
+                        var destinationOffset = (width * h + w) * strideSize;
+                        baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > this._epsilon ? metallicRoughnessFactors.baseColor.r : 1;
+                        baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > this._epsilon ? metallicRoughnessFactors.baseColor.g : 1;
+                        baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > this._epsilon ? metallicRoughnessFactors.baseColor.b : 1;
+                        var baseColorPixel = BABYLON.Color3.FromArray([baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]]);
+                        if (!this.FuzzyEquals(baseColorPixel, BABYLON.Color3.White(), this._epsilon)) {
+                            writeOutBaseColorTexture = true;
+                        }
+                        metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness > this._epsilon ? metallicRoughnessFactors.roughness : 1;
+                        metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic > this._epsilon ? metallicRoughnessFactors.metallic : 1;
+                        var metallicRoughnessPixel = BABYLON.Color3.FromArray([metallicRoughnessBuffer[destinationOffset], metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]]);
+                        if (!this.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), this._epsilon)) {
+                            writeOutMetallicRoughnessTexture = true;
+                        }
+                    }
+                }
+                if (writeOutMetallicRoughnessTexture) {
+                    var metallicRoughnessBase64 = this._CreateBase64FromCanvas(metallicRoughnessBuffer, width, height, mimeType);
+                    metallicRoughnessFactors.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
+                }
+                if (writeOutBaseColorTexture) {
+                    var baseColorBase64 = this._CreateBase64FromCanvas(baseColorBuffer, width, height, mimeType);
+                    metallicRoughnessFactors.baseColorTextureBase64 = baseColorBase64;
+                }
+                return metallicRoughnessFactors;
+            };
+            /**
+             * Converts specular glossiness material properties to metallic roughness.
+             * @param specularGlossiness - interface with specular glossiness material properties.
+             * @returns - interface with metallic roughness material properties.
+             */
+            _GLTFMaterial._ConvertSpecularGlossinessToMetallicRoughness = function (specularGlossiness) {
+                var diffusePerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.diffuseColor);
+                var specularPerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.specularColor);
+                var oneMinusSpecularStrength = 1 - _GLTFMaterial._GetMaxComponent(specularGlossiness.specularColor);
+                var metallic = _GLTFMaterial._SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
+                var baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this._dielectricSpecular.r) / Math.max(1 - metallic, this._epsilon));
+                var baseColorFromSpecular = specularGlossiness.specularColor.subtract(this._dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this._epsilon));
+                var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
+                baseColor = baseColor.clampToRef(0, 1, baseColor);
+                var metallicRoughness = {
+                    baseColor: baseColor,
+                    metallic: metallic,
+                    roughness: 1 - specularGlossiness.glossiness
+                };
+                return metallicRoughness;
+            };
+            /**
+             * Calculates the surface reflectance, independent of lighting conditions.
              * @param color - Color source to calculate brightness from.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              */
-            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+            _GLTFMaterial._GetPerceivedBrightness = function (color) {
                 if (color) {
                     return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
                 }
@@ -1310,7 +1522,7 @@ var BABYLON;
              * @param color
              * @returns maximum color component value, or zero if color is null or undefined.
              */
-            _GLTFMaterial.GetMaxComponent = function (color) {
+            _GLTFMaterial._GetMaxComponent = function (color) {
                 if (color) {
                     return Math.max(color.r, Math.max(color.g, color.b));
                 }
@@ -1326,110 +1538,108 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
              */
-            _GLTFMaterial.ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+            _GLTFMaterial._ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
                 var glTFPbrMetallicRoughness = {};
+                var metallicRoughness;
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                 };
                 var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
-                if (babylonPBRMaterial) {
-                    if (useMetallicRoughness) {
-                        glTFPbrMetallicRoughness.baseColorFactor = [
-                            babylonPBRMaterial.albedoColor.r,
-                            babylonPBRMaterial.albedoColor.g,
-                            babylonPBRMaterial.albedoColor.b,
-                            babylonPBRMaterial.alpha
-                        ];
-                        if (babylonPBRMaterial.metallic != null) {
-                            if (babylonPBRMaterial.metallic !== 1) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                if (!useMetallicRoughness) {
+                    var specGloss = {
+                        diffuseColor: babylonPBRMaterial.albedoColor || BABYLON.Color3.White(),
+                        specularColor: babylonPBRMaterial.reflectivityColor || BABYLON.Color3.White(),
+                        glossiness: babylonPBRMaterial.microSurface || 1,
+                    };
+                    if (babylonPBRMaterial.reflectivityTexture && !babylonPBRMaterial.useMicroSurfaceFromReflectivityMapAlpha) {
+                        throw new Error("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture currently not supported");
+                    }
+                    metallicRoughness = this._ConvertSpecularGlossinessTexturesToMetallicRoughness(babylonPBRMaterial.albedoTexture, babylonPBRMaterial.reflectivityTexture, specGloss, mimeType);
+                    if (!metallicRoughness) {
+                        metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specGloss);
+                    }
+                    else {
+                        if (metallicRoughness.baseColorTextureBase64) {
+                            var glTFBaseColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.baseColorTextureBase64, "bjsBaseColorTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
+                            if (glTFBaseColorTexture != null) {
+                                glTFPbrMetallicRoughness.baseColorTexture = glTFBaseColorTexture;
                             }
                         }
-                        if (babylonPBRMaterial.roughness != null) {
-                            if (babylonPBRMaterial.roughness !== 1) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                        if (metallicRoughness.metallicRoughnessTextureBase64) {
+                            var glTFMRColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.metallicRoughnessTextureBase64, "bjsMetallicRoughnessTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
+                            if (glTFMRColorTexture != null) {
+                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;
                             }
                         }
                     }
-                    else {
-                        var diffuseColor = babylonPBRMaterial.albedoColor || BABYLON.Color3.Black();
-                        var specularColor = babylonPBRMaterial.reflectionColor || BABYLON.Color3.Black();
-                        var diffusePerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(diffuseColor);
-                        var specularPerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(specularColor);
-                        var oneMinusSpecularStrength = 1 - _GLTFMaterial.GetMaxComponent(babylonPBRMaterial.reflectionColor);
-                        var metallic = _GLTFMaterial.SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
-                        var glossiness = babylonPBRMaterial.microSurface || 0;
-                        var baseColorFromDiffuse = diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this.dielectricSpecular.r) / Math.max(1 - metallic, this.epsilon));
-                        var baseColorFromSpecular = specularColor.subtract(this.dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this.epsilon));
-                        var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
-                        baseColor = baseColor.clampToRef(0, 1, baseColor);
-                        glTFPbrMetallicRoughness.baseColorFactor = [
-                            baseColor.r,
-                            baseColor.g,
-                            baseColor.b,
-                            babylonPBRMaterial.alpha
-                        ];
-                        if (metallic !== 1) {
-                            glTFPbrMetallicRoughness.metallicFactor = metallic;
-                        }
-                        if (glossiness) {
-                            glTFPbrMetallicRoughness.roughnessFactor = 1 - glossiness;
-                        }
+                }
+                if (!(this.FuzzyEquals(babylonPBRMaterial.albedoColor, BABYLON.Color3.White(), this._epsilon) && babylonPBRMaterial.alpha >= this._epsilon)) {
+                    glTFPbrMetallicRoughness.baseColorFactor = [
+                        babylonPBRMaterial.albedoColor.r,
+                        babylonPBRMaterial.albedoColor.g,
+                        babylonPBRMaterial.albedoColor.b,
+                        babylonPBRMaterial.alpha
+                    ];
+                }
+                if (babylonPBRMaterial.metallic != null && babylonPBRMaterial.metallic !== 1) {
+                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                }
+                if (babylonPBRMaterial.roughness != null && babylonPBRMaterial.roughness !== 1) {
+                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                }
+                if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {
+                    if (!babylonPBRMaterial.twoSidedLighting) {
+                        BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                     }
-                    if (babylonPBRMaterial.backFaceCulling) {
-                        if (!babylonPBRMaterial.twoSidedLighting) {
-                            BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
+                    glTFMaterial.doubleSided = true;
+                }
+                if (hasTextureCoords) {
+                    if (useMetallicRoughness && babylonPBRMaterial.albedoTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
-                        glTFMaterial.doubleSided = true;
                     }
-                    if (hasTextureCoords) {
-                        if (babylonPBRMaterial.albedoTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                            }
-                        }
-                        if (babylonPBRMaterial.bumpTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                glTFMaterial.normalTexture = glTFTexture;
-                            }
-                        }
-                        if (babylonPBRMaterial.ambientTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture) {
-                                var occlusionTexture = {
-                                    index: glTFTexture.index
-                                };
-                                glTFMaterial.occlusionTexture = occlusionTexture;
-                                if (babylonPBRMaterial.ambientTextureStrength) {
-                                    occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
-                                }
-                            }
+                    if (babylonPBRMaterial.bumpTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            glTFMaterial.normalTexture = glTFTexture;
                         }
-                        if (babylonPBRMaterial.emissiveTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture != null) {
-                                glTFMaterial.emissiveTexture = glTFTexture;
+                    }
+                    if (babylonPBRMaterial.ambientTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            var occlusionTexture = {
+                                index: glTFTexture.index
+                            };
+                            glTFMaterial.occlusionTexture = occlusionTexture;
+                            if (babylonPBRMaterial.ambientTextureStrength) {
+                                occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
                             }
                         }
-                        if (babylonPBRMaterial.metallicTexture) {
-                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
-                            if (glTFTexture != null) {
-                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
-                            }
+                    }
+                    if (babylonPBRMaterial.emissiveTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture != null) {
+                            glTFMaterial.emissiveTexture = glTFTexture;
                         }
                     }
-                    if (!babylonPBRMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
-                        glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                    if (babylonPBRMaterial.metallicTexture) {
+                        var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture != null) {
+                            glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
+                        }
                     }
-                    if (babylonPBRMaterial.transparencyMode != null) {
-                        var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                        if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                            glTFMaterial.alphaMode = alphaMode;
-                            if (alphaMode === "BLEND" /* BLEND */) {
-                                glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
-                            }
+                }
+                if (!this.FuzzyEquals(babylonPBRMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
+                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                }
+                if (babylonPBRMaterial.transparencyMode != null) {
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMaterial);
+                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                        glTFMaterial.alphaMode = alphaMode;
+                        if (alphaMode === "BLEND" /* BLEND */) {
+                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
                         }
                     }
                 }
@@ -1443,17 +1653,13 @@ var BABYLON;
              * @param images - Array of glTF images.
              * @param textures - Array of glTF textures.
              * @param imageData - map of image file name and data.
-             * @return - glTF texture, or null if the texture format is not supported.
+             * @return - glTF texture info, or null if the texture format is not supported.
              */
-            _GLTFMaterial.ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
-                var textureInfo = null;
-                var glTFTexture = {
-                    source: images.length
-                };
+            _GLTFMaterial._ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
                 var textureName = "texture_" + (textures.length - 1).toString();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
-                    textureName = textureData.url;
+                    textureName = textureData.url || textureName;
                 }
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 var baseFile = textureName.split('.')[0];
@@ -1465,28 +1671,37 @@ var BABYLON;
                     extension = ".png";
                 }
                 else {
-                    BABYLON.Tools.Error("Unsupported mime type " + mimeType);
+                    throw new Error("Unsupported mime type " + mimeType);
                 }
                 textureName = baseFile + extension;
                 var pixels = babylonTexture.readPixels();
-                var imageCanvas = document.createElement('canvas');
-                imageCanvas.id = "ImageCanvas";
-                var ctx = imageCanvas.getContext('2d');
                 var size = babylonTexture.getSize();
-                imageCanvas.width = size.width;
-                imageCanvas.height = size.height;
-                var imgData = ctx.createImageData(size.width, size.height);
-                imgData.data.set(pixels);
-                ctx.putImageData(imgData, 0, 0);
-                var base64Data = imageCanvas.toDataURL(mimeType);
-                var binStr = atob(base64Data.split(',')[1]);
+                var base64Data = this._CreateBase64FromCanvas(pixels, size.width, size.height, mimeType);
+                return this._GetTextureInfoFromBase64(base64Data, textureName, mimeType, images, textures, imageData);
+            };
+            /**
+             * Builds a texture from base64 string.
+             * @param base64Texture - base64 texture string.
+             * @param textureName - Name to use for the texture.
+             * @param mimeType - image mime type for the texture.
+             * @param images - array of images.
+             * @param textures - array of textures.
+             * @param imageData - map of image data.
+             * @returns - glTF texture info, or null if the texture format is not supported.
+             */
+            _GLTFMaterial._GetTextureInfoFromBase64 = function (base64Texture, textureName, mimeType, images, textures, imageData) {
+                var textureInfo = null;
+                var glTFTexture = {
+                    source: images.length
+                };
+                var binStr = atob(base64Texture.split(',')[1]);
                 var arr = new Uint8Array(binStr.length);
                 for (var i = 0; i < binStr.length; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 imageData[textureName] = imageValues;
-                if (mimeType === "image/jpeg" /* JPEG */) {
+                if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */) {
                     var glTFImage = {
                         uri: textureName
                     };
@@ -1519,12 +1734,15 @@ var BABYLON;
             /**
              * Represents the dielectric specular values for R, G and B.
              */
-            _GLTFMaterial.dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
+            _GLTFMaterial._dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
             /**
              * Allows the maximum specular power to be defined for material calculations.
              */
-            _GLTFMaterial.maxSpecularPower = 1024;
-            _GLTFMaterial.epsilon = 1e-6;
+            _GLTFMaterial._maxSpecularPower = 1024;
+            /**
+             * Numeric tolerance value
+             */
+            _GLTFMaterial._epsilon = 1e-6;
             return _GLTFMaterial;
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 86 - 29
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -305,23 +305,33 @@ declare module BABYLON.GLTF2 {
         /**
          * Represents the dielectric specular values for R, G and B.
          */
-        private static readonly dielectricSpecular;
+        private static readonly _dielectricSpecular;
         /**
          * Allows the maximum specular power to be defined for material calculations.
          */
-        private static maxSpecularPower;
-        private static epsilon;
+        private static _maxSpecularPower;
+        /**
+         * Numeric tolerance value
+         */
+        private static _epsilon;
+        /**
+         * Specifies if two colors are approximately equal in value.
+         * @param color1 - first color to compare to.
+         * @param color2 - second color to compare to.
+         * @param epsilon - threshold value
+         */
+        private static FuzzyEquals(color1, color2, epsilon);
         /**
          * Gets the materials from a Babylon scene and converts them to glTF materials.
-         * @param scene
-         * @param mimeType
-         * @param images
-         * @param textures
-         * @param materials
-         * @param imageData
-         * @param hasTextureCoords
-         */
-        static ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+         * @param scene - babylonjs scene.
+         * @param mimeType - texture mime type.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param materials - array of materials.
+         * @param imageData - mapping of texture names to base64 textures
+         * @param hasTextureCoords - specifies if texture coordinates are present on the material.
+         */
+        static _ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -332,19 +342,19 @@ declare module BABYLON.GLTF2 {
          * @param originalMaterial - original glTF material.
          * @returns glTF material without texture parameters
          */
-        static StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        static _StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
         /**
          * Specifies if the material has any texture parameters present.
          * @param material - glTF Material.
          * @returns boolean specifying if texture parameters are present
          */
-        static HasTexturesPresent(material: IMaterial): boolean;
+        static _HasTexturesPresent(material: IMaterial): boolean;
         /**
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
          */
-        static ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
         /**
          * Computes the metallic factor
          * @param diffuse - diffused value
@@ -352,13 +362,13 @@ declare module BABYLON.GLTF2 {
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @returns - metallic value
          */
-        static SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
+        static _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
         /**
          * Gets the glTF alpha mode from the Babylon Material
          * @param babylonMaterial - Babylon Material
          * @returns - The Babylon alpha mode value
          */
-        static GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
         /**
          * Converts a Babylon Standard Material to a glTF Material.
          * @param babylonStandardMaterial - BJS Standard Material.
@@ -369,7 +379,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -385,25 +395,66 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * Converts an image typed array buffer to a base64 image.
+         * @param buffer - typed array buffer.
+         * @param width - width of the image.
+         * @param height - height of the image.
+         * @param mimeType - mimetype of the image.
+         * @returns - base64 image string.
+         */
+        private static _CreateBase64FromCanvas(buffer, width, height, mimeType);
+        /**
+         * Generates a white texture based on the specified width and height.
+         * @param width - width of the texture in pixels.
+         * @param height - height of the texture in pixels.
+         * @param scene - babylonjs scene.
+         * @returns - white texture.
+         */
+        private static _CreateWhiteTexture(width, height, scene);
+        /**
+         * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+         * @param texture1 - first texture to resize.
+         * @param texture2 - second texture to resize.
+         * @param scene - babylonjs scene.
+         * @returns resized textures or null.
+         */
+        private static _ResizeTexturesToSameDimensions(texture1, texture2, scene);
+        /**
+         * Convert Specular Glossiness Textures to Metallic Roughness.
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param diffuseTexture - texture used to store diffuse information.
+         * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+         * @param factors - specular glossiness material factors.
+         * @param mimeType - the mime type to use for the texture.
+         * @returns pbr metallic roughness interface or null.
+         */
+        private static _ConvertSpecularGlossinessTexturesToMetallicRoughness(diffuseTexture, specularGlossinessTexture, factors, mimeType);
+        /**
+         * Converts specular glossiness material properties to metallic roughness.
+         * @param specularGlossiness - interface with specular glossiness material properties.
+         * @returns - interface with metallic roughness material properties.
+         */
+        private static _ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+        /**
+         * Calculates the surface reflectance, independent of lighting conditions.
          * @param color - Color source to calculate brightness from.
          * @returns number representing the perceived brightness, or zero if color is undefined.
          */
-        static GetPerceivedBrightness(color: Color3): number;
+        private static _GetPerceivedBrightness(color);
         /**
          * Returns the maximum color component value.
          * @param color
          * @returns maximum color component value, or zero if color is null or undefined.
          */
-        static GetMaxComponent(color: Color3): number;
+        private static _GetMaxComponent(color);
         /**
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
          * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
@@ -414,7 +465,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
          */
-        static ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+        static _ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
             [fileName: string]: {
                 data: Uint8Array;
                 mimeType: ImageMimeType;
@@ -427,13 +478,19 @@ declare module BABYLON.GLTF2 {
          * @param images - Array of glTF images.
          * @param textures - Array of glTF textures.
          * @param imageData - map of image file name and data.
-         * @return - glTF texture, or null if the texture format is not supported.
+         * @return - glTF texture info, or null if the texture format is not supported.
          */
-        static ExportTexture(babylonTexture: BaseTexture, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], imageData: {
-            [fileName: string]: {
-                data: Uint8Array;
-                mimeType: ImageMimeType;
-            };
-        }): Nullable<ITextureInfo>;
+        private static _ExportTexture(babylonTexture, mimeType, images, textures, imageData);
+        /**
+         * Builds a texture from base64 string.
+         * @param base64Texture - base64 texture string.
+         * @param textureName - Name to use for the texture.
+         * @param mimeType - image mime type for the texture.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param imageData - map of image data.
+         * @returns - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _GetTextureInfoFromBase64(base64Texture, textureName, mimeType, images, textures, imageData);
     }
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 430 - 223
dist/preview release/viewer/babylon.viewer.max.js


+ 4 - 0
src/Mesh/Compression/babylon.dracoCompression.ts

@@ -188,6 +188,10 @@ module BABYLON {
         }
 
         private static _GetDefaultDecoderUrl(): Nullable<string> {
+            if (!Tools.IsWindowObjectExist) {
+                return null;
+            }
+
             for (let i = 0; i < document.scripts.length; i++) {
                 if (document.scripts[i].type === "text/x-draco-decoder") {
                     return document.scripts[i].src;