David Catuhe 7 年之前
父节点
当前提交
a69fc1e14d
共有 46 个文件被更改,包括 38953 次插入41637 次删除
  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

文件差异内容过多而无法显示
+ 9328 - 9268
Playground/babylon.d.txt


文件差异内容过多而无法显示
+ 10410 - 10349
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 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();
             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;
             this.parent = null;
             // Callback
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
             this.onDisposeObservable.clear();
             // Behaviors
             // 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();
                 behavior.detach();
             }
             }
             this._behaviors = [];
             this._behaviors = [];
@@ -16323,6 +16341,13 @@ var BABYLON;
             }
             }
             return _this;
             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", {
         Object.defineProperty(TransformNode.prototype, "rotation", {
             /**
             /**
               * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
               * 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;
             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
             // Animations
             this.getScene().stopAnimation(this);
             this.getScene().stopAnimation(this);
             // Remove from scene
             // Remove from scene
             this.getScene().removeTransformNode(this);
             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();
             this.onAfterWorldMatrixUpdateObservable.clear();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         // Statics
         // Statics
         TransformNode.BILLBOARDMODE_NONE = 0;
         TransformNode.BILLBOARDMODE_NONE = 0;
@@ -18459,9 +18470,9 @@ var BABYLON;
             return this;
             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) {
         AbstractMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
             var _this = this;
@@ -18557,7 +18568,7 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onCollideObservable.clear();
             this.onCollideObservable.clear();
             this.onCollisionPositionChangeObservable.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.
          * Adds the passed mesh as a child to the current mesh.
@@ -19419,9 +19430,12 @@ var BABYLON;
             return b.renderPriority - a.renderPriority;
             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) {
             if (this._shadowGenerator) {
                 this._shadowGenerator.dispose();
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
                 this._shadowGenerator = null;
@@ -19436,7 +19450,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             this._uniformBuffer.dispose();
             // Remove from scene
             // Remove from scene
             this.getScene().removeLight(this);
             this.getScene().removeLight(this);
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         /**
         /**
          * Returns the light type ID (integer).
          * Returns the light type ID (integer).
@@ -20226,7 +20240,13 @@ var BABYLON;
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             return new BABYLON.Ray(origin, direction, length);
             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
             // Observables
             this.onViewMatrixChangedObservable.clear();
             this.onViewMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
@@ -20270,7 +20290,7 @@ var BABYLON;
             this.customRenderTargets = [];
             this.customRenderTargets = [];
             // Active Meshes
             // Active Meshes
             this._activeMeshes.dispose();
             this._activeMeshes.dispose();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         Object.defineProperty(Camera.prototype, "leftCamera", {
         Object.defineProperty(Camera.prototype, "leftCamera", {
             // ---- Camera rigs section ----
             // ---- Camera rigs section ----
@@ -28834,9 +28854,9 @@ var BABYLON;
             return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
             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) {
         Mesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
             var _this = this;
@@ -55553,11 +55573,12 @@ var BABYLON;
          * Disposes the InstancedMesh.
          * Disposes the InstancedMesh.
          * Returns nothing.
          * Returns nothing.
          */
          */
-        InstancedMesh.prototype.dispose = function (doNotRecurse) {
+        InstancedMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Remove from mesh
             // Remove from mesh
             var index = this._sourceMesh.instances.indexOf(this);
             var index = this._sourceMesh.instances.indexOf(this);
             this._sourceMesh.instances.splice(index, 1);
             this._sourceMesh.instances.splice(index, 1);
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         return InstancedMesh;
         return InstancedMesh;
     }(BABYLON.AbstractMesh));
     }(BABYLON.AbstractMesh));
@@ -59991,6 +60012,16 @@ var BABYLON;
             return this;
             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.
          * 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 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)
          * @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 attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
             // Alpha test
             // Alpha test
-            if (material && material.needAlphaTesting()) {
+            if (material && material.needAlphaTesting() && material.getAlphaTestTexture()) {
                 defines.push("#define ALPHATEST");
                 defines.push("#define ALPHATEST");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
@@ -68859,7 +68890,7 @@ var BABYLON;
         /**
         /**
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * @param name The name of the effect.
          * @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 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 camera The camera to apply the render pass to.
          * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
          * @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)
              * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
              */
              */
             _this.focalLength = 50;
             _this.focalLength = 50;
+            _this._depthTexture = null;
+            _this._depthTexture = depthTexture;
             _this.onApplyObservable.add(function (effect) {
             _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
                 // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html
                 var aperture = _this.lensSize / _this.fStop;
                 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]
                 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('focusDistance', _this.focusDistance);
                 effect.setFloat('cocPrecalculation', cocPrecalculation);
                 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;
             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;
         return CircleOfConfusionPostProcess;
     }(BABYLON.PostProcess));
     }(BABYLON.PostProcess));
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
@@ -68974,63 +69021,64 @@ var BABYLON;
         /**
         /**
          * Creates a new instance of @see DepthOfFieldEffect
          * Creates a new instance of @see DepthOfFieldEffect
          * @param scene The scene the effect belongs to.
          * @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.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          */
          */
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             var _this = _super.call(this, scene.getEngine(), "depth of field", function () {
             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;
             }, 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;
             return _this;
         }
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
@@ -69085,6 +69133,16 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: 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.
          * Disposes each of the internal effects for a given camera.
          * @param camera The camera to dispose the effect on.
          * @param camera The camera to dispose the effect on.
@@ -69132,6 +69190,7 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            _this._originalCameras = [];
             /**
             /**
              * ID of the sharpen post process,
              * ID of the sharpen post process,
              */
              */
@@ -69195,7 +69254,10 @@ var BABYLON;
              * Specifies the weight of the bloom in the final rendering
              * Specifies the weight of the bloom in the final rendering
              */
              */
             _this._bloomWeight = 0.15;
             _this._bloomWeight = 0.15;
+            _this._prevPostProcess = null;
+            _this._prevPrevPostProcess = null;
             _this._cameras = cameras || [];
             _this._cameras = cameras || [];
+            _this._originalCameras = _this._cameras.slice();
             _this._buildAllowed = automaticBuild;
             _this._buildAllowed = automaticBuild;
             // Initialize
             // Initialize
             _this._scene = scene;
             _this._scene = scene;
@@ -69215,6 +69277,12 @@ var BABYLON;
             }
             }
             // Attach
             // Attach
             scene.postProcessRenderPipelineManager.addPipeline(_this);
             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();
             _this._buildPipeline();
             return _this;
             return _this;
         }
         }
@@ -69317,6 +69385,16 @@ var BABYLON;
                     return;
                     return;
                 }
                 }
                 this._depthOfFieldBlurLevel = value;
                 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();
                 this._buildPipeline();
             },
             },
             enumerable: true,
             enumerable: true,
@@ -69399,6 +69477,27 @@ var BABYLON;
             this._buildPipeline();
             this._buildPipeline();
             this._buildAllowed = previousState;
             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 () {
         DefaultRenderingPipeline.prototype._buildPipeline = function () {
             var _this = this;
             var _this = this;
             if (!this._buildAllowed) {
             if (!this._buildAllowed) {
@@ -69406,19 +69505,32 @@ var BABYLON;
             }
             }
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
             this._disposePostProcesses();
             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._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) {
             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) {
             if (this.depthOfFieldEnabled) {
-                // Enable and get current depth map
                 var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
                 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.addEffect(this.depthOfField);
+                this._setAutoClearAndTextureSharing(this.depthOfField._depthOfFieldMerge);
             }
             }
             if (this.bloomEnabled) {
             if (this.bloomEnabled) {
                 this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 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));
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.PassPostProcessId, function () { return _this.pass; }, true));
                 if (!this._hdr) {
                 if (!this._hdr) {
                     this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                     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;
                     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;
                 this.finalMerge = this.imageProcessing;
             }
             }
             else {
             else {
                 this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 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.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);
                 this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
             }
             }
             if (this.bloomEnabled) {
             if (this.bloomEnabled) {
@@ -69484,25 +69592,17 @@ var BABYLON;
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.autoClear = false;
                         this.imageProcessing.autoClear = false;
                     }
                     }
-                    else if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
                     else {
                     else {
                         this.finalMerge.shareOutputWith(this.pass);
                         this.finalMerge.shareOutputWith(this.pass);
                     }
                     }
                 }
                 }
                 else {
                 else {
-                    if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
-                    else {
-                        this.finalMerge.shareOutputWith(this.pass);
-                    }
+                    this.finalMerge.shareOutputWith(this.pass);
                 }
                 }
             }
             }
             if (this.chromaticAberrationEnabled) {
             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) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 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++) {
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
                 var camera = this._cameras[i];
-                if (this.sharpen) {
-                    this.sharpen.dispose(camera);
-                }
                 if (this.pass) {
                 if (this.pass) {
                     this.pass.dispose(camera);
                     this.pass.dispose(camera);
                 }
                 }
@@ -69543,14 +69641,19 @@ var BABYLON;
                 if (this.finalMerge) {
                 if (this.finalMerge) {
                     this.finalMerge.dispose(camera);
                     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.pass = null;
             this.highlights = null;
             this.highlights = null;
             this.blurX = null;
             this.blurX = null;
@@ -69559,14 +69662,17 @@ var BABYLON;
             this.imageProcessing = null;
             this.imageProcessing = null;
             this.fxaa = null;
             this.fxaa = null;
             this.finalMerge = 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
          * Dispose of the pipeline and stop all post processes
          */
          */
         DefaultRenderingPipeline.prototype.dispose = function () {
         DefaultRenderingPipeline.prototype.dispose = function () {
-            this._disposePostProcesses();
+            this._disposePostProcesses(true);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
             _super.prototype.dispose.call(this);
         };
         };
@@ -70998,6 +71104,54 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: 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", {
         Object.defineProperty(ImageProcessingPostProcess.prototype, "fromLinearSpace", {
             /**
             /**
              * Gets wether the input of the processing is in Gamma or Linear Space.
              * Gets wether the input of the processing is in Gamma or Linear Space.
@@ -91494,13 +91648,16 @@ var BABYLON;
             configurable: true
             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._videoTexture.dispose();
             this._mesh.dispose();
             this._mesh.dispose();
             this._material.dispose();
             this._material.dispose();
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         return VideoDome;
         return VideoDome;
     }(BABYLON.Node));
     }(BABYLON.Node));

文件差异内容过多而无法显示
+ 52 - 52
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 16056 - 15995
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 53 - 53
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


文件差异内容过多而无法显示
+ 350 - 180
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


文件差异内容过多而无法显示
+ 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();
             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;
             this.parent = null;
             // Callback
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
             this.onDisposeObservable.clear();
             // Behaviors
             // 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();
                 behavior.detach();
             }
             }
             this._behaviors = [];
             this._behaviors = [];
@@ -16296,6 +16314,13 @@ var BABYLON;
             }
             }
             return _this;
             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", {
         Object.defineProperty(TransformNode.prototype, "rotation", {
             /**
             /**
               * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z.
               * 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;
             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
             // Animations
             this.getScene().stopAnimation(this);
             this.getScene().stopAnimation(this);
             // Remove from scene
             // Remove from scene
             this.getScene().removeTransformNode(this);
             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();
             this.onAfterWorldMatrixUpdateObservable.clear();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         // Statics
         // Statics
         TransformNode.BILLBOARDMODE_NONE = 0;
         TransformNode.BILLBOARDMODE_NONE = 0;
@@ -18432,9 +18443,9 @@ var BABYLON;
             return this;
             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) {
         AbstractMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
             var _this = this;
@@ -18530,7 +18541,7 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onAfterWorldMatrixUpdateObservable.clear();
             this.onCollideObservable.clear();
             this.onCollideObservable.clear();
             this.onCollisionPositionChangeObservable.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.
          * Adds the passed mesh as a child to the current mesh.
@@ -19392,9 +19403,12 @@ var BABYLON;
             return b.renderPriority - a.renderPriority;
             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) {
             if (this._shadowGenerator) {
                 this._shadowGenerator.dispose();
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
                 this._shadowGenerator = null;
@@ -19409,7 +19423,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             this._uniformBuffer.dispose();
             // Remove from scene
             // Remove from scene
             this.getScene().removeLight(this);
             this.getScene().removeLight(this);
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         /**
         /**
          * Returns the light type ID (integer).
          * Returns the light type ID (integer).
@@ -20199,7 +20213,13 @@ var BABYLON;
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             var direction = BABYLON.Vector3.Normalize(forwardWorld);
             return new BABYLON.Ray(origin, direction, length);
             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
             // Observables
             this.onViewMatrixChangedObservable.clear();
             this.onViewMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
             this.onProjectionMatrixChangedObservable.clear();
@@ -20243,7 +20263,7 @@ var BABYLON;
             this.customRenderTargets = [];
             this.customRenderTargets = [];
             // Active Meshes
             // Active Meshes
             this._activeMeshes.dispose();
             this._activeMeshes.dispose();
-            _super.prototype.dispose.call(this);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         Object.defineProperty(Camera.prototype, "leftCamera", {
         Object.defineProperty(Camera.prototype, "leftCamera", {
             // ---- Camera rigs section ----
             // ---- Camera rigs section ----
@@ -28807,9 +28827,9 @@ var BABYLON;
             return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
             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) {
         Mesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
             var _this = this;
             var _this = this;
@@ -55526,11 +55546,12 @@ var BABYLON;
          * Disposes the InstancedMesh.
          * Disposes the InstancedMesh.
          * Returns nothing.
          * Returns nothing.
          */
          */
-        InstancedMesh.prototype.dispose = function (doNotRecurse) {
+        InstancedMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
+            if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
             // Remove from mesh
             // Remove from mesh
             var index = this._sourceMesh.instances.indexOf(this);
             var index = this._sourceMesh.instances.indexOf(this);
             this._sourceMesh.instances.splice(index, 1);
             this._sourceMesh.instances.splice(index, 1);
-            _super.prototype.dispose.call(this, doNotRecurse);
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         return InstancedMesh;
         return InstancedMesh;
     }(BABYLON.AbstractMesh));
     }(BABYLON.AbstractMesh));
@@ -59964,6 +59985,16 @@ var BABYLON;
             return this;
             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.
          * 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 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)
          * @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 attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
             // Alpha test
             // Alpha test
-            if (material && material.needAlphaTesting()) {
+            if (material && material.needAlphaTesting() && material.getAlphaTestTexture()) {
                 defines.push("#define ALPHATEST");
                 defines.push("#define ALPHATEST");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
@@ -68832,7 +68863,7 @@ var BABYLON;
         /**
         /**
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * Creates a new instance of @see CircleOfConfusionPostProcess
          * @param name The name of the effect.
          * @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 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 camera The camera to apply the render pass to.
          * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
          * @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)
              * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
              */
              */
             _this.focalLength = 50;
             _this.focalLength = 50;
+            _this._depthTexture = null;
+            _this._depthTexture = depthTexture;
             _this.onApplyObservable.add(function (effect) {
             _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
                 // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html
                 var aperture = _this.lensSize / _this.fStop;
                 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]
                 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('focusDistance', _this.focusDistance);
                 effect.setFloat('cocPrecalculation', cocPrecalculation);
                 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;
             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;
         return CircleOfConfusionPostProcess;
     }(BABYLON.PostProcess));
     }(BABYLON.PostProcess));
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
     BABYLON.CircleOfConfusionPostProcess = CircleOfConfusionPostProcess;
@@ -68947,63 +68994,64 @@ var BABYLON;
         /**
         /**
          * Creates a new instance of @see DepthOfFieldEffect
          * Creates a new instance of @see DepthOfFieldEffect
          * @param scene The scene the effect belongs to.
          * @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.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          */
          */
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
         function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType) {
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
             var _this = _super.call(this, scene.getEngine(), "depth of field", function () {
             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;
             }, 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;
             return _this;
         }
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
@@ -69058,6 +69106,16 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: 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.
          * Disposes each of the internal effects for a given camera.
          * @param camera The camera to dispose the effect on.
          * @param camera The camera to dispose the effect on.
@@ -69105,6 +69163,7 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            _this._originalCameras = [];
             /**
             /**
              * ID of the sharpen post process,
              * ID of the sharpen post process,
              */
              */
@@ -69168,7 +69227,10 @@ var BABYLON;
              * Specifies the weight of the bloom in the final rendering
              * Specifies the weight of the bloom in the final rendering
              */
              */
             _this._bloomWeight = 0.15;
             _this._bloomWeight = 0.15;
+            _this._prevPostProcess = null;
+            _this._prevPrevPostProcess = null;
             _this._cameras = cameras || [];
             _this._cameras = cameras || [];
+            _this._originalCameras = _this._cameras.slice();
             _this._buildAllowed = automaticBuild;
             _this._buildAllowed = automaticBuild;
             // Initialize
             // Initialize
             _this._scene = scene;
             _this._scene = scene;
@@ -69188,6 +69250,12 @@ var BABYLON;
             }
             }
             // Attach
             // Attach
             scene.postProcessRenderPipelineManager.addPipeline(_this);
             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();
             _this._buildPipeline();
             return _this;
             return _this;
         }
         }
@@ -69290,6 +69358,16 @@ var BABYLON;
                     return;
                     return;
                 }
                 }
                 this._depthOfFieldBlurLevel = value;
                 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();
                 this._buildPipeline();
             },
             },
             enumerable: true,
             enumerable: true,
@@ -69372,6 +69450,27 @@ var BABYLON;
             this._buildPipeline();
             this._buildPipeline();
             this._buildAllowed = previousState;
             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 () {
         DefaultRenderingPipeline.prototype._buildPipeline = function () {
             var _this = this;
             var _this = this;
             if (!this._buildAllowed) {
             if (!this._buildAllowed) {
@@ -69379,19 +69478,32 @@ var BABYLON;
             }
             }
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
             this._disposePostProcesses();
             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._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) {
             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) {
             if (this.depthOfFieldEnabled) {
-                // Enable and get current depth map
                 var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
                 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.addEffect(this.depthOfField);
+                this._setAutoClearAndTextureSharing(this.depthOfField._depthOfFieldMerge);
             }
             }
             if (this.bloomEnabled) {
             if (this.bloomEnabled) {
                 this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 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));
                 this.addEffect(new BABYLON.PostProcessRenderEffect(engine, this.PassPostProcessId, function () { return _this.pass; }, true));
                 if (!this._hdr) {
                 if (!this._hdr) {
                     this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                     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;
                     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;
                 this.finalMerge = this.imageProcessing;
             }
             }
             else {
             else {
                 this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 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.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);
                 this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
             }
             }
             if (this.bloomEnabled) {
             if (this.bloomEnabled) {
@@ -69457,25 +69565,17 @@ var BABYLON;
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.shareOutputWith(this.pass);
                         this.imageProcessing.autoClear = false;
                         this.imageProcessing.autoClear = false;
                     }
                     }
-                    else if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
                     else {
                     else {
                         this.finalMerge.shareOutputWith(this.pass);
                         this.finalMerge.shareOutputWith(this.pass);
                     }
                     }
                 }
                 }
                 else {
                 else {
-                    if (this.fxaa) {
-                        this.fxaa.shareOutputWith(this.pass);
-                    }
-                    else {
-                        this.finalMerge.shareOutputWith(this.pass);
-                    }
+                    this.finalMerge.shareOutputWith(this.pass);
                 }
                 }
             }
             }
             if (this.chromaticAberrationEnabled) {
             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) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 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++) {
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
                 var camera = this._cameras[i];
-                if (this.sharpen) {
-                    this.sharpen.dispose(camera);
-                }
                 if (this.pass) {
                 if (this.pass) {
                     this.pass.dispose(camera);
                     this.pass.dispose(camera);
                 }
                 }
@@ -69516,14 +69614,19 @@ var BABYLON;
                 if (this.finalMerge) {
                 if (this.finalMerge) {
                     this.finalMerge.dispose(camera);
                     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.pass = null;
             this.highlights = null;
             this.highlights = null;
             this.blurX = null;
             this.blurX = null;
@@ -69532,14 +69635,17 @@ var BABYLON;
             this.imageProcessing = null;
             this.imageProcessing = null;
             this.fxaa = null;
             this.fxaa = null;
             this.finalMerge = 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
          * Dispose of the pipeline and stop all post processes
          */
          */
         DefaultRenderingPipeline.prototype.dispose = function () {
         DefaultRenderingPipeline.prototype.dispose = function () {
-            this._disposePostProcesses();
+            this._disposePostProcesses(true);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
             _super.prototype.dispose.call(this);
         };
         };
@@ -70971,6 +71077,54 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: 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", {
         Object.defineProperty(ImageProcessingPostProcess.prototype, "fromLinearSpace", {
             /**
             /**
              * Gets wether the input of the processing is in Gamma or Linear Space.
              * Gets wether the input of the processing is in Gamma or Linear Space.
@@ -91467,13 +91621,16 @@ var BABYLON;
             configurable: true
             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._videoTexture.dispose();
             this._mesh.dispose();
             this._mesh.dispose();
             this._material.dispose();
             this._material.dispose();
+            _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
         };
         };
         return VideoDome;
         return VideoDome;
     }(BABYLON.Node));
     }(BABYLON.Node));

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


文件差异内容过多而无法显示
+ 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;
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         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>;
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         whenCompleteAsync(): Promise<void>;
         whenCompleteAsync(): Promise<void>;

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

@@ -77,7 +77,7 @@ var BABYLON;
              */
              */
             this.onMaterialLoadedObservable = new BABYLON.Observable();
             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();
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
             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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {

文件差异内容过多而无法显示
+ 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;
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         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>;
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         whenCompleteAsync(): Promise<void>;
         whenCompleteAsync(): Promise<void>;
@@ -321,12 +321,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _createRootNode();
         private _loadNodesAsync(nodes);
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getMeshes();
         private _getSkeletons();
         private _getSkeletons();
         private _startAnimations();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         _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 _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
         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();
             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();
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
             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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
@@ -572,7 +572,7 @@ var BABYLON;
                         nodes = names.map(function (name) {
                         nodes = names.map(function (name) {
                             var node = nodeMap_1[name];
                             var node = nodeMap_1[name];
                             if (!node) {
                             if (!node) {
-                                throw new Error("Failed to find node " + name);
+                                throw new Error("Failed to find node '" + name + "'");
                             }
                             }
                             return node;
                             return node;
                         });
                         });
@@ -728,7 +728,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        throw new Error("Invalid coordinate system mode " + this.coordinateSystemMode);
+                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
                     }
                     }
                 }
                 }
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
@@ -757,6 +757,17 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
                 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 () {
             GLTFLoader.prototype._getMeshes = function () {
                 var meshes = new Array();
                 var meshes = new Array();
                 // Root mesh is always first.
                 // Root mesh is always first.
@@ -765,15 +776,9 @@ var BABYLON;
                 if (nodes) {
                 if (nodes) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                         var node = nodes_2[_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;
                 return meshes;
@@ -814,7 +819,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode " + this.animationStartMode);
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
                         return;
                         return;
                     }
                     }
                 }
                 }
@@ -835,7 +840,7 @@ var BABYLON;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
                 if (node.mesh != undefined) {
                     var mesh = GLTFLoader._GetProperty(context + "/mesh", this._gltf.meshes, node.mesh);
                     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) {
                 if (node.children) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
@@ -847,37 +852,42 @@ var BABYLON;
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
                 return Promise.all(promises).then(function () { });
             };
             };
-            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh) {
+            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 // TODO: instancing
                 // TODO: instancing
+                var _this = this;
                 var promises = new Array();
                 var promises = new Array();
                 var primitives = mesh.primitives;
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                     throw new Error(context + ": Primitives are missing");
                 }
                 }
                 GLTF2.ArrayItem.Assign(primitives);
                 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) {
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
                 }
                 return Promise.all(promises).then(function () {
                 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 _this = this;
                 var promises = new Array();
                 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);
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
@@ -887,12 +897,11 @@ var BABYLON;
                     babylonMesh.material = this._getDefaultMaterial();
                     babylonMesh.material = this._getDefaultMaterial();
                 }
                 }
                 else {
                 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) {
                     promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                         babylonMesh.material = babylonMaterial;
                     }));
                     }));
                 }
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
                 return Promise.all(promises).then(function () { });
             };
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -907,7 +916,7 @@ var BABYLON;
                 }
                 }
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                     // TODO: handle other primitive modes
                     // 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 promises = new Array();
                 var babylonVertexData = new BABYLON.VertexData();
                 var babylonVertexData = new BABYLON.VertexData();
@@ -1049,7 +1058,7 @@ var BABYLON;
                             break;
                             break;
                         }
                         }
                         default: {
                         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) {
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
                 var _this = this;
                 var assignSkeleton = function () {
                 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;
                         babylonMesh.skeleton = skin._babylonSkeleton;
-                    }
+                    });
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
@@ -1194,6 +1202,7 @@ var BABYLON;
                 });
                 });
             };
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
             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);
                 var targetNode = GLTFLoader._GetProperty(context + "/target/node", this._gltf.nodes, channel.target.node);
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                     return Promise.resolve();
                     return Promise.resolve();
@@ -1224,7 +1233,7 @@ var BABYLON;
                             break;
                             break;
                         }
                         }
                         default: {
                         default: {
-                            throw new Error(context + ": Invalid target path " + channel.target.path);
+                            throw new Error(context + ": Invalid target path (" + channel.target.path + ")");
                         }
                         }
                     }
                     }
                     var outputBufferOffset = 0;
                     var outputBufferOffset = 0;
@@ -1316,11 +1325,10 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                                 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);
                                 var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
-                            }
+                            });
                         };
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
                             _loop_1(targetIndex);
@@ -1351,7 +1359,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        throw new Error(context + ": Invalid interpolation " + sampler.interpolation);
+                        throw new Error(context + ": Invalid interpolation (" + sampler.interpolation + ")");
                     }
                     }
                 }
                 }
                 var inputData;
                 var inputData;
@@ -1436,12 +1444,12 @@ var BABYLON;
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                             }
                             }
                             default: {
                             default: {
-                                throw new Error(context + ": Invalid component type " + accessor.componentType);
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                             }
                             }
                         }
                         }
                     }
                     }
                     catch (e) {
                     catch (e) {
-                        throw new Error(context + ": " + e);
+                        throw new Error(context + ": " + e.messsage);
                     }
                     }
                 });
                 });
                 return accessor._data;
                 return accessor._data;
@@ -1605,7 +1613,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     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) {
                 }, function (message, exception) {
                     if (!_this._disposed) {
                     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);
                 promises.push(deferred.promise);
@@ -1727,7 +1735,7 @@ var BABYLON;
             };
             };
             GLTFLoader._GetProperty = function (context, array, index) {
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !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];
                 return array[index];
             };
             };
@@ -1739,7 +1747,7 @@ var BABYLON;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     default:
                     default:
-                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode " + mode);
+                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode (" + mode + ")");
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                 }
                 }
             };
             };
@@ -1756,13 +1764,13 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         default:
                         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;
                             return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                     }
                     }
                 }
                 }
                 else {
                 else {
                     if (magFilter !== 9728 /* NEAREST */) {
                     if (magFilter !== 9728 /* NEAREST */) {
-                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter " + magFilter);
+                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter (" + magFilter + ")");
                     }
                     }
                     switch (minFilter) {
                     switch (minFilter) {
                         case 9728 /* NEAREST */: return BABYLON.Texture.NEAREST_NEAREST;
                         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 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         default:
                         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;
                             return BABYLON.Texture.NEAREST_NEAREST_MIPNEAREST;
                     }
                     }
                 }
                 }
@@ -1787,7 +1795,7 @@ var BABYLON;
                     case "MAT3": return 9;
                     case "MAT3": return 9;
                     case "MAT4": return 16;
                     case "MAT4": return 16;
                 }
                 }
-                throw new Error(context + ": Invalid type " + type);
+                throw new Error(context + ": Invalid type (" + type + ")");
             };
             };
             GLTFLoader._ValidateUri = function (uri) {
             GLTFLoader._ValidateUri = function (uri) {
                 return (BABYLON.Tools.IsBase64(uri) || uri.indexOf("..") === -1);
                 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 () {
                             var promise = _this._loader._loadNodeAsync("#/nodes/" + nodeLOD._index, nodeLOD).then(function () {
                                 if (indexLOD !== 0) {
                                 if (indexLOD !== 0) {
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
-                                    previousNodeLOD._babylonMesh.setEnabled(false);
+                                    if (previousNodeLOD._babylonMesh) {
+                                        previousNodeLOD._babylonMesh.dispose();
+                                        delete previousNodeLOD._babylonMesh;
+                                    }
                                 }
                                 }
                                 if (indexLOD !== nodeLODs.length - 1) {
                                 if (indexLOD !== nodeLODs.length - 1) {
                                     var nodeIndex = nodeLODs[indexLOD + 1]._index;
                                     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 () {
                             var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                 if (indexLOD !== 0) {
                                     assign(materialLOD._babylonMaterial);
                                     assign(materialLOD._babylonMaterial);
+                                    var previousMaterialLOD = materialLODs[indexLOD - 1];
+                                    if (previousMaterialLOD._babylonMaterial) {
+                                        previousMaterialLOD._babylonMaterial.dispose();
+                                        delete previousMaterialLOD._babylonMaterial;
+                                    }
                                 }
                                 }
                                 if (indexLOD !== materialLODs.length - 1) {
                                 if (indexLOD !== materialLODs.length - 1) {
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
@@ -2360,7 +2376,7 @@ var BABYLON;
                                 break;
                                 break;
                             }
                             }
                             default: {
                             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();
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();
@@ -2373,7 +2389,7 @@ var BABYLON;
                     get: function () {
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         var extensions = this._loader._gltf.extensions;
                         if (!extensions || !extensions[this.name]) {
                         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];
                         var extension = extensions[this.name];
                         return extension.lights;
                         return extension.lights;

文件差异内容过多而无法显示
+ 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;
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         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>;
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
         private _onAnimationGroupLoadedObserver;
@@ -143,7 +143,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         whenCompleteAsync(): Promise<void>;
         whenCompleteAsync(): Promise<void>;
@@ -877,12 +877,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _createRootNode();
         private _loadNodesAsync(nodes);
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getMeshes();
         private _getSkeletons();
         private _getSkeletons();
         private _startAnimations();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         _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 _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
         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();
             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();
             this.onAnimationGroupLoadedObservable = new BABYLON.Observable();
             /**
             /**
@@ -184,7 +184,7 @@ var BABYLON;
             configurable: true
             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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
@@ -2749,7 +2749,7 @@ var BABYLON;
                         nodes = names.map(function (name) {
                         nodes = names.map(function (name) {
                             var node = nodeMap_1[name];
                             var node = nodeMap_1[name];
                             if (!node) {
                             if (!node) {
-                                throw new Error("Failed to find node " + name);
+                                throw new Error("Failed to find node '" + name + "'");
                             }
                             }
                             return node;
                             return node;
                         });
                         });
@@ -2905,7 +2905,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        throw new Error("Invalid coordinate system mode " + this.coordinateSystemMode);
+                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
                     }
                     }
                 }
                 }
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
                 this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
@@ -2934,6 +2934,17 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
                 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 () {
             GLTFLoader.prototype._getMeshes = function () {
                 var meshes = new Array();
                 var meshes = new Array();
                 // Root mesh is always first.
                 // Root mesh is always first.
@@ -2942,15 +2953,9 @@ var BABYLON;
                 if (nodes) {
                 if (nodes) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                     for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                         var node = nodes_2[_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;
                 return meshes;
@@ -2991,7 +2996,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode " + this.animationStartMode);
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
                         return;
                         return;
                     }
                     }
                 }
                 }
@@ -3012,7 +3017,7 @@ var BABYLON;
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 GLTFLoader._LoadTransform(node, babylonMesh);
                 if (node.mesh != undefined) {
                 if (node.mesh != undefined) {
                     var mesh = GLTFLoader._GetProperty(context + "/mesh", this._gltf.meshes, node.mesh);
                     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) {
                 if (node.children) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                     for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
@@ -3024,37 +3029,42 @@ var BABYLON;
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
                 return Promise.all(promises).then(function () { });
             };
             };
-            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh) {
+            GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 // TODO: instancing
                 // TODO: instancing
+                var _this = this;
                 var promises = new Array();
                 var promises = new Array();
                 var primitives = mesh.primitives;
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                     throw new Error(context + ": Primitives are missing");
                 }
                 }
                 GLTF2.ArrayItem.Assign(primitives);
                 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) {
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
                 }
                 return Promise.all(promises).then(function () {
                 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 _this = this;
                 var promises = new Array();
                 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);
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
                     new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
@@ -3064,12 +3074,11 @@ var BABYLON;
                     babylonMesh.material = this._getDefaultMaterial();
                     babylonMesh.material = this._getDefaultMaterial();
                 }
                 }
                 else {
                 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) {
                     promises.push(this._loadMaterialAsync("#/materials/" + material._index, material, babylonMesh, function (babylonMaterial) {
                         babylonMesh.material = babylonMaterial;
                         babylonMesh.material = babylonMaterial;
                     }));
                     }));
                 }
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
                 return Promise.all(promises).then(function () { });
                 return Promise.all(promises).then(function () { });
             };
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -3084,7 +3093,7 @@ var BABYLON;
                 }
                 }
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                 if (primitive.mode != undefined && primitive.mode !== 4 /* TRIANGLES */) {
                     // TODO: handle other primitive modes
                     // 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 promises = new Array();
                 var babylonVertexData = new BABYLON.VertexData();
                 var babylonVertexData = new BABYLON.VertexData();
@@ -3226,7 +3235,7 @@ var BABYLON;
                             break;
                             break;
                         }
                         }
                         default: {
                         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) {
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
                 var _this = this;
                 var assignSkeleton = function () {
                 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;
                         babylonMesh.skeleton = skin._babylonSkeleton;
-                    }
+                    });
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.parent = _this._rootBabylonMesh;
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.position = BABYLON.Vector3.Zero();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
                     node._babylonMesh.rotationQuaternion = BABYLON.Quaternion.Identity();
@@ -3371,6 +3379,7 @@ var BABYLON;
                 });
                 });
             };
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
             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);
                 var targetNode = GLTFLoader._GetProperty(context + "/target/node", this._gltf.nodes, channel.target.node);
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                 if (!targetNode._babylonMesh || targetNode.skin != undefined) {
                     return Promise.resolve();
                     return Promise.resolve();
@@ -3401,7 +3410,7 @@ var BABYLON;
                             break;
                             break;
                         }
                         }
                         default: {
                         default: {
-                            throw new Error(context + ": Invalid target path " + channel.target.path);
+                            throw new Error(context + ": Invalid target path (" + channel.target.path + ")");
                         }
                         }
                     }
                     }
                     var outputBufferOffset = 0;
                     var outputBufferOffset = 0;
@@ -3493,11 +3502,10 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                                 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);
                                 var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                                 babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
-                            }
+                            });
                         };
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
                             _loop_1(targetIndex);
@@ -3528,7 +3536,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     default: {
-                        throw new Error(context + ": Invalid interpolation " + sampler.interpolation);
+                        throw new Error(context + ": Invalid interpolation (" + sampler.interpolation + ")");
                     }
                     }
                 }
                 }
                 var inputData;
                 var inputData;
@@ -3613,12 +3621,12 @@ var BABYLON;
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                                 return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
                             }
                             }
                             default: {
                             default: {
-                                throw new Error(context + ": Invalid component type " + accessor.componentType);
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
                             }
                             }
                         }
                         }
                     }
                     }
                     catch (e) {
                     catch (e) {
-                        throw new Error(context + ": " + e);
+                        throw new Error(context + ": " + e.messsage);
                     }
                     }
                 });
                 });
                 return accessor._data;
                 return accessor._data;
@@ -3782,7 +3790,7 @@ var BABYLON;
                         break;
                         break;
                     }
                     }
                     default: {
                     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) {
                 }, function (message, exception) {
                     if (!_this._disposed) {
                     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);
                 promises.push(deferred.promise);
@@ -3904,7 +3912,7 @@ var BABYLON;
             };
             };
             GLTFLoader._GetProperty = function (context, array, index) {
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !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];
                 return array[index];
             };
             };
@@ -3916,7 +3924,7 @@ var BABYLON;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 33648 /* MIRRORED_REPEAT */: return BABYLON.Texture.MIRROR_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     case 10497 /* REPEAT */: return BABYLON.Texture.WRAP_ADDRESSMODE;
                     default:
                     default:
-                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode " + mode);
+                        BABYLON.Tools.Warn(context + ": Invalid texture wrap mode (" + mode + ")");
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                         return BABYLON.Texture.WRAP_ADDRESSMODE;
                 }
                 }
             };
             };
@@ -3933,13 +3941,13 @@ var BABYLON;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                         default:
                         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;
                             return BABYLON.Texture.LINEAR_LINEAR_MIPLINEAR;
                     }
                     }
                 }
                 }
                 else {
                 else {
                     if (magFilter !== 9728 /* NEAREST */) {
                     if (magFilter !== 9728 /* NEAREST */) {
-                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter " + magFilter);
+                        BABYLON.Tools.Warn(context + ": Invalid texture magnification filter (" + magFilter + ")");
                     }
                     }
                     switch (minFilter) {
                     switch (minFilter) {
                         case 9728 /* NEAREST */: return BABYLON.Texture.NEAREST_NEAREST;
                         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 9986 /* NEAREST_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_NEAREST_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         case 9987 /* LINEAR_MIPMAP_LINEAR */: return BABYLON.Texture.NEAREST_LINEAR_MIPLINEAR;
                         default:
                         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;
                             return BABYLON.Texture.NEAREST_NEAREST_MIPNEAREST;
                     }
                     }
                 }
                 }
@@ -3964,7 +3972,7 @@ var BABYLON;
                     case "MAT3": return 9;
                     case "MAT3": return 9;
                     case "MAT4": return 16;
                     case "MAT4": return 16;
                 }
                 }
-                throw new Error(context + ": Invalid type " + type);
+                throw new Error(context + ": Invalid type (" + type + ")");
             };
             };
             GLTFLoader._ValidateUri = function (uri) {
             GLTFLoader._ValidateUri = function (uri) {
                 return (BABYLON.Tools.IsBase64(uri) || uri.indexOf("..") === -1);
                 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 () {
                             var promise = _this._loader._loadNodeAsync("#/nodes/" + nodeLOD._index, nodeLOD).then(function () {
                                 if (indexLOD !== 0) {
                                 if (indexLOD !== 0) {
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
                                     var previousNodeLOD = nodeLODs[indexLOD - 1];
-                                    previousNodeLOD._babylonMesh.setEnabled(false);
+                                    if (previousNodeLOD._babylonMesh) {
+                                        previousNodeLOD._babylonMesh.dispose();
+                                        delete previousNodeLOD._babylonMesh;
+                                    }
                                 }
                                 }
                                 if (indexLOD !== nodeLODs.length - 1) {
                                 if (indexLOD !== nodeLODs.length - 1) {
                                     var nodeIndex = nodeLODs[indexLOD + 1]._index;
                                     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 () {
                             var promise = _this._loader._loadMaterialAsync("#/materials/" + materialLOD._index, materialLOD, babylonMesh, indexLOD === 0 ? assign : function () { }).then(function () {
                                 if (indexLOD !== 0) {
                                 if (indexLOD !== 0) {
                                     assign(materialLOD._babylonMaterial);
                                     assign(materialLOD._babylonMaterial);
+                                    var previousMaterialLOD = materialLODs[indexLOD - 1];
+                                    if (previousMaterialLOD._babylonMaterial) {
+                                        previousMaterialLOD._babylonMaterial.dispose();
+                                        delete previousMaterialLOD._babylonMaterial;
+                                    }
                                 }
                                 }
                                 if (indexLOD !== materialLODs.length - 1) {
                                 if (indexLOD !== materialLODs.length - 1) {
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
                                     var materialIndex = materialLODs[indexLOD + 1]._index;
@@ -4537,7 +4553,7 @@ var BABYLON;
                                 break;
                                 break;
                             }
                             }
                             default: {
                             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();
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();
@@ -4550,7 +4566,7 @@ var BABYLON;
                     get: function () {
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         var extensions = this._loader._gltf.extensions;
                         if (!extensions || !extensions[this.name]) {
                         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];
                         var extension = extensions[this.name];
                         return extension.lights;
                         return extension.lights;

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


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

文件差异内容过多而无法显示
+ 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;
         private _onMaterialLoadedObserver;
         onMaterialLoaded: (material: Material) => void;
         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>;
         readonly onAnimationGroupLoadedObservable: Observable<AnimationGroup>;
         private _onAnimationGroupLoadedObserver;
         private _onAnimationGroupLoadedObserver;
@@ -245,7 +245,7 @@ declare module BABYLON {
         private _onExtensionLoadedObserver;
         private _onExtensionLoadedObserver;
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         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.
          * @returns A promise that resolves when the asset is completely loaded.
          */
          */
         whenCompleteAsync(): Promise<void>;
         whenCompleteAsync(): Promise<void>;
@@ -979,12 +979,13 @@ declare module BABYLON.GLTF2 {
         private _createRootNode();
         private _createRootNode();
         private _loadNodesAsync(nodes);
         private _loadNodesAsync(nodes);
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
+        private _forEachNodeMesh(node, callback);
         private _getMeshes();
         private _getMeshes();
         private _getSkeletons();
         private _getSkeletons();
         private _startAnimations();
         private _startAnimations();
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         _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 _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
         private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);

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

@@ -1,277 +1,5 @@
 
 
 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 {
     class CustomShaderStructure {
         FragmentStore: string;
         FragmentStore: string;
         VertexStore: string;
         VertexStore: string;
@@ -291,26 +19,20 @@ declare module BABYLON {
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: 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;
         static ShaderIndexer: number;
         CustomParts: ShaderSpecialParts;
         CustomParts: ShaderSpecialParts;
-        ShaderVersion: CustomShaderStructure;
         _isCreatedShader: boolean;
         _isCreatedShader: boolean;
         _createdShaderName: string;
         _createdShaderName: string;
         _customUniform: string[];
         _customUniform: string[];
         _newUniforms: string[];
         _newUniforms: string[];
         _newUniformInstances: any[];
         _newUniformInstances: any[];
         _newSamplerInstances: Texture[];
         _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
         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);
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;

文件差异内容过多而无法显示
+ 19 - 1908
dist/preview release/materialsLibrary/babylon.customMaterial.js


文件差异内容过多而无法显示
+ 1 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


文件差异内容过多而无法显示
+ 22 - 1906
dist/preview release/materialsLibrary/babylonjs.materials.js


文件差异内容过多而无法显示
+ 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 {
 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 {
     class CustomShaderStructure {
         FragmentStore: string;
         FragmentStore: string;
         VertexStore: string;
         VertexStore: string;
@@ -797,26 +525,20 @@ declare module BABYLON {
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: 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;
         static ShaderIndexer: number;
         CustomParts: ShaderSpecialParts;
         CustomParts: ShaderSpecialParts;
-        ShaderVersion: CustomShaderStructure;
         _isCreatedShader: boolean;
         _isCreatedShader: boolean;
         _createdShaderName: string;
         _createdShaderName: string;
         _customUniform: string[];
         _customUniform: string[];
         _newUniforms: string[];
         _newUniforms: string[];
         _newUniformInstances: any[];
         _newUniformInstances: any[];
         _newSamplerInstances: Texture[];
         _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
         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);
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;
         Fragment_Begin(shaderPart: string): CustomMaterial;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


文件差异内容过多而无法显示
+ 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.
          * 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.
          * 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.
          * 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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -317,19 +327,19 @@ declare module BABYLON.GLTF2 {
          * @param originalMaterial - original glTF material.
          * @param originalMaterial - original glTF material.
          * @returns glTF material without texture parameters
          * @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.
          * Specifies if the material has any texture parameters present.
          * @param material - glTF Material.
          * @param material - glTF Material.
          * @returns boolean specifying if texture parameters are present
          * @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.
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
          * @returns - glTF Metallic Roughness Material representation
          */
          */
-        static ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
         /**
         /**
          * Computes the metallic factor
          * Computes the metallic factor
          * @param diffuse - diffused value
          * @param diffuse - diffused value
@@ -337,13 +347,13 @@ declare module BABYLON.GLTF2 {
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @returns - metallic value
          * @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
          * Gets the glTF alpha mode from the Babylon Material
          * @param babylonMaterial - Babylon Material
          * @param babylonMaterial - Babylon Material
          * @returns - The Babylon alpha mode value
          * @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.
          * Converts a Babylon Standard Material to a glTF Material.
          * @param babylonStandardMaterial - BJS Standard Material.
          * @param babylonStandardMaterial - BJS Standard Material.
@@ -354,7 +364,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -370,25 +380,66 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
             };
             };
         }, hasTextureCoords: boolean): void;
         }, 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
          * 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
          * @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.
          * @param color - Color source to calculate brightness from.
          * @returns number representing the perceived brightness, or zero if color is undefined.
          * @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.
          * Returns the maximum color component value.
          * @param color
          * @param color
          * @returns maximum color component value, or zero if color is null or undefined.
          * @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.
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
          * @param babylonPBRMaterial - BJS PBR Metallic Roughness 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 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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -412,13 +463,19 @@ declare module BABYLON.GLTF2 {
          * @param images - Array of glTF images.
          * @param images - Array of glTF images.
          * @param textures - Array of glTF textures.
          * @param textures - Array of glTF textures.
          * @param imageData - map of image file name and data.
          * @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 {
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                     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;
                                         meshPrimitive.material = materialIndex;
                                     }
                                     }
                                     else {
                                     else {
                                         // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
                                         // 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);
                                         this.materials.push(newMat);
                                         meshPrimitive.material = this.materials.length - 1;
                                         meshPrimitive.material = this.materials.length - 1;
                                     }
                                     }
@@ -642,7 +642,7 @@ var BABYLON;
                 if (babylonScene.meshes.length) {
                 if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
                     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);
                     var result = this.createNodeMap(babylonScene, byteOffset);
                     this.nodeMap = result.nodeMap;
                     this.nodeMap = result.nodeMap;
                     this.totalByteLength = result.byteOffset;
                     this.totalByteLength = result.byteOffset;
@@ -799,29 +799,40 @@ var BABYLON;
             function _GLTFMaterial() {
             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.
              * 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) {
                 for (var i = 0; i < babylonMaterials.length; ++i) {
                     var babylonMaterial = babylonMaterials[i];
                     var babylonMaterial = babylonMaterials[i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     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) {
                     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) {
                     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 {
                     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.
              * @param originalMaterial - original glTF material.
              * @returns glTF material without texture parameters
              * @returns glTF material without texture parameters
              */
              */
-            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+            _GLTFMaterial._StripTexturesFromMaterial = function (originalMaterial) {
                 var newMaterial = {};
                 var newMaterial = {};
                 if (originalMaterial) {
                 if (originalMaterial) {
                     newMaterial.name = originalMaterial.name;
                     newMaterial.name = originalMaterial.name;
@@ -853,7 +864,7 @@ var BABYLON;
              * @param material - glTF Material.
              * @param material - glTF Material.
              * @returns boolean specifying if texture parameters are present
              * @returns boolean specifying if texture parameters are present
              */
              */
-            _GLTFMaterial.HasTexturesPresent = function (material) {
+            _GLTFMaterial._HasTexturesPresent = function (material) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                     return true;
                     return true;
                 }
                 }
@@ -870,7 +881,7 @@ var BABYLON;
              * @param babylonStandardMaterial
              * @param babylonStandardMaterial
              * @returns - glTF Metallic Roughness Material representation
              * @returns - glTF Metallic Roughness Material representation
              */
              */
-            _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
+            _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P2 = 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.
                  * @param p3 - fourth control point.
                  * @returns - number result of cubic bezier curve at the specified t.
                  * @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 +
                     return ((1 - t) * (1 - t) * (1 - t) * p0 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * t * t * p2 +
                         3 * (1 - t) * t * t * p2 +
@@ -897,14 +908,14 @@ var BABYLON;
                  * @param specularPower - specular power of standard material.
                  * @param specularPower - specular power of standard material.
                  * @returns - Number representing the roughness value.
                  * @returns - Number representing the roughness value.
                  */
                  */
-                function solveForRoughness(specularPower) {
+                function _solveForRoughness(specularPower) {
                     var t = Math.pow(specularPower / P3.x, 0.333333);
                     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 diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
                 var opacity = babylonStandardMaterial.alpha;
                 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 = {
                 var glTFPbrMetallicRoughness = {
                     baseColorFactor: [
                     baseColorFactor: [
                         diffuse.r,
                         diffuse.r,
@@ -924,14 +935,14 @@ var BABYLON;
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @returns - metallic value
              * @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;
                     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;
                 var D = b * b - 4.0 * a * c;
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
             };
             };
@@ -940,7 +951,7 @@ var BABYLON;
              * @param babylonMaterial - Babylon Material
              * @param babylonMaterial - Babylon Material
              * @returns - The Babylon alpha mode value
              * @returns - The Babylon alpha mode value
              */
              */
-            _GLTFMaterial.GetAlphaMode = function (babylonMaterial) {
+            _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     var babylonStandardMaterial = babylonMaterial;
                     var babylonStandardMaterial = babylonMaterial;
                     if ((babylonStandardMaterial.alpha != 1.0) ||
                     if ((babylonStandardMaterial.alpha != 1.0) ||
@@ -1008,11 +1019,11 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @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.
              * @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");
                 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 };
                 var glTFMaterial = { name: babylonStandardMaterial.name };
-                if (babylonStandardMaterial.backFaceCulling) {
+                if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                         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 (hasTextureCoords) {
                     if (babylonStandardMaterial.diffuseTexture) {
                     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) {
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonStandardMaterial.bumpTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonStandardMaterial.emissiveTexture) {
                     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) {
                         if (glTFEmissiveTexture) {
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                         }
                         }
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     }
                     if (babylonStandardMaterial.ambientTexture) {
                     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) {
                         if (glTFTexture) {
                             var occlusionTexture = {
                             var occlusionTexture = {
                                 index: glTFTexture.index
                                 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());
                         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.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
@@ -1073,7 +1084,7 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @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.
              * @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 = {};
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                     glTFPbrMetallicRoughness.baseColorFactor = [
                     glTFPbrMetallicRoughness.baseColorFactor = [
@@ -1083,10 +1094,10 @@ var BABYLON;
                         babylonPBRMetalRoughMaterial.alpha
                         babylonPBRMetalRoughMaterial.alpha
                     ];
                     ];
                 }
                 }
-                if (babylonPBRMetalRoughMaterial.metallic != null) {
+                if (babylonPBRMetalRoughMaterial.metallic != null && babylonPBRMetalRoughMaterial.metallic !== 1) {
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                 }
                 }
-                if (babylonPBRMetalRoughMaterial.roughness != null) {
+                if (babylonPBRMetalRoughMaterial.roughness != null && babylonPBRMetalRoughMaterial.roughness !== 1) {
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                 }
                 }
                 var glTFMaterial = {
                 var glTFMaterial = {
@@ -1097,19 +1108,19 @@ var BABYLON;
                 }
                 }
                 if (hasTextureCoords) {
                 if (hasTextureCoords) {
                     if (babylonPBRMetalRoughMaterial.baseTexture != null) {
                     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) {
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.normalTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.occlusionTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.occlusionTexture = glTFTexture;
                             glTFMaterial.occlusionTexture = glTFTexture;
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
@@ -1118,17 +1129,17 @@ var BABYLON;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.emissiveTexture) {
                     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) {
                         if (glTFTexture != null) {
                             glTFMaterial.emissiveTexture = glTFTexture;
                             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();
                     glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
                 }
                 }
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
-                    var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMetalRoughMaterial);
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMetalRoughMaterial);
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                         glTFMaterial.alphaMode = alphaMode;
                         glTFMaterial.alphaMode = alphaMode;
                         if (alphaMode === "BLEND" /* BLEND */) {
                         if (alphaMode === "BLEND" /* BLEND */) {
@@ -1140,12 +1151,213 @@ var BABYLON;
                 materials.push(glTFMaterial);
                 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
              * 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
              * @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.
              * @param color - Color source to calculate brightness from.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              */
              */
-            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+            _GLTFMaterial._GetPerceivedBrightness = function (color) {
                 if (color) {
                 if (color) {
                     return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
                     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
              * @param color
              * @returns maximum color component value, or zero if color is null or undefined.
              * @returns maximum color component value, or zero if color is null or undefined.
              */
              */
-            _GLTFMaterial.GetMaxComponent = function (color) {
+            _GLTFMaterial._GetMaxComponent = function (color) {
                 if (color) {
                 if (color) {
                     return Math.max(color.r, Math.max(color.g, color.b));
                     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 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.
              * @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 glTFPbrMetallicRoughness = {};
+                var metallicRoughness;
                 var glTFMaterial = {
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                     name: babylonPBRMaterial.name
                 };
                 };
                 var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
                 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 images - Array of glTF images.
              * @param textures - Array of glTF textures.
              * @param textures - Array of glTF textures.
              * @param imageData - map of image file name and data.
              * @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 textureName = "texture_" + (textures.length - 1).toString();
                 var textureData = babylonTexture.getInternalTexture();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
                 if (textureData != null) {
-                    textureName = textureData.url;
+                    textureName = textureData.url || textureName;
                 }
                 }
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 var baseFile = textureName.split('.')[0];
                 var baseFile = textureName.split('.')[0];
@@ -1311,28 +1517,37 @@ var BABYLON;
                     extension = ".png";
                     extension = ".png";
                 }
                 }
                 else {
                 else {
-                    BABYLON.Tools.Error("Unsupported mime type " + mimeType);
+                    throw new Error("Unsupported mime type " + mimeType);
                 }
                 }
                 textureName = baseFile + extension;
                 textureName = baseFile + extension;
                 var pixels = babylonTexture.readPixels();
                 var pixels = babylonTexture.readPixels();
-                var imageCanvas = document.createElement('canvas');
-                imageCanvas.id = "ImageCanvas";
-                var ctx = imageCanvas.getContext('2d');
                 var size = babylonTexture.getSize();
                 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);
                 var arr = new Uint8Array(binStr.length);
                 for (var i = 0; i < binStr.length; ++i) {
                 for (var i = 0; i < binStr.length; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                     arr[i] = binStr.charCodeAt(i);
                 }
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 var imageValues = { data: arr, mimeType: mimeType };
                 imageData[textureName] = imageValues;
                 imageData[textureName] = imageValues;
-                if (mimeType === "image/jpeg" /* JPEG */) {
+                if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */) {
                     var glTFImage = {
                     var glTFImage = {
                         uri: textureName
                         uri: textureName
                     };
                     };
@@ -1365,12 +1580,15 @@ var BABYLON;
             /**
             /**
              * Represents the dielectric specular values for R, G and B.
              * 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.
              * 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;
             return _GLTFMaterial;
         }());
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;
         GLTF2._GLTFMaterial = _GLTFMaterial;

文件差异内容过多而无法显示
+ 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 {
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                     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;
                                         meshPrimitive.material = materialIndex;
                                     }
                                     }
                                     else {
                                     else {
                                         // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
                                         // 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);
                                         this.materials.push(newMat);
                                         meshPrimitive.material = this.materials.length - 1;
                                         meshPrimitive.material = this.materials.length - 1;
                                     }
                                     }
@@ -796,7 +796,7 @@ var BABYLON;
                 if (babylonScene.meshes.length) {
                 if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
                     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);
                     var result = this.createNodeMap(babylonScene, byteOffset);
                     this.nodeMap = result.nodeMap;
                     this.nodeMap = result.nodeMap;
                     this.totalByteLength = result.byteOffset;
                     this.totalByteLength = result.byteOffset;
@@ -953,29 +953,40 @@ var BABYLON;
             function _GLTFMaterial() {
             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.
              * 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) {
                 for (var i = 0; i < babylonMaterials.length; ++i) {
                     var babylonMaterial = babylonMaterials[i];
                     var babylonMaterial = babylonMaterials[i];
                     if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     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) {
                     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) {
                     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 {
                     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.
              * @param originalMaterial - original glTF material.
              * @returns glTF material without texture parameters
              * @returns glTF material without texture parameters
              */
              */
-            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+            _GLTFMaterial._StripTexturesFromMaterial = function (originalMaterial) {
                 var newMaterial = {};
                 var newMaterial = {};
                 if (originalMaterial) {
                 if (originalMaterial) {
                     newMaterial.name = originalMaterial.name;
                     newMaterial.name = originalMaterial.name;
@@ -1007,7 +1018,7 @@ var BABYLON;
              * @param material - glTF Material.
              * @param material - glTF Material.
              * @returns boolean specifying if texture parameters are present
              * @returns boolean specifying if texture parameters are present
              */
              */
-            _GLTFMaterial.HasTexturesPresent = function (material) {
+            _GLTFMaterial._HasTexturesPresent = function (material) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                 if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
                     return true;
                     return true;
                 }
                 }
@@ -1024,7 +1035,7 @@ var BABYLON;
              * @param babylonStandardMaterial
              * @param babylonStandardMaterial
              * @returns - glTF Metallic Roughness Material representation
              * @returns - glTF Metallic Roughness Material representation
              */
              */
-            _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
+            _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P0 = new BABYLON.Vector2(0, 1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P1 = new BABYLON.Vector2(0, 0.1);
                 var P2 = 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.
                  * @param p3 - fourth control point.
                  * @returns - number result of cubic bezier curve at the specified t.
                  * @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 +
                     return ((1 - t) * (1 - t) * (1 - t) * p0 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * (1 - t) * t * p1 +
                         3 * (1 - t) * t * t * p2 +
                         3 * (1 - t) * t * t * p2 +
@@ -1051,14 +1062,14 @@ var BABYLON;
                  * @param specularPower - specular power of standard material.
                  * @param specularPower - specular power of standard material.
                  * @returns - Number representing the roughness value.
                  * @returns - Number representing the roughness value.
                  */
                  */
-                function solveForRoughness(specularPower) {
+                function _solveForRoughness(specularPower) {
                     var t = Math.pow(specularPower / P3.x, 0.333333);
                     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 diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
                 var opacity = babylonStandardMaterial.alpha;
                 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 = {
                 var glTFPbrMetallicRoughness = {
                     baseColorFactor: [
                     baseColorFactor: [
                         diffuse.r,
                         diffuse.r,
@@ -1078,14 +1089,14 @@ var BABYLON;
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @param oneMinusSpecularStrength - one minus the specular strength
              * @returns - metallic value
              * @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;
                     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;
                 var D = b * b - 4.0 * a * c;
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
                 return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
             };
             };
@@ -1094,7 +1105,7 @@ var BABYLON;
              * @param babylonMaterial - Babylon Material
              * @param babylonMaterial - Babylon Material
              * @returns - The Babylon alpha mode value
              * @returns - The Babylon alpha mode value
              */
              */
-            _GLTFMaterial.GetAlphaMode = function (babylonMaterial) {
+            _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                 if (babylonMaterial instanceof BABYLON.StandardMaterial) {
                     var babylonStandardMaterial = babylonMaterial;
                     var babylonStandardMaterial = babylonMaterial;
                     if ((babylonStandardMaterial.alpha != 1.0) ||
                     if ((babylonStandardMaterial.alpha != 1.0) ||
@@ -1162,11 +1173,11 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @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.
              * @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");
                 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 };
                 var glTFMaterial = { name: babylonStandardMaterial.name };
-                if (babylonStandardMaterial.backFaceCulling) {
+                if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                     if (!babylonStandardMaterial.twoSidedLighting) {
                         BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
                         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 (hasTextureCoords) {
                     if (babylonStandardMaterial.diffuseTexture) {
                     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) {
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonStandardMaterial.bumpTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonStandardMaterial.emissiveTexture) {
                     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) {
                         if (glTFEmissiveTexture) {
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                             glTFMaterial.emissiveTexture = glTFEmissiveTexture;
                         }
                         }
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     }
                     if (babylonStandardMaterial.ambientTexture) {
                     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) {
                         if (glTFTexture) {
                             var occlusionTexture = {
                             var occlusionTexture = {
                                 index: glTFTexture.index
                                 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());
                         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.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
                 }
                 }
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
                 glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
@@ -1227,7 +1238,7 @@ var BABYLON;
              * @param imageData - map of image file name to data.
              * @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.
              * @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 = {};
                 var glTFPbrMetallicRoughness = {};
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                 if (babylonPBRMetalRoughMaterial.baseColor) {
                     glTFPbrMetallicRoughness.baseColorFactor = [
                     glTFPbrMetallicRoughness.baseColorFactor = [
@@ -1237,10 +1248,10 @@ var BABYLON;
                         babylonPBRMetalRoughMaterial.alpha
                         babylonPBRMetalRoughMaterial.alpha
                     ];
                     ];
                 }
                 }
-                if (babylonPBRMetalRoughMaterial.metallic != null) {
+                if (babylonPBRMetalRoughMaterial.metallic != null && babylonPBRMetalRoughMaterial.metallic !== 1) {
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                     glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
                 }
                 }
-                if (babylonPBRMetalRoughMaterial.roughness != null) {
+                if (babylonPBRMetalRoughMaterial.roughness != null && babylonPBRMetalRoughMaterial.roughness !== 1) {
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                     glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
                 }
                 }
                 var glTFMaterial = {
                 var glTFMaterial = {
@@ -1251,19 +1262,19 @@ var BABYLON;
                 }
                 }
                 if (hasTextureCoords) {
                 if (hasTextureCoords) {
                     if (babylonPBRMetalRoughMaterial.baseTexture != null) {
                     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) {
                         if (glTFTexture != null) {
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                             glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.normalTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.normalTexture = glTFTexture;
                             glTFMaterial.normalTexture = glTFTexture;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.occlusionTexture) {
                     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) {
                         if (glTFTexture) {
                             glTFMaterial.occlusionTexture = glTFTexture;
                             glTFMaterial.occlusionTexture = glTFTexture;
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
                             if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
@@ -1272,17 +1283,17 @@ var BABYLON;
                         }
                         }
                     }
                     }
                     if (babylonPBRMetalRoughMaterial.emissiveTexture) {
                     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) {
                         if (glTFTexture != null) {
                             glTFMaterial.emissiveTexture = glTFTexture;
                             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();
                     glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
                 }
                 }
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
                 if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
-                    var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMetalRoughMaterial);
+                    var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMetalRoughMaterial);
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                     if (alphaMode !== "OPAQUE" /* OPAQUE */) {
                         glTFMaterial.alphaMode = alphaMode;
                         glTFMaterial.alphaMode = alphaMode;
                         if (alphaMode === "BLEND" /* BLEND */) {
                         if (alphaMode === "BLEND" /* BLEND */) {
@@ -1294,12 +1305,213 @@ var BABYLON;
                 materials.push(glTFMaterial);
                 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
              * 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
              * @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.
              * @param color - Color source to calculate brightness from.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              * @returns number representing the perceived brightness, or zero if color is undefined.
              */
              */
-            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+            _GLTFMaterial._GetPerceivedBrightness = function (color) {
                 if (color) {
                 if (color) {
                     return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
                     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
              * @param color
              * @returns maximum color component value, or zero if color is null or undefined.
              * @returns maximum color component value, or zero if color is null or undefined.
              */
              */
-            _GLTFMaterial.GetMaxComponent = function (color) {
+            _GLTFMaterial._GetMaxComponent = function (color) {
                 if (color) {
                 if (color) {
                     return Math.max(color.r, Math.max(color.g, color.b));
                     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 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.
              * @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 glTFPbrMetallicRoughness = {};
+                var metallicRoughness;
                 var glTFMaterial = {
                 var glTFMaterial = {
                     name: babylonPBRMaterial.name
                     name: babylonPBRMaterial.name
                 };
                 };
                 var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
                 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 images - Array of glTF images.
              * @param textures - Array of glTF textures.
              * @param textures - Array of glTF textures.
              * @param imageData - map of image file name and data.
              * @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 textureName = "texture_" + (textures.length - 1).toString();
                 var textureData = babylonTexture.getInternalTexture();
                 var textureData = babylonTexture.getInternalTexture();
                 if (textureData != null) {
                 if (textureData != null) {
-                    textureName = textureData.url;
+                    textureName = textureData.url || textureName;
                 }
                 }
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 textureName = BABYLON.Tools.GetFilename(textureName);
                 var baseFile = textureName.split('.')[0];
                 var baseFile = textureName.split('.')[0];
@@ -1465,28 +1671,37 @@ var BABYLON;
                     extension = ".png";
                     extension = ".png";
                 }
                 }
                 else {
                 else {
-                    BABYLON.Tools.Error("Unsupported mime type " + mimeType);
+                    throw new Error("Unsupported mime type " + mimeType);
                 }
                 }
                 textureName = baseFile + extension;
                 textureName = baseFile + extension;
                 var pixels = babylonTexture.readPixels();
                 var pixels = babylonTexture.readPixels();
-                var imageCanvas = document.createElement('canvas');
-                imageCanvas.id = "ImageCanvas";
-                var ctx = imageCanvas.getContext('2d');
                 var size = babylonTexture.getSize();
                 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);
                 var arr = new Uint8Array(binStr.length);
                 for (var i = 0; i < binStr.length; ++i) {
                 for (var i = 0; i < binStr.length; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                     arr[i] = binStr.charCodeAt(i);
                 }
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 var imageValues = { data: arr, mimeType: mimeType };
                 imageData[textureName] = imageValues;
                 imageData[textureName] = imageValues;
-                if (mimeType === "image/jpeg" /* JPEG */) {
+                if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */) {
                     var glTFImage = {
                     var glTFImage = {
                         uri: textureName
                         uri: textureName
                     };
                     };
@@ -1519,12 +1734,15 @@ var BABYLON;
             /**
             /**
              * Represents the dielectric specular values for R, G and B.
              * 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.
              * 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;
             return _GLTFMaterial;
         }());
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;
         GLTF2._GLTFMaterial = _GLTFMaterial;

文件差异内容过多而无法显示
+ 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.
          * 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.
          * 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.
          * 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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -332,19 +342,19 @@ declare module BABYLON.GLTF2 {
          * @param originalMaterial - original glTF material.
          * @param originalMaterial - original glTF material.
          * @returns glTF material without texture parameters
          * @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.
          * Specifies if the material has any texture parameters present.
          * @param material - glTF Material.
          * @param material - glTF Material.
          * @returns boolean specifying if texture parameters are present
          * @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.
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
          * @returns - glTF Metallic Roughness Material representation
          */
          */
-        static ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
         /**
         /**
          * Computes the metallic factor
          * Computes the metallic factor
          * @param diffuse - diffused value
          * @param diffuse - diffused value
@@ -352,13 +362,13 @@ declare module BABYLON.GLTF2 {
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @param oneMinusSpecularStrength - one minus the specular strength
          * @returns - metallic value
          * @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
          * Gets the glTF alpha mode from the Babylon Material
          * @param babylonMaterial - Babylon Material
          * @param babylonMaterial - Babylon Material
          * @returns - The Babylon alpha mode value
          * @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.
          * Converts a Babylon Standard Material to a glTF Material.
          * @param babylonStandardMaterial - BJS Standard Material.
          * @param babylonStandardMaterial - BJS Standard Material.
@@ -369,7 +379,7 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -385,25 +395,66 @@ declare module BABYLON.GLTF2 {
          * @param imageData - map of image file name to data.
          * @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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
             };
             };
         }, hasTextureCoords: boolean): void;
         }, 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
          * 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
          * @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.
          * @param color - Color source to calculate brightness from.
          * @returns number representing the perceived brightness, or zero if color is undefined.
          * @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.
          * Returns the maximum color component value.
          * @param color
          * @param color
          * @returns maximum color component value, or zero if color is null or undefined.
          * @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.
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
          * @param babylonPBRMaterial - BJS PBR Metallic Roughness 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 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.
          * @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]: {
             [fileName: string]: {
                 data: Uint8Array;
                 data: Uint8Array;
                 mimeType: ImageMimeType;
                 mimeType: ImageMimeType;
@@ -427,13 +478,19 @@ declare module BABYLON.GLTF2 {
          * @param images - Array of glTF images.
          * @param images - Array of glTF images.
          * @param textures - Array of glTF textures.
          * @param textures - Array of glTF textures.
          * @param imageData - map of image file name and data.
          * @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);
     }
     }
 }
 }

文件差异内容过多而无法显示
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 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> {
         private static _GetDefaultDecoderUrl(): Nullable<string> {
+            if (!Tools.IsWindowObjectExist) {
+                return null;
+            }
+
             for (let i = 0; i < document.scripts.length; i++) {
             for (let i = 0; i < document.scripts.length; i++) {
                 if (document.scripts[i].type === "text/x-draco-decoder") {
                 if (document.scripts[i].type === "text/x-draco-decoder") {
                     return document.scripts[i].src;
                     return document.scripts[i].src;