浏览代码

Merge remote-tracking branch 'upstream/master' into InProgress

sebastien 7 年之前
父节点
当前提交
eae8e68e32
共有 52 个文件被更改,包括 12709 次插入10774 次删除
  1. 5014 4935
      dist/preview release/babylon.d.ts
  2. 36 36
      dist/preview release/babylon.js
  3. 246 52
      dist/preview release/babylon.max.js
  4. 36 36
      dist/preview release/babylon.worker.js
  5. 5398 5319
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  6. 36 36
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  7. 246 52
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  8. 248 54
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  9. 248 54
      dist/preview release/es6.js
  10. 1 1
      dist/preview release/gltf2Interface/package.json
  11. 1 1
      dist/preview release/gui/package.json
  12. 21 2
      dist/preview release/inspector/babylon.inspector.d.ts
  13. 159 8
      dist/preview release/inspector/babylon.inspector.js
  14. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  15. 1 1
      dist/preview release/inspector/package.json
  16. 2 2
      dist/preview release/loaders/package.json
  17. 1 0
      dist/preview release/materialsLibrary/babylon.customMaterial.d.ts
  18. 1 0
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  19. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  20. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.js
  21. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  22. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  23. 1 1
      dist/preview release/materialsLibrary/package.json
  24. 1 1
      dist/preview release/postProcessesLibrary/package.json
  25. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  26. 42 0
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  27. 259 31
      dist/preview release/serializers/babylon.glTF2Serializer.js
  28. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  29. 259 31
      dist/preview release/serializers/babylonjs.serializers.js
  30. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  31. 42 0
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  32. 2 2
      dist/preview release/serializers/package.json
  33. 2 2
      dist/preview release/typedocValidationBaseline.json
  34. 36 36
      dist/preview release/viewer/babylon.viewer.js
  35. 246 52
      dist/preview release/viewer/babylon.viewer.max.js
  36. 1 1
      dist/preview release/viewer/package.json
  37. 3 2
      dist/preview release/what's new.md
  38. 1 0
      materialsLibrary/src/custom/babylon.customMaterial.ts
  39. 1 1
      package.json
  40. 1 1
      src/Engine/babylon.engine.ts
  41. 1 2
      src/Materials/Background/babylon.backgroundMaterial.ts
  42. 1 0
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  43. 1 1
      src/Materials/Textures/babylon.texture.ts
  44. 4 0
      src/Materials/Textures/babylon.videoTexture.ts
  45. 65 1
      src/Materials/babylon.imageProcessingConfiguration.ts
  46. 1 0
      src/Materials/babylon.standardMaterial.ts
  47. 6 5
      src/Mesh/Compression/babylon.dracoCompression.ts
  48. 1 0
      src/PostProcess/babylon.imageProcessingPostProcess.ts
  49. 4 4
      src/Shaders/ShadersInclude/helperFunctions.fx
  50. 5 0
      src/Shaders/ShadersInclude/imageProcessingDeclaration.fx
  51. 5 2
      src/Shaders/background.fragment.fx
  52. 12 0
      src/Shaders/imageProcessing.fragment.fx

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


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


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


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


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


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


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


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


文件差异内容过多而无法显示
+ 248 - 54
dist/preview release/es6.js


+ 1 - 1
dist/preview release/gltf2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 21 - 2
dist/preview release/inspector/babylon.inspector.d.ts

@@ -420,13 +420,20 @@ declare module INSPECTOR {
         private _headerRow;
         private _detailRows;
         private _sortDirection;
+        private _searchDetails;
+        private _details;
         constructor(dr?: Array<PropertyLine>);
         details: Array<PropertyLine>;
         protected _build(): void;
         /** Updates the HTML of the detail panel */
-        update(): void;
+        update(_items?: Array<PropertyLine>): void;
+        /** Add the search bar for the details */
+        private _addSearchBarDetails();
+        /** Search an element by name  */
+        searchByName(searchName: string): void;
         /** Add all lines in the html div. Does not sort them! */
         private _addDetails();
+        private _addSearchDetails(_items);
         /**
          * Sort the details row by comparing the given property of each row
          */
@@ -435,6 +442,10 @@ declare module INSPECTOR {
          * Removes all data in the detail panel but keep the header row
          */
         clean(): void;
+        /**
+         * Clean the rows only
+         */
+        cleanRow(): void;
         /** Overrides basicelement.dispose */
         dispose(): void;
         /**
@@ -670,13 +681,21 @@ declare module INSPECTOR {
      * At each keypress on the input, the treepanel will be filtered.
      */
     class SearchBar extends BasicElement {
-        private _tab;
+        private _propTab;
         private _inputElement;
         constructor(tab: PropertyTab);
         /** Delete all characters typped in the input element */
         reset(): void;
         update(): void;
     }
+    class SearchBarDetails extends BasicElement {
+        private _detailTab;
+        private _inputElement;
+        constructor(tab: DetailPanel);
+        /** Delete all characters typped in the input element */
+        reset(): void;
+        update(): void;
+    }
 }
 
 declare module INSPECTOR {

+ 159 - 8
dist/preview release/inspector/babylon.inspector.js

@@ -1164,6 +1164,9 @@ var INSPECTOR;
         Object.defineProperty(DetailPanel.prototype, "details", {
             set: function (detailsRow) {
                 this.clean();
+                //add the searchBar
+                this._addSearchBarDetails();
+                this._details = INSPECTOR.Helpers.CreateDiv('details', this._div);
                 this._detailRows = detailsRow;
                 // Refresh HTML
                 this.update();
@@ -1179,16 +1182,49 @@ var INSPECTOR;
             this._div.appendChild(this._headerRow);
         };
         /** Updates the HTML of the detail panel */
-        DetailPanel.prototype.update = function () {
+        DetailPanel.prototype.update = function (_items) {
             this._sortDetails('name', 1);
-            this._addDetails();
+            // Check the searchbar
+            if (_items) {
+                this.cleanRow();
+                this._addSearchDetails(_items);
+                //console.log(_items);
+            }
+            else {
+                this._addDetails();
+                //console.log("np");
+            }
+        };
+        /** Add the search bar for the details */
+        DetailPanel.prototype._addSearchBarDetails = function () {
+            var searchDetails = INSPECTOR.Helpers.CreateDiv('searchbar-details', this._div);
+            // Create search bar
+            this._searchDetails = new INSPECTOR.SearchBarDetails(this);
+            searchDetails.appendChild(this._searchDetails.toHtml());
+            this._div.appendChild(searchDetails);
+        };
+        /** Search an element by name  */
+        DetailPanel.prototype.searchByName = function (searchName) {
+            var rows = [];
+            for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
+                var row = _a[_i];
+                if (row.name.indexOf(searchName) >= 0) {
+                    rows.push(row);
+                }
+            }
+            this.update(rows);
         };
         /** Add all lines in the html div. Does not sort them! */
         DetailPanel.prototype._addDetails = function () {
-            var details = INSPECTOR.Helpers.CreateDiv('details', this._div);
             for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
                 var row = _a[_i];
-                details.appendChild(row.toHtml());
+                this._details.appendChild(row.toHtml());
+            }
+        };
+        DetailPanel.prototype._addSearchDetails = function (_items) {
+            for (var _i = 0, _items_1 = _items; _i < _items_1.length; _i++) {
+                var row = _items_1[_i];
+                this._details.appendChild(row.toHtml());
             }
         };
         /**
@@ -1251,6 +1287,17 @@ var INSPECTOR;
             // Header row
             this._div.appendChild(this._headerRow);
         };
+        /**
+         * Clean the rows only
+         */
+        DetailPanel.prototype.cleanRow = function () {
+            // Delete all details row
+            for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
+                var pline = _a[_i];
+                pline.dispose();
+            }
+            INSPECTOR.Helpers.CleanDiv(this._details);
+        };
         /** Overrides basicelement.dispose */
         DetailPanel.prototype.dispose = function () {
             // Delete all details row
@@ -1630,6 +1677,57 @@ var INSPECTOR;
             }
             else {
                 this._valueDiv.childNodes[0].nodeValue = this._displayValueContent();
+                //Doing the Hexa convertion
+                if ((this._property.type == "Color3" && this._children.length == 5 && this._children[1].value == true) || (this._property.type == "Color4" && this._children.length == 6 && this._children[1].value == true)) {
+                    if (this._children[0] != undefined && this._children[0].name == "hex") {
+                        var hexLineString = this._children[0].value;
+                        var rValue = (parseInt((hexLineString.slice(1, 3)), 16)) * (1 / 255);
+                        var rValueRound = Math.round(100 * rValue) / 100;
+                        this.value.r = rValueRound;
+                        var gValue = (parseInt((hexLineString.slice(3, 5)), 16)) * (1 / 255);
+                        var gValueRound = Math.round(100 * gValue) / 100;
+                        this.value.g = gValueRound;
+                        var bValue = (parseInt((hexLineString.slice(5, 7)), 16)) * (1 / 255);
+                        var bValueRound = Math.round(100 * bValue) / 100;
+                        this.value.b = bValueRound;
+                        if (this._children[2].name == "a") {
+                            var aValue = (parseInt((hexLineString.slice(7, 9)), 16)) * (1 / 255);
+                            var aValueRound = Math.round(100 * aValue) / 100;
+                            this.value.a = aValueRound;
+                        }
+                    }
+                }
+                else if (this._property.type == "Color3" || this._property.type == "Color4") {
+                    if (this._property.value.hex != undefined && this._property.value.hex != null) {
+                        var hexLineInfos = [];
+                        var valHexR = ((this._property.value.r * 255) | 0).toString(16);
+                        hexLineInfos.push(valHexR);
+                        if (valHexR == "0") {
+                            hexLineInfos.push("0");
+                        }
+                        var valHexG = ((this._property.value.g * 255) | 0).toString(16);
+                        hexLineInfos.push(valHexG);
+                        if (valHexG == "0") {
+                            hexLineInfos.push("0");
+                        }
+                        var valHexB = ((this._property.value.b * 255) | 0).toString(16);
+                        hexLineInfos.push(valHexB);
+                        if (valHexB == "0") {
+                            hexLineInfos.push("0");
+                        }
+                        if (this._property.value.a != undefined) {
+                            var valHexA = ((this._property.value.a * 255) | 0).toString(16);
+                            hexLineInfos.push(valHexA);
+                            if (valHexA == "0") {
+                                hexLineInfos.push("0");
+                            }
+                        }
+                        hexLineInfos.unshift("#");
+                        var hexLineString = hexLineInfos.join("");
+                        this._property.value.hex = hexLineString;
+                        hexLineInfos.length = 0;
+                    }
+                }
             }
             for (var _i = 0, _a = this._elements; _i < _a.length; _i++) {
                 var elem = _a[_i];
@@ -1714,11 +1812,35 @@ var INSPECTOR;
                         var child = new PropertyLine(infos, this, this._level + PropertyLine._MARGIN_LEFT);
                         this._children.push(child);
                     }
+                    //Add the Hexa converter
+                    if ((propToDisplay.indexOf('r') && propToDisplay.indexOf('g') && propToDisplay.indexOf('b') && propToDisplay.indexOf('a')) == 0) {
+                        var hexLineInfos = [];
+                        var hexLinePropCheck = new INSPECTOR.Property("hexEnable", this._property.value);
+                        hexLinePropCheck.value = false;
+                        var hexLineCheck = new PropertyLine(hexLinePropCheck, this, this._level + PropertyLine._MARGIN_LEFT);
+                        this._children.unshift(hexLineCheck);
+                        for (var _c = 0, propToDisplay_2 = propToDisplay; _c < propToDisplay_2.length; _c++) {
+                            var prop = propToDisplay_2[_c];
+                            var infos = new INSPECTOR.Property(prop, this._property.value);
+                            var valHex = ((infos.value * 255) | 0).toString(16);
+                            hexLineInfos.push(valHex);
+                            if (valHex == "0") {
+                                hexLineInfos.push("0");
+                            }
+                        }
+                        hexLineInfos.push("#");
+                        hexLineInfos.reverse();
+                        var hexLineString = hexLineInfos.join("");
+                        var hexLineProp = new INSPECTOR.Property("hex", this._property.value);
+                        hexLineProp.value = hexLineString;
+                        var hexLine = new PropertyLine(hexLineProp, this, this._level + PropertyLine._MARGIN_LEFT);
+                        this._children.unshift(hexLine);
+                    }
                 }
                 // otherwise display it    
                 if (this._div.parentNode) {
-                    for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
-                        var child = _d[_c];
+                    for (var _d = 0, _e = this._children; _d < _e.length; _d++) {
+                        var child = _e[_d];
                         this._div.parentNode.insertBefore(child.toHtml(), this._div.nextSibling);
                     }
                 }
@@ -2112,7 +2234,7 @@ var INSPECTOR;
         __extends(SearchBar, _super);
         function SearchBar(tab) {
             var _this = _super.call(this) || this;
-            _this._tab = tab;
+            _this._propTab = tab;
             _this._div.classList.add('searchbar');
             var filter = INSPECTOR.Inspector.DOCUMENT.createElement('i');
             filter.className = 'fa fa-search';
@@ -2123,7 +2245,7 @@ var INSPECTOR;
             _this._div.appendChild(_this._inputElement);
             _this._inputElement.addEventListener('keyup', function (evt) {
                 var filter = _this._inputElement.value;
-                _this._tab.filter(filter);
+                _this._propTab.filter(filter);
             });
             return _this;
         }
@@ -2137,6 +2259,35 @@ var INSPECTOR;
         return SearchBar;
     }(INSPECTOR.BasicElement));
     INSPECTOR.SearchBar = SearchBar;
+    var SearchBarDetails = /** @class */ (function (_super) {
+        __extends(SearchBarDetails, _super);
+        function SearchBarDetails(tab) {
+            var _this = _super.call(this) || this;
+            _this._detailTab = tab;
+            _this._div.classList.add('searchbar');
+            var filter = INSPECTOR.Inspector.DOCUMENT.createElement('i');
+            filter.className = 'fa fa-search';
+            _this._div.appendChild(filter);
+            // Create input
+            _this._inputElement = INSPECTOR.Inspector.DOCUMENT.createElement('input');
+            _this._inputElement.placeholder = 'Filter by name...';
+            _this._div.appendChild(_this._inputElement);
+            _this._inputElement.addEventListener('keyup', function (evt) {
+                var filter = _this._inputElement.value;
+                _this._detailTab.searchByName(filter);
+            });
+            return _this;
+        }
+        /** Delete all characters typped in the input element */
+        SearchBarDetails.prototype.reset = function () {
+            this._inputElement.value = '';
+        };
+        SearchBarDetails.prototype.update = function () {
+            // Nothing to update
+        };
+        return SearchBarDetails;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.SearchBarDetails = SearchBarDetails;
 })(INSPECTOR || (INSPECTOR = {}));
 
 var __extends = (this && this.__extends) || (function () {

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


+ 1 - 1
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "3.2.0-alphaA"
+        "babylonjs-gltf2interface": "3.2.0-alphaB"
     },
     "peerDependencies": {
         "babylonjs": ">=3.2.0-alpha"

+ 1 - 0
dist/preview release/materialsLibrary/babylon.customMaterial.d.ts

@@ -73,6 +73,7 @@ declare module BABYLON {
         SAMPLER3DBGRMAP: boolean;
         IMAGEPROCESSINGPOSTPROCESS: boolean;
         EXPOSURE: boolean;
+        GRAIN: boolean;
         constructor();
         setReflectionMode(modeToEnable: string): void;
     }

+ 1 - 0
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -94,6 +94,7 @@ var BABYLON;
             _this.SAMPLER3DBGRMAP = false;
             _this.IMAGEPROCESSINGPOSTPROCESS = false;
             _this.EXPOSURE = false;
+            _this.GRAIN = false;
             _this.rebuild();
             return _this;
         }

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


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -4101,6 +4101,7 @@ var BABYLON;
             _this.SAMPLER3DBGRMAP = false;
             _this.IMAGEPROCESSINGPOSTPROCESS = false;
             _this.EXPOSURE = false;
+            _this.GRAIN = false;
             _this.rebuild();
             return _this;
         }

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


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -579,6 +579,7 @@ declare module BABYLON {
         SAMPLER3DBGRMAP: boolean;
         IMAGEPROCESSINGPOSTPROCESS: boolean;
         EXPOSURE: boolean;
+        GRAIN: boolean;
         constructor();
         setReflectionMode(modeToEnable: string): void;
     }

+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 42 - 0
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -295,6 +295,7 @@ declare module BABYLON.GLTF2 {
          * Allows the maximum specular power to be defined for material calculations.
          */
         private static maxSpecularPower;
+        private static epsilon;
         /**
          * Gets the materials from a Babylon scene and converts them to glTF materials.
          * @param scene
@@ -312,6 +313,18 @@ declare module BABYLON.GLTF2 {
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * Makes a copy of the glTF material without the texture parameters.
+         * @param originalMaterial - original glTF material.
+         * @returns glTF material without texture parameters
+         */
+        static StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        /**
+         * Specifies if the material has any texture parameters present.
+         * @param material - glTF Material.
+         * @returns boolean specifying if texture parameters are present
+         */
+        static HasTexturesPresent(material: IMaterial): boolean;
+        /**
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
@@ -364,6 +377,35 @@ declare module BABYLON.GLTF2 {
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+         * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param color - Color source to calculate brightness from.
+         * @returns number representing the perceived brightness, or zero if color is undefined.
+         */
+        static GetPerceivedBrightness(color: Color3): number;
+        /**
+         * Returns the maximum color component value.
+         * @param color
+         * @returns maximum color component value, or zero if color is null or undefined.
+         */
+        static GetMaxComponent(color: Color3): number;
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
          * Extracts a texture from a Babylon texture into file data and glTF data.
          * @param babylonTexture - Babylon texture to extract.
          * @param mimeType - Mime Type of the babylonTexture.

+ 259 - 31
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -80,7 +80,7 @@ var BABYLON;
                 this.materials = new Array();
                 this.textures = new Array();
                 this.imageData = {};
-                this.convertToRightHandedSystem = !this.babylonScene.useRightHandedSystem;
+                this.convertToRightHandedSystem = this.babylonScene.useRightHandedSystem ? false : true;
                 if (options) {
                     this.options = options;
                 }
@@ -411,10 +411,10 @@ var BABYLON;
              * @param babylonMesh - Babylon mesh used as the source for the transformation data.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh) {
-                if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
+                if (!babylonMesh.position.equalsToFloats(0, 0, 0)) {
                     node.translation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(babylonMesh.position).asArray() : babylonMesh.position.asArray();
                 }
-                if (!(babylonMesh.scaling.x === 1 && babylonMesh.scaling.y === 1 && babylonMesh.scaling.z === 1)) {
+                if (!babylonMesh.scaling.equalsToFloats(1, 1, 1)) {
                     node.scale = babylonMesh.scaling.asArray();
                 }
                 var rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(babylonMesh.rotation.y, babylonMesh.rotation.x, babylonMesh.rotation.z);
@@ -527,6 +527,7 @@ var BABYLON;
                         }
                     }
                     if (babylonMesh.subMeshes) {
+                        var uvCoordsPresent = false;
                         // go through all mesh primitives (submeshes)
                         for (var _a = 0, _b = babylonMesh.subMeshes; _a < _b.length; _a++) {
                             var submesh = _b[_a];
@@ -573,10 +574,12 @@ var BABYLON;
                                                         }
                                                         case BABYLON.VertexBuffer.UVKind: {
                                                             meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                            uvCoordsPresent = true;
                                                             break;
                                                         }
                                                         case BABYLON.VertexBuffer.UV2Kind: {
                                                             meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                            uvCoordsPresent = true;
                                                             break;
                                                         }
                                                         default: {
@@ -596,21 +599,31 @@ var BABYLON;
                                 }
                             }
                             if (bufferMesh.material) {
-                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                                    var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
-                                    meshPrimitive.material = materialIndex;
+                                var materialIndex = null;
+                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial || bufferMesh.material instanceof BABYLON.PBRMaterial) {
+                                    materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
                                 }
                                 else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
                                     var babylonMultiMaterial = bufferMesh.material;
                                     var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
                                     if (material) {
-                                        var materialIndex = babylonMesh.getScene().materials.indexOf(material);
-                                        meshPrimitive.material = materialIndex;
+                                        materialIndex = babylonMesh.getScene().materials.indexOf(material);
                                     }
                                 }
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                 }
+                                if (materialIndex != null) {
+                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial.HasTexturesPresent(this.materials[materialIndex])) {
+                                        meshPrimitive.material = materialIndex;
+                                    }
+                                    else {
+                                        // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
+                                        var newMat = GLTF2._GLTFMaterial.StripTexturesFromMaterial(this.materials[materialIndex]);
+                                        this.materials.push(newMat);
+                                        meshPrimitive.material = this.materials.length - 1;
+                                    }
+                                }
                             }
                             mesh.primitives.push(meshPrimitive);
                         }
@@ -636,30 +649,30 @@ var BABYLON;
                     this.binaryBuffer = new ArrayBuffer(this.totalByteLength);
                     var dataBuffer = new DataView(this.binaryBuffer);
                     for (var i = 0; i < babylonMeshes.length; ++i) {
-                        if (this.options &&
-                            this.options.shouldExportMesh != undefined &&
-                            !this.options.shouldExportMesh(babylonMeshes[i])) {
-                            continue;
-                        }
-                        else {
-                            var babylonMesh = babylonMeshes[i];
-                            // Build Hierarchy with the node map.
-                            var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
-                            var glTFNode = this.nodes[glTFNodeIndex];
-                            if (!babylonMesh.parent) {
+                        var babylonMesh = babylonMeshes[i];
+                        // Build Hierarchy with the node map.
+                        var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
+                        var glTFNode = this.nodes[glTFNodeIndex];
+                        if (!babylonMesh.parent) {
+                            if (this.options &&
+                                this.options.shouldExportMesh != undefined &&
+                                !this.options.shouldExportMesh(babylonMesh)) {
+                                BABYLON.Tools.Log("Omitting " + babylonMesh.name + " from scene.");
+                            }
+                            else {
                                 scene.nodes.push(glTFNodeIndex);
                             }
-                            var directDescendents = babylonMesh.getDescendants(true);
-                            if (!glTFNode.children && directDescendents && directDescendents.length) {
-                                glTFNode.children = [];
-                                for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
-                                    var descendent = directDescendents_1[_i];
-                                    glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
-                                }
+                        }
+                        var directDescendents = babylonMesh.getDescendants(true);
+                        if (!glTFNode.children && directDescendents && directDescendents.length) {
+                            glTFNode.children = [];
+                            for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
+                                var descendent = directDescendents_1[_i];
+                                glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
                             }
-                            var mesh = { primitives: new Array() };
-                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                         }
+                        var mesh = { primitives: new Array() };
+                        byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                     }
                     this.scenes.push(scene);
                 }
@@ -804,7 +817,53 @@ var BABYLON;
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
                         _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
+                    else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
+                        _GLTFMaterial.ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                    }
+                    else {
+                        BABYLON.Tools.Error("Unsupported material type: " + babylonMaterial.name);
+                    }
+                }
+            };
+            /**
+             * Makes a copy of the glTF material without the texture parameters.
+             * @param originalMaterial - original glTF material.
+             * @returns glTF material without texture parameters
+             */
+            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+                var newMaterial = {};
+                if (originalMaterial) {
+                    newMaterial.name = originalMaterial.name;
+                    newMaterial.doubleSided = originalMaterial.doubleSided;
+                    newMaterial.alphaMode = originalMaterial.alphaMode;
+                    newMaterial.alphaCutoff = originalMaterial.alphaCutoff;
+                    newMaterial.emissiveFactor = originalMaterial.emissiveFactor;
+                    var originalPBRMetallicRoughness = originalMaterial.pbrMetallicRoughness;
+                    if (originalPBRMetallicRoughness) {
+                        newMaterial.pbrMetallicRoughness = {};
+                        newMaterial.pbrMetallicRoughness.baseColorFactor = originalPBRMetallicRoughness.baseColorFactor;
+                        newMaterial.pbrMetallicRoughness.metallicFactor = originalPBRMetallicRoughness.metallicFactor;
+                        newMaterial.pbrMetallicRoughness.roughnessFactor = originalPBRMetallicRoughness.roughnessFactor;
+                    }
+                }
+                return newMaterial;
+            };
+            /**
+             * Specifies if the material has any texture parameters present.
+             * @param material - glTF Material.
+             * @returns boolean specifying if texture parameters are present
+             */
+            _GLTFMaterial.HasTexturesPresent = function (material) {
+                if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
+                    return true;
+                }
+                var pbrMat = material.pbrMetallicRoughness;
+                if (pbrMat) {
+                    if (pbrMat.baseColorTexture || pbrMat.metallicRoughnessTexture) {
+                        return true;
+                    }
                 }
+                return false;
             };
             /**
              * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
@@ -914,6 +973,27 @@ var BABYLON;
                         }
                     }
                 }
+                else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
+                    var babylonPBRMaterial = babylonMaterial;
+                    switch (babylonPBRMaterial.transparencyMode) {
+                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
+                            return "OPAQUE" /* OPAQUE */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
+                            return "BLEND" /* BLEND */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
+                            return "MASK" /* MASK */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
+                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
+                            return "BLEND" /* BLEND */;
+                        }
+                        default: {
+                            throw new Error("Unsupported alpha mode " + babylonPBRMaterial.transparencyMode);
+                        }
+                    }
+                }
                 else {
                     throw new Error("Unsupported Babylon material type");
                 }
@@ -959,9 +1039,13 @@ var BABYLON;
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     if (babylonStandardMaterial.ambientTexture) {
-                        var glTFOcclusionTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
-                        if (glTFOcclusionTexture) {
-                            glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            var occlusionTexture = {
+                                index: glTFTexture.index
+                            };
+                            glTFMaterial.occlusionTexture = occlusionTexture;
+                            occlusionTexture.strength = 1.0;
                         }
                     }
                 }
@@ -1056,6 +1140,149 @@ var BABYLON;
                 materials.push(glTFMaterial);
             };
             /**
+             * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+             * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+             * @param color - Color source to calculate brightness from.
+             * @returns number representing the perceived brightness, or zero if color is undefined.
+             */
+            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+                if (color) {
+                    return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
+                }
+                return 0;
+            };
+            /**
+             * Returns the maximum color component value.
+             * @param color
+             * @returns maximum color component value, or zero if color is null or undefined.
+             */
+            _GLTFMaterial.GetMaxComponent = function (color) {
+                if (color) {
+                    return Math.max(color.r, Math.max(color.g, color.b));
+                }
+                return 0;
+            };
+            /**
+             * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+             * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+             * @param mimeType - mime type to use for the textures.
+             * @param images - array of glTF image interfaces.
+             * @param textures - array of glTF texture interfaces.
+             * @param materials - array of glTF material interfaces.
+             * @param imageData - map of image file name to data.
+             * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+             */
+            _GLTFMaterial.ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+                var glTFPbrMetallicRoughness = {};
+                var glTFMaterial = {
+                    name: babylonPBRMaterial.name
+                };
+                var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
+                if (babylonPBRMaterial) {
+                    if (useMetallicRoughness) {
+                        glTFPbrMetallicRoughness.baseColorFactor = [
+                            babylonPBRMaterial.albedoColor.r,
+                            babylonPBRMaterial.albedoColor.g,
+                            babylonPBRMaterial.albedoColor.b,
+                            babylonPBRMaterial.alpha
+                        ];
+                        if (babylonPBRMaterial.metallic != null) {
+                            if (babylonPBRMaterial.metallic !== 1) {
+                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            }
+                        }
+                        if (babylonPBRMaterial.roughness != null) {
+                            if (babylonPBRMaterial.roughness !== 1) {
+                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            }
+                        }
+                    }
+                    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 (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 (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.emissiveTexture) {
+                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                            if (glTFTexture != null) {
+                                glTFMaterial.emissiveTexture = glTFTexture;
+                            }
+                        }
+                        if (babylonPBRMaterial.metallicTexture) {
+                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
+                            if (glTFTexture != null) {
+                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
+                            }
+                        }
+                    }
+                    if (!babylonPBRMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
+                        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;
+                            }
+                        }
+                    }
+                }
+                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                materials.push(glTFMaterial);
+            };
+            /**
              * Extracts a texture from a Babylon texture into file data and glTF data.
              * @param babylonTexture - Babylon texture to extract.
              * @param mimeType - Mime Type of the babylonTexture.
@@ -1143,6 +1370,7 @@ var BABYLON;
              * Allows the maximum specular power to be defined for material calculations.
              */
             _GLTFMaterial.maxSpecularPower = 1024;
+            _GLTFMaterial.epsilon = 1e-6;
             return _GLTFMaterial;
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;

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


+ 259 - 31
dist/preview release/serializers/babylonjs.serializers.js

@@ -234,7 +234,7 @@ var BABYLON;
                 this.materials = new Array();
                 this.textures = new Array();
                 this.imageData = {};
-                this.convertToRightHandedSystem = !this.babylonScene.useRightHandedSystem;
+                this.convertToRightHandedSystem = this.babylonScene.useRightHandedSystem ? false : true;
                 if (options) {
                     this.options = options;
                 }
@@ -565,10 +565,10 @@ var BABYLON;
              * @param babylonMesh - Babylon mesh used as the source for the transformation data.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh) {
-                if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
+                if (!babylonMesh.position.equalsToFloats(0, 0, 0)) {
                     node.translation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(babylonMesh.position).asArray() : babylonMesh.position.asArray();
                 }
-                if (!(babylonMesh.scaling.x === 1 && babylonMesh.scaling.y === 1 && babylonMesh.scaling.z === 1)) {
+                if (!babylonMesh.scaling.equalsToFloats(1, 1, 1)) {
                     node.scale = babylonMesh.scaling.asArray();
                 }
                 var rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(babylonMesh.rotation.y, babylonMesh.rotation.x, babylonMesh.rotation.z);
@@ -681,6 +681,7 @@ var BABYLON;
                         }
                     }
                     if (babylonMesh.subMeshes) {
+                        var uvCoordsPresent = false;
                         // go through all mesh primitives (submeshes)
                         for (var _a = 0, _b = babylonMesh.subMeshes; _a < _b.length; _a++) {
                             var submesh = _b[_a];
@@ -727,10 +728,12 @@ var BABYLON;
                                                         }
                                                         case BABYLON.VertexBuffer.UVKind: {
                                                             meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                            uvCoordsPresent = true;
                                                             break;
                                                         }
                                                         case BABYLON.VertexBuffer.UV2Kind: {
                                                             meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                            uvCoordsPresent = true;
                                                             break;
                                                         }
                                                         default: {
@@ -750,21 +753,31 @@ var BABYLON;
                                 }
                             }
                             if (bufferMesh.material) {
-                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                                    var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
-                                    meshPrimitive.material = materialIndex;
+                                var materialIndex = null;
+                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial || bufferMesh.material instanceof BABYLON.PBRMaterial) {
+                                    materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
                                 }
                                 else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
                                     var babylonMultiMaterial = bufferMesh.material;
                                     var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
                                     if (material) {
-                                        var materialIndex = babylonMesh.getScene().materials.indexOf(material);
-                                        meshPrimitive.material = materialIndex;
+                                        materialIndex = babylonMesh.getScene().materials.indexOf(material);
                                     }
                                 }
                                 else {
                                     BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
                                 }
+                                if (materialIndex != null) {
+                                    if (uvCoordsPresent || !GLTF2._GLTFMaterial.HasTexturesPresent(this.materials[materialIndex])) {
+                                        meshPrimitive.material = materialIndex;
+                                    }
+                                    else {
+                                        // If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
+                                        var newMat = GLTF2._GLTFMaterial.StripTexturesFromMaterial(this.materials[materialIndex]);
+                                        this.materials.push(newMat);
+                                        meshPrimitive.material = this.materials.length - 1;
+                                    }
+                                }
                             }
                             mesh.primitives.push(meshPrimitive);
                         }
@@ -790,30 +803,30 @@ var BABYLON;
                     this.binaryBuffer = new ArrayBuffer(this.totalByteLength);
                     var dataBuffer = new DataView(this.binaryBuffer);
                     for (var i = 0; i < babylonMeshes.length; ++i) {
-                        if (this.options &&
-                            this.options.shouldExportMesh != undefined &&
-                            !this.options.shouldExportMesh(babylonMeshes[i])) {
-                            continue;
-                        }
-                        else {
-                            var babylonMesh = babylonMeshes[i];
-                            // Build Hierarchy with the node map.
-                            var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
-                            var glTFNode = this.nodes[glTFNodeIndex];
-                            if (!babylonMesh.parent) {
+                        var babylonMesh = babylonMeshes[i];
+                        // Build Hierarchy with the node map.
+                        var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
+                        var glTFNode = this.nodes[glTFNodeIndex];
+                        if (!babylonMesh.parent) {
+                            if (this.options &&
+                                this.options.shouldExportMesh != undefined &&
+                                !this.options.shouldExportMesh(babylonMesh)) {
+                                BABYLON.Tools.Log("Omitting " + babylonMesh.name + " from scene.");
+                            }
+                            else {
                                 scene.nodes.push(glTFNodeIndex);
                             }
-                            var directDescendents = babylonMesh.getDescendants(true);
-                            if (!glTFNode.children && directDescendents && directDescendents.length) {
-                                glTFNode.children = [];
-                                for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
-                                    var descendent = directDescendents_1[_i];
-                                    glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
-                                }
+                        }
+                        var directDescendents = babylonMesh.getDescendants(true);
+                        if (!glTFNode.children && directDescendents && directDescendents.length) {
+                            glTFNode.children = [];
+                            for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
+                                var descendent = directDescendents_1[_i];
+                                glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
                             }
-                            var mesh = { primitives: new Array() };
-                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                         }
+                        var mesh = { primitives: new Array() };
+                        byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                     }
                     this.scenes.push(scene);
                 }
@@ -958,7 +971,53 @@ var BABYLON;
                     else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
                         _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
                     }
+                    else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
+                        _GLTFMaterial.ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
+                    }
+                    else {
+                        BABYLON.Tools.Error("Unsupported material type: " + babylonMaterial.name);
+                    }
+                }
+            };
+            /**
+             * Makes a copy of the glTF material without the texture parameters.
+             * @param originalMaterial - original glTF material.
+             * @returns glTF material without texture parameters
+             */
+            _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
+                var newMaterial = {};
+                if (originalMaterial) {
+                    newMaterial.name = originalMaterial.name;
+                    newMaterial.doubleSided = originalMaterial.doubleSided;
+                    newMaterial.alphaMode = originalMaterial.alphaMode;
+                    newMaterial.alphaCutoff = originalMaterial.alphaCutoff;
+                    newMaterial.emissiveFactor = originalMaterial.emissiveFactor;
+                    var originalPBRMetallicRoughness = originalMaterial.pbrMetallicRoughness;
+                    if (originalPBRMetallicRoughness) {
+                        newMaterial.pbrMetallicRoughness = {};
+                        newMaterial.pbrMetallicRoughness.baseColorFactor = originalPBRMetallicRoughness.baseColorFactor;
+                        newMaterial.pbrMetallicRoughness.metallicFactor = originalPBRMetallicRoughness.metallicFactor;
+                        newMaterial.pbrMetallicRoughness.roughnessFactor = originalPBRMetallicRoughness.roughnessFactor;
+                    }
+                }
+                return newMaterial;
+            };
+            /**
+             * Specifies if the material has any texture parameters present.
+             * @param material - glTF Material.
+             * @returns boolean specifying if texture parameters are present
+             */
+            _GLTFMaterial.HasTexturesPresent = function (material) {
+                if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
+                    return true;
+                }
+                var pbrMat = material.pbrMetallicRoughness;
+                if (pbrMat) {
+                    if (pbrMat.baseColorTexture || pbrMat.metallicRoughnessTexture) {
+                        return true;
+                    }
                 }
+                return false;
             };
             /**
              * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
@@ -1068,6 +1127,27 @@ var BABYLON;
                         }
                     }
                 }
+                else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
+                    var babylonPBRMaterial = babylonMaterial;
+                    switch (babylonPBRMaterial.transparencyMode) {
+                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
+                            return "OPAQUE" /* OPAQUE */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
+                            return "BLEND" /* BLEND */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
+                            return "MASK" /* MASK */;
+                        }
+                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
+                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
+                            return "BLEND" /* BLEND */;
+                        }
+                        default: {
+                            throw new Error("Unsupported alpha mode " + babylonPBRMaterial.transparencyMode);
+                        }
+                    }
+                }
                 else {
                     throw new Error("Unsupported Babylon material type");
                 }
@@ -1113,9 +1193,13 @@ var BABYLON;
                         glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
                     }
                     if (babylonStandardMaterial.ambientTexture) {
-                        var glTFOcclusionTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
-                        if (glTFOcclusionTexture) {
-                            glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                        var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
+                        if (glTFTexture) {
+                            var occlusionTexture = {
+                                index: glTFTexture.index
+                            };
+                            glTFMaterial.occlusionTexture = occlusionTexture;
+                            occlusionTexture.strength = 1.0;
                         }
                     }
                 }
@@ -1210,6 +1294,149 @@ var BABYLON;
                 materials.push(glTFMaterial);
             };
             /**
+             * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+             * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+             * @param color - Color source to calculate brightness from.
+             * @returns number representing the perceived brightness, or zero if color is undefined.
+             */
+            _GLTFMaterial.GetPerceivedBrightness = function (color) {
+                if (color) {
+                    return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
+                }
+                return 0;
+            };
+            /**
+             * Returns the maximum color component value.
+             * @param color
+             * @returns maximum color component value, or zero if color is null or undefined.
+             */
+            _GLTFMaterial.GetMaxComponent = function (color) {
+                if (color) {
+                    return Math.max(color.r, Math.max(color.g, color.b));
+                }
+                return 0;
+            };
+            /**
+             * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+             * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+             * @param mimeType - mime type to use for the textures.
+             * @param images - array of glTF image interfaces.
+             * @param textures - array of glTF texture interfaces.
+             * @param materials - array of glTF material interfaces.
+             * @param imageData - map of image file name to data.
+             * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+             */
+            _GLTFMaterial.ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
+                var glTFPbrMetallicRoughness = {};
+                var glTFMaterial = {
+                    name: babylonPBRMaterial.name
+                };
+                var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
+                if (babylonPBRMaterial) {
+                    if (useMetallicRoughness) {
+                        glTFPbrMetallicRoughness.baseColorFactor = [
+                            babylonPBRMaterial.albedoColor.r,
+                            babylonPBRMaterial.albedoColor.g,
+                            babylonPBRMaterial.albedoColor.b,
+                            babylonPBRMaterial.alpha
+                        ];
+                        if (babylonPBRMaterial.metallic != null) {
+                            if (babylonPBRMaterial.metallic !== 1) {
+                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            }
+                        }
+                        if (babylonPBRMaterial.roughness != null) {
+                            if (babylonPBRMaterial.roughness !== 1) {
+                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            }
+                        }
+                    }
+                    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 (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 (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.emissiveTexture) {
+                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
+                            if (glTFTexture != null) {
+                                glTFMaterial.emissiveTexture = glTFTexture;
+                            }
+                        }
+                        if (babylonPBRMaterial.metallicTexture) {
+                            var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
+                            if (glTFTexture != null) {
+                                glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
+                            }
+                        }
+                    }
+                    if (!babylonPBRMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
+                        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;
+                            }
+                        }
+                    }
+                }
+                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                materials.push(glTFMaterial);
+            };
+            /**
              * Extracts a texture from a Babylon texture into file data and glTF data.
              * @param babylonTexture - Babylon texture to extract.
              * @param mimeType - Mime Type of the babylonTexture.
@@ -1297,6 +1524,7 @@ var BABYLON;
              * Allows the maximum specular power to be defined for material calculations.
              */
             _GLTFMaterial.maxSpecularPower = 1024;
+            _GLTFMaterial.epsilon = 1e-6;
             return _GLTFMaterial;
         }());
         GLTF2._GLTFMaterial = _GLTFMaterial;

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


+ 42 - 0
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -310,6 +310,7 @@ declare module BABYLON.GLTF2 {
          * Allows the maximum specular power to be defined for material calculations.
          */
         private static maxSpecularPower;
+        private static epsilon;
         /**
          * Gets the materials from a Babylon scene and converts them to glTF materials.
          * @param scene
@@ -327,6 +328,18 @@ declare module BABYLON.GLTF2 {
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * Makes a copy of the glTF material without the texture parameters.
+         * @param originalMaterial - original glTF material.
+         * @returns glTF material without texture parameters
+         */
+        static StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        /**
+         * Specifies if the material has any texture parameters present.
+         * @param material - glTF Material.
+         * @returns boolean specifying if texture parameters are present
+         */
+        static HasTexturesPresent(material: IMaterial): boolean;
+        /**
          * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
          * @param babylonStandardMaterial
          * @returns - glTF Metallic Roughness Material representation
@@ -379,6 +392,35 @@ declare module BABYLON.GLTF2 {
             };
         }, hasTextureCoords: boolean): void;
         /**
+         * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+         * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param color - Color source to calculate brightness from.
+         * @returns number representing the perceived brightness, or zero if color is undefined.
+         */
+        static GetPerceivedBrightness(color: Color3): number;
+        /**
+         * Returns the maximum color component value.
+         * @param color
+         * @returns maximum color component value, or zero if color is null or undefined.
+         */
+        static GetMaxComponent(color: Color3): number;
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
          * Extracts a texture from a Babylon texture into file data and glTF data.
          * @param babylonTexture - Babylon texture to extract.
          * @param mimeType - Mime Type of the babylonTexture.

+ 2 - 2
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "3.2.0-alphaA"
+        "babylonjs-gltf2interface": "3.2.0-alphaB"
     },
     "peerDependencies": {
         "babylonjs": ">=3.2.0-alpha"

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

@@ -1,7 +1,7 @@
 {
-  "errors": 7219,
+  "errors": 7220,
   "babylon.typedoc.json": {
-    "errors": 7219,
+    "errors": 7220,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {

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


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


+ 1 - 1
dist/preview release/viewer/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-viewer",
     "description": "A simple-to-use viewer based on BabylonJS to display 3D elements natively",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -14,7 +14,7 @@
 - Added [VideoDome](http://doc.babylonjs.com/how_to/360videodome) class to easily support 360 videos ([DavidHGillen](https://github.com/DavidHGillen))
 - Added [GlowLayer](https://doc.babylonjs.com/how_to/glow_layer) to easily support glow from emissive materials ([sebavan](https://github.com/sebavan))
 - New [AssetContainer](http://doc.babylonjs.com/how_to/how_to_use_assetcontainer) Class and loading methods ([trevordev](https://github.com/trevordev))
-- Added depth of field, MSAA, sharpening and chromatic aberration effect to the default pipeline ([trevordev](https://github.com/trevordev))
+- Added depth of field, MSAA, sharpening, grain and chromatic aberration effect to the default pipeline ([trevordev](https://github.com/trevordev))
 
 ## Updates
 
@@ -99,7 +99,8 @@
 - AMD "define" declaration is no longer anonymous ([RaananW](https://github.com/RaananW))
 - Collision worker didn't initialize instanced meshes correctly - [#3819](https://github.com/BabylonJS/Babylon.js/issues/3819) ([RaananW](https://github.com/RaananW))
 - postMessage calls in webworkers were fixed. ([RaananW](https://github.com/RaananW))
-- fixed WebCam Texture on Firefox and Edge - [#3825](https://github.com/BabylonJS/Babylon.js/issues/3825) ([sebavan](https://github.com/sebavan))
+- Fixed WebCam Texture on Firefox and Edge - [#3825](https://github.com/BabylonJS/Babylon.js/issues/3825) ([sebavan](https://github.com/sebavan))
+- Add onLoadObservable on VideoTexture - [#3845](https://github.com/BabylonJS/Babylon.js/issues/3845) ([sebavan](https://github.com/sebavan))
 
 ## Breaking changes
 

+ 1 - 0
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -77,6 +77,7 @@ module BABYLON {
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
         public EXPOSURE = false;
+        public GRAIN = false;
 
         constructor() {
             super();

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.2.0-alphaA",
+    "version": "3.2.0-alphaB",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
src/Engine/babylon.engine.ts

@@ -588,7 +588,7 @@
         }
 
         public static get Version(): string {
-            return "3.2.0-alphaA";
+            return "3.2.0-alphaB";
         }
 
         // Updatable statics so stick with vars here

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

@@ -64,8 +64,6 @@
          */
         public NOISE = false;
 
-
-
         /**
          * is the reflection texture in BGR color scheme? 
          * Mainly used to solve a bug in ios10 video tag
@@ -85,6 +83,7 @@
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
         public EXPOSURE = false;
+        public GRAIN = false;
 
         // Reflection.
         public REFLECTION = false;

+ 1 - 0
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -119,6 +119,7 @@
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
         public EXPOSURE = false;
+        public GRAIN = false;
 
         public USEPHYSICALLIGHTFALLOFF = false;
         public TWOSIDEDLIGHTING = false;

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

@@ -93,7 +93,7 @@
         protected _format: Nullable<number>;
         private _delayedOnLoad: Nullable<() => void>;
         private _delayedOnError: Nullable<() => void>;
-        private _onLoadObservable: Nullable<Observable<Texture>>;
+        protected _onLoadObservable: Nullable<Observable<Texture>>;
 
         protected _isBlocking: boolean = true;
         public set isBlocking(value: boolean) {

+ 4 - 0
src/Materials/Textures/babylon.videoTexture.ts

@@ -142,6 +142,10 @@
 
             this._texture.isReady = true;
             this._updateInternalTexture();
+
+            if (this._onLoadObservable && this._onLoadObservable.hasObservers()) {
+                this.onLoadObservable.notifyObservers(this);
+            }
         };
 
         private reset = (): void => {

+ 65 - 1
src/Materials/babylon.imageProcessingConfiguration.ts

@@ -2,6 +2,7 @@ module BABYLON {
     /**
      * Interface to follow in your material defines to integrate easily the
      * Image proccessing functions.
+     * @ignore
      */
     export interface IImageProcessingConfigurationDefines {
         IMAGEPROCESSING: boolean;
@@ -17,6 +18,10 @@ module BABYLON {
         SAMPLER3DGREENDEPTH: boolean;
         SAMPLER3DBGRMAP: boolean;
         IMAGEPROCESSINGPOSTPROCESS: boolean;
+        /** 
+         * If the grain should be performed in the image processing shader.
+         */
+        GRAIN: boolean;
     }
 
     /**
@@ -216,6 +221,57 @@ module BABYLON {
         public vignetteCameraFov = 0.5;
 
         @serialize()
+        private _grainEnabled = false;
+
+        /**
+         * If the grain effect should be enabled.
+         */
+        public get grainEnabled(): boolean {
+            return this._grainEnabled;
+        }
+        public set grainEnabled(value: boolean) {
+            if (this._grainEnabled === value) {
+                return;
+            }
+
+            this._grainEnabled = value;
+            this._updateParameters();
+        }
+
+        @serialize()
+        private _grainIntensity = 30;
+        /**
+         * Amount of grain to be applied by the grain effect.
+         */
+        public get grainIntensity(): number {
+            return this._grainIntensity;
+        }
+        public set grainIntensity(value: number) {
+            if (this._grainIntensity === value) {
+                return;
+            }
+            this._grainIntensity = value;
+        }
+
+        @serialize()
+        private _grainAnimated = false;
+
+        /**
+         * If the grain effect should be animated.
+         */
+        public get grainAnimated(): boolean {
+            return this._grainAnimated;
+        }
+        public set grainAnimated(value: boolean) {
+            if (this._grainAnimated === value) {
+                return;
+            }
+
+            this._grainAnimated = value;
+            this._updateParameters();
+        }
+
+        @serialize()
         private _vignetteBlendMode = ImageProcessingConfiguration.VIGNETTEMODE_MULTIPLY;
         /**
          * Gets the vignette blend mode allowing different kind of effect.
@@ -335,6 +391,10 @@ module BABYLON {
             if (defines.COLORCURVES) {
                 ColorCurves.PrepareUniforms(uniforms);
             }
+            if (defines.GRAIN){
+                uniforms.push("grainVarianceAmount");
+                uniforms.push("grainAnimatedSeed");
+            }
         }
 
         /**
@@ -382,7 +442,8 @@ module BABYLON {
             defines.SAMPLER3DGREENDEPTH = this.colorGradingWithGreenDepth;
             defines.SAMPLER3DBGRMAP = this.colorGradingBGR;
             defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;
-            defines.IMAGEPROCESSING = defines.VIGNETTE || defines.TONEMAPPING || defines.CONTRAST || defines.EXPOSURE || defines.COLORCURVES || defines.COLORGRADING;
+            defines.GRAIN = this.grainEnabled;
+            defines.IMAGEPROCESSING = defines.VIGNETTE || defines.TONEMAPPING || defines.CONTRAST || defines.EXPOSURE || defines.COLORCURVES || defines.COLORGRADING || defines.GRAIN;
         }
 
         /**
@@ -440,6 +501,9 @@ module BABYLON {
                     this.colorGradingTexture.level // weight
                 );
             }
+
+            effect.setFloat("grainVarianceAmount", this.grainIntensity);
+            effect.setFloat("grainAnimatedSeed", this.grainAnimated ? Math.random() + 1 : 1);
         }
 
         /**

+ 1 - 0
src/Materials/babylon.standardMaterial.ts

@@ -88,6 +88,7 @@ module BABYLON {
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
         public EXPOSURE = false;
+        public GRAIN = false;
 
         constructor() {
             super();

+ 6 - 5
src/Mesh/Compression/babylon.dracoCompression.ts

@@ -1,5 +1,3 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts" />
-
 declare var DracoDecoderModule: any;
 
 module BABYLON {
@@ -19,9 +17,14 @@ module BABYLON {
          * @param numWorkers The number of workers for async operations
          */
         constructor(numWorkers = (navigator.hardwareConcurrency || 4)) {
+            let workerBlobUrl = URL && URL.createObjectURL && URL.createObjectURL(new Blob([`(${DracoCompression._Worker.toString()})()`], { type: "application/javascript" }));
+            if (!workerBlobUrl || !Worker) {
+                Tools.Error("Draco Compression disabled. The current context doesn't support worker creation or URL.createObjectURL");
+                return;
+            }
             const workers = new Array<Worker>(numWorkers);
             for (let i = 0; i < workers.length; i++) {
-                const worker = new Worker(DracoCompression._WorkerBlobUrl);
+                const worker = new Worker(workerBlobUrl);
                 worker.postMessage({ id: "initDecoder", url: DracoCompression.DecoderUrl });
                 workers[i] = worker;
             }
@@ -184,8 +187,6 @@ module BABYLON {
             };
         }
 
-        private static _WorkerBlobUrl = URL.createObjectURL(new Blob([`(${DracoCompression._Worker.toString()})()`], { type: "application/javascript" }));
-
         private static _GetDefaultDecoderUrl(): Nullable<string> {
             for (let i = 0; i < document.scripts.length; i++) {
                 if (document.scripts[i].type === "text/x-draco-decoder") {

+ 1 - 0
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -310,6 +310,7 @@
             SAMPLER3DBGRMAP: false,
             IMAGEPROCESSINGPOSTPROCESS: false,
             EXPOSURE: false,
+            GRAIN: false,
         }
 
         constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, imageProcessingConfiguration?: ImageProcessingConfiguration) {

+ 4 - 4
src/Shaders/ShadersInclude/helperFunctions.fx

@@ -70,9 +70,9 @@ float getRand(vec2 seed) {
 	return fract(sin(dot(seed.xy ,vec2(12.9898,78.233))) * 43758.5453);
 }
 
-vec3 dither(vec2 seed, vec3 color) {
+float dither(vec2 seed, float varianceAmount) {
 	float rand = getRand(seed);
-	color += mix(-0.5/255.0, 0.5/255.0, rand);
-	color = max(color, 0.0);
-	return color;
+	float dither = mix(-varianceAmount/255.0, varianceAmount/255.0, rand);
+	
+	return dither;
 }

+ 5 - 0
src/Shaders/ShadersInclude/imageProcessingDeclaration.fx

@@ -25,4 +25,9 @@
 		uniform sampler2D txColorTransform;
 	#endif
 	uniform vec4 colorTransformSettings;
+#endif
+
+#ifdef GRAIN
+	uniform float grainVarianceAmount;
+	uniform float grainAnimatedSeed;
 #endif

+ 5 - 2
src/Shaders/background.fragment.fx

@@ -287,8 +287,11 @@ vec4 color = vec4(finalColor, finalAlpha);
     color.rgb *= color.a;
 #endif
 
-#ifdef NOISE
-    color.rgb = dither(vPositionW.xy, color.rgb);
+#ifndef GRAIN // Do not apply noise multiple times
+    #ifdef NOISE
+        color.rgb += dither(vPositionW.xy, 0.5);
+        color = max(color, 0.0);
+    #endif
 #endif
 
     gl_FragColor = color;

+ 12 - 0
src/Shaders/imageProcessing.fragment.fx

@@ -18,6 +18,18 @@ void main(void)
 		result.rgb = toLinearSpace(result.rgb);
 	#endif
 
+	#ifdef GRAIN
+		vec2 seed = vUV*(grainAnimatedSeed);
+		float grain = dither(seed, grainVarianceAmount);
+
+		// Add less grain when luminance is high or low
+		float lum = getLuminance(result.rgb);
+		float grainAmount = (cos(-PI + (lum*PI*2.))+1.)/2.;
+		result.rgb += grain * grainAmount;
+
+		result.rgb = max(result.rgb, 0.0);
+	#endif
+
 	result = applyImageProcessing(result);
 #else
 	// In case where the input is in linear space we at least need to put it back in gamma.