Explorar el Código

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

Temechon hace 8 años
padre
commit
29dbfcf610
Se han modificado 51 ficheros con 2810 adiciones y 2245 borrados
  1. 7 2
      .vscode/settings.json
  2. BIN
      Exporters/Blender/Blender2Babylon-5.0.zip
  3. BIN
      Exporters/Blender/Blender2Babylon-5.1.zip
  4. 1 1
      Exporters/Blender/readme.md
  5. 1 1
      Exporters/Blender/src/__init__.py
  6. 7 23
      Exporters/Blender/src/exporter_settings_panel.py
  7. 4 5
      Exporters/Blender/src/json_exporter.py
  8. 5 28
      Exporters/Blender/src/material.py
  9. 23 23
      dist/preview release/babylon.core.js
  10. 1713 1676
      dist/preview release/babylon.d.ts
  11. 36 36
      dist/preview release/babylon.js
  12. 592 257
      dist/preview release/babylon.max.js
  13. 33 33
      dist/preview release/babylon.noworker.js
  14. 9 5
      dist/preview release/loaders/babylon.glTFFileLoader.js
  15. 1 1
      dist/preview release/loaders/babylon.objFileLoader.js
  16. 1 1
      dist/preview release/loaders/babylon.stlFileLoader.js
  17. 2 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  18. 2 1
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  19. 2 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  20. 2 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  21. 2 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  22. 2 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  23. 2 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  24. 2 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  25. 2 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  26. 2 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  27. 2 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  28. 2 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js
  29. 2 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js
  30. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js
  31. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js
  32. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js
  33. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js
  34. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js
  35. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js
  36. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js
  37. 2 1
      dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js
  38. 1 1
      dist/preview release/serializers/babylon.objSerializer.js
  39. 1 1
      dist/preview release/what's new.md
  40. 1 1
      localDev/index.html
  41. 4 0
      src/Cameras/babylon.targetCamera.ts
  42. 27 9
      src/Culling/babylon.ray.ts
  43. 27 12
      src/Layer/babylon.highlightlayer.ts
  44. 3 12
      src/Materials/Textures/babylon.texture.ts
  45. 63 15
      src/Materials/babylon.pbrMaterial.ts
  46. 5 5
      src/Mesh/babylon.geometry.ts
  47. 60 27
      src/Shaders/pbr.fragment.fx
  48. 2 2
      src/Shaders/pbr.vertex.fx
  49. 59 24
      src/Tools/babylon.gamepads.ts
  50. 8 0
      src/Tools/babylon.sceneSerializer.ts
  51. 74 23
      src/babylon.engine.ts

+ 7 - 2
.vscode/settings.json

@@ -15,6 +15,9 @@
         "**/*.js.fx": true,
         "**/*.js": { 
             "when":"$(basename).ts"
+        },
+        "**/*.d.ts": { 
+            "when":"$(basename).ts"
         }
     },
     "files.associations": {
@@ -30,6 +33,8 @@
         "**/*.map": true,
         "**/*.js": { 
              "when":"$(basename).ts"
-         }       
-    }
+         },
+        "**/*.d.ts": true
+    },
+    "typescript.check.workspaceVersion": false
 }

BIN
Exporters/Blender/Blender2Babylon-5.0.zip


BIN
Exporters/Blender/Blender2Babylon-5.1.zip


+ 1 - 1
Exporters/Blender/readme.md

@@ -56,7 +56,7 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Child materials
  * 32 bit vertex limit for multi-materials
 * **Textures**
- * Name(s) - Multiples for compressed texture prioritization
+ * Name
  * Associated file
  * Level
  * Use alpha

+ 1 - 1
Exporters/Blender/src/__init__.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (5, 1, 0),
+    'version': (5, 1, 1),
     'blender': (2, 76, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',

+ 7 - 23
Exporters/Blender/src/exporter_settings_panel.py

@@ -1,9 +1,6 @@
 from .package_level import *
 
 import bpy
-LEGACY      = 'LEGACY'
-INLINE      = 'INLINE'
-PRIORITIZED = 'PRIORITIZED'
 # Panel displayed in Scene Tab of properties, so settings can be saved in a .blend file
 class ExporterSettingsPanel(bpy.types.Panel):
     bl_label = get_title()
@@ -36,21 +33,11 @@ class ExporterSettingsPanel(bpy.types.Panel):
         description='',
         default = True
         )
-    bpy.types.Scene.textureMethod = bpy.props.EnumProperty(
-        name='Method',
-        description='How are textures to be implemented',
-        items = (
-                 (LEGACY     , 'Legacy'     , 'Just the single Blender texture'),
-                 (INLINE     , 'Inline'     , 'Place a base64 version of texture directly in the output'),
-                 (PRIORITIZED, 'Prioritized', 'Allow various compressed texture formats to be tried first')
-                ),
-        default = LEGACY
+    bpy.types.Scene.inlineTextures = bpy.props.BoolProperty(
+        name='inline',
+        description='turn textures into encoded strings, for direct inclusion into source code',
+        default = False
     )
-    bpy.types.Scene.texturePriority = bpy.props.StringProperty(
-        name='Order',
-        description='Space delimited list of extensions to try\nnot including format supplied by Blender\nwhich will be last.',
-        default = '.ASTC .DDS .ETC'
-        )
     bpy.types.Scene.textureDir = bpy.props.StringProperty(
         name='Sub-directory',
         description='The path below the output directory to write texture files (any separators OS dependent)',
@@ -71,13 +58,10 @@ class ExporterSettingsPanel(bpy.types.Panel):
         layout.prop(scene, 'ignoreIKBones')
 
         box = layout.box()
-        box.label(text='Texture Options:')
-        box.prop(scene, 'textureMethod')
-        row = box.row()
-        row.enabled = scene.textureMethod == PRIORITIZED
-        row.prop(scene, 'texturePriority')
+        box.label(text='Texture Location:')
+        box.prop(scene, 'inlineTextures')
         row = box.row()
-        row.enabled = scene.textureMethod != INLINE
+        row.enabled = not scene.inlineTextures
         row.prop(scene, 'textureDir')
 
         box = layout.box()

+ 4 - 5
Exporters/Blender/src/json_exporter.py

@@ -32,7 +32,7 @@ class JsonExporter:
 
             # assign texture location, purely temporary if inlining
             self.textureDir = path.dirname(filepath)
-            if scene.textureMethod != INLINE:
+            if not scene.inlineTextures:
                 self.textureDir = path.join(self.textureDir, scene.textureDir)
                 if not path.isdir(self.textureDir):
                     makedirs(self.textureDir)
@@ -42,11 +42,10 @@ class JsonExporter:
             Logger.log('Scene settings used:', 1)
             Logger.log('selected layers only:  ' + format_bool(scene.export_onlySelectedLayer), 2)
             Logger.log('flat shading entire scene:  ' + format_bool(scene.export_flatshadeScene), 2)
-            Logger.log('texture Method:  ' + scene.textureMethod, 2)
-            if scene.textureMethod != INLINE:
+            Logger.log('inline textures:  ' + format_bool(scene.inlineTextures), 2)
+            if not scene.inlineTextures:
                 Logger.log('texture directory:  ' + self.textureDir, 2)
-            if scene.textureMethod == PRIORITIZED:
-                Logger.log('Priority Order:  ' + scene.texturePriority)
+                
             self.world = World(scene)
 
             bpy.ops.screen.animation_cancel()

+ 5 - 28
Exporters/Blender/src/material.py

@@ -1,4 +1,3 @@
-from .exporter_settings_panel import *
 from .logger import *
 from .package_level import *
 
@@ -84,7 +83,7 @@ class Texture:
 
             # when coming from either a packed image or a baked image, then save_render
             if internalImage:
-                if exporter.scene.textureMethod == INLINE:
+                if exporter.scene.inlineTextures:
                     textureFile = path.join(exporter.textureDir, self.fileNoPath + 'temp')
                 else:
                     textureFile = path.join(exporter.textureDir, self.fileNoPath)
@@ -100,7 +99,7 @@ class Texture:
             ex = exc_info()
             Logger.warn('Error encountered processing image file:  ' + ', Error:  '+ str(ex[1]))
 
-        if exporter.scene.textureMethod == INLINE:
+        if exporter.scene.inlineTextures:
             # base64 is easiest from a file, so sometimes a temp file was made above;  need to delete those
             with open(textureFile, "rb") as image_file:
                 asString = b64encode(image_file.read()).decode()
@@ -109,16 +108,6 @@ class Texture:
             if internalImage:
                 remove(textureFile)
 
-        # build priority Order
-        if exporter.scene.textureMethod == PRIORITIZED:
-            nameNoExtension = self.fileNoPath.rpartition('.')[0]
-            self.priorityNames = []
-            for ext in exporter.scene.texturePriority.split():
-                self.priorityNames.append(nameNoExtension + ext)
-
-            # add blend image last
-            self.priorityNames.append(self.fileNoPath)
-
         # capture texture attributes
         self.slot = slot
         self.level = level
@@ -154,21 +143,7 @@ class Texture:
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
         file_handler.write(', \n"' + self.slot + '":{')
-        if hasattr(self,'encoded_URI'):
-            write_string(file_handler, 'base64String', self.encoded_URI)
-
-        elif hasattr(self,'priorityNames'):
-            file_handler.write('"name":[')
-            first = True
-            for name in self.priorityNames:
-                if first == False:
-                    file_handler.write(',')
-                file_handler.write('"' + name + '"')
-                first = False
-            file_handler.write(']')
-
-        else:
-            write_string(file_handler, 'name', self.fileNoPath, True)
+        write_string(file_handler, 'name', self.fileNoPath, True)
 
         write_float(file_handler, 'level', self.level)
         write_float(file_handler, 'hasAlpha', self.hasAlpha)
@@ -183,6 +158,8 @@ class Texture:
         write_int(file_handler, 'wrapU', self.wrapU)
         write_int(file_handler, 'wrapV', self.wrapV)
         write_int(file_handler, 'coordinatesIndex', self.coordinatesIndex)
+        if hasattr(self,'encoded_URI'):
+            write_string(file_handler, 'base64String', self.encoded_URI)
         file_handler.write('}')
 #===============================================================================
 # need to evaluate the need to bake a mesh before even starting; class also stores specific types of bakes

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 23 - 23
dist/preview release/babylon.core.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1713 - 1676
dist/preview release/babylon.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 36 - 36
dist/preview release/babylon.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 592 - 257
dist/preview release/babylon.max.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 33 - 33
dist/preview release/babylon.noworker.js


+ 9 - 5
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -90,7 +90,8 @@ var BABYLON;
     var EBlendingFunction = BABYLON.EBlendingFunction;
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/glTF/babylon.glTFFileLoaderInterfaces.js.map
+//# sourceMappingURL=babylon.glTFFileLoaderInterfaces.js.map
+
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
@@ -1499,7 +1500,8 @@ var BABYLON;
     BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/glTF/babylon.glTFFileLoader.js.map
+//# sourceMappingURL=babylon.glTFFileLoader.js.map
+
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
@@ -1701,7 +1703,8 @@ var BABYLON;
     BABYLON.GLTFUtils = GLTFUtils;
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/glTF/babylon.glTFFileLoaderUtils.js.map
+//# sourceMappingURL=babylon.glTFFileLoaderUtils.js.map
+
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
@@ -1822,7 +1825,8 @@ var BABYLON;
     BABYLON.GLTFFileLoaderExtension = GLTFFileLoaderExtension;
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/glTF/babylon.glTFFileLoaderExtension.js.map
+//# sourceMappingURL=babylon.glTFFileLoaderExtension.js.map
+
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -1965,4 +1969,4 @@ var BABYLON;
     BABYLON.GLTFFileLoader.RegisterExtension(new GLTFBinaryExtension());
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/glTF/babylon.glTFBinaryExtension.js.map
+//# sourceMappingURL=babylon.glTFBinaryExtension.js.map

+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.js

@@ -740,4 +740,4 @@ var BABYLON;
     BABYLON.SceneLoader.RegisterPlugin(new OBJFileLoader());
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/OBJ/babylon.objFileLoader.js.map
+//# sourceMappingURL=babylon.objFileLoader.js.map

+ 1 - 1
dist/preview release/loaders/babylon.stlFileLoader.js

@@ -80,4 +80,4 @@ var BABYLON;
     BABYLON.SceneLoader.RegisterPlugin(new STLFileLoader());
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/STL/babylon.stlFileLoader.js.map
+//# sourceMappingURL=babylon.stlFileLoader.js.map

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 1
dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js


+ 1 - 1
dist/preview release/serializers/babylon.objSerializer.js

@@ -87,4 +87,4 @@ var BABYLON;
     BABYLON.OBJExport = OBJExport;
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=../../src/OBJ/babylon.objSerializer.js.map
+//# sourceMappingURL=babylon.objSerializer.js.map

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

@@ -14,7 +14,7 @@
 - Added `scene.multiPick` and `scene.multiPickWithRay` to return an array of pickedMesh objects ([deltakosh](https://github.com/deltakosh))
 - Added `Effect.GetVertexShaderSource()` and `Effect.GetFragmentShaderSource()` ([deltakosh](https://github.com/deltakosh))
 - New `Texture.LoadFromDataString()` to help loading base64 encoded textures ([deltakosh](https://github.com/deltakosh))
-- You can now specify an array of string when loading a texture (they will be considered as fallbacks) ([deltakosh](https://github.com/deltakosh))
+- Added Engine detection of the compresed texture formats supported by Hw / browser.  You can specify those formats you have files for using `Engine.setTextureFormatToUse()`, and an appropriate one will be chosen. ([Palmer-JC](https://github.com/Palmer-JC/))
 - Added Bone.getAbsolutePosition and Bone.getAbsolutePositionToRef ([abow](https://github.com/abow))
 - Added Bone.setYawPitchRoll ([abow](https://github.com/abow))
 - Added Bone.rotate ([abow](https://github.com/abow))

+ 1 - 1
localDev/index.html

@@ -59,7 +59,7 @@
 			.require(indexjs)
 			.load(function() {
 				if (BABYLON.Engine.isSupported()) {
-					engine = new BABYLON.Engine(canvas, true);				
+					engine = new BABYLON.Engine(canvas, true, { stencil: true });				
 
 					// call the scene creation from the js.
 					var scene = createScene();

+ 4 - 0
src/Cameras/babylon.targetCamera.ts

@@ -48,6 +48,10 @@
                 return null;
             }
 
+            if (this.lockedTarget.absolutePosition) {
+                this.lockedTarget.computeWorldMatrix();
+            }
+
             return this.lockedTarget.absolutePosition || this.lockedTarget;
         }
 

+ 27 - 9
src/Culling/babylon.ray.ts

@@ -11,6 +11,7 @@
         private _renderFunction: () => void;
         private _scene: Scene;
         private _show = false;
+        private _tmpRay: Ray;
 
         constructor(public origin: Vector3, public direction: Vector3, public length: number = Number.MAX_VALUE) {
         }
@@ -205,26 +206,34 @@
 
             mesh.getWorldMatrix().invertToRef(tm);
 
-            var ray = Ray.Transform(this, tm);
+            if(this._tmpRay){
+                Ray.TransformToRef(this, tm, this._tmpRay);
+            }else{
+                this._tmpRay = Ray.Transform(this, tm);
+            }
 
-            return mesh.intersects(ray, fastCheck);
+            return mesh.intersects(this._tmpRay, fastCheck);
 
         }
 
         public show(scene:Scene, color:Color3): void{
 
-            this._renderFunction = this._render.bind(this);
-            this._show = true;
-            this._scene = scene;
-            this._renderPoints = [this.origin, this.origin.add(this.direction.scale(this.length))];
-            this._renderLine = Mesh.CreateLines("ray", this._renderPoints, scene, true);
+            if(!this._show){
+
+                this._renderFunction = this._render.bind(this);
+                this._show = true;
+                this._scene = scene;
+                this._renderPoints = [this.origin, this.origin.add(this.direction.scale(this.length))];
+                this._renderLine = Mesh.CreateLines("ray", this._renderPoints, scene, true);
+
+                this._scene.registerBeforeRender(this._renderFunction);
+
+            }
 
             if (color) {
                 this._renderLine.color.copyFrom(color);
             }
 
-            this._scene.registerBeforeRender(this._renderFunction);
-
         }
 
         public hide(): void{
@@ -373,5 +382,14 @@
 
             return new Ray(newOrigin, newDirection, ray.length);
         }
+
+        public static TransformToRef(ray: Ray, matrix: Matrix, result:Ray): void {
+            
+            Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);
+            Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);
+
+            ray.direction.normalize();
+            
+        }
     }
 }

+ 27 - 12
src/Layer/babylon.highlightlayer.ts

@@ -133,8 +133,8 @@
         private _vertexBuffers: { [key: string]: VertexBuffer } = {};
         private _indexBuffer: WebGLBuffer;
         private _downSamplePostprocess: PassPostProcess;
-        private _horizontalBlurPostprocess: GlowBlurPostProcess;
-        private _verticalBlurPostprocess: GlowBlurPostProcess;
+        private _horizontalBlurPostprocess: BlurPostProcess;
+        private _verticalBlurPostprocess: BlurPostProcess;
         private _cachedDefines: string;
         private _glowMapGenerationEffect: Effect;
         private _glowMapMergeEffect: Effect;
@@ -352,17 +352,32 @@
                 effect.setTexture("textureSampler", this._mainTexture);
             });
 
-            this._horizontalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerHBP", new BABYLON.Vector2(1.0, 0), this._options.blurHorizontalSize, 1,
-                null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
-            this._horizontalBlurPostprocess.onApplyObservable.add(effect => {
-                effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
-            });
-
-            this._verticalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerVBP", new BABYLON.Vector2(0, 1.0), this._options.blurVerticalSize, 1,
+            if (this._options.alphaBlendingMode === Engine.ALPHA_COMBINE) {
+                this._horizontalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerHBP", new BABYLON.Vector2(1.0, 0), this._options.blurHorizontalSize, 1,
+                    null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
+                this._horizontalBlurPostprocess.onApplyObservable.add(effect => {
+                    effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
+                });
+
+                this._verticalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerVBP", new BABYLON.Vector2(0, 1.0), this._options.blurVerticalSize, 1,
+                    null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
+                this._verticalBlurPostprocess.onApplyObservable.add(effect => {
+                    effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
+                });
+            }
+            else {
+                this._horizontalBlurPostprocess = new BlurPostProcess("HighlightLayerHBP", new BABYLON.Vector2(1.0, 0), this._options.blurHorizontalSize, 1,
                 null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
-            this._verticalBlurPostprocess.onApplyObservable.add(effect => {
-                effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
-            });
+                this._horizontalBlurPostprocess.onApplyObservable.add(effect => {
+                    effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
+                });
+
+                this._verticalBlurPostprocess = new BlurPostProcess("HighlightLayerVBP", new BABYLON.Vector2(0, 1.0), this._options.blurVerticalSize, 1,
+                    null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
+                this._verticalBlurPostprocess.onApplyObservable.add(effect => {
+                    effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
+                });
+            }
 
             this._mainTexture.onAfterUnbindObservable.add(() => {
                 this.onBeforeBlurObservable.notifyObservers(this);

+ 3 - 12
src/Materials/Textures/babylon.texture.ts

@@ -71,16 +71,12 @@
         private _delayedOnLoad: () => void;
         private _delayedOnError: () => void;
         private _onLoadObservarble: Observable<boolean>;
-        private _delayReloadData: string | Array<string>
 
-        constructor(urlOrList: string | Array<string>, scene: Scene, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false) {
+        constructor(url: string, scene: Scene, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null, deleteBuffer: boolean = false) {
             super(scene);
 
-            var url = <string>((urlOrList instanceof Array) ? urlOrList[0] : urlOrList);
-
             this.name = url;
             this.url = url;
-            this._delayReloadData = urlOrList;
             this._noMipmap = noMipmap;
             this._invertY = invertY;
             this._samplingMode = samplingMode;
@@ -104,7 +100,7 @@
 
             if (!this._texture) {
                 if (!scene.useDelayedTextureLoading) {
-                    this._texture = scene.getEngine().createTexture(urlOrList, noMipmap, invertY, scene, this._samplingMode, load, onError, this._buffer);
+                    this._texture = scene.getEngine().createTexture(url, noMipmap, invertY, scene, this._samplingMode, load, onError, this._buffer);
                     if (deleteBuffer) {
                         delete this._buffer;
                     }
@@ -132,7 +128,7 @@
             this._texture = this._getFromCache(this.url, this._noMipmap, this._samplingMode);
 
             if (!this._texture) {
-                this._texture = this.getScene().getEngine().createTexture(this._delayReloadData, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, this._delayedOnLoad, this._delayedOnError, this._buffer);
+                this._texture = this.getScene().getEngine().createTexture(this.url, this._noMipmap, this._invertY, this.getScene(), this._samplingMode, this._delayedOnLoad, this._delayedOnError, this._buffer);
                 if (this._deleteBuffer) {
                     delete this._buffer;
                 }
@@ -301,11 +297,6 @@
                     var texture: Texture;
                     if (parsedTexture.base64String) {
                         texture = Texture.CreateFromBase64String(parsedTexture.base64String, parsedTexture.name, scene);
-                    } else if (parsedTexture.name instanceof Array) {
-                        for (var i = 0, len = parsedTexture.name.length; i < len; i++) {
-                            parsedTexture.name[i] = rootUrl + parsedTexture.name[i];
-                        }
-                        texture = new Texture(parsedTexture.name, scene);
                     } else {
                         texture = new Texture(rootUrl + parsedTexture.name, scene);
                     }

+ 63 - 15
src/Materials/babylon.pbrMaterial.ts

@@ -64,6 +64,10 @@
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPY = false;
         public SHADOWFULLFLOAT = false;
+        
+        public METALLICWORKFLOW = false;
+        public METALLICROUGHNESSGSTOREINALPHA = false;
+        public METALLICROUGHNESSGSTOREINGREEN = false;
 
         constructor() {
             super();
@@ -282,6 +286,12 @@
         @serializeAsTexture()
         public reflectivityTexture: BaseTexture;
 
+        /**
+         * Used to switch from specular/glossiness to metallic/roughness workflow.
+         */
+        @serializeAsTexture()
+        public metallicTexture: BaseTexture;
+
         @serializeAsTexture()
         public bumpTexture: BaseTexture;
 
@@ -313,12 +323,11 @@
         public emissiveColor = new Color3(0, 0, 0);
         
         /**
-
          * AKA Glossiness in other nomenclature.
          */
         @serialize()
         public microSurface = 0.9;
-        
+
         /**
          * source material index of refraction (IOR)' / 'destination material IOR.
          */
@@ -378,6 +387,18 @@
          */
         @serialize()
         public useMicroSurfaceFromReflectivityMapAlpha = false;
+
+        /**
+         * Specifies if the metallic texture contains the roughness information in its alpha channel.
+         */
+        @serialize()
+        public useRoughnessFromMetallicTextureAlpha = true;
+
+        /**
+         * Specifies if the metallic texture contains the roughness information in its green channel.
+         */
+        @serialize()
+        public useRoughnessFromMetallicTextureGreen = false;
         
         /**
          * In case the reflectivity map does not contain the microsurface information in its alpha channel,
@@ -725,14 +746,26 @@
                     }
                 }
 
-                if (this.reflectivityTexture && StandardMaterial.SpecularTextureEnabled) {
-                    if (!this.reflectivityTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.REFLECTIVITY = true;
-                        this._defines.MICROSURFACEFROMREFLECTIVITYMAP = this.useMicroSurfaceFromReflectivityMapAlpha;
-                        this._defines.MICROSURFACEAUTOMATIC = this.useAutoMicroSurfaceFromReflectivityMap;
+                if (StandardMaterial.SpecularTextureEnabled) {                        
+                    if (this.metallicTexture) {
+                        if (!this.metallicTexture.isReady()) {
+                            return false;
+                        } else {
+                            needUVs = true;
+                            this._defines.METALLICWORKFLOW = true;
+                            this._defines.METALLICROUGHNESSGSTOREINALPHA = this.useRoughnessFromMetallicTextureAlpha;
+                            this._defines.METALLICROUGHNESSGSTOREINGREEN = !this.useRoughnessFromMetallicTextureAlpha && this.useRoughnessFromMetallicTextureGreen;
+                        }
+                    }
+                    else if (this.reflectivityTexture) {
+                        if (!this.reflectivityTexture.isReady()) {
+                            return false;
+                        } else {
+                            needUVs = true;
+                            this._defines.REFLECTIVITY = true;
+                            this._defines.MICROSURFACEFROMREFLECTIVITYMAP = this.useMicroSurfaceFromReflectivityMapAlpha;
+                            this._defines.MICROSURFACEAUTOMATIC = this.useAutoMicroSurfaceFromReflectivityMap;
+                        }
                     }
                 }
 
@@ -1174,11 +1207,19 @@
                         this._effect.setMatrix("lightmapMatrix", this.lightmapTexture.getTextureMatrix());
                     }
 
-                    if (this.reflectivityTexture && StandardMaterial.SpecularTextureEnabled) {
-                        this._effect.setTexture("reflectivitySampler", this.reflectivityTexture);
+                    if (StandardMaterial.SpecularTextureEnabled) {
+                        if (this.metallicTexture) {
+                            this._effect.setTexture("reflectivitySampler", this.metallicTexture);
+
+                            this._effect.setFloat2("vReflectivityInfos", this.metallicTexture.coordinatesIndex, this.metallicTexture.level);
+                            this._effect.setMatrix("reflectivityMatrix", this.metallicTexture.getTextureMatrix());
+                        }
+                        else if (this.reflectivityTexture) {
+                            this._effect.setTexture("reflectivitySampler", this.reflectivityTexture);
 
-                        this._effect.setFloat2("vReflectivityInfos", this.reflectivityTexture.coordinatesIndex, this.reflectivityTexture.level);
-                        this._effect.setMatrix("reflectivityMatrix", this.reflectivityTexture.getTextureMatrix());
+                            this._effect.setFloat2("vReflectivityInfos", this.reflectivityTexture.coordinatesIndex, this.reflectivityTexture.level);
+                            this._effect.setMatrix("reflectivityMatrix", this.reflectivityTexture.getTextureMatrix());
+                        }
                     }
 
                     if (this.bumpTexture && this._myScene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled && !this.disableBumpMap) {
@@ -1331,7 +1372,10 @@
                 results.push(this.emissiveTexture);
             }
 
-            if (this.reflectivityTexture && this.reflectivityTexture.animations && this.reflectivityTexture.animations.length > 0) {
+            if (this.metallicTexture && this.metallicTexture.animations && this.metallicTexture.animations.length > 0) {
+                results.push(this.metallicTexture);
+            }
+            else if (this.reflectivityTexture && this.reflectivityTexture.animations && this.reflectivityTexture.animations.length > 0) {
                 results.push(this.reflectivityTexture);
             }
 
@@ -1376,6 +1420,10 @@
                     this.emissiveTexture.dispose();
                 }
 
+                if (this.metallicTexture) {
+                    this.metallicTexture.dispose();
+                }
+
                 if (this.reflectivityTexture) {
                     this.reflectivityTexture.dispose();
                 }

+ 5 - 5
src/Mesh/babylon.geometry.ts

@@ -594,23 +594,23 @@
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                serializationObject.uvs2 = this.getVerticesData(VertexBuffer.UV2Kind);
+                serializationObject.uv2s = this.getVerticesData(VertexBuffer.UV2Kind);
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.UV3Kind)) {
-                serializationObject.uvs3 = this.getVerticesData(VertexBuffer.UV3Kind);
+                serializationObject.uv3s = this.getVerticesData(VertexBuffer.UV3Kind);
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.UV4Kind)) {
-                serializationObject.uvs4 = this.getVerticesData(VertexBuffer.UV4Kind);
+                serializationObject.uv4s = this.getVerticesData(VertexBuffer.UV4Kind);
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.UV5Kind)) {
-                serializationObject.uvs5 = this.getVerticesData(VertexBuffer.UV5Kind);
+                serializationObject.uv5s = this.getVerticesData(VertexBuffer.UV5Kind);
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.UV6Kind)) {
-                serializationObject.uvs6 = this.getVerticesData(VertexBuffer.UV6Kind);
+                serializationObject.uv6s = this.getVerticesData(VertexBuffer.UV6Kind);
             }
 
             if (this.isVerticesDataPresent(VertexBuffer.ColorKind)) {

+ 60 - 27
src/Shaders/pbr.fragment.fx

@@ -87,7 +87,7 @@ uniform vec2 vLightmapInfos;
 uniform sampler2D lightmapSampler;
 #endif
 
-#if defined(REFLECTIVITY)
+#if defined(REFLECTIVITY) || defined(METALLICWORKFLOW) 
 varying vec2 vReflectivityUV;
 uniform vec2 vReflectivityInfos;
 uniform sampler2D reflectivitySampler;
@@ -255,17 +255,49 @@ void main(void) {
 	surfaceReflectivityColor = surfaceReflectivityColorMap.rgb;
 	surfaceReflectivityColor = toLinearSpace(surfaceReflectivityColor);
 
-#ifdef OVERLOADEDVALUES
-	surfaceReflectivityColor = mix(surfaceReflectivityColor, vOverloadedReflectivity, vOverloadedIntensity.z);
-#endif
+	#ifdef OVERLOADEDVALUES
+		surfaceReflectivityColor = mix(surfaceReflectivityColor, vOverloadedReflectivity, vOverloadedIntensity.z);
+	#endif
 
-#ifdef MICROSURFACEFROMREFLECTIVITYMAP
-	microSurface = surfaceReflectivityColorMap.a;
-#else
-#ifdef MICROSURFACEAUTOMATIC
-	microSurface = computeDefaultMicroSurface(microSurface, surfaceReflectivityColor);
-#endif
+	#ifdef MICROSURFACEFROMREFLECTIVITYMAP
+		microSurface = surfaceReflectivityColorMap.a;
+	#else
+		#ifdef MICROSURFACEAUTOMATIC
+			microSurface = computeDefaultMicroSurface(microSurface, surfaceReflectivityColor);
+		#endif
+	#endif
 #endif
+
+#ifdef METALLICWORKFLOW
+	vec4 surfaceMetallicColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
+
+	// No gamma space fro the metallic map in metallic workflow.
+	float metallic = surfaceMetallicColorMap.r; // Unity like base channel for metallness.
+
+	// Diffuse is used as the base of the reflectivity.
+	vec3 baseColor = surfaceAlbedo.rgb;
+
+	// Drop the surface diffuse by the 1.0 - metalness.
+	surfaceAlbedo.rgb *= (1.0 - metallic);
+	
+	// Default specular reflectance at normal incidence.
+	// 4% corresponds to index of refraction (IOR) of 1.50, approximately equal to glass.    
+	const vec3 DefaultSpecularReflectanceDielectric = vec3(0.04, 0.04, 0.04);
+
+	// Compute the converted reflectivity.
+	surfaceReflectivityColor = mix(DefaultSpecularReflectanceDielectric, baseColor, metallic);
+
+	#ifdef OVERLOADEDVALUES
+		surfaceReflectivityColor = mix(surfaceReflectivityColor, vOverloadedReflectivity, vOverloadedIntensity.z);
+	#endif
+
+	#ifdef METALLICROUGHNESSGSTOREINALPHA
+		microSurface = 1.0 - surfaceMetallicColorMap.a;
+	#else
+		#ifdef METALLICROUGHNESSGSTOREINGREEN
+			microSurface = 1.0 - surfaceMetallicColorMap.g;
+		#endif
+	#endif
 #endif
 
 #ifdef OVERLOADEDVALUES
@@ -488,30 +520,31 @@ void main(void) {
 
 	// Compute refractance
 	vec3 refractance = vec3(0.0, 0.0, 0.0);
+
 #ifdef REFRACTION
 	vec3 transmission = vec3(1.0, 1.0, 1.0);
-#ifdef LINKREFRACTIONTOTRANSPARENCY
-	// Transmission based on alpha.
-	transmission *= (1.0 - alpha);
+	#ifdef LINKREFRACTIONTOTRANSPARENCY
+		// Transmission based on alpha.
+		transmission *= (1.0 - alpha);
 
-	// Tint the material with albedo.
-	// TODO. PBR Tinting.
-	vec3 mixedAlbedo = surfaceAlbedoContribution.rgb * surfaceAlbedo.rgb;
-	float maxChannel = max(max(mixedAlbedo.r, mixedAlbedo.g), mixedAlbedo.b);
-	vec3 tint = clamp(maxChannel * mixedAlbedo, 0.0, 1.0);
+		// Tint the material with albedo.
+		// TODO. PBR Tinting.
+		vec3 mixedAlbedo = surfaceAlbedoContribution.rgb * surfaceAlbedo.rgb;
+		float maxChannel = max(max(mixedAlbedo.r, mixedAlbedo.g), mixedAlbedo.b);
+		vec3 tint = clamp(maxChannel * mixedAlbedo, 0.0, 1.0);
 
-	// Decrease Albedo Contribution
-	surfaceAlbedoContribution *= alpha;
+		// Decrease Albedo Contribution
+		surfaceAlbedoContribution *= alpha;
 
-	// Decrease irradiance Contribution
-	environmentIrradiance *= alpha;
+		// Decrease irradiance Contribution
+		environmentIrradiance *= alpha;
 
-	// Tint reflectance
-	surfaceRefractionColor *= tint;
+		// Tint reflectance
+		surfaceRefractionColor *= tint;
 
-	// Put alpha back to 1;
-	alpha = 1.0;
-#endif
+		// Put alpha back to 1;
+		alpha = 1.0;
+	#endif
 
 	// Add Multiple internal bounces.
 	vec3 bounceSpecularEnvironmentReflectance = (2.0 * specularEnvironmentReflectance) / (1.0 + specularEnvironmentReflectance);

+ 2 - 2
src/Shaders/pbr.vertex.fx

@@ -53,7 +53,7 @@ uniform vec2 vLightmapInfos;
 uniform mat4 lightmapMatrix;
 #endif
 
-#if defined(REFLECTIVITY)
+#if defined(REFLECTIVITY) || defined(METALLICWORKFLOW) 
 varying vec2 vReflectivityUV;
 uniform vec2 vReflectivityInfos;
 uniform mat4 reflectivityMatrix;
@@ -178,7 +178,7 @@ void main(void) {
     }
 #endif
 
-#if defined(REFLECTIVITY)
+#if defined(REFLECTIVITY) || defined(METALLICWORKFLOW) 
     if (vReflectivityInfos.x == 0.)
     {
         vReflectivityUV = vec2(reflectivityMatrix * vec4(uv, 1.0, 0.0));

+ 59 - 24
src/Tools/babylon.gamepads.ts

@@ -66,9 +66,9 @@
             }
 
             var newGamepad;
-
-            if ((<string>gamepad.id).search("Xbox 360") !== -1 || (<string>gamepad.id).search("xinput") !== -1) {
-                newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad);
+            var xboxOne: boolean = ((<string>gamepad.id).search("Xbox One") !== -1);
+            if (xboxOne || (<string>gamepad.id).search("Xbox 360") !== -1 || (<string>gamepad.id).search("xinput") !== -1) {
+                newGamepad = new Xbox360Pad(gamepad.id, gamepad.index, gamepad, xboxOne);
             }
             else {
                 newGamepad = new GenericPad(gamepad.id, gamepad.index, gamepad);
@@ -150,15 +150,24 @@
         private _leftStick: StickValues;
         private _rightStick: StickValues;
 
+        private _leftStickAxisX: number;
+        private _leftStickAxisY: number;
+        private _rightStickAxisX: number;
+        private _rightStickAxisY: number;
+
         private _onleftstickchanged: (values: StickValues) => void;
         private _onrightstickchanged: (values: StickValues) => void;
 
-        constructor(public id: string, public index: number, public browserGamepad) {
+        constructor(public id: string, public index: number, public browserGamepad, leftStickX:number = 0, leftStickY:number = 1, rightStickX:number = 2, rightStickY:number = 3) {
+            this._leftStickAxisX = leftStickX;
+            this._leftStickAxisY = leftStickY;
+            this._rightStickAxisX = rightStickX;
+            this._rightStickAxisY = rightStickY;
             if (this.browserGamepad.axes.length >= 2) {
-                this._leftStick = { x: this.browserGamepad.axes[0], y: this.browserGamepad.axes[1] };
+                this._leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };
             }
             if (this.browserGamepad.axes.length >= 4) {
-                this._rightStick = { x: this.browserGamepad.axes[2], y: this.browserGamepad.axes[3] };
+                this._rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };
             }
         }
 
@@ -191,10 +200,10 @@
 
         public update() {
             if (this._leftStick) {
-                this.leftStick = { x: this.browserGamepad.axes[0], y: this.browserGamepad.axes[1] };
+                this.leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };
             }
             if (this._rightStick) {
-                this.rightStick = { x: this.browserGamepad.axes[2], y: this.browserGamepad.axes[3] };
+                this.rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };
             }
         }
     }
@@ -284,6 +293,13 @@
         private _dPadLeft: number = 0;
         private _dPadRight: number = 0;
 
+        private _isXboxOnePad:boolean = false;
+
+        constructor(id: string, index: number, gamepad:any, xboxOne:boolean = false) {
+            super(id, index, gamepad, 0, 1, (xboxOne ? 3 : 2), (xboxOne ? 4 : 3));
+            this._isXboxOnePad = xboxOne;
+        }
+
         public onlefttriggerchanged(callback: (value: number) => void) {
             this._onlefttriggerchanged = callback;
         }
@@ -435,22 +451,41 @@
         }
         public update() {
             super.update();
-            this.buttonA = this.browserGamepad.buttons[0].value;
-            this.buttonB = this.browserGamepad.buttons[1].value;
-            this.buttonX = this.browserGamepad.buttons[2].value;
-            this.buttonY = this.browserGamepad.buttons[3].value;
-            this.buttonLB = this.browserGamepad.buttons[4].value;
-            this.buttonRB = this.browserGamepad.buttons[5].value;
-            this.leftTrigger = this.browserGamepad.buttons[6].value;
-            this.rightTrigger = this.browserGamepad.buttons[7].value;
-            this.buttonBack = this.browserGamepad.buttons[8].value;
-            this.buttonStart = this.browserGamepad.buttons[9].value;
-            this.buttonLeftStick = this.browserGamepad.buttons[10].value;
-            this.buttonRightStick = this.browserGamepad.buttons[11].value;
-            this.dPadUp = this.browserGamepad.buttons[12].value;
-            this.dPadDown = this.browserGamepad.buttons[13].value;
-            this.dPadLeft = this.browserGamepad.buttons[14].value;
-            this.dPadRight = this.browserGamepad.buttons[15].value;
+            if (this._isXboxOnePad) {
+                this.buttonA = this.browserGamepad.buttons[0].value;
+                this.buttonB = this.browserGamepad.buttons[1].value;
+                this.buttonX = this.browserGamepad.buttons[2].value;
+                this.buttonY = this.browserGamepad.buttons[3].value;
+                this.buttonLB = this.browserGamepad.buttons[4].value;
+                this.buttonRB = this.browserGamepad.buttons[5].value;
+                this.leftTrigger = this.browserGamepad.axes[2];
+                this.rightTrigger = this.browserGamepad.axes[5];
+                this.buttonBack = this.browserGamepad.buttons[9].value;
+                this.buttonStart = this.browserGamepad.buttons[8].value;
+                this.buttonLeftStick = this.browserGamepad.buttons[6].value;
+                this.buttonRightStick = this.browserGamepad.buttons[7].value;
+                this.dPadUp = this.browserGamepad.buttons[11].value;
+                this.dPadDown = this.browserGamepad.buttons[12].value;
+                this.dPadLeft = this.browserGamepad.buttons[13].value;
+                this.dPadRight = this.browserGamepad.buttons[14].value;
+            } else {
+                this.buttonA = this.browserGamepad.buttons[0].value;
+                this.buttonB = this.browserGamepad.buttons[1].value;
+                this.buttonX = this.browserGamepad.buttons[2].value;
+                this.buttonY = this.browserGamepad.buttons[3].value;
+                this.buttonLB = this.browserGamepad.buttons[4].value;
+                this.buttonRB = this.browserGamepad.buttons[5].value;
+                this.leftTrigger = this.browserGamepad.buttons[6].value;
+                this.rightTrigger = this.browserGamepad.buttons[7].value;
+                this.buttonBack = this.browserGamepad.buttons[8].value;
+                this.buttonStart = this.browserGamepad.buttons[9].value;
+                this.buttonLeftStick = this.browserGamepad.buttons[10].value;
+                this.buttonRightStick = this.browserGamepad.buttons[11].value;
+                this.dPadUp = this.browserGamepad.buttons[12].value;
+                this.dPadDown = this.browserGamepad.buttons[13].value;
+                this.dPadLeft = this.browserGamepad.buttons[14].value;
+                this.dPadRight = this.browserGamepad.buttons[15].value;
+            }
         }
     }
 }

+ 8 - 0
src/Tools/babylon.sceneSerializer.ts

@@ -159,6 +159,14 @@
         // Layer mask
         serializationObject.layerMask = mesh.layerMask;
 
+        // Alpha
+        serializationObject.alphaIndex = mesh.alphaIndex;
+        serializationObject.hasVertexAlpha = mesh.hasVertexAlpha;
+        serializationObject.overlayAlpha = mesh.overlayAlpha;
+
+        // Fog
+        serializationObject.applyFog = mesh.applyFog;
+
         // Action Manager
         if (mesh.actionManager) {
             serializationObject.actions = mesh.actionManager.serialize(mesh.name);

+ 74 - 23
src/babylon.engine.ts

@@ -174,6 +174,10 @@
         public maxVertexAttribs: number;
         public standardDerivatives: boolean;
         public s3tc: WEBGL_compressed_texture_s3tc;
+        public pvrtc: any; //WEBGL_compressed_texture_pvrtc;
+        public etc1: any; //WEBGL_compressed_texture_etc1;
+        public etc2: any; //WEBGL_compressed_texture_etc;
+        public astc: any; //WEBGL_compressed_texture_astc;
         public textureFloat: boolean;
         public textureAnisotropicFilterExtension: EXT_texture_filter_anisotropic;
         public maxAnisotropy: number;
@@ -481,7 +485,19 @@
 
         private _externalData: StringDictionary<Object>;
         private _bindedRenderFunction: any;
-
+        
+        // Hardware supported Compressed Textures
+        private _texturesSupported = new Array<string>();
+        private _textureFormatInUse : string; 
+        
+        public get texturesSupported(): Array<string> {
+            return this._texturesSupported;
+        }
+        
+        public get textureFormatInUse(): string {
+            return this._textureFormatInUse;
+        }
+        
         /**
          * @constructor
          * @param {HTMLCanvasElement} canvas - the canvas to be used for rendering
@@ -576,7 +592,13 @@
 
             // Extensions
             this._caps.standardDerivatives = (this._gl.getExtension('OES_standard_derivatives') !== null);
-            this._caps.s3tc = this._gl.getExtension('WEBGL_compressed_texture_s3tc');
+            
+            this._caps.astc  = this._gl.getExtension('WEBGL_compressed_texture_astc');
+            this._caps.s3tc  = this._gl.getExtension('WEBGL_compressed_texture_s3tc');
+            this._caps.pvrtc = this._gl.getExtension('WEBGL_compressed_texture_pvrtc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); // 2nd is what iOS reports
+            this._caps.etc1  = this._gl.getExtension('WEBGL_compressed_texture_etc1');
+            this._caps.etc2  = this._gl.getExtension('WEBGL_compressed_texture_etc') || this._gl.getExtension('WEBGL_compressed_texture_es3_0'); // first is the final name, found hardware using 2nd
+            
             this._caps.textureFloat = (this._gl.getExtension('OES_texture_float') !== null);
             this._caps.textureAnisotropicFilterExtension = this._gl.getExtension('EXT_texture_filter_anisotropic') || this._gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') || this._gl.getExtension('MOZ_EXT_texture_filter_anisotropic');
             this._caps.maxAnisotropy = this._caps.textureAnisotropicFilterExtension ? this._gl.getParameter(this._caps.textureAnisotropicFilterExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0;
@@ -592,7 +614,18 @@
             this._caps.textureHalfFloat = (this._gl.getExtension('OES_texture_half_float') !== null);
             this._caps.textureHalfFloatLinearFiltering = this._gl.getExtension('OES_texture_half_float_linear');
             this._caps.textureHalfFloatRender = renderToHalfFloat;
-
+            
+            // Intelligently add supported commpressed formats in order to check for.
+            // Check for ASTC support first as it is most powerful and to be very cross platform.
+            // Next PVR & S3, which are probably superior to ETC1/2.  
+            // Likely no hardware which supports both PVR & S3, so order matters little.
+            // ETC2 is newer and handles ETC1, so check for first.
+            if (this._caps.astc ) this.texturesSupported.push('.astc');
+            if (this._caps.s3tc ) this.texturesSupported.push('.dds');
+            if (this._caps.pvrtc) this.texturesSupported.push('.pvr');
+            if (this._caps.etc2 ) this.texturesSupported.push('.etc2');
+            if (this._caps.etc1 ) this.texturesSupported.push('.etc1');
+            
             if (this._gl.getShaderPrecisionFormat) {
                 var highp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.HIGH_FLOAT);
                 this._caps.highPrecisionShaderSupported = highp.precision !== 0;
@@ -1916,21 +1949,53 @@
 
             texture.samplingMode = samplingMode;
         }
+        /**
+         * Set the compressed texture format to use, based on the formats you have,
+         * the formats supported by the hardware / browser, and those currently implemented
+         * in BJS.
+         * 
+         * Note: The result of this call is not taken into account texture is base64 or when
+         * using a database / manifest.
+         * 
+         * @param {Array<string>} formatsAvailable - Extension names including dot.  Case
+         * and order do not matter.
+         * @returns The extension selected.
+         */
+        public setTextureFormatToUse(formatsAvailable : Array<string>) : string {
+            for (var i = 0, len1 = this.texturesSupported.length; i < len1; i++) {
+                // code to allow the formats to be added as they can be developed / hw tested
+                if (this._texturesSupported[i] === '.astc') continue;
+                if (this._texturesSupported[i] === '.pvr' ) continue;
+                if (this._texturesSupported[i] === '.etc1') continue;
+                if (this._texturesSupported[i] === '.etc2') continue;
+                
+                for (var j = 0, len2 = formatsAvailable.length; j < len2; j++) {
+                    if (this._texturesSupported[i] === formatsAvailable[j].toLowerCase()) {
+                        return this._textureFormatInUse = this._texturesSupported[i];
+                    }
+                }
+            }
+            // actively set format to nothing, to allow this to be called more than once
+            // and possibly fail the 2nd time
+            return this._textureFormatInUse = null;
+        }
 
-        public createTexture(urlOrList: string | Array<string>, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null): WebGLTexture {
+        public createTexture(url: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null): WebGLTexture {
             var texture = this._gl.createTexture();
 
-            var url = <string>((urlOrList.constructor === Array) ? urlOrList[0] : urlOrList);
-
             var extension: string;
             var fromData: any = false;
             if (url.substr(0, 5) === "data:") {
                 fromData = true;
             }
 
-            if (!fromData)
-                extension = url.substr(url.length - 4, 4).toLowerCase();
-            else {
+            if (!fromData) {
+                var lastDot = url.lastIndexOf('.')
+                extension = url.substring(lastDot).toLowerCase();
+                if (this._textureFormatInUse && !fromData && !scene.database) {
+                    url = url.substring(0, lastDot) + this._textureFormatInUse;
+                }
+            } else {
                 var oldUrl = url;
                 fromData = oldUrl.split(':');
                 url = oldUrl;
@@ -1974,20 +2039,6 @@
                     callback(buffer);
 
             } else if (isDDS) {
-                if (!this.getCaps().s3tc) {
-                    if (urlOrList instanceof Array) {
-                        var newList = (<Array<string>>urlOrList).slice(1);
-
-                        if (newList.length > 0) {
-                            return this.createTexture(newList, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer);
-                        }
-                    }
-
-                    onerror();
-
-                    return null;
-                }
-
                 callback = (data) => {
                     var info = Internals.DDSTools.GetDDSInfo(data);