Browse Source

Merge pull request #4 from BabylonJS/master

get from main repo
Etienne Margraff 10 năm trước cách đây
mục cha
commit
e7f7bf40af
61 tập tin đã thay đổi với 7142 bổ sung4426 xóa
  1. 247 105
      Exporters/Blender/io_export_babylon.py
  2. 4 0
      Exporters/Blender/readme.md
  3. 16 16
      dist/preview release/babylon.core.js
  4. 939 939
      dist/preview release/babylon.d.ts
  5. 15 15
      dist/preview release/babylon.js
  6. 23 5
      dist/preview release/babylon.max.js
  7. 19 19
      dist/preview release/babylon.noworker.js
  8. 11 5
      loaders/glTF/README.md
  9. 124 24
      loaders/glTF/babylon.glTFFileLoader.js
  10. 149 26
      loaders/glTF/babylon.glTFFileLoader.ts
  11. 7 1
      loaders/glTF/babylon.glTFFileLoaderInterfaces.ts
  12. 8 0
      materialsLibrary/config.json
  13. 2 2
      materialsLibrary/dist/babylon.fireMaterial.js
  14. 1 1
      materialsLibrary/dist/babylon.fireMaterial.min.js
  15. 13 3
      materialsLibrary/dist/babylon.lavaMaterial.js
  16. 1 1
      materialsLibrary/dist/babylon.lavaMaterial.min.js
  17. 13 4
      materialsLibrary/dist/babylon.normalMaterial.js
  18. 1 1
      materialsLibrary/dist/babylon.normalMaterial.min.js
  19. 147 137
      materialsLibrary/dist/babylon.pbrMaterial.js
  20. 3 3
      materialsLibrary/dist/babylon.pbrMaterial.min.js
  21. 13 4
      materialsLibrary/dist/babylon.simpleMaterial.js
  22. 1 1
      materialsLibrary/dist/babylon.simpleMaterial.min.js
  23. 2 2
      materialsLibrary/dist/babylon.terrainMaterial.js
  24. 1 1
      materialsLibrary/dist/babylon.terrainMaterial.min.js
  25. 509 0
      materialsLibrary/dist/babylon.triPlanarMaterial.js
  26. 1 0
      materialsLibrary/dist/babylon.triPlanarMaterial.min.js
  27. 1 1
      materialsLibrary/dist/babylon.waterMaterial.js
  28. 1 1
      materialsLibrary/dist/babylon.waterMaterial.min.js
  29. 19 18
      materialsLibrary/dist/dts/babylon.pbrMaterial.d.ts
  30. 36 0
      materialsLibrary/dist/dts/babylon.triPlanarMaterial.d.ts
  31. 11 2
      materialsLibrary/materials/lava/babylon.lavaMaterial.ts
  32. 14 10
      materialsLibrary/materials/lava/lava.fragment.fx
  33. 10 2
      materialsLibrary/materials/normal/babylon.normalMaterial.ts
  34. 562 558
      materialsLibrary/materials/normal/normal.fragment.fx
  35. 146 136
      materialsLibrary/materials/pbr/babylon.pbrMaterial.ts
  36. 59 73
      materialsLibrary/materials/pbr/legacypbr.fragment.fx
  37. 16 16
      materialsLibrary/materials/pbr/legacypbr.vertex.fx
  38. 75 90
      materialsLibrary/materials/pbr/pbr.fragment.fx
  39. 16 16
      materialsLibrary/materials/pbr/pbr.vertex.fx
  40. 10 2
      materialsLibrary/materials/simple/babylon.simpleMaterial.ts
  41. 560 555
      materialsLibrary/materials/simple/simple.fragment.fx
  42. 713 712
      materialsLibrary/materials/terrain/terrain.fragment.fx
  43. 622 0
      materialsLibrary/materials/triPlanar/babylon.triPlanarMaterial.ts
  44. 686 0
      materialsLibrary/materials/triPlanar/triplanar.fragment.fx
  45. 190 0
      materialsLibrary/materials/triPlanar/triplanar.vertex.fx
  46. 695 693
      materialsLibrary/materials/water/water.fragment.fx
  47. 71 61
      materialsLibrary/test/add/addpbr.js
  48. 19 0
      materialsLibrary/test/add/addtriplanar.js
  49. 252 146
      materialsLibrary/test/babylon.max.js
  50. 14 5
      materialsLibrary/test/index.html
  51. 1 1
      readme.md
  52. 4 0
      src/Animations/babylon.animation.js
  53. 4 0
      src/Animations/babylon.animation.ts
  54. 10 3
      src/Lights/Shadows/babylon.shadowGenerator.js
  55. 12 3
      src/Lights/Shadows/babylon.shadowGenerator.ts
  56. 1 1
      src/Lights/babylon.spotLight.ts
  57. 8 1
      src/Materials/babylon.standardMaterial.js
  58. 7 1
      src/Materials/babylon.standardMaterial.ts
  59. 6 3
      src/Shaders/default.fragment.fx
  60. 14 0
      src/Shaders/shadowMap.fragment.fx
  61. 7 1
      src/Shaders/shadowMap.vertex.fx

+ 247 - 105
Exporters/Blender/io_export_babylon.py

@@ -1,7 +1,7 @@
 bl_info = {
 bl_info = {
     'name': 'Babylon.js',
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (3, 0, 6),
+    'version': (4, 0, 0),
     'blender': (2, 75, 0),
     'blender': (2, 75, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -38,9 +38,9 @@ if __name__ == '__main__':
 # output related constants
 # output related constants
 MAX_VERTEX_ELEMENTS = 65535
 MAX_VERTEX_ELEMENTS = 65535
 MAX_VERTEX_ELEMENTS_32Bit = 16777216
 MAX_VERTEX_ELEMENTS_32Bit = 16777216
-VERTEX_OUTPUT_PER_LINE = 1000
+VERTEX_OUTPUT_PER_LINE = 100
 MAX_FLOAT_PRECISION = '%.4f'
 MAX_FLOAT_PRECISION = '%.4f'
-MAX_INFLUENCERS_PER_VERTEX = 4
+COMPRESS_MATRIX_INDICES = True # this is True for .babylon exporter & False for TOB
 
 
 # used in World constructor, defined in BABYLON.Scene
 # used in World constructor, defined in BABYLON.Scene
 #FOGMODE_NONE = 0
 #FOGMODE_NONE = 0
@@ -110,6 +110,8 @@ CUBIC_MODE = 3
 #PROJECTION_MODE = 4
 #PROJECTION_MODE = 4
 #SKYBOX_MODE = 5
 #SKYBOX_MODE = 5
 
 
+DEFAULT_MATERIAL_NAMESPACE = 'Same as Filename'
+
 # passed to Animation constructor from animatable objects, defined in BABYLON.Animation
 # passed to Animation constructor from animatable objects, defined in BABYLON.Animation
 #ANIMATIONTYPE_FLOAT = 0
 #ANIMATIONTYPE_FLOAT = 0
 ANIMATIONTYPE_VECTOR3 = 1
 ANIMATIONTYPE_VECTOR3 = 1
@@ -134,9 +136,9 @@ class ExporterSettingsPanel(bpy.types.Panel):
         description="Export only selected layers",
         description="Export only selected layers",
         default = False,
         default = False,
         )
         )
-    bpy.types.Scene.export_noVertexOpt = bpy.props.BoolProperty(
-        name="No vertex sharing",
-        description="Turns off an optimization which reduces vertices",
+    bpy.types.Scene.export_flatshadeScene = bpy.props.BoolProperty(
+        name="Flat shade entire scene",
+        description="Use face normals on all meshes.  Increases vertices.",
         default = False,
         default = False,
         )        
         )        
     bpy.types.Scene.attachedSound = bpy.props.StringProperty(
     bpy.types.Scene.attachedSound = bpy.props.StringProperty(
@@ -165,7 +167,7 @@ class ExporterSettingsPanel(bpy.types.Panel):
 
 
         scene = context.scene
         scene = context.scene
         layout.prop(scene, "export_onlySelectedLayer")
         layout.prop(scene, "export_onlySelectedLayer")
-        layout.prop(scene, "export_noVertexOpt")
+        layout.prop(scene, "export_flatshadeScene")
         layout.prop(scene, "inlineTextures")
         layout.prop(scene, "inlineTextures")
 
 
         box = layout.box()
         box = layout.box()
@@ -238,6 +240,10 @@ class Main(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
                 bpy.ops.object.mode_set(mode = 'OBJECT')
                 bpy.ops.object.mode_set(mode = 'OBJECT')
 
 
             Main.log('========= Conversion from Blender to Babylon.js =========', 0)
             Main.log('========= Conversion from Blender to Babylon.js =========', 0)
+            Main.log('Scene settings used:', 1)
+            Main.log('selected layers only:  ' + format_bool(scene.export_onlySelectedLayer), 2)
+            Main.log('flat shading entire scene:  ' + format_bool(scene.export_flatshadeScene), 2)
+            Main.log('inline textures:  ' + format_bool(scene.inlineTextures), 2)
             self.world = World(scene)
             self.world = World(scene)
 
 
             bpy.ops.screen.animation_cancel()
             bpy.ops.screen.animation_cancel()
@@ -591,8 +597,8 @@ class Mesh(FCurveAnimatable):
         self.name = object.name + str(nameID)
         self.name = object.name + str(nameID)
         Main.log('processing begun of mesh:  ' + self.name)
         Main.log('processing begun of mesh:  ' + self.name)
         self.isVisible = not object.hide_render
         self.isVisible = not object.hide_render
-        self.isEnabled = True
-        self.useFlatShading = object.data.useFlatShading
+        self.isEnabled = not object.data.loadDisabled
+        useFlatShading = scene.export_flatshadeScene or object.data.useFlatShading
         self.checkCollisions = object.data.checkCollisions
         self.checkCollisions = object.data.checkCollisions
         self.receiveShadows = object.data.receiveShadows
         self.receiveShadows = object.data.receiveShadows
         self.castShadows = object.data.castShadows
         self.castShadows = object.data.castShadows
@@ -701,7 +707,6 @@ class Mesh(FCurveAnimatable):
                 # None will be returned when either the first encounter or must be unique due to baked textures
                 # None will be returned when either the first encounter or must be unique due to baked textures
                 material = exporter.getMaterial(slot.name)
                 material = exporter.getMaterial(slot.name)
                 if (material != None):
                 if (material != None):
-                    material.numOfUsers = material.numOfUsers + 1
                     Main.log('registered as also a user of material:  ' + slot.name, 2)
                     Main.log('registered as also a user of material:  ' + slot.name, 2)
                 else:
                 else:
                     material = StdMaterial(slot, exporter, object)
                     material = StdMaterial(slot, exporter, object)
@@ -749,8 +754,10 @@ class Mesh(FCurveAnimatable):
             Colormap = mesh.tessface_vertex_colors.active.data
             Colormap = mesh.tessface_vertex_colors.active.data
 
 
         if hasSkeleton:
         if hasSkeleton:
-            self.skeletonWeights = []
-            self.skeletonIndicesCompressed = []
+            weightsPerVertex = []
+            indicesPerVertex = []
+            influenceCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0] # 9, so accessed orign 1
+            highestInfluenceObserved = 0
 
 
         # used tracking of vertices as they are received
         # used tracking of vertices as they are received
         alreadySavedVertices = []
         alreadySavedVertices = []
@@ -759,6 +766,8 @@ class Mesh(FCurveAnimatable):
         vertices_UV2s = []
         vertices_UV2s = []
         vertices_Colors = []
         vertices_Colors = []
         vertices_indices = []
         vertices_indices = []
+        vertices_sk_weights = []
+        vertices_sk_indices = []
 
 
         self.offsetFace = 0
         self.offsetFace = 0
 
 
@@ -769,11 +778,12 @@ class Mesh(FCurveAnimatable):
             vertices_UV2s.append([])
             vertices_UV2s.append([])
             vertices_Colors.append([])
             vertices_Colors.append([])
             vertices_indices.append([])
             vertices_indices.append([])
+            vertices_sk_weights.append([])
+            vertices_sk_indices.append([])
 
 
         materialsCount = 1 if recipe.needsBaking else max(1, len(object.material_slots))
         materialsCount = 1 if recipe.needsBaking else max(1, len(object.material_slots))
         verticesCount = 0
         verticesCount = 0
         indicesCount = 0
         indicesCount = 0
-        maxInfluencersExceeded = 0
 
 
         for materialIndex in range(materialsCount):
         for materialIndex in range(materialsCount):
             if self.offsetFace != 0:
             if self.offsetFace != 0:
@@ -797,38 +807,22 @@ class Mesh(FCurveAnimatable):
 
 
                     vertex = mesh.vertices[vertex_index]
                     vertex = mesh.vertices[vertex_index]
                     position = vertex.co
                     position = vertex.co
+                    normal = face.normal if useFlatShading else vertex.normal
                     
                     
-                    if (scene.export_noVertexOpt):
-                        normal = face.normal
-                    else:
-                        normal = vertex.normal
-
                     #skeletons
                     #skeletons
                     if hasSkeleton:
                     if hasSkeleton:
                         matricesWeights = []
                         matricesWeights = []
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesIndicesCompressed = 0
+                        matricesIndices = []
 
 
                         # Getting influences
                         # Getting influences
-                        i = 0
-                        offset = 0
                         for group in vertex.groups:
                         for group in vertex.groups:
                             index = group.group
                             index = group.group
                             weight = group.weight
                             weight = group.weight
 
 
                             for boneIndex, bone in enumerate(objArmature.pose.bones):
                             for boneIndex, bone in enumerate(objArmature.pose.bones):
                                 if object.vertex_groups[index].name == bone.name:
                                 if object.vertex_groups[index].name == bone.name:
-                                    if (i == MAX_INFLUENCERS_PER_VERTEX):
-                                        maxInfluencersExceeded += 1
-                                        break
-                                    matricesWeights[i] = weight
-                                    matricesIndicesCompressed += boneIndex << offset
-                                    offset = offset + 8
-
-                                    i = i + 1
+                                    matricesWeights.append(weight)
+                                    matricesIndices.append(boneIndex)
 
 
                     # Texture coordinates
                     # Texture coordinates
                     if hasUV:
                     if hasUV:
@@ -847,7 +841,7 @@ class Mesh(FCurveAnimatable):
                             vertex_Color = Colormap[face.index].color3
                             vertex_Color = Colormap[face.index].color3
 
 
                     # Check if the current vertex is already saved
                     # Check if the current vertex is already saved
-                    alreadySaved = alreadySavedVertices[vertex_index] and not (hasSkeleton or scene.export_noVertexOpt)
+                    alreadySaved = alreadySavedVertices[vertex_index] and not useFlatShading
                     if alreadySaved:
                     if alreadySaved:
                         alreadySaved = False
                         alreadySaved = False
 
 
@@ -873,6 +867,12 @@ class Mesh(FCurveAnimatable):
                                 if (vColor.r != vertex_Color.r or vColor.g != vertex_Color.g or vColor.b != vertex_Color.b):
                                 if (vColor.r != vertex_Color.r or vColor.g != vertex_Color.g or vColor.b != vertex_Color.b):
                                     continue
                                     continue
 
 
+                            if hasSkeleton:
+                                vSkWeight = vertices_sk_weights[vertex_index]
+                                vSkIndices = vertices_sk_indices[vertex_index]
+                                if not same_array(vSkWeight[index_UV], matricesWeights) or not same_array(vSkIndices[index_UV], matricesIndices):
+                                    continue 
+
                             if vertices_indices[vertex_index][index_UV] >= subMeshVerticesStart:
                             if vertices_indices[vertex_index][index_UV] >= subMeshVerticesStart:
                                 alreadySaved = True
                                 alreadySaved = True
                                 break
                                 break
@@ -905,11 +905,13 @@ class Mesh(FCurveAnimatable):
                             self.colors.append(vertex_Color.b)
                             self.colors.append(vertex_Color.b)
                             self.colors.append(1.0)
                             self.colors.append(1.0)
                         if hasSkeleton:
                         if hasSkeleton:
-                            self.skeletonWeights.append(matricesWeights[0])
-                            self.skeletonWeights.append(matricesWeights[1])
-                            self.skeletonWeights.append(matricesWeights[2])
-                            self.skeletonWeights.append(matricesWeights[3])
-                            self.skeletonIndicesCompressed.append(matricesIndicesCompressed)
+                            vertices_sk_weights[vertex_index].append(matricesWeights)
+                            vertices_sk_indices[vertex_index].append(matricesIndices)
+                            nInfluencers = len(matricesWeights)
+                            influenceCounts[nInfluencers] += 1
+                            highestInfluenceObserved = nInfluencers if nInfluencers > highestInfluenceObserved else highestInfluenceObserved
+                            weightsPerVertex.append(matricesWeights)
+                            indicesPerVertex.append(matricesIndices)
 
 
                         vertices_indices[vertex_index].append(index)
                         vertices_indices[vertex_index].append(index)
 
 
@@ -922,11 +924,8 @@ class Mesh(FCurveAnimatable):
             self.subMeshes.append(SubMesh(materialIndex, subMeshVerticesStart, subMeshIndexStart, verticesCount - subMeshVerticesStart, indicesCount - subMeshIndexStart))
             self.subMeshes.append(SubMesh(materialIndex, subMeshVerticesStart, subMeshIndexStart, verticesCount - subMeshVerticesStart, indicesCount - subMeshIndexStart))
 
 
         if verticesCount > MAX_VERTEX_ELEMENTS:
         if verticesCount > MAX_VERTEX_ELEMENTS:
-            Main.warn('Due to multi-materials & this meshes size, 32bit indices must be used.  This may not run on all hardware.', 2)
+            Main.warn('Due to multi-materials / Shapekeys & this meshes size, 32bit indices must be used.  This may not run on all hardware.', 2)
 
 
-        if maxInfluencersExceeded > 0:
-            Main.warn('Maximum # of influencers exceeded for ' + format_int(maxInfluencersExceeded) + ' vertices, extras ignored', 2)
-            
         BakedMaterial.meshBakingClean(object)
         BakedMaterial.meshBakingClean(object)
 
 
         Main.log('num positions      :  ' + str(len(self.positions)), 2)
         Main.log('num positions      :  ' + str(len(self.positions)), 2)
@@ -935,9 +934,29 @@ class Mesh(FCurveAnimatable):
         Main.log('num uvs2           :  ' + str(len(self.uvs2     )), 2)
         Main.log('num uvs2           :  ' + str(len(self.uvs2     )), 2)
         Main.log('num colors         :  ' + str(len(self.colors   )), 2)
         Main.log('num colors         :  ' + str(len(self.colors   )), 2)
         Main.log('num indices        :  ' + str(len(self.indices  )), 2)
         Main.log('num indices        :  ' + str(len(self.indices  )), 2)
-        if hasattr(self, 'skeletonWeights'):
-            Main.log('num skeletonWeights:  ' + str(len(self.skeletonWeights)), 2)
-            Main.log('num skeletonIndices:  ' + str(len(self.skeletonIndicesCompressed * 4)), 2)
+        if hasSkeleton:
+            Main.log('Skeleton stats:  ', 2)
+            self.toFixedInfluencers(weightsPerVertex, indicesPerVertex, object.data.maxInfluencers, highestInfluenceObserved)
+
+            if (COMPRESS_MATRIX_INDICES):
+                self.skeletonIndices = Mesh.packSkeletonIndices(self.skeletonIndices)
+                if (self.numBoneInfluencers > 4):
+                    self.skeletonIndicesExtra = Mesh.packSkeletonIndices(self.skeletonIndicesExtra)
+                
+            totalInfluencers  = influenceCounts[1]
+            totalInfluencers += influenceCounts[2] * 2
+            totalInfluencers += influenceCounts[3] * 3
+            totalInfluencers += influenceCounts[4] * 4
+            totalInfluencers += influenceCounts[5] * 5
+            totalInfluencers += influenceCounts[6] * 6
+            totalInfluencers += influenceCounts[7] * 7
+            totalInfluencers += influenceCounts[8] * 8
+            Main.log('Total Influencers:  ' + format_f(totalInfluencers), 3)
+            Main.log('Avg # of influencers per vertex:  ' + format_f(totalInfluencers / len(self.positions)), 3)
+            Main.log('Highest # of influencers observed:  ' + str(highestInfluenceObserved) + ', num vertices with this:  ' + format_int(influenceCounts[highestInfluenceObserved]), 3)
+            Main.log('exported as ' + str(self.numBoneInfluencers) + ' influencers', 3)
+            nWeights = len(self.skeletonWeights) + len(self.skeletonWeightsExtra) if hasattr(self, 'skeletonWeightsExtra') else 0
+            Main.log('num skeletonWeights and skeletonIndices:  ' + str(nWeights), 3)
 
 
         numZeroAreaFaces = self.find_zero_area_faces()
         numZeroAreaFaces = self.find_zero_area_faces()
         if numZeroAreaFaces > 0:
         if numZeroAreaFaces > 0:
@@ -969,6 +988,85 @@ class Mesh(FCurveAnimatable):
         except:
         except:
             pass
             pass
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    def toFixedInfluencers(self, weightsPerVertex, indicesPerVertex, maxInfluencers, highestObserved):
+        if (maxInfluencers > 8 or maxInfluencers < 1):
+            maxInfluencers = 8
+            Main.warn('Maximum # of influencers invalid, set to 8', 3)
+            
+        self.numBoneInfluencers = maxInfluencers if maxInfluencers < highestObserved else highestObserved
+        needExtras = self.numBoneInfluencers > 4
+        
+        maxInfluencersExceeded = 0
+        
+        fixedWeights = []
+        fixedIndices = []
+        
+        fixedWeightsExtra = []
+        fixedIndicesExtra = []
+        
+        for i in range(len(weightsPerVertex)):
+            weights = weightsPerVertex[i]
+            indices = indicesPerVertex[i]
+            nInfluencers = len(weights)
+            
+            if (nInfluencers > self.numBoneInfluencers):
+                maxInfluencersExceeded += 1
+                Mesh.sortByDescendingInfluence(weights, indices)
+                
+            for j in range(4):
+                fixedWeights.append(weights[j] if nInfluencers > j else 0.0)
+                fixedIndices.append(indices[j] if nInfluencers > j else 0  )
+                
+            if needExtras:
+                for j in range(4, 8):
+                    fixedWeightsExtra.append(weights[j] if nInfluencers > j else 0.0)
+                    fixedIndicesExtra.append(indices[j] if nInfluencers > j else 0  )
+                            
+        self.skeletonWeights = fixedWeights
+        self.skeletonIndices = fixedIndices
+        
+        if needExtras:
+            self.skeletonWeightsExtra = fixedWeightsExtra
+            self.skeletonIndicesExtra = fixedIndicesExtra
+            
+        if maxInfluencersExceeded > 0:
+            Main.warn('Maximum # of influencers exceeded for ' + format_int(maxInfluencersExceeded) + ' vertices, extras ignored', 3)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # sorts one set of weights & indices by descending weight, by reference
+    # not shown to help with MakeHuman, but did not hurt.  In just so it is not lost for future.
+    @staticmethod
+    def sortByDescendingInfluence(weights, indices):
+        notSorted = True
+        while(notSorted):
+            notSorted = False
+            for idx in range(1, len(weights)):
+                if weights[idx - 1] < weights[idx]:
+                    tmp = weights[idx]
+                    weights[idx    ] = weights[idx - 1]
+                    weights[idx - 1] = tmp
+                    
+                    tmp = indices[idx]
+                    indices[idx    ] = indices[idx - 1]
+                    indices[idx - 1] = tmp
+                    
+                    notSorted = True    
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # assume that toFixedInfluencers has already run, which ensures indices length is a multiple of 4
+    @staticmethod
+    def packSkeletonIndices(indices):
+        compressedIndices = []
+
+        for i in range(math.floor(len(indices) / 4)):
+            idx = i * 4
+            matricesIndicesCompressed  = indices[idx    ]
+            matricesIndicesCompressed += indices[idx + 1] <<  8
+            matricesIndicesCompressed += indices[idx + 2] << 16
+            matricesIndicesCompressed += indices[idx + 3] << 24
+            
+            compressedIndices.append(matricesIndicesCompressed)
+            
+        return compressedIndices
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
     def to_scene_file(self, file_handler):
         file_handler.write('{')
         file_handler.write('{')
         write_string(file_handler, 'name', self.name, True)
         write_string(file_handler, 'name', self.name, True)
@@ -988,7 +1086,6 @@ class Mesh(FCurveAnimatable):
         write_bool(file_handler, 'isVisible', self.isVisible)
         write_bool(file_handler, 'isVisible', self.isVisible)
         write_bool(file_handler, 'freezeWorldMatrix', self.freezeWorldMatrix)
         write_bool(file_handler, 'freezeWorldMatrix', self.freezeWorldMatrix)
         write_bool(file_handler, 'isEnabled', self.isEnabled)
         write_bool(file_handler, 'isEnabled', self.isEnabled)
-        write_bool(file_handler, 'useFlatShading', self.useFlatShading)
         write_bool(file_handler, 'checkCollisions', self.checkCollisions)
         write_bool(file_handler, 'checkCollisions', self.checkCollisions)
         write_bool(file_handler, 'receiveShadows', self.receiveShadows)
         write_bool(file_handler, 'receiveShadows', self.receiveShadows)
 
 
@@ -999,7 +1096,10 @@ class Mesh(FCurveAnimatable):
             write_float(file_handler, 'physicsRestitution', self.physicsRestitution)
             write_float(file_handler, 'physicsRestitution', self.physicsRestitution)
 
 
         # Geometry
         # Geometry
-        if hasattr(self, 'skeletonId'): write_int(file_handler, 'skeletonId', self.skeletonId)
+        if hasattr(self, 'skeletonId'): 
+            write_int(file_handler, 'skeletonId', self.skeletonId)
+            write_int(file_handler, 'numBoneInfluencers', self.numBoneInfluencers)
+
         write_vector_array(file_handler, 'positions', self.positions)
         write_vector_array(file_handler, 'positions', self.positions)
         write_vector_array(file_handler, 'normals'  , self.normals  )
         write_vector_array(file_handler, 'normals'  , self.normals  )
 
 
@@ -1014,7 +1114,11 @@ class Mesh(FCurveAnimatable):
 
 
         if hasattr(self, 'skeletonWeights'):
         if hasattr(self, 'skeletonWeights'):
             write_array(file_handler, 'matricesWeights', self.skeletonWeights)
             write_array(file_handler, 'matricesWeights', self.skeletonWeights)
-            write_array(file_handler, 'matricesIndices', self.skeletonIndicesCompressed)
+            write_array(file_handler, 'matricesIndices', self.skeletonIndices)
+
+        if hasattr(self, 'skeletonWeightsExtra'):
+            write_array(file_handler, 'matricesWeightsExtra', self.skeletonWeightsExtra)
+            write_array(file_handler, 'matricesIndicesExtra', self.skeletonIndicesExtra)
 
 
         write_array(file_handler, 'indices', self.indices)
         write_array(file_handler, 'indices', self.indices)
 
 
@@ -1135,7 +1239,7 @@ class SubMesh:
 #===============================================================================
 #===============================================================================
 class Bone:
 class Bone:
     def __init__(self, bone, skeleton, scene, index):
     def __init__(self, bone, skeleton, scene, index):
-        Main.log('processing begun of bone:  ' + bone.name + ', index:  '+ str(index))
+        Main.log('processing begun of bone:  ' + bone.name + ', index:  '+ str(index), 2)
         self.name = bone.name
         self.name = bone.name
         self.index = index
         self.index = index
 
 
@@ -1153,7 +1257,7 @@ class Bone:
 
 
         #animation
         #animation
         if (skeleton.animation_data):
         if (skeleton.animation_data):
-            Main.log('animation begun of bone:  ' + self.name)
+            Main.log('animation begun of bone:  ' + self.name, 3)
             self.animation = Animation(ANIMATIONTYPE_MATRIX, scene.render.fps, ANIMATIONLOOPMODE_CYCLE, 'anim', '_matrix')
             self.animation = Animation(ANIMATIONTYPE_MATRIX, scene.render.fps, ANIMATIONLOOPMODE_CYCLE, 'anim', '_matrix')
 
 
             start_frame = scene.frame_start
             start_frame = scene.frame_start
@@ -1668,7 +1772,7 @@ class BakingRecipe:
                         continue
                         continue
                     
                     
                     # for images, just need to make sure there is only 1 per type
                     # for images, just need to make sure there is only 1 per type
-                    if mtex.texture.type == 'IMAGE':
+                    if mtex.texture.type == 'IMAGE' and not forceBaking:
                         if mtex.use_map_diffuse or mtex.use_map_color_diffuse:
                         if mtex.use_map_diffuse or mtex.use_map_color_diffuse:
                             if mtex.texture_coords == 'REFLECTION':
                             if mtex.texture_coords == 'REFLECTION':
                                 nReflectionImages += 1
                                 nReflectionImages += 1
@@ -1739,10 +1843,8 @@ class BakingRecipe:
 #===============================================================================
 #===============================================================================
 # Not intended to be instanced directly
 # Not intended to be instanced directly
 class Material:
 class Material:
-    def __init__(self):
-        # the number of users == 1 will cause the checkReadyOnlyOnce attribute to be set to true
-        self.numOfUsers = 1
-
+    def __init__(self, checkReadyOnlyOnce):
+        self.checkReadyOnlyOnce = checkReadyOnlyOnce
         # first pass of textures, either appending image type or recording types of bakes to do
         # first pass of textures, either appending image type or recording types of bakes to do
         self.textures = []
         self.textures = []
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1757,8 +1859,7 @@ class Material:
         write_float(file_handler, 'specularPower', self.specularPower)
         write_float(file_handler, 'specularPower', self.specularPower)
         write_float(file_handler, 'alpha', self.alpha)
         write_float(file_handler, 'alpha', self.alpha)
         write_bool(file_handler, 'backFaceCulling', self.backFaceCulling)
         write_bool(file_handler, 'backFaceCulling', self.backFaceCulling)
-        if self.numOfUsers == 1:
-             write_bool(file_handler, 'checkReadyOnlyOnce', True)
+        write_bool(file_handler, 'checkReadyOnlyOnce', self.checkReadyOnlyOnce)
         for texSlot in self.textures:
         for texSlot in self.textures:
             texSlot.to_scene_file(file_handler)
             texSlot.to_scene_file(file_handler)
 
 
@@ -1766,8 +1867,10 @@ class Material:
 #===============================================================================
 #===============================================================================
 class StdMaterial(Material):
 class StdMaterial(Material):
     def __init__(self, material_slot, exporter, mesh):
     def __init__(self, material_slot, exporter, mesh):
-        super().__init__()
-        self.name = Main.nameSpace + '.' + material_slot.name
+        super().__init__(mesh.data.checkReadyOnlyOnce)
+        nameSpace = Main.nameSpace if mesh.data.materialNameSpace == DEFAULT_MATERIAL_NAMESPACE else mesh.data.materialNameSpace 
+        self.name = nameSpace + '.' + material_slot.name
+                
         Main.log('processing begun of Standard material:  ' +  material_slot.name, 2)
         Main.log('processing begun of Standard material:  ' +  material_slot.name, 2)
 
 
         # a material slot is not a reference to an actual material; need to look up
         # a material slot is not a reference to an actual material; need to look up
@@ -1796,36 +1899,41 @@ class StdMaterial(Material):
 
 
             if mtex.use_map_diffuse or mtex.use_map_color_diffuse:
             if mtex.use_map_diffuse or mtex.use_map_color_diffuse:
                 if mtex.texture_coords == 'REFLECTION':
                 if mtex.texture_coords == 'REFLECTION':
-                    Main.log('Reflection texture found', 2)
+                    Main.log('Reflection texture found"' + mtex.name + '"', 2)
                     self.textures.append(Texture('reflectionTexture', mtex.diffuse_color_factor, mtex, mesh, exporter))
                     self.textures.append(Texture('reflectionTexture', mtex.diffuse_color_factor, mtex, mesh, exporter))
                 else:
                 else:
-                    Main.log('Diffuse texture found', 2)
+                    Main.log('Diffuse texture found"' + mtex.name + '"', 2)
                     self.textures.append(Texture('diffuseTexture', mtex.diffuse_color_factor, mtex, mesh, exporter))
                     self.textures.append(Texture('diffuseTexture', mtex.diffuse_color_factor, mtex, mesh, exporter))
 
 
             if mtex.use_map_ambient:
             if mtex.use_map_ambient:
-                Main.log('Ambient texture found', 2)
+                Main.log('Ambient texture found"' + mtex.name + '"', 2)
                 self.textures.append(Texture('ambientTexture', mtex.ambient_factor, mtex, mesh, exporter))
                 self.textures.append(Texture('ambientTexture', mtex.ambient_factor, mtex, mesh, exporter))
 
 
             if mtex.use_map_alpha:
             if mtex.use_map_alpha:
-                Main.log('Opacity texture found', 2)
-                self.textures.append(Texture('opacityTexture', mtex.alpha_factor, mtex, mesh, exporter))
+                if self.alpha > 0:
+                    Main.log('Opacity texture found"' + mtex.name + '"', 2)
+                    self.textures.append(Texture('opacityTexture', mtex.alpha_factor, mtex, mesh, exporter))
+                else:
+                    Main.warn('Opacity non-std way to indicate opacity, use material alpha to also use Opacity texture', 2)
+                    self.alpha = 1
 
 
             if mtex.use_map_emit:
             if mtex.use_map_emit:
-                Main.log('Emissive texture found', 2)
+                Main.log('Emissive texture found"' + mtex.name + '"', 2)
                 self.textures.append(Texture('emissiveTexture', mtex.emit_factor, mtex, mesh, exporter))
                 self.textures.append(Texture('emissiveTexture', mtex.emit_factor, mtex, mesh, exporter))
 
 
             if mtex.use_map_normal:
             if mtex.use_map_normal:
-                Main.log('Bump texture found', 2)
+                Main.log('Bump texture found"' + mtex.name + '"', 2)
                 self.textures.append(Texture('bumpTexture', 1.0 / mtex.normal_factor, mtex, mesh, exporter))
                 self.textures.append(Texture('bumpTexture', 1.0 / mtex.normal_factor, mtex, mesh, exporter))
 
 
             if mtex.use_map_color_spec:
             if mtex.use_map_color_spec:
-                Main.log('Specular texture found', 2)
+                Main.log('Specular texture found"' + mtex.name + '"', 2)
                 self.textures.append(Texture('specularTexture', mtex.specular_color_factor, mtex, mesh, exporter))
                 self.textures.append(Texture('specularTexture', mtex.specular_color_factor, mtex, mesh, exporter))
 #===============================================================================
 #===============================================================================
 class BakedMaterial(Material):
 class BakedMaterial(Material):
     def __init__(self, exporter, mesh, recipe):
     def __init__(self, exporter, mesh, recipe):
-        super().__init__()
-        self.name = Main.nameSpace + '.' + mesh.name
+        super().__init__(mesh.data.checkReadyOnlyOnce)
+        nameSpace = Main.nameSpace if mesh.data.materialNameSpace == DEFAULT_MATERIAL_NAMESPACE else mesh.data.materialNameSpace 
+        self.name = nameSpace + '.' + mesh.name
         Main.log('processing begun of baked material:  ' +  mesh.name, 2)
         Main.log('processing begun of baked material:  ' +  mesh.name, 2)
 
 
         # any baking already took in the values. Do not want to apply them again, but want shadows to show.
         # any baking already took in the values. Do not want to apply them again, but want shadows to show.
@@ -1851,11 +1959,7 @@ class BakedMaterial(Material):
 
 
         # you need UV on a mesh in order to bake image.  This is not reqd for procedural textures, so may not exist
         # you need UV on a mesh in order to bake image.  This is not reqd for procedural textures, so may not exist
         # need to look if it might already be created, as for a mesh with multi-materials
         # need to look if it might already be created, as for a mesh with multi-materials
-        uv = None
-        for uvMap in mesh.data.uv_textures:
-            if uvMap.name == 'BakingUV':
-                uv = uvMap
-                break
+        uv = mesh.data.uv_textures[0] if len(mesh.data.uv_textures) > 0 else None
 
 
         if uv == None:
         if uv == None:
             mesh.data.uv_textures.new('BakingUV')
             mesh.data.uv_textures.new('BakingUV')
@@ -1883,25 +1987,25 @@ class BakedMaterial(Material):
 
 
         # now go thru all the textures that need to be baked
         # now go thru all the textures that need to be baked
         if recipe.diffuseBaking:
         if recipe.diffuseBaking:
-            self.bake('diffuseTexture', 'DIFFUSE_COLOR', 'TEXTURE', image, mesh, exporter, recipe)
+            self.bake('diffuseTexture', 'DIFFUSE_COLOR', 'TEXTURE', image, mesh, uv, exporter, recipe)
 
 
         if recipe.ambientBaking:
         if recipe.ambientBaking:
-            self.bake('ambientTexture', 'AO', 'AO', image, mesh, exporter, recipe)
+            self.bake('ambientTexture', 'AO', 'AO', image, mesh, uv, exporter, recipe)
 
 
         if recipe.opacityBaking:  # no eqivalent found for cycles
         if recipe.opacityBaking:  # no eqivalent found for cycles
-            self.bake('opacityTexture', None, 'ALPHA', image, mesh, exporter, recipe)
+            self.bake('opacityTexture', None, 'ALPHA', image, mesh, uv, exporter, recipe)
 
 
         if recipe.reflectionBaking:
         if recipe.reflectionBaking:
-            self.bake('reflectionTexture', 'REFLECTION', 'MIRROR_COLOR', image, mesh, exporter, recipe)
+            self.bake('reflectionTexture', 'REFLECTION', 'MIRROR_COLOR', image, mesh, uv, exporter, recipe)
 
 
         if recipe.emissiveBaking:
         if recipe.emissiveBaking:
-            self.bake('emissiveTexture', 'EMIT', 'EMIT', image, mesh, exporter, recipe)
+            self.bake('emissiveTexture', 'EMIT', 'EMIT', image, mesh, uv, exporter, recipe)
 
 
         if recipe.bumpBaking:
         if recipe.bumpBaking:
-            self.bake('bumpTexture', 'NORMAL', 'NORMALS', image, mesh, exporter, recipe)
+            self.bake('bumpTexture', 'NORMAL', 'NORMALS', image, mesh, uv, exporter, recipe)
 
 
         if recipe.specularBaking:
         if recipe.specularBaking:
-            self.bake('specularTexture', 'SPECULAR', 'SPEC_COLOR', image, mesh, exporter, recipe)
+            self.bake('specularTexture', 'SPECULAR', 'SPEC_COLOR', image, mesh, uv, exporter, recipe)
 
 
         # Toggle vertex selection & mode, if setting changed their value
         # Toggle vertex selection & mode, if setting changed their value
         bpy.ops.mesh.select_all(action='TOGGLE')  # still in edit mode toggle select back to previous
         bpy.ops.mesh.select_all(action='TOGGLE')  # still in edit mode toggle select back to previous
@@ -1911,19 +2015,21 @@ class BakedMaterial(Material):
 
 
         exporter.scene.render.engine = engine
         exporter.scene.render.engine = engine
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def bake(self, bjs_type, cycles_type, internal_type, image, mesh, exporter, recipe):
+    def bake(self, bjs_type, cycles_type, internal_type, image, mesh, uv, exporter, recipe):
         if recipe.cyclesRender:
         if recipe.cyclesRender:
             if cycles_type is None:
             if cycles_type is None:
                 return
                 return
-            self.bakeCycles(cycles_type, image, recipe.nodeTrees)
+            self.bakeCycles(cycles_type, image, uv, recipe.nodeTrees)
         else:
         else:
-            self.bakeInternal(internal_type, image)
+            self.bakeInternal(internal_type, image, uv)
 
 
         self.textures.append(Texture(bjs_type, 1.0, image, mesh, exporter))
         self.textures.append(Texture(bjs_type, 1.0, image, mesh, exporter))
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def bakeInternal(self, bake_type, image):
-        Main.log('Internal baking texture, type: ' + bake_type + ', mapped using: BakingUV', 3)
-        image.filepath = self.name + '_' + bake_type + '.jpg'
+    def bakeInternal(self, bake_type, image, uv):
+        Main.log('Internal baking texture, type: ' + bake_type + ', mapped using: ' + uv.name, 3)
+        # need to use the legal name, since this will become the file name, chars like ':' not legal
+        legalName = legal_js_identifier(self.name)
+        image.filepath = legalName + '_' + bake_type + '.jpg'
 
 
         scene = bpy.context.scene
         scene = bpy.context.scene
         scene.render.engine = 'BLENDER_RENDER'
         scene.render.engine = 'BLENDER_RENDER'
@@ -1946,9 +2052,10 @@ class BakedMaterial(Material):
 
 
         bpy.ops.object.bake_image()
         bpy.ops.object.bake_image()
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def bakeCycles(self, bake_type, image, nodeTrees):
-        Main.log('Cycles baking texture, type: ' + bake_type + ', mapped using: BakingUV', 3)
-        image.filepath = self.name + '_' + bake_type + '.jpg'
+    def bakeCycles(self, bake_type, image, uv, nodeTrees):
+        Main.log('Cycles baking texture, type: ' + bake_type + ', mapped using: ' + uv.name, 3)
+        legalName = legal_js_identifier(self.name)
+        image.filepath = legalName + '_' + bake_type + '.jpg'
 
 
         scene = bpy.context.scene
         scene = bpy.context.scene
         scene.render.engine = 'CYCLES'
         scene.render.engine = 'CYCLES'
@@ -2199,6 +2306,13 @@ def scale_vector(vector, mult, xOffset = 0):
 
 
 def same_vertex(vertA, vertB):
 def same_vertex(vertA, vertB):
     return vertA.x == vertB.x and vertA.y == vertB.y and vertA.z == vertB.z
     return vertA.x == vertB.x and vertA.y == vertB.y and vertA.z == vertB.z
+
+def same_array(arrayA, arrayB):
+    if len(arrayA) != len(arrayB): return False
+    for i in range(len(arrayA)):
+        if arrayA[i] != arrayB[i] : return False
+        
+    return True
 #===============================================================================
 #===============================================================================
 # module level methods for writing JSON (.babylon) files
 # module level methods for writing JSON (.babylon) files
 #===============================================================================
 #===============================================================================
@@ -2250,7 +2364,7 @@ bpy.types.Mesh.autoAnimate = bpy.props.BoolProperty(
 )
 )
 bpy.types.Mesh.useFlatShading = bpy.props.BoolProperty(
 bpy.types.Mesh.useFlatShading = bpy.props.BoolProperty(
     name='Use Flat Shading',
     name='Use Flat Shading',
-    description='',
+    description='Use face normals.  Increases vertices.',
     default = False
     default = False
 )
 )
 bpy.types.Mesh.checkCollisions = bpy.props.BoolProperty(
 bpy.types.Mesh.checkCollisions = bpy.props.BoolProperty(
@@ -2276,13 +2390,28 @@ bpy.types.Mesh.bakeSize = bpy.props.IntProperty(
 bpy.types.Mesh.bakeQuality = bpy.props.IntProperty(
 bpy.types.Mesh.bakeQuality = bpy.props.IntProperty(
     name='Quality 1-100',
     name='Quality 1-100',
     description='The trade-off between Quality - File size(100 highest quality)',
     description='The trade-off between Quality - File size(100 highest quality)',
-    default = 50
+    default = 50, min = 1, max = 100
+)
+bpy.types.Mesh.materialNameSpace = bpy.props.StringProperty(
+    name='Name Space',
+    description='Prefix to use for materials for sharing across .blends.',
+    default = DEFAULT_MATERIAL_NAMESPACE
+)
+bpy.types.Mesh.checkReadyOnlyOnce = bpy.props.BoolProperty(
+    name='Check Ready Only Once',
+    description='When checked better CPU utilization.  Advanced user option.',
+    default = False
 )
 )
 bpy.types.Mesh.freezeWorldMatrix = bpy.props.BoolProperty(
 bpy.types.Mesh.freezeWorldMatrix = bpy.props.BoolProperty(
     name='Freeze World Matrix',
     name='Freeze World Matrix',
     description='Indicate the position, rotation, & scale do not change for performance reasons',
     description='Indicate the position, rotation, & scale do not change for performance reasons',
     default = False
     default = False
 )
 )
+bpy.types.Mesh.loadDisabled = bpy.props.BoolProperty(
+    name='Load Disabled',
+    description='Indicate this mesh & children should not be active until enabled by code.',
+    default = False
+)
 bpy.types.Mesh.attachedSound = bpy.props.StringProperty(
 bpy.types.Mesh.attachedSound = bpy.props.StringProperty(
     name='Sound',
     name='Sound',
     description='',
     description='',
@@ -2303,6 +2432,11 @@ bpy.types.Mesh.maxSoundDistance = bpy.props.FloatProperty(
     description='',
     description='',
     default = 100
     default = 100
 )
 )
+bpy.types.Mesh.maxInfluencers = bpy.props.IntProperty(
+    name='Max bone Influencers / Vertex',
+    description='When fewer than this are observed, the lower value is used.',
+    default = 8, min = 1, max = 8
+)
 #===============================================================================
 #===============================================================================
 bpy.types.Camera.autoAnimate = bpy.props.BoolProperty(
 bpy.types.Camera.autoAnimate = bpy.props.BoolProperty(
     name='Auto launch animations',
     name='Auto launch animations',
@@ -2417,22 +2551,31 @@ class ObjectPanel(bpy.types.Panel):
         isLight = isinstance(ob.data, bpy.types.Lamp)
         isLight = isinstance(ob.data, bpy.types.Lamp)
 
 
         if isMesh:
         if isMesh:
-            layout.prop(ob.data, 'useFlatShading')
-            layout.prop(ob.data, 'checkCollisions')
-            layout.prop(ob.data, 'castShadows')
-            layout.prop(ob.data, 'receiveShadows')
-
-            layout.separator()
-
-            layout.prop(ob.data, 'autoAnimate')
+            row = layout.row()
+            row.prop(ob.data, 'useFlatShading')
+            row.prop(ob.data, 'checkCollisions')
+            
+            row = layout.row()
+            row.prop(ob.data, 'castShadows')
+            row.prop(ob.data, 'receiveShadows')
+            
+            row = layout.row()
+            row.prop(ob.data, 'freezeWorldMatrix')
+            row.prop(ob.data, 'loadDisabled')
+            
+            layout.prop(ob.data, 'autoAnimate')            
+            layout.prop(ob.data, 'maxInfluencers')
 
 
             box = layout.box()
             box = layout.box()
-            box.label(text="Procedural Texture / Cycles Baking")
+            box.label('Materials')
+            box.prop(ob.data, 'materialNameSpace')
+            box.prop(ob.data, 'checkReadyOnlyOnce')
+            
+            box = layout.box()
+            box.label(text='Procedural Texture / Cycles Baking')
             box.prop(ob.data, 'bakeSize')
             box.prop(ob.data, 'bakeSize')
             box.prop(ob.data, 'bakeQuality')
             box.prop(ob.data, 'bakeQuality')
 
 
-            layout.prop(ob.data, 'freezeWorldMatrix')
-
             box = layout.box()
             box = layout.box()
             box.prop(ob.data, 'attachedSound')
             box.prop(ob.data, 'attachedSound')
             box.prop(ob.data, 'autoPlaySound')
             box.prop(ob.data, 'autoPlaySound')
@@ -2463,4 +2606,3 @@ class ObjectPanel(bpy.types.Panel):
             box.prop(ob.data, 'shadowBlurBoxOffset')
             box.prop(ob.data, 'shadowBlurBoxOffset')
 
 
             layout.prop(ob.data, 'autoAnimate')
             layout.prop(ob.data, 'autoAnimate')
-

+ 4 - 0
Exporters/Blender/readme.md

@@ -31,6 +31,7 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Animations
  * Animations
 * **Materials**
 * **Materials**
  * Name
  * Name
+ * Name space
  * Ambient color
  * Ambient color
  * Diffuse color
  * Diffuse color
  * Specular color
  * Specular color
@@ -46,6 +47,7 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Bump texture
  * Bump texture
  * Procedural Texture Baking
  * Procedural Texture Baking
  * Cycles Render Baking
  * Cycles Render Baking
+ * Check Ready Only Once
 * **Multi-materials**
 * **Multi-materials**
  * Name
  * Name
  * Child materials
  * Child materials
@@ -71,10 +73,12 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Texture coordinates (2 channels)
  * Texture coordinates (2 channels)
  * Vertex colors
  * Vertex colors
  * Visibility
  * Visibility
+ * Load disabled
  * Check collisions
  * Check collisions
  * Billboard
  * Billboard
  * Receive and cast shadows
  * Receive and cast shadows
  * Bones (armatures) and bones' animations
  * Bones (armatures) and bones' animations
+ 	* Variable Max Bone Influencers / vertex
  * Animations
  * Animations
 
 
 
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 16 - 16
dist/preview release/babylon.core.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 939 - 939
dist/preview release/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 15 - 15
dist/preview release/babylon.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 23 - 5
dist/preview release/babylon.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 19 - 19
dist/preview release/babylon.noworker.js


+ 11 - 5
loaders/glTF/README.md

@@ -5,7 +5,7 @@ The glTF file loader is a SceneLoader plugin.
 Just reference the loader in your HTML file:
 Just reference the loader in your HTML file:
 
 
 ```
 ```
-<script src="babylon.2.1.js"></script>
+<script src="babylon.2.2.js"></script>
 <script src="babylon.glTFFileLoader.js"></script>
 <script src="babylon.glTFFileLoader.js"></script>
 ```
 ```
 
 
@@ -16,8 +16,17 @@ BABYLON.SceneLoader.Load("./", "duck.gltf", engine, function (scene) {
 });
 });
 ```
 ```
 
 
+You can also call the ImportMesh function and import specific meshes
+```
+// meshesNames can be set to "null" to load all meshes and skeletons
+BABYLON.SceneLoader.ImportMesh(["myMesh1", "myMesh2", "..."], "./", "duck.gltf", scene, function (meshes, particleSystems, skeletons) { 
+   // do somethings with the meshes, particleSystems (not handled in glTF files) and skeletons
+});
+```
+
 ## Supported features
 ## Supported features
-* Load scenes (SceneLoader.Load)
+* Load scenes (SceneLoader.Load and SceneLoader.Append)
+* Support of ImportMesh function
 * Import geometries
 * Import geometries
     * From binary files
     * From binary files
     * From base64 buffers
     * From base64 buffers
@@ -34,8 +43,5 @@ BABYLON.SceneLoader.Load("./", "duck.gltf", engine, function (scene) {
     * Bones import
     * Bones import
 * Handle dummy nodes (empty nodes)
 * Handle dummy nodes (empty nodes)
 
 
-## Unsupported features
-* ImportMesh function
-
 ## To improve
 ## To improve
 * Test on more models
 * Test on more models

+ 124 - 24
loaders/glTF/babylon.glTFFileLoader.js

@@ -447,8 +447,13 @@ var BABYLON;
     /**
     /**
     * Imports a skeleton
     * Imports a skeleton
     */
     */
-    var importSkeleton = function (gltfRuntime, skins, mesh) {
-        var newSkeleton = new BABYLON.Skeleton(skins.name, "", gltfRuntime.scene);
+    var importSkeleton = function (gltfRuntime, skins, mesh, newSkeleton) {
+        if (!newSkeleton) {
+            newSkeleton = new BABYLON.Skeleton(skins.name, "", gltfRuntime.scene);
+        }
+        if (!skins.babylonSkeleton) {
+            return newSkeleton;
+        }
         // Matrices
         // Matrices
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
         var buffer = getBufferFromAccessor(gltfRuntime, accessor);
         var buffer = getBufferFromAccessor(gltfRuntime, accessor);
@@ -533,9 +538,14 @@ var BABYLON;
     /**
     /**
     * Imports a mesh and its geometries
     * Imports a mesh and its geometries
     */
     */
-    var importMesh = function (gltfRuntime, node, meshes, id, skin) {
-        var newMesh = new BABYLON.Mesh(node.name, gltfRuntime.scene);
-        newMesh.id = id;
+    var importMesh = function (gltfRuntime, node, meshes, id, newMesh) {
+        if (!newMesh) {
+            newMesh = new BABYLON.Mesh(node.name, gltfRuntime.scene);
+            newMesh.id = id;
+        }
+        if (!node.babylonNode) {
+            return newMesh;
+        }
         var multiMat = new BABYLON.MultiMaterial("multimat" + id, gltfRuntime.scene);
         var multiMat = new BABYLON.MultiMaterial("multimat" + id, gltfRuntime.scene);
         newMesh.material = multiMat;
         newMesh.material = multiMat;
         var vertexData = new BABYLON.VertexData();
         var vertexData = new BABYLON.VertexData();
@@ -555,7 +565,7 @@ var BABYLON;
                 // Temporary vertex data
                 // Temporary vertex data
                 var tempVertexData = new BABYLON.VertexData();
                 var tempVertexData = new BABYLON.VertexData();
                 var primitive = mesh.primitives[i];
                 var primitive = mesh.primitives[i];
-                if (primitive.primitive !== 4) {
+                if (primitive.mode !== 4) {
                 }
                 }
                 var attributes = primitive.attributes;
                 var attributes = primitive.attributes;
                 var accessor = null;
                 var accessor = null;
@@ -639,7 +649,7 @@ var BABYLON;
                 continue;
                 continue;
             }
             }
             for (var i = 0; i < mesh.primitives.length; i++) {
             for (var i = 0; i < mesh.primitives.length; i++) {
-                if (mesh.primitives[i].primitive !== 4) {
+                if (mesh.primitives[i].mode !== 4) {
                 }
                 }
                 var subMesh = new BABYLON.SubMesh(index, verticesStarts[index], verticesCounts[index], indexStarts[index], indexCounts[index], newMesh, newMesh, true);
                 var subMesh = new BABYLON.SubMesh(index, verticesStarts[index], verticesCounts[index], indexStarts[index], indexCounts[index], newMesh, newMesh, true);
                 index++;
                 index++;
@@ -687,14 +697,22 @@ var BABYLON;
     */
     */
     var importNode = function (gltfRuntime, node, id) {
     var importNode = function (gltfRuntime, node, id) {
         var lastNode = null;
         var lastNode = null;
+        if (gltfRuntime.importOnlyMeshes && (node.skin || node.meshes)) {
+            if (gltfRuntime.importMeshesNames.length > 0 && gltfRuntime.importMeshesNames.indexOf(node.name) === -1) {
+                return null;
+            }
+        }
         // Meshes
         // Meshes
         if (node.skin) {
         if (node.skin) {
             if (node.meshes) {
             if (node.meshes) {
                 var skin = gltfRuntime.skins[node.skin];
                 var skin = gltfRuntime.skins[node.skin];
-                var newMesh = importMesh(gltfRuntime, node, node.meshes, id, skin);
+                var newMesh = importMesh(gltfRuntime, node, node.meshes, id, node.babylonNode);
                 newMesh.skeleton = gltfRuntime.scene.getLastSkeletonByID(node.skin);
                 newMesh.skeleton = gltfRuntime.scene.getLastSkeletonByID(node.skin);
                 if (newMesh.skeleton === null) {
                 if (newMesh.skeleton === null) {
-                    newMesh.skeleton = importSkeleton(gltfRuntime, skin, newMesh);
+                    newMesh.skeleton = importSkeleton(gltfRuntime, skin, newMesh, skin.babylonSkeleton);
+                    if (!skin.babylonSkeleton) {
+                        skin.babylonSkeleton = newMesh.skeleton;
+                    }
                 }
                 }
                 if (newMesh.skeleton !== null) {
                 if (newMesh.skeleton !== null) {
                     newMesh.useBones = true;
                     newMesh.useBones = true;
@@ -706,10 +724,10 @@ var BABYLON;
             /**
             /**
             * Improve meshes property
             * Improve meshes property
             */
             */
-            var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id);
+            var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id, node.babylonNode);
             lastNode = newMesh;
             lastNode = newMesh;
         }
         }
-        else if (node.light) {
+        else if (node.light && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var light = gltfRuntime.lights[node.light];
             var light = gltfRuntime.lights[node.light];
             if (light) {
             if (light) {
                 if (light.type === "ambient") {
                 if (light.type === "ambient") {
@@ -756,7 +774,7 @@ var BABYLON;
                 }
                 }
             }
             }
         }
         }
-        else if (node.camera) {
+        else if (node.camera && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var camera = gltfRuntime.cameras[node.camera];
             var camera = gltfRuntime.cameras[node.camera];
             if (camera) {
             if (camera) {
                 if (camera.type === "orthographic") {
                 if (camera.type === "orthographic") {
@@ -784,9 +802,15 @@ var BABYLON;
             }
             }
         }
         }
         // Empty node
         // Empty node
-        if (lastNode === null && !node.jointName) {
-            var dummy = new BABYLON.Mesh(node.name, gltfRuntime.scene);
-            lastNode = dummy;
+        if (!node.jointName) {
+            if (node.babylonNode) {
+                return node.babylonNode;
+            }
+            else if (lastNode === null) {
+                var dummy = new BABYLON.Mesh(node.name, gltfRuntime.scene);
+                node.babylonNode = dummy;
+                lastNode = dummy;
+            }
         }
         }
         if (lastNode !== null) {
         if (lastNode !== null) {
             if (node.matrix) {
             if (node.matrix) {
@@ -796,19 +820,48 @@ var BABYLON;
                 configureNode(lastNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray(node.rotation).normalize(), node.rotation[3]), BABYLON.Vector3.FromArray(node.scale));
                 configureNode(lastNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray(node.rotation).normalize(), node.rotation[3]), BABYLON.Vector3.FromArray(node.scale));
             }
             }
             lastNode.updateCache(true);
             lastNode.updateCache(true);
+            node.babylonNode = lastNode;
         }
         }
         return lastNode;
         return lastNode;
     };
     };
-    var traverseNodes = function (gltfRuntime, id, parent) {
+    /**
+    * Util for ImportMesh function, checks if a given node
+    * is a descendant of the included mesh(es)
+    */
+    var nodeIsDescendantOf = function (node, gltfRuntime) {
+        for (var nde in gltfRuntime.nodes) {
+            var n = gltfRuntime.nodes[nde];
+            for (var i = 0; i < n.children.length; i++) {
+            }
+        }
+        return false;
+    };
+    /**
+    * Traverses nodes and creates them
+    */
+    var traverseNodes = function (gltfRuntime, id, parent, meshIncluded) {
         var node = gltfRuntime.nodes[id];
         var node = gltfRuntime.nodes[id];
         var newNode = null;
         var newNode = null;
-        if (!node.jointName) {
+        if (gltfRuntime.importOnlyMeshes && !meshIncluded) {
+            if (gltfRuntime.importMeshesNames.indexOf(node.name) !== -1 || gltfRuntime.importMeshesNames.length === 0) {
+                meshIncluded = true;
+            }
+            else {
+                meshIncluded = false;
+            }
+        }
+        else {
+            meshIncluded = true;
+        }
+        if (!node.jointName && meshIncluded) {
             newNode = importNode(gltfRuntime, node, id);
             newNode = importNode(gltfRuntime, node, id);
-            newNode.id = id;
-            newNode.parent = parent;
+            if (newNode !== null) {
+                newNode.id = id;
+                newNode.parent = parent;
+            }
         }
         }
         for (var i = 0; i < node.children.length; i++) {
         for (var i = 0; i < node.children.length; i++) {
-            traverseNodes(gltfRuntime, node.children[i], newNode);
+            traverseNodes(gltfRuntime, node.children[i], newNode, meshIncluded);
         }
         }
     };
     };
     /**
     /**
@@ -1206,6 +1259,39 @@ var BABYLON;
         * Import meshes
         * Import meshes
         */
         */
         GLTFFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
         GLTFFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
+            var parsedData = JSON.parse(data);
+            var gltfRuntime = this._createGlTFRuntime(parsedData, scene, rootUrl);
+            gltfRuntime.importOnlyMeshes = true;
+            if (meshesNames === "") {
+                gltfRuntime.importMeshesNames = [];
+            }
+            else if (typeof meshesNames === "string") {
+                gltfRuntime.importMeshesNames = [meshesNames];
+            }
+            else if (meshesNames && !(meshesNames instanceof Array)) {
+                gltfRuntime.importMeshesNames = [meshesNames];
+            }
+            else {
+                gltfRuntime.importMeshesNames = [];
+                BABYLON.Tools.Warn("Argument meshesNames must be of type string or string[]");
+            }
+            // Create nodes
+            this._createNodes(gltfRuntime);
+            // Fill arrays of meshes and skeletons
+            for (var nde in gltfRuntime.nodes) {
+                var node = gltfRuntime.nodes[nde];
+                if (node.babylonNode instanceof BABYLON.AbstractMesh) {
+                    meshes.push(node.babylonNode);
+                }
+            }
+            for (var skl in gltfRuntime.skins) {
+                var skin = gltfRuntime.skins[skl];
+                if (skin.babylonSkeleton instanceof BABYLON.Skeleton) {
+                    skeletons.push(skin.babylonSkeleton);
+                }
+            }
+            // Load shaders and buffers to apply
+            load(gltfRuntime);
             return true;
             return true;
         };
         };
         /**
         /**
@@ -1213,6 +1299,23 @@ var BABYLON;
         */
         */
         GLTFFileLoader.prototype.load = function (scene, data, rootUrl) {
         GLTFFileLoader.prototype.load = function (scene, data, rootUrl) {
             var parsedData = JSON.parse(data);
             var parsedData = JSON.parse(data);
+            var gltfRuntime = this._createGlTFRuntime(parsedData, scene, rootUrl);
+            // Create nodes
+            this._createNodes(gltfRuntime);
+            // Load shaders and buffers to apply
+            load(gltfRuntime);
+            // Finish
+            return true;
+        };
+        // Creates nodes before loading buffers and shaders
+        GLTFFileLoader.prototype._createNodes = function (gltfRuntime) {
+            var currentScene = gltfRuntime.currentScene;
+            for (var i = 0; i < currentScene.nodes.length; i++) {
+                traverseNodes(gltfRuntime, currentScene.nodes[i], null);
+            }
+        };
+        // Creates the gltfRuntime
+        GLTFFileLoader.prototype._createGlTFRuntime = function (parsedData, scene, rootUrl) {
             var gltfRuntime = {
             var gltfRuntime = {
                 accessors: {},
                 accessors: {},
                 buffers: {},
                 buffers: {},
@@ -1293,10 +1396,7 @@ var BABYLON;
             if (parsedData.scene && parsedData.scenes) {
             if (parsedData.scene && parsedData.scenes) {
                 gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
                 gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
             }
             }
-            // Load shaders and buffers
-            load(gltfRuntime);
-            // Finish
-            return true;
+            return gltfRuntime;
         };
         };
         return GLTFFileLoader;
         return GLTFFileLoader;
     })();
     })();

+ 149 - 26
loaders/glTF/babylon.glTFFileLoader.ts

@@ -493,8 +493,15 @@
     /**
     /**
     * Imports a skeleton
     * Imports a skeleton
     */
     */
-    var importSkeleton = (gltfRuntime: IGLTFRuntime, skins: IGLTFSkins, mesh: Mesh): Skeleton => {
-        var newSkeleton = new Skeleton(skins.name, "", gltfRuntime.scene);
+    var importSkeleton = (gltfRuntime: IGLTFRuntime, skins: IGLTFSkins, mesh: Mesh, newSkeleton: Skeleton): Skeleton => {
+
+        if (!newSkeleton) {
+            newSkeleton = new Skeleton(skins.name, "", gltfRuntime.scene);
+        }
+
+        if (!skins.babylonSkeleton) {
+            return newSkeleton;
+        }
 
 
         // Matrices
         // Matrices
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
@@ -600,9 +607,15 @@
     /**
     /**
     * Imports a mesh and its geometries
     * Imports a mesh and its geometries
     */
     */
-    var importMesh = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, meshes: string[], id: string, skin?: IGLTFSkins): Mesh => {
-        var newMesh = new Mesh(node.name, gltfRuntime.scene);
-        newMesh.id = id;
+    var importMesh = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, meshes: string[], id: string, newMesh: Mesh): Mesh => {
+        if (!newMesh) {
+            newMesh = new Mesh(node.name, gltfRuntime.scene);
+            newMesh.id = id;
+        }
+
+        if (!node.babylonNode) {
+            return newMesh;
+        }
 
 
         var multiMat = new MultiMaterial("multimat" + id, gltfRuntime.scene);
         var multiMat = new MultiMaterial("multimat" + id, gltfRuntime.scene);
         newMesh.material = multiMat;
         newMesh.material = multiMat;
@@ -629,7 +642,7 @@
                 var tempVertexData = new VertexData();
                 var tempVertexData = new VertexData();
 
 
                 var primitive = mesh.primitives[i];
                 var primitive = mesh.primitives[i];
-                if (primitive.primitive !== 4) {
+                if (primitive.mode !== 4) {
                     //continue;
                     //continue;
                 }
                 }
 
 
@@ -728,7 +741,7 @@
             }
             }
 
 
             for (var i = 0; i < mesh.primitives.length; i++) {
             for (var i = 0; i < mesh.primitives.length; i++) {
-                if (mesh.primitives[i].primitive !== 4) {
+                if (mesh.primitives[i].mode !== 4) {
                     //continue;
                     //continue;
                 }
                 }
 
 
@@ -786,16 +799,26 @@
     var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string): Node => {
     var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string): Node => {
         var lastNode: Node = null;
         var lastNode: Node = null;
 
 
+        if (gltfRuntime.importOnlyMeshes && (node.skin || node.meshes)) {
+            if (gltfRuntime.importMeshesNames.length > 0 && gltfRuntime.importMeshesNames.indexOf(node.name) === -1) {
+                return null;
+            }
+        }
+
         // Meshes
         // Meshes
         if (node.skin) {
         if (node.skin) {
             if (node.meshes) {
             if (node.meshes) {
                 var skin: IGLTFSkins = gltfRuntime.skins[node.skin];
                 var skin: IGLTFSkins = gltfRuntime.skins[node.skin];
 
 
-                var newMesh = importMesh(gltfRuntime, node, node.meshes, id, skin);
+                var newMesh = importMesh(gltfRuntime, node, node.meshes, id, <Mesh>node.babylonNode);
                 newMesh.skeleton = gltfRuntime.scene.getLastSkeletonByID(node.skin);
                 newMesh.skeleton = gltfRuntime.scene.getLastSkeletonByID(node.skin);
 
 
                 if (newMesh.skeleton === null) {
                 if (newMesh.skeleton === null) {
-                    newMesh.skeleton = importSkeleton(gltfRuntime, skin, newMesh);
+                    newMesh.skeleton = importSkeleton(gltfRuntime, skin, newMesh, skin.babylonSkeleton);
+
+                    if (!skin.babylonSkeleton) {
+                        skin.babylonSkeleton = newMesh.skeleton;
+                    }
                 }
                 }
 
 
                 if (newMesh.skeleton !== null) {
                 if (newMesh.skeleton !== null) {
@@ -809,11 +832,11 @@
             /**
             /**
             * Improve meshes property
             * Improve meshes property
             */
             */
-            var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id);
+            var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id, <Mesh>node.babylonNode);
             lastNode = newMesh;
             lastNode = newMesh;
         }
         }
         // Lights
         // Lights
-        else if (node.light) {
+        else if (node.light && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var light = gltfRuntime.lights[node.light];
             var light = gltfRuntime.lights[node.light];
 
 
             if (light) {
             if (light) {
@@ -872,7 +895,7 @@
             }
             }
         }
         }
         // Cameras
         // Cameras
-        else if (node.camera) {
+        else if (node.camera && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var camera: IGLTFCamera = gltfRuntime.cameras[node.camera];
             var camera: IGLTFCamera = gltfRuntime.cameras[node.camera];
 
 
             if (camera) {
             if (camera) {
@@ -908,9 +931,15 @@
         }
         }
 
 
         // Empty node
         // Empty node
-        if (lastNode === null && !node.jointName) {
-            var dummy = new Mesh(node.name, gltfRuntime.scene);
-            lastNode = dummy;
+        if (!node.jointName) {
+            if (node.babylonNode) {
+                return node.babylonNode;
+            }
+            else if (lastNode === null) {
+                var dummy = new Mesh(node.name, gltfRuntime.scene);
+                node.babylonNode = dummy;
+                lastNode = dummy;
+            }
         }
         }
 
 
         if (lastNode !== null) {
         if (lastNode !== null) {
@@ -922,24 +951,59 @@
             }
             }
 
 
             lastNode.updateCache(true);
             lastNode.updateCache(true);
+
+            node.babylonNode = lastNode;
         }
         }
 
 
         return lastNode;
         return lastNode;
     };
     };
 
 
-    var traverseNodes = (gltfRuntime: IGLTFRuntime, id: string, parent: Node) => {
-        var node: IGLTFNode = gltfRuntime.nodes[id];
+    /**
+    * Util for ImportMesh function, checks if a given node
+    * is a descendant of the included mesh(es)
+    */
+    var nodeIsDescendantOf = (node: IGLTFRuntime, gltfRuntime: IGLTFRuntime): boolean => {
+        for (var nde in gltfRuntime.nodes) {
+            var n: IGLTFNode = gltfRuntime.nodes[nde];
+
+            for (var i = 0; i < n.children.length; i++) {
+
+            }
+        }
 
 
+        return false;
+    }
+
+    /**
+    * Traverses nodes and creates them
+    */
+    var traverseNodes = (gltfRuntime: IGLTFRuntime, id: string, parent: Node, meshIncluded?: boolean) => {
+        var node: IGLTFNode = gltfRuntime.nodes[id];
         var newNode: Node = null;
         var newNode: Node = null;
 
 
-        if (!node.jointName) {
+        if (gltfRuntime.importOnlyMeshes && !meshIncluded) {
+            if (gltfRuntime.importMeshesNames.indexOf(node.name) !== -1 || gltfRuntime.importMeshesNames.length === 0) {
+                meshIncluded = true;
+            }
+            else {
+                meshIncluded = false;
+            }
+        }
+        else {
+            meshIncluded = true;
+        }
+
+        if (!node.jointName && meshIncluded) {
             newNode = importNode(gltfRuntime, node, id);
             newNode = importNode(gltfRuntime, node, id);
-            newNode.id = id;
-            newNode.parent = parent;
+
+            if (newNode !== null) {
+                newNode.id = id;
+                newNode.parent = parent;
+            }
         }
         }
 
 
         for (var i = 0; i < node.children.length; i++) {
         for (var i = 0; i < node.children.length; i++) {
-            traverseNodes(gltfRuntime, node.children[i], newNode);
+            traverseNodes(gltfRuntime, node.children[i], newNode, meshIncluded);
         }
         }
     };
     };
 
 
@@ -1410,6 +1474,47 @@
         * Import meshes
         * Import meshes
         */
         */
         public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]): boolean {
         public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]): boolean {
+            var parsedData = JSON.parse(data);
+            var gltfRuntime = this._createGlTFRuntime(parsedData, scene, rootUrl);
+            gltfRuntime.importOnlyMeshes = true;
+
+            if (meshesNames === "") {
+                gltfRuntime.importMeshesNames = [];
+            }
+            else if (typeof meshesNames === "string") {
+                gltfRuntime.importMeshesNames = [meshesNames];
+            }
+            else if (meshesNames && !(meshesNames instanceof Array)) {
+                gltfRuntime.importMeshesNames = [meshesNames];
+            }
+            else {
+                gltfRuntime.importMeshesNames = [];
+                Tools.Warn("Argument meshesNames must be of type string or string[]");
+            }
+
+            // Create nodes
+            this._createNodes(gltfRuntime);
+
+            // Fill arrays of meshes and skeletons
+            for (var nde in gltfRuntime.nodes) {
+                var node: IGLTFNode = gltfRuntime.nodes[nde];
+
+                if (node.babylonNode instanceof AbstractMesh) {
+                    meshes.push(<AbstractMesh>node.babylonNode);
+                }
+            }
+
+            for (var skl in gltfRuntime.skins) {
+                var skin: IGLTFSkins = gltfRuntime.skins[skl];
+
+                if (skin.babylonSkeleton instanceof Skeleton) {
+                    skeletons.push(skin.babylonSkeleton);
+                }
+            }
+
+            // Load shaders and buffers to apply
+            load(gltfRuntime);
+
             return true;
             return true;
         }
         }
 
 
@@ -1418,7 +1523,29 @@
         */
         */
         public load(scene: Scene, data: string, rootUrl: string): boolean {
         public load(scene: Scene, data: string, rootUrl: string): boolean {
             var parsedData = JSON.parse(data);
             var parsedData = JSON.parse(data);
+            var gltfRuntime = this._createGlTFRuntime(parsedData, scene, rootUrl);
+
+            // Create nodes
+            this._createNodes(gltfRuntime);
+
+            // Load shaders and buffers to apply
+            load(gltfRuntime);
+
+            // Finish
+            return true;
+        }
+
+        // Creates nodes before loading buffers and shaders
+        private _createNodes(gltfRuntime: IGLTFRuntime): void {
+            var currentScene: IGLTFScene = <IGLTFScene>gltfRuntime.currentScene;
+
+            for (var i = 0; i < currentScene.nodes.length; i++) {
+                traverseNodes(gltfRuntime, currentScene.nodes[i], null);
+            }
+        }
 
 
+        // Creates the gltfRuntime
+        private _createGlTFRuntime(parsedData: any, scene: Scene, rootUrl: string): IGLTFRuntime {
             var gltfRuntime: IGLTFRuntime = {
             var gltfRuntime: IGLTFRuntime = {
                 accessors: {},
                 accessors: {},
                 buffers: {},
                 buffers: {},
@@ -1521,11 +1648,7 @@
                 gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
                 gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
             }
             }
 
 
-            // Load shaders and buffers
-            load(gltfRuntime);
-
-            // Finish
-            return true;
+            return gltfRuntime;
         }
         }
     };
     };
 
 

+ 7 - 1
loaders/glTF/babylon.glTFFileLoaderInterfaces.ts

@@ -96,7 +96,7 @@
         indices: string;
         indices: string;
         material: string;
         material: string;
 
 
-        primitive?: number;
+        mode?: number;
     }
     }
 
 
     export interface IGLTFMesh extends IGLTFChildRootProperty {
     export interface IGLTFMesh extends IGLTFChildRootProperty {
@@ -206,6 +206,8 @@
         bindShapeMatrix: number[];
         bindShapeMatrix: number[];
         inverseBindMatrices: string;
         inverseBindMatrices: string;
         jointNames: string[];
         jointNames: string[];
+
+        babylonSkeleton?: Skeleton;
     }
     }
 
 
     export interface IGLTFNode extends IGLTFChildRootProperty {
     export interface IGLTFNode extends IGLTFChildRootProperty {
@@ -220,6 +222,9 @@
         rotation?: number[];
         rotation?: number[];
         scale?: number[];
         scale?: number[];
         translation?: number[];
         translation?: number[];
+
+        // Babylon.js values (optimize)
+        babylonNode?: Node;
     }
     }
 
 
     export interface IGLTFScene extends IGLTFChildRootProperty {
     export interface IGLTFScene extends IGLTFChildRootProperty {
@@ -258,6 +263,7 @@
         arrayBuffers: Object;
         arrayBuffers: Object;
 
 
         importOnlyMeshes: boolean;
         importOnlyMeshes: boolean;
+        importMeshesNames?: string[];
 
 
         dummyNodes: Node[];
         dummyNodes: Node[];
     }
     }

+ 8 - 0
materialsLibrary/config.json

@@ -65,6 +65,14 @@
         "materials/terrain/terrain.fragment.fx"
         "materials/terrain/terrain.fragment.fx"
       ],
       ],
       "output": "babylon.terrainMaterial.js"
       "output": "babylon.terrainMaterial.js"
+    },
+    {
+      "file": "materials/triPlanar/babylon.triPlanarMaterial.ts",
+      "shaderFiles": [
+        "materials/triPlanar/triplanar.vertex.fx",
+        "materials/triPlanar/triplanar.fragment.fx"
+      ],
+      "output": "babylon.triPlanarMaterial.js"
     }
     }
   ],
   ],
   "build": {
   "build": {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
materialsLibrary/dist/babylon.fireMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 13 - 3
materialsLibrary/dist/babylon.lavaMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.lavaMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 13 - 4
materialsLibrary/dist/babylon.normalMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.normalMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 147 - 137
materialsLibrary/dist/babylon.pbrMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3 - 3
materialsLibrary/dist/babylon.pbrMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 13 - 4
materialsLibrary/dist/babylon.simpleMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.simpleMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
materialsLibrary/dist/babylon.terrainMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.terrainMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 509 - 0
materialsLibrary/dist/babylon.triPlanarMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 0
materialsLibrary/dist/babylon.triPlanarMaterial.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.waterMaterial.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
materialsLibrary/dist/babylon.waterMaterial.min.js


+ 19 - 18
materialsLibrary/dist/dts/babylon.pbrMaterial.d.ts

@@ -4,6 +4,7 @@ declare module BABYLON {
         directIntensity: number;
         directIntensity: number;
         emissiveIntensity: number;
         emissiveIntensity: number;
         environmentIntensity: number;
         environmentIntensity: number;
+        specularIntensity: number;
         private _lightingInfos;
         private _lightingInfos;
         overloadedShadowIntensity: number;
         overloadedShadowIntensity: number;
         overloadedShadeIntensity: number;
         overloadedShadeIntensity: number;
@@ -12,43 +13,43 @@ declare module BABYLON {
         cameraContrast: number;
         cameraContrast: number;
         private _cameraInfos;
         private _cameraInfos;
         overloadedAmbientIntensity: number;
         overloadedAmbientIntensity: number;
-        overloadedDiffuseIntensity: number;
-        overloadedSpecularIntensity: number;
+        overloadedAlbedoIntensity: number;
+        overloadedReflectivityIntensity: number;
         overloadedEmissiveIntensity: number;
         overloadedEmissiveIntensity: number;
         private _overloadedIntensity;
         private _overloadedIntensity;
         overloadedAmbient: Color3;
         overloadedAmbient: Color3;
-        overloadedDiffuse: Color3;
-        overloadedSpecular: Color3;
+        overloadedAlbedo: Color3;
+        overloadedReflectivity: Color3;
         overloadedEmissive: Color3;
         overloadedEmissive: Color3;
         overloadedReflection: Color3;
         overloadedReflection: Color3;
-        overloadedGlossiness: number;
-        overloadedGlossinessIntensity: number;
+        overloadedMicroSurface: number;
+        overloadedMicroSurfaceIntensity: number;
         overloadedReflectionIntensity: number;
         overloadedReflectionIntensity: number;
-        private _overloadedGlossiness;
+        private _overloadedMicroSurface;
         disableBumpMap: boolean;
         disableBumpMap: boolean;
-        diffuseTexture: BaseTexture;
+        albedoTexture: BaseTexture;
         ambientTexture: BaseTexture;
         ambientTexture: BaseTexture;
         opacityTexture: BaseTexture;
         opacityTexture: BaseTexture;
         reflectionTexture: BaseTexture;
         reflectionTexture: BaseTexture;
         emissiveTexture: BaseTexture;
         emissiveTexture: BaseTexture;
-        specularTexture: BaseTexture;
+        reflectivityTexture: BaseTexture;
         bumpTexture: BaseTexture;
         bumpTexture: BaseTexture;
         lightmapTexture: BaseTexture;
         lightmapTexture: BaseTexture;
         ambientColor: Color3;
         ambientColor: Color3;
-        diffuseColor: Color3;
-        specularColor: Color3;
+        albedoColor: Color3;
+        reflectivityColor: Color3;
         reflectionColor: Color3;
         reflectionColor: Color3;
-        glossiness: number;
+        microSurface: number;
         emissiveColor: Color3;
         emissiveColor: Color3;
-        useAlphaFromDiffuseTexture: boolean;
+        useAlphaFromAlbedoTexture: boolean;
         useEmissiveAsIllumination: boolean;
         useEmissiveAsIllumination: boolean;
-        linkEmissiveWithDiffuse: boolean;
+        linkEmissiveWithAlbedo: boolean;
         useSpecularOverAlpha: boolean;
         useSpecularOverAlpha: boolean;
         disableLighting: boolean;
         disableLighting: boolean;
         useLightmapAsShadowmap: boolean;
         useLightmapAsShadowmap: boolean;
         opacityFresnelParameters: FresnelParameters;
         opacityFresnelParameters: FresnelParameters;
         emissiveFresnelParameters: FresnelParameters;
         emissiveFresnelParameters: FresnelParameters;
-        useGlossinessFromSpecularMapAlpha: boolean;
+        useMicroSurfaceFromReflectivityMapAlpha: boolean;
         private _renderTargets;
         private _renderTargets;
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _globalAmbientColor;
         private _globalAmbientColor;
@@ -61,12 +62,12 @@ declare module BABYLON {
         useLogarithmicDepth: boolean;
         useLogarithmicDepth: boolean;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
-        private _shouldUseAlphaFromDiffuseTexture();
+        private _shouldUseAlphaFromAlbedoTexture();
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
         private _checkCache(scene, mesh?, useInstances?);
         private _checkCache(scene, mesh?, useInstances?);
         static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean;
         static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines): boolean;
-        private static _scaledDiffuse;
-        private static _scaledSpecular;
+        private static _scaledAlbedo;
+        private static _scaledReflectivity;
         private static _scaledEmissive;
         private static _scaledEmissive;
         private static _scaledReflection;
         private static _scaledReflection;
         static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines): void;
         static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines): void;

+ 36 - 0
materialsLibrary/dist/dts/babylon.triPlanarMaterial.d.ts

@@ -0,0 +1,36 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts" />
+declare module BABYLON {
+    class TriPlanarMaterial extends Material {
+        mixTexture: BaseTexture;
+        diffuseTextureX: Texture;
+        diffuseTextureY: Texture;
+        diffuseTextureZ: Texture;
+        normalTextureX: Texture;
+        normalTextureY: Texture;
+        normalTextureZ: Texture;
+        tileSize: number;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        disableLighting: boolean;
+        private _worldViewProjectionMatrix;
+        private _scaledDiffuse;
+        private _scaledSpecular;
+        private _renderId;
+        private _defines;
+        private _cachedDefines;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): BaseTexture;
+        private _checkCache(scene, mesh?, useInstances?);
+        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        bindOnlyWorldMatrix(world: Matrix): void;
+        bind(world: Matrix, mesh?: Mesh): void;
+        getAnimatables(): IAnimatable[];
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): TriPlanarMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial;
+    }
+}

+ 11 - 2
materialsLibrary/materials/lava/babylon.lavaMaterial.ts

@@ -364,7 +364,8 @@ module BABYLON {
                         "vDiffuseInfos",
                         "vDiffuseInfos",
                         "mBones",
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3","time", "speed","movingSpeed",
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues",
+                        "time", "speed","movingSpeed",
                         "fogColor","fogDensity", "lowFrequencySpeed"
                         "fogColor","fogDensity", "lowFrequencySpeed"
                     ],
                     ],
                     ["diffuseSampler",
                     ["diffuseSampler",
@@ -437,6 +438,7 @@ module BABYLON {
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
                     var light = scene.lights[index];
 
 
@@ -469,7 +471,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         var shadowGenerator = light.getShadowGenerator();
                         if (mesh.receiveShadows && shadowGenerator) {
                         if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            if (!(<any>light).needCube()) {
+                                this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            } else {
+                                if (!depthValuesAlreadySet) {
+                                    depthValuesAlreadySet = true;
+                                    this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                                }
+                            }
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         }
                         }

+ 14 - 10
materialsLibrary/materials/lava/lava.fragment.fx

@@ -124,14 +124,16 @@ float unpack(vec4 color)
 }
 }
 
 
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+uniform vec2 depthValues;
+
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	vec3 directionToLight = vPositionW - lightPosition;
 	float depth = length(directionToLight);
 	float depth = length(directionToLight);
+	depth = clamp(depth, 0., 1.0);
 
 
-	depth = clamp(depth, 0., 1.);
-
-	directionToLight.y = 1.0 - directionToLight.y;
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = - directionToLight.y;
 
 
 	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 
 
@@ -142,14 +144,16 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 	return 1.0;
 	return 1.0;
 }
 }
 
 
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness)
+float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness, float mapSize)
 {
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	vec3 directionToLight = vPositionW - lightPosition;
 	float depth = length(directionToLight);
 	float depth = length(directionToLight);
 
 
-	depth = clamp(depth, 0., 1.);
+	depth = clamp(depth, 0., 1.0);
+	float diskScale = 2.0 / mapSize;
 
 
-	directionToLight.y = 1.0 - directionToLight.y;
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = -directionToLight.y;
 
 
 	float visibility = 1.;
 	float visibility = 1.;
 
 
@@ -466,7 +470,7 @@ void main(void) {
 #else
 #else
 #ifdef SHADOWPCF0
 #ifdef SHADOWPCF0
 	#if defined(POINTLIGHT0)
 	#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
+	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x, shadowsInfo0.y);
 	#else
 	#else
 	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
 	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
 	#endif
 	#endif
@@ -500,7 +504,7 @@ void main(void) {
 #else
 #else
 #ifdef SHADOWPCF1
 #ifdef SHADOWPCF1
 #if defined(POINTLIGHT1)
 #if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
+	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x, shadowsInfo1.y);
 #else
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
 	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
 #endif
 #endif
@@ -534,7 +538,7 @@ void main(void) {
 #else
 #else
 #ifdef SHADOWPCF2
 #ifdef SHADOWPCF2
 #if defined(POINTLIGHT2)
 #if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
+	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x, shadowsInfo2.y);
 #else
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
 	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
 #endif
 #endif
@@ -568,7 +572,7 @@ void main(void) {
 #else
 #else
 #ifdef SHADOWPCF3
 #ifdef SHADOWPCF3
 #if defined(POINTLIGHT3)
 #if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x, shadowsInfo3.y);
 #else
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
 	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
 #endif
 #endif

+ 10 - 2
materialsLibrary/materials/normal/babylon.normalMaterial.ts

@@ -353,7 +353,7 @@ module BABYLON {
                         "vDiffuseInfos", 
                         "vDiffuseInfos", 
                         "mBones",
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3"
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                     ],
                     ],
                     ["diffuseSampler",
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -420,6 +420,7 @@ module BABYLON {
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
                     var light = scene.lights[index];
 
 
@@ -452,7 +453,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         var shadowGenerator = light.getShadowGenerator();
                         if (mesh.receiveShadows && shadowGenerator) {
                         if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            if (!(<any>light).needCube()) {
+                                this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            } else {
+                                if (!depthValuesAlreadySet) {
+                                    depthValuesAlreadySet = true;
+                                    this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                                }
+                            }
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         }
                         }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 562 - 558
materialsLibrary/materials/normal/normal.fragment.fx


+ 146 - 136
materialsLibrary/materials/pbr/babylon.pbrMaterial.ts

@@ -4,18 +4,18 @@ module BABYLON {
     var maxSimultaneousLights = 4;
     var maxSimultaneousLights = 4;
 
 
     class PBRMaterialDefines extends MaterialDefines {
     class PBRMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
+        public ALBEDO = false;
         public AMBIENT = false;
         public AMBIENT = false;
         public OPACITY = false;
         public OPACITY = false;
         public OPACITYRGB = false;
         public OPACITYRGB = false;
         public REFLECTION = false;
         public REFLECTION = false;
         public EMISSIVE = false;
         public EMISSIVE = false;
-        public SPECULAR = false;
+        public REFLECTIVITY = false;
         public BUMP = false;
         public BUMP = false;
         public SPECULAROVERALPHA = false;
         public SPECULAROVERALPHA = false;
         public CLIPPLANE = false;
         public CLIPPLANE = false;
         public ALPHATEST = false;
         public ALPHATEST = false;
-        public ALPHAFROMDIFFUSE = false;
+        public ALPHAFROMALBEDO = false;
         public POINTSIZE = false;
         public POINTSIZE = false;
         public FOG = false;
         public FOG = false;
         public LIGHT0 = false;
         public LIGHT0 = false;
@@ -63,9 +63,9 @@ module BABYLON {
         public NUM_BONE_INFLUENCERS = 0;
         public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public INSTANCES = false;
-        public GLOSSINESSFROMSPECULARMAP = false;
+        public MICROSURFACEFROMREFLECTIVITYMAP = false;
         public EMISSIVEASILLUMINATION = false;
         public EMISSIVEASILLUMINATION = false;
-        public LINKEMISSIVEWITHDIFFUSE = false;
+        public LINKEMISSIVEWITHALBEDO = false;
         public LIGHTMAP = false;
         public LIGHTMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public REFLECTIONMAP_3D = false;
         public REFLECTIONMAP_3D = false;
@@ -94,7 +94,9 @@ module BABYLON {
         public directIntensity: number = 1.0;
         public directIntensity: number = 1.0;
         public emissiveIntensity: number = 1.0;
         public emissiveIntensity: number = 1.0;
         public environmentIntensity: number = 1.0;
         public environmentIntensity: number = 1.0;
-        private _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, 0.0);
+        public specularIntensity: number = 1.0;
+
+        private _lightingInfos: Vector4 = new Vector4(this.directIntensity, this.emissiveIntensity, this.environmentIntensity, this.specularIntensity);
 
 
         public overloadedShadowIntensity: number = 1.0;
         public overloadedShadowIntensity: number = 1.0;
         public overloadedShadeIntensity: number = 1.0;
         public overloadedShadeIntensity: number = 1.0;
@@ -105,42 +107,42 @@ module BABYLON {
         private _cameraInfos: Vector4 = new Vector4(1.0, 1.0, 0.0, 0.0);
         private _cameraInfos: Vector4 = new Vector4(1.0, 1.0, 0.0, 0.0);
 
 
         public overloadedAmbientIntensity: number = 0.0;
         public overloadedAmbientIntensity: number = 0.0;
-        public overloadedDiffuseIntensity: number = 0.0;
-        public overloadedSpecularIntensity: number = 0.0;
+        public overloadedAlbedoIntensity: number = 0.0;
+        public overloadedReflectivityIntensity: number = 0.0;
         public overloadedEmissiveIntensity: number = 0.0;
         public overloadedEmissiveIntensity: number = 0.0;
-        private _overloadedIntensity: Vector4 = new Vector4(this.overloadedAmbientIntensity, this.overloadedDiffuseIntensity, this.overloadedSpecularIntensity, this.overloadedEmissiveIntensity);
+        private _overloadedIntensity: Vector4 = new Vector4(this.overloadedAmbientIntensity, this.overloadedAlbedoIntensity, this.overloadedReflectivityIntensity, this.overloadedEmissiveIntensity);
 
 
         public overloadedAmbient: Color3 = BABYLON.Color3.White();
         public overloadedAmbient: Color3 = BABYLON.Color3.White();
-        public overloadedDiffuse: Color3 = BABYLON.Color3.White();
-        public overloadedSpecular: Color3 = BABYLON.Color3.White();
+        public overloadedAlbedo: Color3 = BABYLON.Color3.White();
+        public overloadedReflectivity: Color3 = BABYLON.Color3.White();
         public overloadedEmissive: Color3 = BABYLON.Color3.White();
         public overloadedEmissive: Color3 = BABYLON.Color3.White();
         public overloadedReflection: Color3 = BABYLON.Color3.White();
         public overloadedReflection: Color3 = BABYLON.Color3.White();
 
 
-        public overloadedGlossiness: number = 0.0;
-        public overloadedGlossinessIntensity: number = 0.0;
+        public overloadedMicroSurface: number = 0.0;
+        public overloadedMicroSurfaceIntensity: number = 0.0;
         public overloadedReflectionIntensity: number = 0.0;
         public overloadedReflectionIntensity: number = 0.0;
-        private _overloadedGlossiness: Vector3 = new Vector3(this.overloadedGlossiness, this.overloadedGlossinessIntensity, this.overloadedReflectionIntensity);
+        private _overloadedMicroSurface: Vector3 = new Vector3(this.overloadedMicroSurface, this.overloadedMicroSurfaceIntensity, this.overloadedReflectionIntensity);
        
        
         public disableBumpMap: boolean = false;
         public disableBumpMap: boolean = false;
 
 
-        public diffuseTexture: BaseTexture;
+        public albedoTexture: BaseTexture;
         public ambientTexture: BaseTexture;
         public ambientTexture: BaseTexture;
         public opacityTexture: BaseTexture;
         public opacityTexture: BaseTexture;
         public reflectionTexture: BaseTexture;
         public reflectionTexture: BaseTexture;
         public emissiveTexture: BaseTexture;
         public emissiveTexture: BaseTexture;
-        public specularTexture: BaseTexture;
+        public reflectivityTexture: BaseTexture;
         public bumpTexture: BaseTexture;
         public bumpTexture: BaseTexture;
         public lightmapTexture: BaseTexture;
         public lightmapTexture: BaseTexture;
 
 
         public ambientColor = new Color3(0, 0, 0);
         public ambientColor = new Color3(0, 0, 0);
-        public diffuseColor = new Color3(1, 1, 1);
-        public specularColor = new Color3(1, 1, 1);
+        public albedoColor = new Color3(1, 1, 1);
+        public reflectivityColor = new Color3(1, 1, 1);
         public reflectionColor = new Color3(0.5, 0.5, 0.5);
         public reflectionColor = new Color3(0.5, 0.5, 0.5);
-        public glossiness = 0.5;
+        public microSurface = 0.5;
         public emissiveColor = new Color3(0, 0, 0);
         public emissiveColor = new Color3(0, 0, 0);
-        public useAlphaFromDiffuseTexture = false;
+        public useAlphaFromAlbedoTexture = false;
         public useEmissiveAsIllumination = false;
         public useEmissiveAsIllumination = false;
-        public linkEmissiveWithDiffuse = false;
+        public linkEmissiveWithAlbedo = false;
         public useSpecularOverAlpha = true;
         public useSpecularOverAlpha = true;
         public disableLighting = false;
         public disableLighting = false;
 
 
@@ -149,7 +151,7 @@ module BABYLON {
         public opacityFresnelParameters: FresnelParameters;
         public opacityFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
 
 
-        public useGlossinessFromSpecularMapAlpha = false;
+        public useMicroSurfaceFromReflectivityMapAlpha = false;
 
 
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
@@ -188,19 +190,19 @@ module BABYLON {
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
-            return (this.alpha < 1.0) || (this.opacityTexture != null) || this._shouldUseAlphaFromDiffuseTexture() || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled;
+            return (this.alpha < 1.0) || (this.opacityTexture != null) || this._shouldUseAlphaFromAlbedoTexture() || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled;
         }
         }
 
 
         public needAlphaTesting(): boolean {
         public needAlphaTesting(): boolean {
-            return this.diffuseTexture != null && this.diffuseTexture.hasAlpha;
+            return this.albedoTexture != null && this.albedoTexture.hasAlpha;
         }
         }
 
 
-        private _shouldUseAlphaFromDiffuseTexture(): boolean {
-            return this.diffuseTexture != null && this.diffuseTexture.hasAlpha && this.useAlphaFromDiffuseTexture;
+        private _shouldUseAlphaFromAlbedoTexture(): boolean {
+            return this.albedoTexture != null && this.albedoTexture.hasAlpha && this.useAlphaFromAlbedoTexture;
         }
         }
 
 
         public getAlphaTestTexture(): BaseTexture {
         public getAlphaTestTexture(): BaseTexture {
-            return this.diffuseTexture;
+            return this.albedoTexture;
         }
         }
 
 
         private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
         private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
@@ -305,13 +307,14 @@ module BABYLON {
             return needNormals;
             return needNormals;
         }
         }
 
 
-        private static _scaledDiffuse = new Color3();
-        private static _scaledSpecular = new Color3();
+        private static _scaledAlbedo = new Color3();
+        private static _scaledReflectivity = new Color3();
         private static _scaledEmissive = new Color3();
         private static _scaledEmissive = new Color3();
         private static _scaledReflection = new Color3();
         private static _scaledReflection = new Color3();
 
 
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
                 var light = scene.lights[index];
 
 
@@ -338,15 +341,15 @@ module BABYLON {
                 }
                 }
 
 
                 // GAMMA CORRECTION.
                 // GAMMA CORRECTION.
-                light.diffuse.toLinearSpaceToRef(PBRMaterial._scaledDiffuse);
-                PBRMaterial._scaledDiffuse.scaleToRef(light.intensity, PBRMaterial._scaledDiffuse);
+                light.diffuse.toLinearSpaceToRef(PBRMaterial._scaledAlbedo);
+                PBRMaterial._scaledAlbedo.scaleToRef(light.intensity, PBRMaterial._scaledAlbedo);
 
 
-                light.diffuse.scaleToRef(light.intensity, PBRMaterial._scaledDiffuse);
-                effect.setColor4("vLightDiffuse" + lightIndex, PBRMaterial._scaledDiffuse, light.range);
+                light.diffuse.scaleToRef(light.intensity, PBRMaterial._scaledAlbedo);
+                effect.setColor4("vLightDiffuse" + lightIndex, PBRMaterial._scaledAlbedo, light.range);
                 if (defines["SPECULARTERM"]) {
                 if (defines["SPECULARTERM"]) {
-                    light.specular.toLinearSpaceToRef(PBRMaterial._scaledSpecular);
-                    PBRMaterial._scaledSpecular.scaleToRef(light.intensity, PBRMaterial._scaledSpecular);
-                    effect.setColor3("vLightSpecular" + lightIndex, PBRMaterial._scaledSpecular);
+                    light.specular.toLinearSpaceToRef(PBRMaterial._scaledReflectivity);
+                    PBRMaterial._scaledReflectivity.scaleToRef(light.intensity, PBRMaterial._scaledReflectivity);
+                    effect.setColor3("vLightSpecular" + lightIndex, PBRMaterial._scaledReflectivity);
                 }
                 }
 
 
                 // Shadows
                 // Shadows
@@ -355,6 +358,11 @@ module BABYLON {
                     if (mesh.receiveShadows && shadowGenerator) {
                     if (mesh.receiveShadows && shadowGenerator) {
                         if (!(<any>light).needCube()) {
                         if (!(<any>light).needCube()) {
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                        } else {
+                            if (!depthValuesAlreadySet) {
+                                depthValuesAlreadySet = true;
+                                effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                            }
                         }
                         }
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
@@ -394,12 +402,12 @@ module BABYLON {
 
 
             // Textures
             // Textures
             if (scene.texturesEnabled) {
             if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
+                if (this.albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this.albedoTexture.isReady()) {
                         return false;
                         return false;
                     } else {
                     } else {
                         needUVs = true;
                         needUVs = true;
-                        this._defines.DIFFUSE = true;
+                        this._defines.ALBEDO = true;
                     }
                     }
                 }
                 }
 
 
@@ -484,13 +492,13 @@ module BABYLON {
                     }
                     }
                 }
                 }
 
 
-                if (this.specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                    if (!this.specularTexture.isReady()) {
+                if (this.reflectivityTexture && StandardMaterial.SpecularTextureEnabled) {
+                    if (!this.reflectivityTexture.isReady()) {
                         return false;
                         return false;
                     } else {
                     } else {
                         needUVs = true;
                         needUVs = true;
-                        this._defines.SPECULAR = true;
-                        this._defines.GLOSSINESSFROMSPECULARMAP = this.useGlossinessFromSpecularMapAlpha;
+                        this._defines.REFLECTIVITY = true;
+                        this._defines.MICROSURFACEFROMREFLECTIVITYMAP = this.useMicroSurfaceFromReflectivityMapAlpha;
                     }
                     }
                 }
                 }
             }
             }
@@ -513,16 +521,16 @@ module BABYLON {
                 this._defines.ALPHATEST = true;
                 this._defines.ALPHATEST = true;
             }
             }
 
 
-            if (this._shouldUseAlphaFromDiffuseTexture()) {
-                this._defines.ALPHAFROMDIFFUSE = true;
+            if (this._shouldUseAlphaFromAlbedoTexture()) {
+                this._defines.ALPHAFROMALBEDO = true;
             }
             }
 
 
             if (this.useEmissiveAsIllumination) {
             if (this.useEmissiveAsIllumination) {
                 this._defines.EMISSIVEASILLUMINATION = true;
                 this._defines.EMISSIVEASILLUMINATION = true;
             }
             }
 
 
-            if (this.linkEmissiveWithDiffuse) {
-                this._defines.LINKEMISSIVEWITHDIFFUSE = true;
+            if (this.linkEmissiveWithAlbedo) {
+                this._defines.LINKEMISSIVEWITHALBEDO = true;
             }
             }
 
 
             if (this.useLogarithmicDepth) {
             if (this.useLogarithmicDepth) {
@@ -542,10 +550,10 @@ module BABYLON {
                 this._defines.OVERLOADEDSHADOWVALUES = true;
                 this._defines.OVERLOADEDSHADOWVALUES = true;
             }
             }
 
 
-            if (this.overloadedGlossinessIntensity > 0 ||
+            if (this.overloadedMicroSurfaceIntensity > 0 ||
                 this.overloadedEmissiveIntensity > 0 ||
                 this.overloadedEmissiveIntensity > 0 ||
-                this.overloadedSpecularIntensity > 0 ||
-                this.overloadedDiffuseIntensity > 0 ||
+                this.overloadedReflectivityIntensity > 0 ||
+                this.overloadedAlbedoIntensity > 0 ||
                 this.overloadedAmbientIntensity > 0 ||
                 this.overloadedAmbientIntensity > 0 ||
                 this.overloadedReflectionIntensity > 0) {
                 this.overloadedReflectionIntensity > 0) {
                 this._defines.OVERLOADEDVALUES = true;
                 this._defines.OVERLOADEDVALUES = true;
@@ -630,8 +638,8 @@ module BABYLON {
                     fallbacks.addFallback(0, "REFLECTION");
                     fallbacks.addFallback(0, "REFLECTION");
                 }
                 }
 
 
-                if (this._defines.SPECULAR) {
-                    fallbacks.addFallback(0, "SPECULAR");
+                if (this._defines.REFLECTIVITY) {
+                    fallbacks.addFallback(0, "REFLECTIVITY");
                 }
                 }
 
 
                 if (this._defines.BUMP) {
                 if (this._defines.BUMP) {
@@ -739,21 +747,21 @@ module BABYLON {
                 var join = this._defines.toString();
                 var join = this._defines.toString();
                 this._effect = scene.getEngine().createEffect(shaderName,
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor", "vReflectionColor",
+                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vAlbedoColor", "vReflectivityColor", "vEmissiveColor", "vReflectionColor",
                         "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                         "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
                         "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
                         "vFogInfos", "vFogColor", "pointSize",
                         "vFogInfos", "vFogColor", "pointSize",
-                        "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
+                        "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vReflectivityInfos", "vBumpInfos", "vLightmapInfos",
                         "mBones",
                         "mBones",
-                        "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
+                        "vClipPlane", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "bumpMatrix", "lightmapMatrix",
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues",
                         "opacityParts", "emissiveLeftColor", "emissiveRightColor",
                         "opacityParts", "emissiveLeftColor", "emissiveRightColor",
-                        "vLightingIntensity", "vOverloadedShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedDiffuse", "vOverloadedReflection", "vOverloadedSpecular", "vOverloadedEmissive", "vOverloadedGlossiness",
+                        "vLightingIntensity", "vOverloadedShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedAlbedo", "vOverloadedReflection", "vOverloadedReflectivity", "vOverloadedEmissive", "vOverloadedMicroSurface",
                         "logarithmicDepthConstant"
                         "logarithmicDepthConstant"
                     ],
                     ],
-                    ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
+                    ["albedoSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "reflectivitySampler", "bumpSampler", "lightmapSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     ],
                     ],
                     join, fallbacks, this.onCompiled, this.onError);
                     join, fallbacks, this.onCompiled, this.onError);
@@ -818,11 +826,11 @@ module BABYLON {
                 }
                 }
 
 
                 // Textures        
                 // Textures        
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
+                if (this.albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    this._effect.setTexture("albedoSampler", this.albedoTexture);
 
 
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._effect.setFloat2("vAlbedoInfos", this.albedoTexture.coordinatesIndex, this.albedoTexture.level);
+                    this._effect.setMatrix("albedoMatrix", this.albedoTexture.getTextureMatrix());
                 }
                 }
 
 
                 if (this.ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                 if (this.ambientTexture && StandardMaterial.AmbientTextureEnabled) {
@@ -864,11 +872,11 @@ module BABYLON {
                     this._effect.setMatrix("lightmapMatrix", this.lightmapTexture.getTextureMatrix());
                     this._effect.setMatrix("lightmapMatrix", this.lightmapTexture.getTextureMatrix());
                 }
                 }
 
 
-                if (this.specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                    this._effect.setTexture("specularSampler", this.specularTexture);
+                if (this.reflectivityTexture && StandardMaterial.SpecularTextureEnabled) {
+                    this._effect.setTexture("reflectivitySampler", this.reflectivityTexture);
 
 
-                    this._effect.setFloat2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
-                    this._effect.setMatrix("specularMatrix", this.specularTexture.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) {
                 if (this.bumpTexture && this._myScene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled && !this.disableBumpMap) {
@@ -895,14 +903,11 @@ module BABYLON {
                 this._myScene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
                 this._myScene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
                 
                 
                 // GAMMA CORRECTION.
                 // GAMMA CORRECTION.
-                this.specularColor.toLinearSpaceToRef(PBRMaterial._scaledSpecular);
+                this.reflectivityColor.toLinearSpaceToRef(PBRMaterial._scaledReflectivity);
 
 
                 this._effect.setVector3("vEyePosition", this._myScene._mirroredCameraPosition ? this._myScene._mirroredCameraPosition : this._myScene.activeCamera.position);
                 this._effect.setVector3("vEyePosition", this._myScene._mirroredCameraPosition ? this._myScene._mirroredCameraPosition : this._myScene.activeCamera.position);
                 this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
                 this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
-
-                if (this._defines.SPECULARTERM) {
-                    this._effect.setColor4("vSpecularColor", PBRMaterial._scaledSpecular, this.glossiness);
-                }
+                this._effect.setColor4("vReflectivityColor", PBRMaterial._scaledReflectivity, this.microSurface);
 
 
                 // GAMMA CORRECTION.
                 // GAMMA CORRECTION.
                 this.emissiveColor.toLinearSpaceToRef(PBRMaterial._scaledEmissive); 
                 this.emissiveColor.toLinearSpaceToRef(PBRMaterial._scaledEmissive); 
@@ -914,8 +919,8 @@ module BABYLON {
             }
             }
 
 
             // GAMMA CORRECTION.
             // GAMMA CORRECTION.
-            this.diffuseColor.toLinearSpaceToRef(PBRMaterial._scaledDiffuse);
-            this._effect.setColor4("vDiffuseColor", PBRMaterial._scaledDiffuse, this.alpha * mesh.visibility);
+            this.albedoColor.toLinearSpaceToRef(PBRMaterial._scaledAlbedo);
+            this._effect.setColor4("vAlbedoColor", PBRMaterial._scaledAlbedo, this.alpha * mesh.visibility);
 
 
             // Lights
             // Lights
             if (this._myScene.lightsEnabled && !this.disableLighting) {
             if (this._myScene.lightsEnabled && !this.disableLighting) {
@@ -936,6 +941,8 @@ module BABYLON {
             this._lightingInfos.x = this.directIntensity;
             this._lightingInfos.x = this.directIntensity;
             this._lightingInfos.y = this.emissiveIntensity;
             this._lightingInfos.y = this.emissiveIntensity;
             this._lightingInfos.z = this.environmentIntensity;
             this._lightingInfos.z = this.environmentIntensity;
+            this._lightingInfos.w = this.specularIntensity;
+
             this._effect.setVector4("vLightingIntensity", this._lightingInfos);
             this._effect.setVector4("vLightingIntensity", this._lightingInfos);
 
 
             this._overloadedShadowInfos.x = this.overloadedShadowIntensity;
             this._overloadedShadowInfos.x = this.overloadedShadowIntensity;
@@ -947,26 +954,26 @@ module BABYLON {
             this._effect.setVector4("vCameraInfos", this._cameraInfos);
             this._effect.setVector4("vCameraInfos", this._cameraInfos);
 
 
             this._overloadedIntensity.x = this.overloadedAmbientIntensity;
             this._overloadedIntensity.x = this.overloadedAmbientIntensity;
-            this._overloadedIntensity.y = this.overloadedDiffuseIntensity;
-            this._overloadedIntensity.z = this.overloadedSpecularIntensity;
+            this._overloadedIntensity.y = this.overloadedAlbedoIntensity;
+            this._overloadedIntensity.z = this.overloadedReflectivityIntensity;
             this._overloadedIntensity.w = this.overloadedEmissiveIntensity;
             this._overloadedIntensity.w = this.overloadedEmissiveIntensity;
             this._effect.setVector4("vOverloadedIntensity", this._overloadedIntensity);
             this._effect.setVector4("vOverloadedIntensity", this._overloadedIntensity);
 
 
             this.overloadedAmbient.toLinearSpaceToRef(this._tempColor);
             this.overloadedAmbient.toLinearSpaceToRef(this._tempColor);
             this._effect.setColor3("vOverloadedAmbient", this._tempColor);
             this._effect.setColor3("vOverloadedAmbient", this._tempColor);
-            this.overloadedDiffuse.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vOverloadedDiffuse", this._tempColor);
-            this.overloadedSpecular.toLinearSpaceToRef(this._tempColor);
-            this._effect.setColor3("vOverloadedSpecular", this._tempColor);
+            this.overloadedAlbedo.toLinearSpaceToRef(this._tempColor);
+            this._effect.setColor3("vOverloadedAlbedo", this._tempColor);
+            this.overloadedReflectivity.toLinearSpaceToRef(this._tempColor);
+            this._effect.setColor3("vOverloadedReflectivity", this._tempColor);
             this.overloadedEmissive.toLinearSpaceToRef(this._tempColor);
             this.overloadedEmissive.toLinearSpaceToRef(this._tempColor);
             this._effect.setColor3("vOverloadedEmissive", this._tempColor);
             this._effect.setColor3("vOverloadedEmissive", this._tempColor);
             this.overloadedReflection.toLinearSpaceToRef(this._tempColor);
             this.overloadedReflection.toLinearSpaceToRef(this._tempColor);
             this._effect.setColor3("vOverloadedReflection", this._tempColor);
             this._effect.setColor3("vOverloadedReflection", this._tempColor);
 
 
-            this._overloadedGlossiness.x = this.overloadedGlossiness;
-            this._overloadedGlossiness.y = this.overloadedGlossinessIntensity;
-            this._overloadedGlossiness.z = this.overloadedReflectionIntensity;
-            this._effect.setVector3("vOverloadedGlossiness", this._overloadedGlossiness);
+            this._overloadedMicroSurface.x = this.overloadedMicroSurface;
+            this._overloadedMicroSurface.y = this.overloadedMicroSurfaceIntensity;
+            this._overloadedMicroSurface.z = this.overloadedReflectionIntensity;
+            this._effect.setVector3("vOverloadedMicroSurface", this._overloadedMicroSurface);
 
 
             // Log. depth
             // Log. depth
             if (this._defines.LOGARITHMICDEPTH) {
             if (this._defines.LOGARITHMICDEPTH) {
@@ -981,8 +988,8 @@ module BABYLON {
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {
             var results = [];
             var results = [];
 
 
-            if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
-                results.push(this.diffuseTexture);
+            if (this.albedoTexture && this.albedoTexture.animations && this.albedoTexture.animations.length > 0) {
+                results.push(this.albedoTexture);
             }
             }
 
 
             if (this.ambientTexture && this.ambientTexture.animations && this.ambientTexture.animations.length > 0) {
             if (this.ambientTexture && this.ambientTexture.animations && this.ambientTexture.animations.length > 0) {
@@ -1001,8 +1008,8 @@ module BABYLON {
                 results.push(this.emissiveTexture);
                 results.push(this.emissiveTexture);
             }
             }
 
 
-            if (this.specularTexture && this.specularTexture.animations && this.specularTexture.animations.length > 0) {
-                results.push(this.specularTexture);
+            if (this.reflectivityTexture && this.reflectivityTexture.animations && this.reflectivityTexture.animations.length > 0) {
+                results.push(this.reflectivityTexture);
             }
             }
 
 
             if (this.bumpTexture && this.bumpTexture.animations && this.bumpTexture.animations.length > 0) {
             if (this.bumpTexture && this.bumpTexture.animations && this.bumpTexture.animations.length > 0) {
@@ -1013,8 +1020,8 @@ module BABYLON {
         }
         }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
-            if (this.diffuseTexture) {
-                this.diffuseTexture.dispose();
+            if (this.albedoTexture) {
+                this.albedoTexture.dispose();
             }
             }
 
 
             if (this.ambientTexture) {
             if (this.ambientTexture) {
@@ -1033,8 +1040,8 @@ module BABYLON {
                 this.emissiveTexture.dispose();
                 this.emissiveTexture.dispose();
             }
             }
 
 
-            if (this.specularTexture) {
-                this.specularTexture.dispose();
+            if (this.reflectivityTexture) {
+                this.reflectivityTexture.dispose();
             }
             }
 
 
             if (this.bumpTexture) {
             if (this.bumpTexture) {
@@ -1053,6 +1060,7 @@ module BABYLON {
             newPBRMaterial.directIntensity = this.directIntensity;
             newPBRMaterial.directIntensity = this.directIntensity;
             newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
             newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
             newPBRMaterial.environmentIntensity = this.environmentIntensity;
             newPBRMaterial.environmentIntensity = this.environmentIntensity;
+            newPBRMaterial.specularIntensity = this.specularIntensity;
         
         
             newPBRMaterial.cameraExposure = this.cameraExposure;
             newPBRMaterial.cameraExposure = this.cameraExposure;
             newPBRMaterial.cameraContrast = this.cameraContrast;
             newPBRMaterial.cameraContrast = this.cameraContrast;
@@ -1061,24 +1069,24 @@ module BABYLON {
             newPBRMaterial.overloadedShadeIntensity = this.overloadedShadeIntensity;
             newPBRMaterial.overloadedShadeIntensity = this.overloadedShadeIntensity;
         
         
             newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
             newPBRMaterial.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
-            newPBRMaterial.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
-            newPBRMaterial.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
+            newPBRMaterial.overloadedAlbedoIntensity = this.overloadedAlbedoIntensity;
+            newPBRMaterial.overloadedReflectivityIntensity = this.overloadedReflectivityIntensity;
             newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
             newPBRMaterial.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
             newPBRMaterial.overloadedAmbient = this.overloadedAmbient;
             newPBRMaterial.overloadedAmbient = this.overloadedAmbient;
-            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse;
-            newPBRMaterial.overloadedSpecular = this.overloadedSpecular;
+            newPBRMaterial.overloadedAlbedo = this.overloadedAlbedo;
+            newPBRMaterial.overloadedReflectivity = this.overloadedReflectivity;
             newPBRMaterial.overloadedEmissive = this.overloadedEmissive;
             newPBRMaterial.overloadedEmissive = this.overloadedEmissive;
             newPBRMaterial.overloadedReflection = this.overloadedReflection;
             newPBRMaterial.overloadedReflection = this.overloadedReflection;
 
 
-            newPBRMaterial.overloadedGlossiness = this.overloadedGlossiness;
-            newPBRMaterial.overloadedGlossinessIntensity = this.overloadedGlossinessIntensity;
+            newPBRMaterial.overloadedMicroSurface = this.overloadedMicroSurface;
+            newPBRMaterial.overloadedMicroSurfaceIntensity = this.overloadedMicroSurfaceIntensity;
             newPBRMaterial.overloadedReflectionIntensity = this.overloadedReflectionIntensity;
             newPBRMaterial.overloadedReflectionIntensity = this.overloadedReflectionIntensity;
         
         
             newPBRMaterial.disableBumpMap = this.disableBumpMap;
             newPBRMaterial.disableBumpMap = this.disableBumpMap;
 
 
             // Standard material
             // Standard material
-            if (this.diffuseTexture && this.diffuseTexture.clone) {
-                newPBRMaterial.diffuseTexture = this.diffuseTexture.clone();
+            if (this.albedoTexture && this.albedoTexture.clone) {
+                newPBRMaterial.albedoTexture = this.albedoTexture.clone();
             }
             }
             if (this.ambientTexture && this.ambientTexture.clone) {
             if (this.ambientTexture && this.ambientTexture.clone) {
                 newPBRMaterial.ambientTexture = this.ambientTexture.clone();
                 newPBRMaterial.ambientTexture = this.ambientTexture.clone();
@@ -1092,8 +1100,8 @@ module BABYLON {
             if (this.emissiveTexture && this.emissiveTexture.clone) {
             if (this.emissiveTexture && this.emissiveTexture.clone) {
                 newPBRMaterial.emissiveTexture = this.emissiveTexture.clone();
                 newPBRMaterial.emissiveTexture = this.emissiveTexture.clone();
             }
             }
-            if (this.specularTexture && this.specularTexture.clone) {
-                newPBRMaterial.specularTexture = this.specularTexture.clone();
+            if (this.reflectivityTexture && this.reflectivityTexture.clone) {
+                newPBRMaterial.reflectivityTexture = this.reflectivityTexture.clone();
             }
             }
             if (this.bumpTexture && this.bumpTexture.clone) {
             if (this.bumpTexture && this.bumpTexture.clone) {
                 newPBRMaterial.bumpTexture = this.bumpTexture.clone();
                 newPBRMaterial.bumpTexture = this.bumpTexture.clone();
@@ -1104,14 +1112,14 @@ module BABYLON {
             }
             }
 
 
             newPBRMaterial.ambientColor = this.ambientColor.clone();
             newPBRMaterial.ambientColor = this.ambientColor.clone();
-            newPBRMaterial.diffuseColor = this.diffuseColor.clone();
-            newPBRMaterial.specularColor = this.specularColor.clone();
+            newPBRMaterial.albedoColor = this.albedoColor.clone();
+            newPBRMaterial.reflectivityColor = this.reflectivityColor.clone();
             newPBRMaterial.reflectionColor = this.reflectionColor.clone();
             newPBRMaterial.reflectionColor = this.reflectionColor.clone();
-            newPBRMaterial.glossiness = this.glossiness;
+            newPBRMaterial.microSurface = this.microSurface;
             newPBRMaterial.emissiveColor = this.emissiveColor.clone();
             newPBRMaterial.emissiveColor = this.emissiveColor.clone();
-            newPBRMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
+            newPBRMaterial.useAlphaFromAlbedoTexture = this.useAlphaFromAlbedoTexture;
             newPBRMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
             newPBRMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            newPBRMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
+            newPBRMaterial.useMicroSurfaceFromReflectivityMapAlpha = this.useMicroSurfaceFromReflectivityMapAlpha;
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
             
             
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
@@ -1128,6 +1136,7 @@ module BABYLON {
             serializationObject.directIntensity = this.directIntensity;
             serializationObject.directIntensity = this.directIntensity;
             serializationObject.emissiveIntensity = this.emissiveIntensity;
             serializationObject.emissiveIntensity = this.emissiveIntensity;
             serializationObject.environmentIntensity = this.environmentIntensity;
             serializationObject.environmentIntensity = this.environmentIntensity;
+            serializationObject.specularIntensity = this.specularIntensity;
         
         
             serializationObject.cameraExposure = this.cameraExposure;
             serializationObject.cameraExposure = this.cameraExposure;
             serializationObject.cameraContrast = this.cameraContrast;
             serializationObject.cameraContrast = this.cameraContrast;
@@ -1136,24 +1145,24 @@ module BABYLON {
             serializationObject.overloadedShadeIntensity = this.overloadedShadeIntensity;
             serializationObject.overloadedShadeIntensity = this.overloadedShadeIntensity;
         
         
             serializationObject.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
             serializationObject.overloadedAmbientIntensity = this.overloadedAmbientIntensity;
-            serializationObject.overloadedDiffuseIntensity = this.overloadedDiffuseIntensity;
-            serializationObject.overloadedSpecularIntensity = this.overloadedSpecularIntensity;
+            serializationObject.overloadedAlbedoIntensity = this.overloadedAlbedoIntensity;
+            serializationObject.overloadedReflectivityIntensity = this.overloadedReflectivityIntensity;
             serializationObject.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
             serializationObject.overloadedEmissiveIntensity = this.overloadedEmissiveIntensity;
             serializationObject.overloadedAmbient = this.overloadedAmbient.asArray();
             serializationObject.overloadedAmbient = this.overloadedAmbient.asArray();
-            serializationObject.overloadedDiffuse = this.overloadedDiffuse.asArray();
-            serializationObject.overloadedSpecular = this.overloadedSpecular.asArray();
+            serializationObject.overloadedAlbedo = this.overloadedAlbedo.asArray();
+            serializationObject.overloadedReflectivity = this.overloadedReflectivity.asArray();
             serializationObject.overloadedEmissive = this.overloadedEmissive.asArray();
             serializationObject.overloadedEmissive = this.overloadedEmissive.asArray();
             serializationObject.overloadedReflection = this.overloadedReflection.asArray();
             serializationObject.overloadedReflection = this.overloadedReflection.asArray();
 
 
-            serializationObject.overloadedGlossiness = this.overloadedGlossiness;
-            serializationObject.overloadedGlossinessIntensity = this.overloadedGlossinessIntensity;
+            serializationObject.overloadedMicroSurface = this.overloadedMicroSurface;
+            serializationObject.overloadedMicroSurfaceIntensity = this.overloadedMicroSurfaceIntensity;
             serializationObject.overloadedReflectionIntensity = this.overloadedReflectionIntensity;
             serializationObject.overloadedReflectionIntensity = this.overloadedReflectionIntensity;
         
         
             serializationObject.disableBumpMap = this.disableBumpMap;
             serializationObject.disableBumpMap = this.disableBumpMap;
 
 
             // Standard material
             // Standard material
-            if (this.diffuseTexture) {
-                serializationObject.diffuseTexture = this.diffuseTexture.serialize();
+            if (this.albedoTexture) {
+                serializationObject.albedoTexture = this.albedoTexture.serialize();
             }
             }
             if (this.ambientTexture) {
             if (this.ambientTexture) {
                 serializationObject.ambientTexture = this.ambientTexture.serialize();
                 serializationObject.ambientTexture = this.ambientTexture.serialize();
@@ -1167,8 +1176,8 @@ module BABYLON {
             if (this.emissiveTexture) {
             if (this.emissiveTexture) {
                 serializationObject.emissiveTexture = this.emissiveTexture.serialize();
                 serializationObject.emissiveTexture = this.emissiveTexture.serialize();
             }
             }
-            if (this.specularTexture) {
-                serializationObject.specularTexture = this.specularTexture.serialize();
+            if (this.reflectivityTexture) {
+                serializationObject.reflectivityTexture = this.reflectivityTexture.serialize();
             }
             }
             if (this.bumpTexture) {
             if (this.bumpTexture) {
                 serializationObject.bumpTexture = this.bumpTexture.serialize();
                 serializationObject.bumpTexture = this.bumpTexture.serialize();
@@ -1179,14 +1188,14 @@ module BABYLON {
             }
             }
 
 
             serializationObject.ambientColor = this.ambientColor.asArray();
             serializationObject.ambientColor = this.ambientColor.asArray();
-            serializationObject.diffuseColor = this.diffuseColor.asArray();
-            serializationObject.specularColor = this.specularColor.asArray();
+            serializationObject.albedoColor = this.albedoColor.asArray();
+            serializationObject.reflectivityColor = this.reflectivityColor.asArray();
             serializationObject.reflectionColor = this.reflectionColor.asArray();
             serializationObject.reflectionColor = this.reflectionColor.asArray();
-            serializationObject.glossiness = this.glossiness;
+            serializationObject.microSurface = this.microSurface;
             serializationObject.emissiveColor = this.emissiveColor.asArray();
             serializationObject.emissiveColor = this.emissiveColor.asArray();
-            serializationObject.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
+            serializationObject.useAlphaFromAlbedoTexture = this.useAlphaFromAlbedoTexture;
             serializationObject.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
             serializationObject.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            serializationObject.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
+            serializationObject.useMicroSurfaceFromReflectivityMapAlpha = this.useMicroSurfaceFromReflectivityMapAlpha;
             serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;
             serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;
             
             
             serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
             serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
@@ -1216,6 +1225,7 @@ module BABYLON {
             material.directIntensity = source.directIntensity;
             material.directIntensity = source.directIntensity;
             material.emissiveIntensity = source.emissiveIntensity;
             material.emissiveIntensity = source.emissiveIntensity;
             material.environmentIntensity = source.environmentIntensity;
             material.environmentIntensity = source.environmentIntensity;
+            material.specularIntensity = source.specularIntensity;
         
         
             material.cameraExposure = source.cameraExposure;
             material.cameraExposure = source.cameraExposure;
             material.cameraContrast = source.cameraContrast;
             material.cameraContrast = source.cameraContrast;
@@ -1224,24 +1234,24 @@ module BABYLON {
             material.overloadedShadeIntensity = source.overloadedShadeIntensity;
             material.overloadedShadeIntensity = source.overloadedShadeIntensity;
         
         
             material.overloadedAmbientIntensity = source.overloadedAmbientIntensity;
             material.overloadedAmbientIntensity = source.overloadedAmbientIntensity;
-            material.overloadedDiffuseIntensity = source.overloadedDiffuseIntensity;
-            material.overloadedSpecularIntensity = source.overloadedSpecularIntensity;
+            material.overloadedAlbedoIntensity = source.overloadedAlbedoIntensity;
+            material.overloadedReflectivityIntensity = source.overloadedReflectivityIntensity;
             material.overloadedEmissiveIntensity = source.overloadedEmissiveIntensity;
             material.overloadedEmissiveIntensity = source.overloadedEmissiveIntensity;
             material.overloadedAmbient = Color3.FromArray(source.overloadedAmbient);
             material.overloadedAmbient = Color3.FromArray(source.overloadedAmbient);
-            material.overloadedDiffuse = Color3.FromArray(source.overloadedDiffuse);
-            material.overloadedSpecular = Color3.FromArray(source.overloadedSpecular);
+            material.overloadedAlbedo = Color3.FromArray(source.overloadedAlbedo);
+            material.overloadedReflectivity = Color3.FromArray(source.overloadedReflectivity);
             material.overloadedEmissive = Color3.FromArray(source.overloadedEmissive);
             material.overloadedEmissive = Color3.FromArray(source.overloadedEmissive);
             material.overloadedReflection = Color3.FromArray(source.overloadedReflection);
             material.overloadedReflection = Color3.FromArray(source.overloadedReflection);
 
 
-            material.overloadedGlossiness = source.overloadedGlossiness;
-            material.overloadedGlossinessIntensity = source.overloadedGlossinessIntensity;
+            material.overloadedMicroSurface = source.overloadedMicroSurface;
+            material.overloadedMicroSurfaceIntensity = source.overloadedMicroSurfaceIntensity;
             material.overloadedReflectionIntensity = source.overloadedReflectionIntensity;
             material.overloadedReflectionIntensity = source.overloadedReflectionIntensity;
         
         
             material.disableBumpMap = source.disableBumpMap;
             material.disableBumpMap = source.disableBumpMap;
 
 
             // Standard material
             // Standard material
-            if (source.diffuseTexture) {
-                material.diffuseTexture = Texture.Parse(source.diffuseTexture, scene, rootUrl);
+            if (source.albedoTexture) {
+                material.albedoTexture = Texture.Parse(source.albedoTexture, scene, rootUrl);
             }
             }
             if (source.ambientTexture) {
             if (source.ambientTexture) {
                 material.ambientTexture = Texture.Parse(source.ambientTexture, scene, rootUrl);
                 material.ambientTexture = Texture.Parse(source.ambientTexture, scene, rootUrl);
@@ -1255,8 +1265,8 @@ module BABYLON {
             if (source.emissiveTexture) {
             if (source.emissiveTexture) {
                 material.emissiveTexture = Texture.Parse(source.emissiveTexture, scene, rootUrl);
                 material.emissiveTexture = Texture.Parse(source.emissiveTexture, scene, rootUrl);
             }
             }
-            if (source.specularTexture) {
-                material.specularTexture = Texture.Parse(source.specularTexture, scene, rootUrl);
+            if (source.reflectivityTexture) {
+                material.reflectivityTexture = Texture.Parse(source.reflectivityTexture, scene, rootUrl);
             }
             }
             if (source.bumpTexture) {
             if (source.bumpTexture) {
                 material.bumpTexture = Texture.Parse(source.bumpTexture, scene, rootUrl);
                 material.bumpTexture = Texture.Parse(source.bumpTexture, scene, rootUrl);
@@ -1267,14 +1277,14 @@ module BABYLON {
             }
             }
 
 
             material.ambientColor = Color3.FromArray(source.ambient);
             material.ambientColor = Color3.FromArray(source.ambient);
-            material.diffuseColor = Color3.FromArray(source.diffuse);
-            material.specularColor = Color3.FromArray(source.specular);
+            material.albedoColor = Color3.FromArray(source.albedo);
+            material.reflectivityColor = Color3.FromArray(source.reflectivity);
             material.reflectionColor = Color3.FromArray(source.reflectionColor);
             material.reflectionColor = Color3.FromArray(source.reflectionColor);
-            material.glossiness = source.glossiness;
+            material.microSurface = source.microSurface;
             material.emissiveColor = Color3.FromArray(source.emissive);
             material.emissiveColor = Color3.FromArray(source.emissive);
-            material.useAlphaFromDiffuseTexture = source.useAlphaFromDiffuseTexture;
+            material.useAlphaFromAlbedoTexture = source.useAlphaFromAlbedoTexture;
             material.useEmissiveAsIllumination = source.useEmissiveAsIllumination;
             material.useEmissiveAsIllumination = source.useEmissiveAsIllumination;
-            material.useGlossinessFromSpecularMapAlpha = source.useGlossinessFromSpecularMapAlpha;
+            material.useMicroSurfaceFromReflectivityMapAlpha = source.useMicroSurfaceFromReflectivityMapAlpha;
             material.useSpecularOverAlpha = source.useSpecularOverAlpha;
             material.useSpecularOverAlpha = source.useSpecularOverAlpha;
             
             
             material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);
             material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);

+ 59 - 73
materialsLibrary/materials/pbr/legacypbr.fragment.fx

@@ -6,7 +6,7 @@
 
 
 uniform vec3 vEyePosition;
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
 uniform vec3 vAmbientColor;
-uniform vec4 vDiffuseColor;
+uniform vec4 vAlbedoColor;
 uniform vec3 vReflectionColor;
 uniform vec3 vReflectionColor;
 
 
 // CUSTOM CONTROLS
 // CUSTOM CONTROLS
@@ -16,11 +16,11 @@ uniform vec4 vCameraInfos;
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
 uniform vec4 vOverloadedIntensity;
 uniform vec4 vOverloadedIntensity;
 uniform vec3 vOverloadedAmbient;
 uniform vec3 vOverloadedAmbient;
-uniform vec3 vOverloadedDiffuse;
-uniform vec3 vOverloadedSpecular;
+uniform vec3 vOverloadedAlbedo;
+uniform vec3 vOverloadedReflectivity;
 uniform vec3 vOverloadedEmissive;
 uniform vec3 vOverloadedEmissive;
 uniform vec3 vOverloadedReflection;
 uniform vec3 vOverloadedReflection;
-uniform vec3 vOverloadedGlossiness;
+uniform vec3 vOverloadedMicroSurface;
 #endif
 #endif
 
 
 #ifdef OVERLOADEDSHADOWVALUES
 #ifdef OVERLOADEDSHADOWVALUES
@@ -113,17 +113,17 @@ float computeDiffuseTerm(float NdotL, float NdotV, float VdotH, float roughness)
     return diffuseFresnelTerm * NdotL;
     return diffuseFresnelTerm * NdotL;
 }
 }
 
 
-float computeDefaultGlossiness(float glossiness, vec3 specularColor)
+float computeDefaultMicroSurface(float microSurface, vec3 reflectivityColor)
 {
 {
-    if (glossiness == 0.)
+    if (microSurface == 0.)
     {
     {
-        float kSpecularNoAlphaWorkflow_SmoothnessMax = 0.95;
+        float kReflectivityNoAlphaWorkflow_SmoothnessMax = 0.95;
 
 
-        float specularLuminance = getLuminance(specularColor);
-        float specularLuma = sqrt(specularLuminance);
-        glossiness = specularLuma * kSpecularNoAlphaWorkflow_SmoothnessMax;
+        float reflectivityLuminance = getLuminance(reflectivityColor);
+        float reflectivityLuma = sqrt(reflectivityLuminance);
+        microSurface = reflectivityLuma * kReflectivityNoAlphaWorkflow_SmoothnessMax;
     }
     }
-    return glossiness;
+    return microSurface;
 }
 }
 
 
 vec3 toLinearSpace(vec3 color)
 vec3 toLinearSpace(vec3 color)
@@ -174,9 +174,7 @@ vec3 toGammaSpace(vec3 color)
 #endif
 #endif
 // END PBR HELPER METHODS
 // END PBR HELPER METHODS
 
 
-#ifdef SPECULARTERM
-uniform vec4 vSpecularColor;
-#endif
+uniform vec4 vReflectivityColor;
 uniform vec3 vEmissiveColor;
 uniform vec3 vEmissiveColor;
 
 
 // Input
 // Input
@@ -284,10 +282,10 @@ uniform vec3 vLightGround3;
 #endif
 #endif
 
 
 // Samplers
 // Samplers
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform sampler2D diffuseSampler;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform sampler2D albedoSampler;
+uniform vec2 vAlbedoInfos;
 #endif
 #endif
 
 
 #ifdef AMBIENT
 #ifdef AMBIENT
@@ -314,10 +312,10 @@ uniform vec2 vLightmapInfos;
 uniform sampler2D lightmapSampler;
 uniform sampler2D lightmapSampler;
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-varying vec2 vSpecularUV;
-uniform vec2 vSpecularInfos;
-uniform sampler2D specularSampler;
+#if defined(REFLECTIVITY)
+varying vec2 vReflectivityUV;
+uniform vec2 vReflectivityInfos;
+uniform sampler2D reflectivitySampler;
 #endif
 #endif
 
 
 #ifdef CLIPPLANE
 #ifdef CLIPPLANE
@@ -446,13 +444,13 @@ void main(void) {
 
 
     // Base color
     // Base color
     vec4 baseColor = vec4(1., 1., 1., 1.);
     vec4 baseColor = vec4(1., 1., 1., 1.);
-    vec3 diffuseColor = vDiffuseColor.rgb;
+    vec3 diffuseColor = vAlbedoColor.rgb;
     
     
     // Alpha
     // Alpha
-    float alpha = vDiffuseColor.a;
+    float alpha = vAlbedoColor.a;
 
 
-#ifdef DIFFUSE
-    baseColor = texture2D(diffuseSampler, vDiffuseUV);
+#ifdef ALBEDO
+    baseColor = texture2D(diffuseSampler, vAlbedoUV);
     baseColor = vec4(toLinearSpace(baseColor.rgb), baseColor.a);
     baseColor = vec4(toLinearSpace(baseColor.rgb), baseColor.a);
 
 
 #ifdef ALPHATEST
 #ifdef ALPHATEST
@@ -460,11 +458,11 @@ void main(void) {
         discard;
         discard;
 #endif
 #endif
 
 
-#ifdef ALPHAFROMDIFFUSE
+#ifdef ALPHAFROMALBEDO
     alpha *= baseColor.a;
     alpha *= baseColor.a;
 #endif
 #endif
 
 
-    baseColor.rgb *= vDiffuseInfos.y;
+    baseColor.rgb *= vAlbedoInfos.y;
 #endif
 #endif
 
 
 #ifdef VERTEXCOLOR
 #ifdef VERTEXCOLOR
@@ -472,8 +470,8 @@ void main(void) {
 #endif
 #endif
 
 
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
-    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
-    diffuseColor.rgb = mix(diffuseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedAlbedo, vOverloadedIntensity.y);
+    albedoColor.rgb = mix(albedoColor.rgb, vOverloadedAlbedo, vOverloadedIntensity.y);
 #endif
 #endif
 
 
     // Bump
     // Bump
@@ -493,57 +491,45 @@ void main(void) {
     #endif
     #endif
 #endif
 #endif
 
 
-    // Specular map
-#ifdef SPECULARTERM
-    float glossiness = vSpecularColor.a;
-    vec3 specularColor = vSpecularColor.rgb;
+    // Reflectivity map
+    float microSurface = vReflectivityColor.a;
+    vec3 reflectivityColor = vReflectivityColor.rgb;
 
 
     #ifdef OVERLOADEDVALUES
     #ifdef OVERLOADEDVALUES
-        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
     #endif
     #endif
 
 
-    #ifdef SPECULAR
-            vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
-            specularColor = toLinearSpace(specularMapColor.rgb);
+    #ifdef REFLECTIVITY
+            vec4 reflectivityMapColor = texture2D(reflectivitySampler, vReflectivityUV);
+            reflectivityColor = toLinearSpace(reflectivityMapColor.rgb);
 
 
         #ifdef OVERLOADEDVALUES
         #ifdef OVERLOADEDVALUES
-                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+                reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
         #endif
         #endif
 
 
-        #ifdef GLOSSINESSFROMSPECULARMAP
-            glossiness = specularMapColor.a;
+        #ifdef MICROSURFACEFROMREFLECTIVITYMAP
+            microSurface = reflectivityMapColor.a;
         #else
         #else
-            glossiness = computeDefaultGlossiness(glossiness, specularColor);
+            microSurface = computeDefaultMicroSurface(microSurface, reflectivityColor);
         #endif
         #endif
     #endif
     #endif
 
 
     #ifdef OVERLOADEDVALUES
     #ifdef OVERLOADEDVALUES
-        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
-    #endif
-#else
-    float glossiness = 0.;
-    #ifdef OVERLOADEDVALUES
-        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
-    #endif
-
-    vec3 specularColor = vec3(0., 0., 0);
-    #ifdef OVERLOADEDVALUES
-            specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        microSurface = mix(microSurface, vOverloadedMicroSurface.x, vOverloadedMicroSurface.y);
     #endif
     #endif
-#endif
 
 
     // Apply Energy Conservation taking in account the environment level only if the environment is present.
     // Apply Energy Conservation taking in account the environment level only if the environment is present.
-    float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+    float reflectance = max(max(reflectivityColor.r, reflectivityColor.g), reflectivityColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
 
     // Compute Specular Fresnel + Reflectance.
     // Compute Specular Fresnel + Reflectance.
     float NdotV = max(0.00000000001, dot(normalW, viewDirectionW));
     float NdotV = max(0.00000000001, dot(normalW, viewDirectionW));
 
 
-    // Adapt glossiness.
-    glossiness = clamp(glossiness, 0., 1.) * 0.98;
+    // Adapt microSurface.
+    microSurface = clamp(microSurface, 0., 1.) * 0.98;
 
 
     // Call rough to not conflict with previous one.
     // Call rough to not conflict with previous one.
-    float rough = clamp(1. - glossiness, 0.000001, 1.0);
+    float rough = clamp(1. - microSurface, 0.000001, 1.0);
 
 
     // Lighting
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
     vec3 diffuseBase = vec3(0., 0., 0.);
@@ -664,15 +650,15 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
 reflectionColor *= vLightingIntensity.z;
 reflectionColor *= vLightingIntensity.z;
 ambientReflectionColor *= vLightingIntensity.z;
 ambientReflectionColor *= vLightingIntensity.z;
 
 
-// Compute reflection specular fresnel
-vec3 specularEnvironmentR0 = specularColor.rgb;
-vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
-vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
-reflectionColor *= specularEnvironmentReflectanceViewer;
+// Compute reflection reflectivity fresnel
+vec3 reflectivityEnvironmentR0 = reflectivityColor.rgb;
+vec3 reflectivityEnvironmentR90 = vec3(1.0, 1.0, 1.0);
+vec3 reflectivityEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), reflectivityEnvironmentR0, reflectivityEnvironmentR90, sqrt(microSurface));
+reflectionColor *= reflectivityEnvironmentReflectanceViewer;
 
 
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
-    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
-    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
+    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedMicroSurface.z);
+    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedMicroSurface.z);
 #endif
 #endif
 
 
 #ifdef OPACITY
 #ifdef OPACITY
@@ -704,21 +690,21 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 
 
     // Composition
     // Composition
 #ifdef EMISSIVEASILLUMINATION
 #ifdef EMISSIVEASILLUMINATION
-    vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    vec3 finalDiffuse = max(diffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
 
 
     #ifdef OVERLOADEDSHADOWVALUES
     #ifdef OVERLOADEDSHADOWVALUES
-        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
     #endif
 #else
 #else
-    #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    #ifdef LINKEMISSIVEWITHALBEDO
+        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
         #ifdef OVERLOADEDSHADOWVALUES
         #ifdef OVERLOADEDSHADOWVALUES
-                shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+                shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
         #endif
     #else
     #else
-        vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+        vec3 finalDiffuse = max(diffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
         #ifdef OVERLOADEDSHADOWVALUES
         #ifdef OVERLOADEDSHADOWVALUES
-            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
         #endif
     #endif
     #endif
 #endif
 #endif
@@ -732,7 +718,7 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 
 
 #ifdef SPECULARTERM
 #ifdef SPECULARTERM
-    vec3 finalSpecular = specularBase * specularColor;
+    vec3 finalSpecular = specularBase * reflectivityColor * vLightingIntensity.w;
 #else
 #else
     vec3 finalSpecular = vec3(0.0);
     vec3 finalSpecular = vec3(0.0);
 #endif
 #endif

+ 16 - 16
materialsLibrary/materials/pbr/legacypbr.vertex.fx

@@ -29,10 +29,10 @@ uniform mat4 world;
 uniform mat4 view;
 uniform mat4 view;
 uniform mat4 viewProjection;
 uniform mat4 viewProjection;
 
 
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform mat4 diffuseMatrix;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform mat4 albedoMatrix;
+uniform vec2 vAlbedoInfos;
 #endif
 #endif
 
 
 #ifdef AMBIENT
 #ifdef AMBIENT
@@ -53,10 +53,10 @@ uniform vec2 vEmissiveInfos;
 uniform mat4 emissiveMatrix;
 uniform mat4 emissiveMatrix;
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-varying vec2 vSpecularUV;
-uniform vec2 vSpecularInfos;
-uniform mat4 specularMatrix;
+#if defined(REFLECTIVITY)
+varying vec2 vReflectivityUV;
+uniform vec2 vReflectivityInfos;
+uniform mat4 reflectivityMatrix;
 #endif
 #endif
 
 
 // Output
 // Output
@@ -119,14 +119,14 @@ void main(void) {
 	vec2 uv2 = vec2(0., 0.);
 	vec2 uv2 = vec2(0., 0.);
 #endif
 #endif
 
 
-#ifdef DIFFUSE
-	if (vDiffuseInfos.x == 0.)
+#ifdef ALBEDO
+	if (vAlbedoInfos.x == 0.)
 	{
 	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
+		vAlbedoUV = vec2(albedoMatrix * vec4(uv, 1.0, 0.0));
 	}
 	}
 	else
 	else
 	{
 	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+		vAlbedoUV = vec2(albedoMatrix * vec4(uv2, 1.0, 0.0));
 	}
 	}
 #endif
 #endif
 
 
@@ -163,14 +163,14 @@ void main(void) {
 	}
 	}
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-	if (vSpecularInfos.x == 0.)
+#if defined(REFLECTIVITY)
+	if (vReflectivityInfos.x == 0.)
 	{
 	{
-		vSpecularUV = vec2(specularMatrix * vec4(uv, 1.0, 0.0));
+		vReflectivityUV = vec2(reflectivityMatrix * vec4(uv, 1.0, 0.0));
 	}
 	}
 	else
 	else
 	{
 	{
-		vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
+		vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2, 1.0, 0.0));
 	}
 	}
 #endif
 #endif
 
 

+ 75 - 90
materialsLibrary/materials/pbr/pbr.fragment.fx

@@ -15,7 +15,7 @@ precision highp float;
 uniform vec3 vEyePosition;
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
 uniform vec3 vAmbientColor;
 uniform vec3 vReflectionColor;
 uniform vec3 vReflectionColor;
-uniform vec4 vDiffuseColor;
+uniform vec4 vAlbedoColor;
 
 
 // CUSTOM CONTROLS
 // CUSTOM CONTROLS
 uniform vec4 vLightingIntensity;
 uniform vec4 vLightingIntensity;
@@ -24,11 +24,11 @@ uniform vec4 vCameraInfos;
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
     uniform vec4 vOverloadedIntensity;
     uniform vec4 vOverloadedIntensity;
     uniform vec3 vOverloadedAmbient;
     uniform vec3 vOverloadedAmbient;
-    uniform vec3 vOverloadedDiffuse;
-    uniform vec3 vOverloadedSpecular;
+    uniform vec3 vOverloadedAlbedo;
+    uniform vec3 vOverloadedReflectivity;
     uniform vec3 vOverloadedEmissive;
     uniform vec3 vOverloadedEmissive;
     uniform vec3 vOverloadedReflection;
     uniform vec3 vOverloadedReflection;
-    uniform vec3 vOverloadedGlossiness;
+    uniform vec3 vOverloadedMicroSurface;
 #endif
 #endif
 
 
 #ifdef OVERLOADEDSHADOWVALUES
 #ifdef OVERLOADEDSHADOWVALUES
@@ -124,15 +124,15 @@ float computeDiffuseTerm(float NdotL, float NdotV, float VdotH, float roughness)
     // diffuseFresnelTerm /= kPi;
     // diffuseFresnelTerm /= kPi;
 }
 }
 
 
-float computeDefaultGlossiness(float glossiness, vec3 specularColor)
+float computeDefaultMicroSurface(float microSurface, vec3 reflectivityColor)
 {
 {
-    float kSpecularNoAlphaWorkflow_SmoothnessMax = 0.95;
+    float kReflectivityNoAlphaWorkflow_SmoothnessMax = 0.95;
 
 
-    float specularLuminance = getLuminance(specularColor);
-    float specularLuma = sqrt(specularLuminance);
-    glossiness = specularLuma * kSpecularNoAlphaWorkflow_SmoothnessMax;
+    float reflectivityLuminance = getLuminance(reflectivityColor);
+    float reflectivityLuma = sqrt(reflectivityLuminance);
+    microSurface = reflectivityLuma * kReflectivityNoAlphaWorkflow_SmoothnessMax;
 
 
-    return glossiness;
+    return microSurface;
 }
 }
 
 
 vec3 toLinearSpace(vec3 color)
 vec3 toLinearSpace(vec3 color)
@@ -185,10 +185,8 @@ vec3 toGammaSpace(vec3 color)
 #endif
 #endif
 // END PBR HELPER METHODS
 // END PBR HELPER METHODS
 
 
-#ifdef SPECULARTERM
-uniform vec4 vSpecularColor;
-#endif
-uniform vec3 vEmissiveColor;
+    uniform vec4 vReflectivityColor;
+    uniform vec3 vEmissiveColor;
 
 
 // Input
 // Input
 varying vec3 vPositionW;
 varying vec3 vPositionW;
@@ -295,10 +293,10 @@ uniform vec3 vLightGround3;
 #endif
 #endif
 
 
 // Samplers
 // Samplers
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform sampler2D diffuseSampler;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform sampler2D albedoSampler;
+uniform vec2 vAlbedoInfos;
 #endif
 #endif
 
 
 #ifdef AMBIENT
 #ifdef AMBIENT
@@ -325,10 +323,10 @@ uniform vec2 vLightmapInfos;
 uniform sampler2D lightmapSampler;
 uniform sampler2D lightmapSampler;
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-varying vec2 vSpecularUV;
-uniform vec2 vSpecularInfos;
-uniform sampler2D specularSampler;
+#if defined(REFLECTIVITY)
+varying vec2 vReflectivityUV;
+uniform vec2 vReflectivityInfos;
+uniform sampler2D reflectivitySampler;
 #endif
 #endif
 
 
 // Fresnel
 // Fresnel
@@ -438,16 +436,18 @@ float unpack(vec4 color)
 }
 }
 
 
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+uniform vec2 depthValues;
+
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
 {
-    vec3 directionToLight = vPositionW - lightPosition;
-    float depth = length(directionToLight);
-
-    depth = clamp(depth, 0., 1.);
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
+	depth = clamp(depth, 0., 1.0);
 
 
-    directionToLight.y = 1.0 - directionToLight.y;
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = - directionToLight.y;
 
 
-    float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 
 
     if (depth > shadow)
     if (depth > shadow)
     {
     {
@@ -462,13 +462,14 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 
 
 float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
 float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
 {
 {
-    vec3 directionToLight = vPositionW - lightPosition;
-    float depth = length(directionToLight);
-    float diskScale = (1.0 - (1.0 + depth * 3.0)) / mapSize;
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
 
 
-    depth = clamp(depth, 0., 1.);
+	depth = clamp(depth, 0., 1.0);
+	float diskScale = 2.0 / mapSize;
 
 
-    directionToLight.y = 1.0 - directionToLight.y;
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = -directionToLight.y;
 
 
     float visibility = 1.;
     float visibility = 1.;
 
 
@@ -800,13 +801,13 @@ void main(void) {
 
 
     // Base color
     // Base color
     vec4 baseColor = vec4(1., 1., 1., 1.);
     vec4 baseColor = vec4(1., 1., 1., 1.);
-    vec3 diffuseColor = vDiffuseColor.rgb;
+    vec3 albedoColor = vAlbedoColor.rgb;
     
     
     // Alpha
     // Alpha
-    float alpha = vDiffuseColor.a;
+    float alpha = vAlbedoColor.a;
 
 
-#ifdef DIFFUSE
-    baseColor = texture2D(diffuseSampler, vDiffuseUV);
+#ifdef ALBEDO
+    baseColor = texture2D(albedoSampler, vAlbedoUV);
     baseColor = vec4(toLinearSpace(baseColor.rgb), baseColor.a);
     baseColor = vec4(toLinearSpace(baseColor.rgb), baseColor.a);
 
 
 #ifdef ALPHATEST
 #ifdef ALPHATEST
@@ -814,11 +815,11 @@ void main(void) {
         discard;
         discard;
 #endif
 #endif
 
 
-#ifdef ALPHAFROMDIFFUSE
+#ifdef ALPHAFROMALBEDO
     alpha *= baseColor.a;
     alpha *= baseColor.a;
 #endif
 #endif
 
 
-    baseColor.rgb *= vDiffuseInfos.y;
+    baseColor.rgb *= vAlbedoInfos.y;
 #endif
 #endif
 
 
 #ifdef VERTEXCOLOR
 #ifdef VERTEXCOLOR
@@ -826,8 +827,8 @@ void main(void) {
 #endif
 #endif
 
 
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
-    baseColor.rgb = mix(baseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
-    diffuseColor.rgb = mix(diffuseColor.rgb, vOverloadedDiffuse, vOverloadedIntensity.y);
+    baseColor.rgb = mix(baseColor.rgb, vOverloadedAlbedo, vOverloadedIntensity.y);
+    albedoColor.rgb = mix(albedoColor.rgb, vOverloadedAlbedo, vOverloadedIntensity.y);
 #endif
 #endif
 
 
     // Bump
     // Bump
@@ -854,56 +855,44 @@ void main(void) {
 #endif
 #endif
 
 
     // Specular map
     // Specular map
-#ifdef SPECULARTERM
-    float glossiness = vSpecularColor.a;
-    vec3 specularColor = vSpecularColor.rgb;
+    float microSurface = vReflectivityColor.a;
+    vec3 reflectivityColor = vReflectivityColor.rgb;
     
     
     #ifdef OVERLOADEDVALUES
     #ifdef OVERLOADEDVALUES
-        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
     #endif
     #endif
 
 
-    #ifdef SPECULAR
-        vec4 specularMapColor = texture2D(specularSampler, vSpecularUV);
-        specularColor = toLinearSpace(specularMapColor.rgb);
+    #ifdef REFLECTIVITY
+        vec4 reflectivityMapColor = texture2D(reflectivitySampler, vReflectivityUV);
+        reflectivityColor = toLinearSpace(reflectivityMapColor.rgb);
 
 
         #ifdef OVERLOADEDVALUES
         #ifdef OVERLOADEDVALUES
-                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+                reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
         #endif
         #endif
 
 
-        #ifdef GLOSSINESSFROMSPECULARMAP
-            glossiness = specularMapColor.a;
+        #ifdef MICROSURFACEFROMREFLECTIVITYMAP
+            microSurface = reflectivityMapColor.a;
         #else
         #else
-            glossiness = computeDefaultGlossiness(glossiness, specularColor);
+            microSurface = computeDefaultMicroSurface(microSurface, reflectivityColor);
         #endif
         #endif
     #endif
     #endif
 
 
     #ifdef OVERLOADEDVALUES
     #ifdef OVERLOADEDVALUES
-        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
-    #endif
-#else
-    float glossiness = 0.;
-    #ifdef OVERLOADEDVALUES
-        glossiness = mix(glossiness, vOverloadedGlossiness.x, vOverloadedGlossiness.y);
-    #endif
-    
-    vec3 specularColor = vec3(0., 0., 0);
-    #ifdef OVERLOADEDVALUES
-        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        microSurface = mix(microSurface, vOverloadedMicroSurface.x, vOverloadedMicroSurface.y);
     #endif
     #endif
-#endif
 
 
     // Apply Energy Conservation taking in account the environment level only if the environment is present.
     // Apply Energy Conservation taking in account the environment level only if the environment is present.
-    float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+    float reflectance = max(max(reflectivityColor.r, reflectivityColor.g), reflectivityColor.b);
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
     baseColor.rgb = (1. - reflectance) * baseColor.rgb;
 
 
     // Compute Specular Fresnel + Reflectance.
     // Compute Specular Fresnel + Reflectance.
     float NdotV = max(0.00000000001, dot(normalW, viewDirectionW));
     float NdotV = max(0.00000000001, dot(normalW, viewDirectionW));
 
 
-    // Adapt glossiness.
-    glossiness = clamp(glossiness, 0., 1.) * 0.98;
+    // Adapt microSurface.
+    microSurface = clamp(microSurface, 0., 1.) * 0.98;
 
 
     // Call rough to not conflict with previous one.
     // Call rough to not conflict with previous one.
-    float rough = clamp(1. - glossiness, 0.000001, 1.0);
+    float rough = clamp(1. - microSurface, 0.000001, 1.0);
 
 
     // Lighting
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
     vec3 diffuseBase = vec3(0., 0., 0.);
@@ -1104,12 +1093,8 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
 
 
     #ifdef REFLECTIONMAP_3D
     #ifdef REFLECTIONMAP_3D
-        float bias = 0.;
-
-        #ifdef SPECULARTERM
-            // Go mat -> blurry reflexion according to glossiness
-            bias = 20. * (1.0 - glossiness);
-        #endif
+        // Go mat -> blurry reflexion according to microSurface
+        float bias = 20. * (1.0 - microSurface);
 
 
         reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
         reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
         reflectionColor = toLinearSpace(reflectionColor.rgb);
         reflectionColor = toLinearSpace(reflectionColor.rgb);
@@ -1134,17 +1119,17 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
 #endif
 #endif
 
 
 #ifdef OVERLOADEDVALUES
 #ifdef OVERLOADEDVALUES
-    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
-    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedGlossiness.z);
+    ambientReflectionColor = mix(ambientReflectionColor, vOverloadedReflection, vOverloadedMicroSurface.z);
+    reflectionColor = mix(reflectionColor, vOverloadedReflection, vOverloadedMicroSurface.z);
 #endif
 #endif
 
 
 reflectionColor *= vLightingIntensity.z;
 reflectionColor *= vLightingIntensity.z;
 ambientReflectionColor *= vLightingIntensity.z;
 ambientReflectionColor *= vLightingIntensity.z;
 
 
 // Compute reflection specular fresnel
 // Compute reflection specular fresnel
-vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR0 = reflectivityColor.rgb;
 vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
 vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0);
-vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(glossiness));
+vec3 specularEnvironmentReflectanceViewer = FresnelSchlickEnvironmentGGX(clamp(NdotV, 0., 1.), specularEnvironmentR0, specularEnvironmentR90, sqrt(microSurface));
 reflectionColor *= specularEnvironmentReflectanceViewer;
 reflectionColor *= specularEnvironmentReflectanceViewer;
 
 
 #ifdef OPACITY
 #ifdef OPACITY
@@ -1188,23 +1173,23 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 
 
     // Composition
     // Composition
 #ifdef EMISSIVEASILLUMINATION
 #ifdef EMISSIVEASILLUMINATION
-    vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    vec3 finalDiffuse = max(diffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     
     
     #ifdef OVERLOADEDSHADOWVALUES
     #ifdef OVERLOADEDSHADOWVALUES
-        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
     #endif
 #else
 #else
-    #ifdef LINKEMISSIVEWITHDIFFUSE
-        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    #ifdef LINKEMISSIVEWITHALBEDO
+        vec3 finalDiffuse = max((diffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
 
 
         #ifdef OVERLOADEDSHADOWVALUES
         #ifdef OVERLOADEDSHADOWVALUES
-            shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
         #endif
     #else
     #else
-        vec3 finalDiffuse = max(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+        vec3 finalDiffuse = max(diffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
 
 
         #ifdef OVERLOADEDSHADOWVALUES
         #ifdef OVERLOADEDSHADOWVALUES
-            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
         #endif
     #endif
     #endif
 #endif
 #endif
@@ -1218,7 +1203,7 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 
 
 #ifdef SPECULARTERM
 #ifdef SPECULARTERM
-    vec3 finalSpecular = specularBase * specularColor;
+    vec3 finalSpecular = specularBase * reflectivityColor * vLightingIntensity.w;
 #else
 #else
     vec3 finalSpecular = vec3(0.0);
     vec3 finalSpecular = vec3(0.0);
 #endif
 #endif
@@ -1279,13 +1264,13 @@ finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
     // gl_FragColor = vec4(baseColor.rgb, 1.0);
     // gl_FragColor = vec4(baseColor.rgb, 1.0);
 
 
     // Specular color.
     // Specular color.
-    // gl_FragColor = vec4(specularColor.rgb, 1.0);
+    // gl_FragColor = vec4(reflectivityColor.rgb, 1.0);
 
 
-    // Glossiness color.
-    // gl_FragColor = vec4(glossiness, glossiness, glossiness, 1.0);
+    // MicroSurface color.
+    // gl_FragColor = vec4(microSurface, microSurface, microSurface, 1.0);
 
 
     // Specular Map
     // Specular Map
-    // gl_FragColor = vec4(specularMapColor.rgb, 1.0);
+    // gl_FragColor = vec4(reflectivityMapColor.rgb, 1.0);
 
 
     //// Emissive Color
     //// Emissive Color
     //vec2 test = vEmissiveUV * 0.5 + 0.5;
     //vec2 test = vEmissiveUV * 0.5 + 0.5;

+ 16 - 16
materialsLibrary/materials/pbr/pbr.vertex.fx

@@ -39,10 +39,10 @@ uniform mat4 world;
 uniform mat4 view;
 uniform mat4 view;
 uniform mat4 viewProjection;
 uniform mat4 viewProjection;
 
 
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform mat4 diffuseMatrix;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform mat4 albedoMatrix;
+uniform vec2 vAlbedoInfos;
 #endif
 #endif
 
 
 #ifdef AMBIENT
 #ifdef AMBIENT
@@ -69,10 +69,10 @@ uniform vec2 vLightmapInfos;
 uniform mat4 lightmapMatrix;
 uniform mat4 lightmapMatrix;
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-varying vec2 vSpecularUV;
-uniform vec2 vSpecularInfos;
-uniform mat4 specularMatrix;
+#if defined(REFLECTIVITY)
+varying vec2 vReflectivityUV;
+uniform vec2 vReflectivityInfos;
+uniform mat4 reflectivityMatrix;
 #endif
 #endif
 
 
 #ifdef BUMP
 #ifdef BUMP
@@ -199,14 +199,14 @@ void main(void) {
     vec2 uv2 = vec2(0., 0.);
     vec2 uv2 = vec2(0., 0.);
 #endif
 #endif
 
 
-#ifdef DIFFUSE
-    if (vDiffuseInfos.x == 0.)
+#ifdef ALBEDO
+    if (vAlbedoInfos.x == 0.)
     {
     {
-        vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
+        vAlbedoUV = vec2(albedoMatrix * vec4(uv, 1.0, 0.0));
     }
     }
     else
     else
     {
     {
-        vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+        vAlbedoUV = vec2(albedoMatrix * vec4(uv2, 1.0, 0.0));
     }
     }
 #endif
 #endif
 
 
@@ -254,14 +254,14 @@ void main(void) {
     }
     }
 #endif
 #endif
 
 
-#if defined(SPECULAR) && defined(SPECULARTERM)
-    if (vSpecularInfos.x == 0.)
+#if defined(REFLECTIVITY)
+    if (vReflectivityInfos.x == 0.)
     {
     {
-        vSpecularUV = vec2(specularMatrix * vec4(uv, 1.0, 0.0));
+        vReflectivityUV = vec2(reflectivityMatrix * vec4(uv, 1.0, 0.0));
     }
     }
     else
     else
     {
     {
-        vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
+        vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2, 1.0, 0.0));
     }
     }
 #endif
 #endif
 
 

+ 10 - 2
materialsLibrary/materials/simple/babylon.simpleMaterial.ts

@@ -353,7 +353,7 @@ module BABYLON {
                         "vDiffuseInfos", 
                         "vDiffuseInfos", 
                         "mBones",
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3"
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                     ],
                     ],
                     ["diffuseSampler",
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -420,6 +420,7 @@ module BABYLON {
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
                     var light = scene.lights[index];
 
 
@@ -452,7 +453,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         var shadowGenerator = light.getShadowGenerator();
                         if (mesh.receiveShadows && shadowGenerator) {
                         if (mesh.receiveShadows && shadowGenerator) {
-                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            if (!(<any>light).needCube()) {
+                                this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            } else {
+                                if (!depthValuesAlreadySet) {
+                                    depthValuesAlreadySet = true;
+                                    this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                                }
+                            }
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                             this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         }
                         }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 560 - 555
materialsLibrary/materials/simple/simple.fragment.fx


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 713 - 712
materialsLibrary/materials/terrain/terrain.fragment.fx


+ 622 - 0
materialsLibrary/materials/triPlanar/babylon.triPlanarMaterial.ts

@@ -0,0 +1,622 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON {
+    var maxSimultaneousLights = 4;
+
+    class TriPlanarMaterialDefines extends MaterialDefines {
+        public DIFFUSEX = false;
+        public DIFFUSEY = false;
+        public DIFFUSEZ = false;
+        
+        public BUMPX = false;
+        public BUMPY = false;
+        public BUMPZ = false;
+        
+        public CLIPPLANE = false;
+        public ALPHATEST = false;
+        public POINTSIZE = false;
+        public FOG = false;
+        public LIGHT0 = false;
+        public LIGHT1 = false;
+        public LIGHT2 = false;
+        public LIGHT3 = false;
+        public SPOTLIGHT0 = false;
+        public SPOTLIGHT1 = false;
+        public SPOTLIGHT2 = false;
+        public SPOTLIGHT3 = false;
+        public HEMILIGHT0 = false;
+        public HEMILIGHT1 = false;
+        public HEMILIGHT2 = false;
+        public HEMILIGHT3 = false;
+        public DIRLIGHT0 = false;
+        public DIRLIGHT1 = false;
+        public DIRLIGHT2 = false;
+        public DIRLIGHT3 = false;
+        public POINTLIGHT0 = false;
+        public POINTLIGHT1 = false;
+        public POINTLIGHT2 = false;
+        public POINTLIGHT3 = false;        
+        public SHADOW0 = false;
+        public SHADOW1 = false;
+        public SHADOW2 = false;
+        public SHADOW3 = false;
+        public SHADOWS = false;
+        public SHADOWVSM0 = false;
+        public SHADOWVSM1 = false;
+        public SHADOWVSM2 = false;
+        public SHADOWVSM3 = false;
+        public SHADOWPCF0 = false;
+        public SHADOWPCF1 = false;
+        public SHADOWPCF2 = false;
+        public SHADOWPCF3 = false;
+        public SPECULARTERM = false;
+        public NORMAL = false;
+        public VERTEXCOLOR = false;
+        public VERTEXALPHA = false;
+        public BONES = false;
+        public BONES4 = false;
+        public BonesPerMesh = 0;
+        public INSTANCES = false;
+
+        constructor() {
+            super();
+            this._keys = Object.keys(this);
+        }
+    }
+
+    export class TriPlanarMaterial extends Material {
+        public mixTexture: BaseTexture;
+        
+        public diffuseTextureX: Texture;
+        public diffuseTextureY: Texture;
+        public diffuseTextureZ: Texture;
+        
+        public normalTextureX: Texture;
+        public normalTextureY: Texture;
+        public normalTextureZ: Texture;
+        
+        public tileSize: number = 1;
+        
+        public diffuseColor = new Color3(1, 1, 1);
+        public specularColor = new Color3(0.2, 0.2, 0.2);
+        public specularPower = 64;
+        public disableLighting = false;
+
+        private _worldViewProjectionMatrix = Matrix.Zero();
+        private _scaledDiffuse = new Color3();
+        private _scaledSpecular = new Color3();
+        private _renderId: number;
+
+        private _defines = new TriPlanarMaterialDefines();
+        private _cachedDefines = new TriPlanarMaterialDefines();
+
+        constructor(name: string, scene: Scene) {
+            super(name, scene);
+
+            this._cachedDefines.BonesPerMesh = -1;
+        }
+
+        public needAlphaBlending(): boolean {
+            return (this.alpha < 1.0);
+        }
+
+        public needAlphaTesting(): boolean {
+            return false;
+        }
+
+        public getAlphaTestTexture(): BaseTexture {
+            return null;
+        }
+
+        // Methods   
+        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
+            if (!mesh) {
+                return true;
+            }
+
+            if (this._defines.INSTANCES !== useInstances) {
+                return false;
+            }
+
+            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
+                return true;
+            }
+
+            return false;
+        }
+
+        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
+            if (this.checkReadyOnlyOnce) {
+                if (this._wasPreviouslyReady) {
+                    return true;
+                }
+            }
+
+            var scene = this.getScene();
+
+            if (!this.checkReadyOnEveryCall) {
+                if (this._renderId === scene.getRenderId()) {
+                    if (this._checkCache(scene, mesh, useInstances)) {
+                        return true;
+                    }
+                }
+            }
+
+            var engine = scene.getEngine();
+            var needNormals = false;
+
+            this._defines.reset();
+
+            // Textures
+            if (scene.texturesEnabled) {
+                if (StandardMaterial.DiffuseTextureEnabled) {
+                    var textures = [this.diffuseTextureX, this.diffuseTextureY, this.diffuseTextureZ];
+                    var textureDefines = ["DIFFUSEX", "DIFFUSEY", "DIFFUSEZ"];
+                    
+                    for (var i=0; i < textures.length; i++) {
+                        if (textures[i]) {
+                            if (!textures[i].isReady()) {
+                                return false;
+                            } else {
+                                this._defines[textureDefines[i]] = true;
+                            }
+                        }
+                    }
+                }
+                if (StandardMaterial.BumpTextureEnabled) {
+                    var textures = [this.normalTextureX, this.normalTextureY, this.normalTextureZ];
+                    var textureDefines = ["BUMPX", "BUMPY", "BUMPZ"];
+                    
+                    for (var i=0; i < textures.length; i++) {
+                        if (textures[i]) {
+                            if (!textures[i].isReady()) {
+                                return false;
+                            } else {
+                                this._defines[textureDefines[i]] = true;
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Effect
+            if (scene.clipPlane) {
+                this._defines.CLIPPLANE = true;
+            }
+
+            if (engine.getAlphaTesting()) {
+                this._defines.ALPHATEST = true;
+            }
+
+            // Point size
+            if (this.pointsCloud || scene.forcePointsCloud) {
+                this._defines.POINTSIZE = true;
+            }
+
+            // Fog
+            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
+                this._defines.FOG = true;
+            }
+
+            var lightIndex = 0;
+            if (scene.lightsEnabled && !this.disableLighting) {
+                for (var index = 0; index < scene.lights.length; index++) {
+                    var light = scene.lights[index];
+
+                    if (!light.isEnabled()) {
+                        continue;
+                    }
+
+                    // Excluded check
+                    if (light._excludedMeshesIds.length > 0) {
+                        for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
+                            var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
+
+                            if (excludedMesh) {
+                                light.excludedMeshes.push(excludedMesh);
+                            }
+                        }
+
+                        light._excludedMeshesIds = [];
+                    }
+
+                    // Included check
+                    if (light._includedOnlyMeshesIds.length > 0) {
+                        for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
+                            var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
+
+                            if (includedOnlyMesh) {
+                                light.includedOnlyMeshes.push(includedOnlyMesh);
+                            }
+                        }
+
+                        light._includedOnlyMeshesIds = [];
+                    }
+
+                    if (!light.canAffectMesh(mesh)) {
+                        continue;
+                    }
+                    needNormals = true;
+                    this._defines["LIGHT" + lightIndex] = true;
+
+                    var type;
+                    if (light instanceof SpotLight) {
+                        type = "SPOTLIGHT" + lightIndex;
+                    } else if (light instanceof HemisphericLight) {
+                        type = "HEMILIGHT" + lightIndex;
+                    } else if (light instanceof PointLight) {
+                        type = "POINTLIGHT" + lightIndex;
+                    } else {
+                        type = "DIRLIGHT" + lightIndex;
+                    }
+
+                    this._defines[type] = true;
+                    
+                    // Specular
+                    if (!light.specular.equalsFloats(0, 0, 0)) {
+                        this._defines.SPECULARTERM = true;
+                    }
+
+                    // Shadows
+                    if (scene.shadowsEnabled) {
+                        var shadowGenerator = light.getShadowGenerator();
+                        if (mesh && mesh.receiveShadows && shadowGenerator) {
+                            this._defines["SHADOW" + lightIndex] = true;
+
+                            this._defines.SHADOWS = true;
+
+                            if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
+                                this._defines["SHADOWVSM" + lightIndex] = true;
+                            }
+
+                            if (shadowGenerator.usePoissonSampling) {
+                                this._defines["SHADOWPCF" + lightIndex] = true;
+                            }
+                        }
+                    }
+
+                    lightIndex++;
+                    if (lightIndex === maxSimultaneousLights)
+                        break;
+                }
+            }
+
+            // Attribs
+            if (mesh) {
+                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
+                    this._defines.NORMAL = true;
+                }
+                if (mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {
+                    this._defines.VERTEXCOLOR = true;
+
+                    if (mesh.hasVertexAlpha) {
+                        this._defines.VERTEXALPHA = true;
+                    }
+                }
+                if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                    this._defines.BONES = true;
+                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                    this._defines.BONES4 = true;
+                }
+
+                // Instances
+                if (useInstances) {
+                    this._defines.INSTANCES = true;
+                }
+            }
+
+            // Get correct effect      
+            if (!this._defines.isEqual(this._cachedDefines)) {
+                this._defines.cloneTo(this._cachedDefines);
+
+                scene.resetCachedMaterial();
+
+                // Fallbacks
+                var fallbacks = new EffectFallbacks();             
+                if (this._defines.FOG) {
+                    fallbacks.addFallback(1, "FOG");
+                }
+
+                for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
+                    if (!this._defines["LIGHT" + lightIndex]) {
+                        continue;
+                    }
+
+                    if (lightIndex > 0) {
+                        fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
+                    }
+
+                    if (this._defines["SHADOW" + lightIndex]) {
+                        fallbacks.addFallback(0, "SHADOW" + lightIndex);
+                    }
+
+                    if (this._defines["SHADOWPCF" + lightIndex]) {
+                        fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
+                    }
+
+                    if (this._defines["SHADOWVSM" + lightIndex]) {
+                        fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
+                    }
+                }
+             
+                if (this._defines.BONES4) {
+                    fallbacks.addFallback(0, "BONES4");
+                }
+
+                //Attributes
+                var attribs = [VertexBuffer.PositionKind];
+
+                if (this._defines.NORMAL) {
+                    attribs.push(VertexBuffer.NormalKind);
+                }
+
+                if (this._defines.VERTEXCOLOR) {
+                    attribs.push(VertexBuffer.ColorKind);
+                }
+
+                if (this._defines.BONES) {
+                    attribs.push(VertexBuffer.MatricesIndicesKind);
+                    attribs.push(VertexBuffer.MatricesWeightsKind);
+                }
+
+                if (this._defines.INSTANCES) {
+                    attribs.push("world0");
+                    attribs.push("world1");
+                    attribs.push("world2");
+                    attribs.push("world3");
+                }
+
+                // Legacy browser patch
+                var shaderName = "triplanar";
+                var join = this._defines.toString();
+                this._effect = scene.getEngine().createEffect(shaderName,
+                    attribs,
+                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
+                        "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
+                        "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
+                        "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
+                        "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
+                        "vFogInfos", "vFogColor", "pointSize",
+                        "mBones",
+                        "vClipPlane",
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
+                        "tileSize"
+                    ],
+                    ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
+                        "normalSamplerX", "normalSamplerY", "normalSamplerZ",
+                        "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
+                    ],
+                    join, fallbacks, this.onCompiled, this.onError);
+            }
+            if (!this._effect.isReady()) {
+                return false;
+            }
+
+            this._renderId = scene.getRenderId();
+            this._wasPreviouslyReady = true;
+
+            if (mesh) {
+                if (!mesh._materialDefines) {
+                    mesh._materialDefines = new TriPlanarMaterialDefines();
+                }
+
+                this._defines.cloneTo(mesh._materialDefines);
+            }
+
+            return true;
+        }
+
+        public bindOnlyWorldMatrix(world: Matrix): void {
+            this._effect.setMatrix("world", world);
+        }
+
+        public bind(world: Matrix, mesh?: Mesh): void {
+            var scene = this.getScene();
+
+            // Matrices        
+            this.bindOnlyWorldMatrix(world);
+            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+
+            // Bones
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+            }
+            
+            this._effect.setFloat("tileSize", this.tileSize);
+
+            if (scene.getCachedMaterial() !== this) {
+                // Textures        
+                if (this.diffuseTextureX) {
+                    this._effect.setTexture("diffuseSamplerX", this.diffuseTextureX);
+                }
+                if (this.diffuseTextureY) {
+                    this._effect.setTexture("diffuseSamplerY", this.diffuseTextureY);
+                }
+                if (this.diffuseTextureZ) {
+                    this._effect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
+                }
+                if (this.normalTextureX) {
+                    this._effect.setTexture("normalSamplerX", this.normalTextureX);
+                }
+                if (this.normalTextureY) {
+                    this._effect.setTexture("normalSamplerY", this.normalTextureY);
+                }
+                if (this.normalTextureZ) {
+                    this._effect.setTexture("normalSamplerZ", this.normalTextureZ);
+                }
+                // Clip plane
+                if (scene.clipPlane) {
+                    var clipPlane = scene.clipPlane;
+                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
+                }
+
+                // Point size
+                if (this.pointsCloud) {
+                    this._effect.setFloat("pointSize", this.pointSize);
+                }
+
+                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+            }
+
+            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            
+            if (this._defines.SPECULARTERM) {
+                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            }
+
+            if (scene.lightsEnabled && !this.disableLighting) {
+                var lightIndex = 0;
+                for (var index = 0; index < scene.lights.length; index++) {
+                    var light = scene.lights[index];
+
+                    if (!light.isEnabled()) {
+                        continue;
+                    }
+
+                    if (!light.canAffectMesh(mesh)) {
+                        continue;
+                    }
+
+                    if (light instanceof PointLight) {
+                        // Point Light
+                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
+                    } else if (light instanceof DirectionalLight) {
+                        // Directional Light
+                        light.transferToEffect(this._effect, "vLightData" + lightIndex);
+                    } else if (light instanceof SpotLight) {
+                        // Spot Light
+                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
+                    } else if (light instanceof HemisphericLight) {
+                        // Hemispheric Light
+                        light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
+                    }
+
+                    light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
+                    this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
+                    
+                    if (this._defines.SPECULARTERM) {
+                        light.specular.scaleToRef(light.intensity, this._scaledSpecular);
+                        this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
+                    }
+
+                    // Shadows
+                    if (scene.shadowsEnabled) {
+                        var shadowGenerator = light.getShadowGenerator();
+                        if (mesh.receiveShadows && shadowGenerator) {
+                            this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                            this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
+                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
+                        }
+                    }
+
+                    lightIndex++;
+
+                    if (lightIndex === maxSimultaneousLights)
+                        break;
+                }
+            }
+
+            // View
+            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+                this._effect.setMatrix("view", scene.getViewMatrix());
+            }
+
+            // Fog
+            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
+                this._effect.setColor3("vFogColor", scene.fogColor);
+            }
+
+            super.bind(world, mesh);
+        }
+
+        public getAnimatables(): IAnimatable[] {
+            var results = [];
+
+            if (this.mixTexture && this.mixTexture.animations && this.mixTexture.animations.length > 0) {
+                results.push(this.mixTexture);
+            }
+
+            return results;
+        }
+
+        public dispose(forceDisposeEffect?: boolean): void {
+            if (this.mixTexture) {
+                this.mixTexture.dispose();
+            }
+
+            super.dispose(forceDisposeEffect);
+        }
+
+        public clone(name: string): TriPlanarMaterial {
+            var newMaterial = new TriPlanarMaterial(name, this.getScene());
+
+            // Base material
+            this.copyTo(newMaterial);
+
+            // Simple material
+            if (this.mixTexture && this.mixTexture.clone) {
+                newMaterial.mixTexture = this.mixTexture.clone();
+            }
+
+            newMaterial.diffuseColor = this.diffuseColor.clone();
+            return newMaterial;
+        }
+		
+		public serialize(): any {
+		
+            var serializationObject = super.serialize();
+            serializationObject.customType      = "BABYLON.TerrainMaterial";
+            serializationObject.diffuseColor    = this.diffuseColor.asArray();
+			serializationObject.specularColor   = this.specularColor.asArray();
+            serializationObject.specularPower   = this.specularPower;
+            serializationObject.disableLighting = this.disableLighting;
+
+            if (this.diffuseTextureX) {
+                serializationObject.diffuseTextureX = this.diffuseTextureX.serialize();
+            }
+			
+			if (this.diffuseTextureY) {
+                serializationObject.diffuseTextureY = this.diffuseTextureY.serialize();
+            }
+			
+			if (this.diffuseTextureZ) {
+                serializationObject.diffuseTextureZ = this.diffuseTextureZ.serialize();
+            }
+
+            return serializationObject;
+        }
+
+        public static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial {
+            var material = new TriPlanarMaterial(source.name, scene);
+
+            material.diffuseColor   = Color3.FromArray(source.diffuseColor);
+			material.specularColor   = Color3.FromArray(source.specularColor);
+            material.specularPower          = source.specularPower;
+            material.disableLighting    = source.disableLighting;
+
+            material.alpha          = source.alpha;
+
+            material.id             = source.id;
+
+            Tags.AddTagsTo(material, source.tags);
+            material.backFaceCulling = source.backFaceCulling;
+            material.wireframe = source.wireframe;
+
+            if (source.diffuseTextureX) {
+                material.diffuseTextureX = <Texture>Texture.Parse(source.diffuseTextureX, scene, rootUrl);
+            }
+			
+			if (source.diffuseTextureY) {
+                material.diffuseTextureY = <Texture>Texture.Parse(source.diffuseTextureY, scene, rootUrl);
+            }
+
+			if (source.diffuseTextureZ) {
+                material.diffuseTextureZ = <Texture>Texture.Parse(source.diffuseTextureZ, scene, rootUrl);
+            }
+
+            return material;
+        }
+    }
+} 
+

+ 686 - 0
materialsLibrary/materials/triPlanar/triplanar.fragment.fx

@@ -0,0 +1,686 @@
+precision highp float;
+
+// Constants
+uniform vec3 vEyePosition;
+uniform vec4 vDiffuseColor;
+
+#ifdef SPECULARTERM
+uniform vec4 vSpecularColor;
+#endif
+
+// Input
+varying vec3 vPositionW;
+
+#ifdef VERTEXCOLOR
+varying vec4 vColor;
+#endif
+
+// Lights
+#ifdef LIGHT0
+uniform vec4 vLightData0;
+uniform vec4 vLightDiffuse0;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular0;
+#endif
+#ifdef SHADOW0
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
+varying vec4 vPositionFromLight0;
+uniform sampler2D shadowSampler0;
+#else
+uniform samplerCube shadowSampler0;
+#endif
+uniform vec3 shadowsInfo0;
+#endif
+#ifdef SPOTLIGHT0
+uniform vec4 vLightDirection0;
+#endif
+#ifdef HEMILIGHT0
+uniform vec3 vLightGround0;
+#endif
+#endif
+
+#ifdef LIGHT1
+uniform vec4 vLightData1;
+uniform vec4 vLightDiffuse1;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular1;
+#endif
+#ifdef SHADOW1
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
+varying vec4 vPositionFromLight1;
+uniform sampler2D shadowSampler1;
+#else
+uniform samplerCube shadowSampler1;
+#endif
+uniform vec3 shadowsInfo1;
+#endif
+#ifdef SPOTLIGHT1
+uniform vec4 vLightDirection1;
+#endif
+#ifdef HEMILIGHT1
+uniform vec3 vLightGround1;
+#endif
+#endif
+
+#ifdef LIGHT2
+uniform vec4 vLightData2;
+uniform vec4 vLightDiffuse2;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular2;
+#endif
+#ifdef SHADOW2
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
+varying vec4 vPositionFromLight2;
+uniform sampler2D shadowSampler2;
+#else
+uniform samplerCube shadowSampler2;
+#endif
+uniform vec3 shadowsInfo2;
+#endif
+#ifdef SPOTLIGHT2
+uniform vec4 vLightDirection2;
+#endif
+#ifdef HEMILIGHT2
+uniform vec3 vLightGround2;
+#endif
+#endif
+
+#ifdef LIGHT3
+uniform vec4 vLightData3;
+uniform vec4 vLightDiffuse3;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular3;
+#endif
+#ifdef SHADOW3
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
+varying vec4 vPositionFromLight3;
+uniform sampler2D shadowSampler3;
+#else
+uniform samplerCube shadowSampler3;
+#endif
+uniform vec3 shadowsInfo3;
+#endif
+#ifdef SPOTLIGHT3
+uniform vec4 vLightDirection3;
+#endif
+#ifdef HEMILIGHT3
+uniform vec3 vLightGround3;
+#endif
+#endif
+
+// Samplers
+#ifdef DIFFUSEX
+varying vec2 vTextureUVX;
+uniform sampler2D diffuseSamplerX;
+#ifdef BUMPX
+uniform sampler2D normalSamplerX;
+#endif
+#endif
+
+#ifdef DIFFUSEY
+varying vec2 vTextureUVY;
+uniform sampler2D diffuseSamplerY;
+#ifdef BUMPY
+uniform sampler2D normalSamplerY;
+#endif
+#endif
+
+#ifdef DIFFUSEZ
+varying vec2 vTextureUVZ;
+uniform sampler2D diffuseSamplerZ;
+#ifdef BUMPZ
+uniform sampler2D normalSamplerZ;
+#endif
+#endif
+
+#ifdef NORMAL
+varying mat3 tangentSpace;
+#endif
+
+// Shadows
+#ifdef SHADOWS
+
+float unpack(vec4 color)
+{
+	const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
+	return dot(color, bit_shift);
+}
+
+#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
+{
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
+	depth = clamp(depth, 0., 1.0);
+
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = - directionToLight.y;
+
+	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+
+	if (depth > shadow)
+	{
+		return darkness;
+	}
+	return 1.0;
+}
+
+float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
+{
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
+
+	depth = clamp(depth, 0., 1.0);
+	float diskScale = 2.0 / mapSize;
+
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = -directionToLight.y;
+
+	float visibility = 1.;
+
+	vec3 poissonDisk[4];
+	poissonDisk[0] = vec3(-1.0, 1.0, -1.0);
+	poissonDisk[1] = vec3(1.0, -1.0, -1.0);
+	poissonDisk[2] = vec3(-1.0, -1.0, -1.0);
+	poissonDisk[3] = vec3(1.0, -1.0, 1.0);
+
+	// Poisson Sampling
+	float biasedDepth = depth - bias;
+
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
+
+	return  min(1.0, visibility + darkness);
+}
+#endif
+
+#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
+float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
+{
+	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
+	depth = 0.5 * depth + vec3(0.5);
+	vec2 uv = depth.xy;
+
+	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
+	{
+		return 1.0;
+	}
+
+	float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+
+	if (depth.z > shadow)
+	{
+		return darkness;
+	}
+	return 1.;
+}
+
+float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
+{
+	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
+	depth = 0.5 * depth + vec3(0.5);
+	vec2 uv = depth.xy;
+
+	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
+	{
+		return 1.0;
+	}
+
+	float visibility = 1.;
+
+	vec2 poissonDisk[4];
+	poissonDisk[0] = vec2(-0.94201624, -0.39906216);
+	poissonDisk[1] = vec2(0.94558609, -0.76890725);
+	poissonDisk[2] = vec2(-0.094184101, -0.92938870);
+	poissonDisk[3] = vec2(0.34495938, 0.29387760);
+
+	// Poisson Sampling
+	float biasedDepth = depth.z - bias;
+
+	if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] / mapSize)) < biasedDepth) visibility -= 0.25;
+	if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] / mapSize)) < biasedDepth) visibility -= 0.25;
+	if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] / mapSize)) < biasedDepth) visibility -= 0.25;
+	if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] / mapSize)) < biasedDepth) visibility -= 0.25;
+
+	return  min(1.0, visibility + darkness);
+}
+
+// Thanks to http://devmaster.net/
+float unpackHalf(vec2 color)
+{
+	return color.x + (color.y / 255.0);
+}
+
+float linstep(float low, float high, float v) {
+	return clamp((v - low) / (high - low), 0.0, 1.0);
+}
+
+float ChebychevInequality(vec2 moments, float compare, float bias)
+{
+	float p = smoothstep(compare - bias, compare, moments.x);
+	float variance = max(moments.y - moments.x * moments.x, 0.02);
+	float d = compare - moments.x;
+	float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
+
+	return clamp(max(p, p_max), 0.0, 1.0);
+}
+
+float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
+{
+	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
+	depth = 0.5 * depth + vec3(0.5);
+	vec2 uv = depth.xy;
+
+	if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
+	{
+		return 1.0;
+	}
+
+	vec4 texel = texture2D(shadowSampler, uv);
+
+	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
+}
+#endif
+#endif
+
+
+#ifdef CLIPPLANE
+varying float fClipDistance;
+#endif
+
+// Fog
+#ifdef FOG
+
+#define FOGMODE_NONE    0.
+#define FOGMODE_EXP     1.
+#define FOGMODE_EXP2    2.
+#define FOGMODE_LINEAR  3.
+#define E 2.71828
+
+uniform vec4 vFogInfos;
+uniform vec3 vFogColor;
+varying float fFogDistance;
+
+float CalcFogFactor()
+{
+	float fogCoeff = 1.0;
+	float fogStart = vFogInfos.y;
+	float fogEnd = vFogInfos.z;
+	float fogDensity = vFogInfos.w;
+
+	if (FOGMODE_LINEAR == vFogInfos.x)
+	{
+		fogCoeff = (fogEnd - fFogDistance) / (fogEnd - fogStart);
+	}
+	else if (FOGMODE_EXP == vFogInfos.x)
+	{
+		fogCoeff = 1.0 / pow(E, fFogDistance * fogDensity);
+	}
+	else if (FOGMODE_EXP2 == vFogInfos.x)
+	{
+		fogCoeff = 1.0 / pow(E, fFogDistance * fFogDistance * fogDensity * fogDensity);
+	}
+
+	return clamp(fogCoeff, 0.0, 1.0);
+}
+#endif
+
+// Light Computing
+struct lightingInfo
+{
+	vec3 diffuse;
+#ifdef SPECULARTERM
+	vec3 specular;
+#endif
+};
+
+lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
+	lightingInfo result;
+
+	vec3 lightVectorW;
+	float attenuation = 1.0;
+	if (lightData.w == 0.)
+	{
+		vec3 direction = lightData.xyz - vPositionW;
+
+		attenuation = max(0., 1.0 - length(direction) / range);
+		lightVectorW = normalize(direction);
+	}
+	else
+	{
+		lightVectorW = normalize(-lightData.xyz);
+	}
+
+	// diffuse
+	float ndl = max(0., dot(vNormal, lightVectorW));
+	result.diffuse = ndl * diffuseColor * attenuation;
+
+#ifdef SPECULARTERM
+	// Specular
+	vec3 angleW = normalize(viewDirectionW + lightVectorW);
+	float specComp = max(0., dot(vNormal, angleW));
+	specComp = pow(specComp, max(1., glossiness));
+
+	result.specular = specComp * specularColor * attenuation;
+#endif
+	return result;
+}
+
+lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float range, float glossiness) {
+	lightingInfo result;
+
+	vec3 direction = lightData.xyz - vPositionW;
+	vec3 lightVectorW = normalize(direction);
+	float attenuation = max(0., 1.0 - length(direction) / range);
+
+	// diffuse
+	float cosAngle = max(0., dot(-lightDirection.xyz, lightVectorW));
+	float spotAtten = 0.0;
+
+	if (cosAngle >= lightDirection.w)
+	{
+		cosAngle = max(0., pow(cosAngle, lightData.w));
+		spotAtten = clamp((cosAngle - lightDirection.w) / (1. - cosAngle), 0.0, 1.0);
+
+		// Diffuse
+		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
+		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
+
+#ifdef SPECULARTERM
+		// Specular
+		vec3 angleW = normalize(viewDirectionW - lightDirection.xyz);
+		float specComp = max(0., dot(vNormal, angleW));
+		specComp = pow(specComp, max(1., glossiness));
+
+		result.specular = specComp * specularColor * spotAtten * attenuation;
+#endif
+
+		return result;
+	}
+
+	result.diffuse = vec3(0.);
+#ifdef SPECULARTERM
+	result.specular = vec3(0.);
+#endif
+
+	return result;
+}
+
+lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float glossiness) {
+	lightingInfo result;
+
+	// Diffuse
+	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
+	result.diffuse = mix(groundColor, diffuseColor, ndl);
+
+#ifdef SPECULARTERM
+	// Specular
+	vec3 angleW = normalize(viewDirectionW + lightData.xyz);
+	float specComp = max(0., dot(vNormal, angleW));
+	specComp = pow(specComp, max(1., glossiness));
+
+	result.specular = specComp * specularColor;
+#endif
+
+	return result;
+}
+
+void main(void) {
+	// Clip plane
+#ifdef CLIPPLANE
+	if (fClipDistance > 0.0)
+		discard;
+#endif
+
+	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
+
+	// Base color
+	vec4 baseColor = vec4(0., 0., 0., 1.);
+	vec3 diffuseColor = vDiffuseColor.rgb;
+	
+#ifdef SPECULARTERM
+	float glossiness = vSpecularColor.a;
+	vec3 specularColor = vSpecularColor.rgb;
+#else
+	float glossiness = 0.;
+#endif
+
+	// Alpha
+	float alpha = vDiffuseColor.a;
+	
+	// Bump
+#ifdef NORMAL
+	vec3 normalW = tangentSpace[2];
+#else
+	vec3 normalW = vec3(1.0, 1.0, 1.0);
+#endif
+
+	vec4 baseNormal = vec4(0.0, 0.0, 0.0, 1.0);
+	normalW *= normalW;
+
+#ifdef DIFFUSEX
+	baseColor += texture2D(diffuseSamplerX, vTextureUVX) * normalW.x;
+#ifdef BUMPX
+	baseNormal += texture2D(normalSamplerX, vTextureUVX) * normalW.x;
+#endif
+#endif
+
+#ifdef DIFFUSEY
+	baseColor += texture2D(diffuseSamplerY, vTextureUVY) * normalW.y;
+#ifdef BUMPY
+	baseNormal += texture2D(normalSamplerY, vTextureUVY) * normalW.y;
+#endif
+#endif
+
+#ifdef DIFFUSEZ
+	baseColor += texture2D(diffuseSamplerZ, vTextureUVZ) * normalW.z;
+#ifdef BUMPZ
+	baseNormal += texture2D(normalSamplerZ, vTextureUVZ) * normalW.z;
+#endif
+#endif
+
+#ifdef NORMAL
+	normalW = normalize((2.0 * baseNormal.xyz - 1.0) * tangentSpace);
+#endif
+
+#ifdef ALPHATEST
+	if (baseColor.a < 0.4)
+		discard;
+#endif
+
+#ifdef VERTEXCOLOR
+	baseColor.rgb *= vColor.rgb;
+#endif
+
+	// Lighting
+	vec3 diffuseBase = vec3(0., 0., 0.);
+#ifdef SPECULARTERM
+	vec3 specularBase = vec3(0., 0., 0.);
+#endif
+	float shadow = 1.;
+
+#ifdef LIGHT0
+#ifndef SPECULARTERM
+	vec3 vLightSpecular0 = vec3(0.0);
+#endif
+#ifdef SPOTLIGHT0
+	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
+#endif
+#ifdef HEMILIGHT0
+	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightGround0, glossiness);
+#endif
+#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
+	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness);
+#endif
+#ifdef SHADOW0
+#ifdef SHADOWVSM0
+	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
+#else
+#ifdef SHADOWPCF0
+#if defined(POINTLIGHT0)
+	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
+#else
+	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
+#endif
+#else
+#if defined(POINTLIGHT0)
+	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
+#else
+	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
+#endif
+#endif
+#endif
+#else
+	shadow = 1.;
+#endif
+	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
+#endif
+
+#ifdef LIGHT1
+#ifndef SPECULARTERM
+	vec3 vLightSpecular1 = vec3(0.0);
+#endif
+#ifdef SPOTLIGHT1
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
+#endif
+#ifdef HEMILIGHT1
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightGround1, glossiness);
+#endif
+#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
+	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness);
+#endif
+#ifdef SHADOW1
+#ifdef SHADOWVSM1
+	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
+#else
+#ifdef SHADOWPCF1
+#if defined(POINTLIGHT1)
+	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
+#else
+	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
+#endif
+#else
+#if defined(POINTLIGHT1)
+	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
+#else
+	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
+#endif
+#endif
+#endif
+#else
+	shadow = 1.;
+#endif
+	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
+#endif
+
+#ifdef LIGHT2
+#ifndef SPECULARTERM
+	vec3 vLightSpecular2 = vec3(0.0);
+#endif
+#ifdef SPOTLIGHT2
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
+#endif
+#ifdef HEMILIGHT2
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightGround2, glossiness);
+#endif
+#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
+	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness);
+#endif
+#ifdef SHADOW2
+#ifdef SHADOWVSM2
+	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
+#else
+#ifdef SHADOWPCF2
+#if defined(POINTLIGHT2)
+	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
+#else
+	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
+#endif
+#else
+#if defined(POINTLIGHT2)
+	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
+#else
+	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
+#endif
+#endif	
+#endif	
+#else
+	shadow = 1.;
+#endif
+	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
+#endif
+
+#ifdef LIGHT3
+#ifndef SPECULARTERM
+	vec3 vLightSpecular3 = vec3(0.0);
+#endif
+#ifdef SPOTLIGHT3
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
+#endif
+#ifdef HEMILIGHT3
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightGround3, glossiness);
+#endif
+#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
+	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness);
+#endif
+#ifdef SHADOW3
+#ifdef SHADOWVSM3
+	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+#else
+#ifdef SHADOWPCF3
+#if defined(POINTLIGHT3)
+	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
+#else
+	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
+#endif
+#else
+#if defined(POINTLIGHT3)
+	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
+#else
+	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
+#endif
+#endif	
+#endif	
+#else
+	shadow = 1.;
+#endif
+	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
+#endif
+
+#ifdef VERTEXALPHA
+	alpha *= vColor.a;
+#endif
+
+#ifdef SPECULARTERM
+	vec3 finalSpecular = specularBase * specularColor;
+#else
+	vec3 finalSpecular = vec3(0.0);
+#endif
+
+	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor, 0.0, 1.0) * baseColor.rgb;
+
+	// Composition
+	vec4 color = vec4(finalDiffuse + finalSpecular, alpha);
+
+#ifdef FOG
+	float fog = CalcFogFactor();
+	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;
+#endif
+
+	gl_FragColor = color;
+}

+ 190 - 0
materialsLibrary/materials/triPlanar/triplanar.vertex.fx

@@ -0,0 +1,190 @@
+precision highp float;
+
+// Attributes
+attribute vec3 position;
+#ifdef NORMAL
+attribute vec3 normal;
+#endif
+#ifdef VERTEXCOLOR
+attribute vec4 color;
+#endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#endif
+
+// Uniforms
+
+#ifdef INSTANCES
+attribute vec4 world0;
+attribute vec4 world1;
+attribute vec4 world2;
+attribute vec4 world3;
+#else
+uniform mat4 world;
+#endif
+
+uniform mat4 view;
+uniform mat4 viewProjection;
+
+#ifdef DIFFUSEX
+varying vec2 vTextureUVX;
+#endif
+
+#ifdef DIFFUSEY
+varying vec2 vTextureUVY;
+#endif
+
+#ifdef DIFFUSEZ
+varying vec2 vTextureUVZ;
+#endif
+
+uniform float tileSize;
+
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
+#endif
+
+#ifdef POINTSIZE
+uniform float pointSize;
+#endif
+
+// Output
+varying vec3 vPositionW;
+#ifdef NORMAL
+varying mat3 tangentSpace;
+#endif
+
+#ifdef VERTEXCOLOR
+varying vec4 vColor;
+#endif
+
+#ifdef CLIPPLANE
+uniform vec4 vClipPlane;
+varying float fClipDistance;
+#endif
+
+#ifdef FOG
+varying float fFogDistance;
+#endif
+
+#ifdef SHADOWS
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
+uniform mat4 lightMatrix0;
+varying vec4 vPositionFromLight0;
+#endif
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
+uniform mat4 lightMatrix1;
+varying vec4 vPositionFromLight1;
+#endif
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
+uniform mat4 lightMatrix2;
+varying vec4 vPositionFromLight2;
+#endif
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
+uniform mat4 lightMatrix3;
+varying vec4 vPositionFromLight3;
+#endif
+#endif
+
+void main(void) {
+	mat4 finalWorld;
+
+#ifdef INSTANCES
+	finalWorld = mat4(world0, world1, world2, world3);
+#else
+	finalWorld = world;
+#endif
+
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
+
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = finalWorld * (m0 + m1 + m2);
+#endif 
+
+#endif
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+
+	vec4 worldPos = finalWorld * vec4(position, 1.0);
+	vPositionW = vec3(worldPos);
+
+#ifdef DIFFUSEX
+	vTextureUVX = worldPos.zy / tileSize;
+#endif
+
+#ifdef DIFFUSEY
+	vTextureUVY = worldPos.xz / tileSize;
+#endif
+
+#ifdef DIFFUSEZ
+	vTextureUVZ = worldPos.xy / tileSize;
+#endif
+
+#ifdef NORMAL
+	// Compute tangent space (used for normal mapping + tri planar color mapping)
+	vec3 xtan = vec3(0,0,1);//tangent space for the X aligned plane
+   	vec3 xbin = vec3(0,1,0);
+   
+   	vec3 ytan = vec3(1,0,0);//tangent space for the Y aligned plane
+   	vec3 ybin = vec3(0,0,1);
+   
+   	vec3 ztan = vec3(1,0,0);//tangent space for the Z aligned plane
+   	vec3 zbin = vec3(0,1,0);
+	   
+	vec3 normalizedNormal = normalize(normal);
+   	normalizedNormal *= normalizedNormal;
+
+	vec3 worldBinormal = normalize(xbin * normalizedNormal.x + ybin * normalizedNormal.y + zbin * normalizedNormal.z);
+   	vec3 worldTangent = normalize(xtan * normalizedNormal.x + ytan * normalizedNormal.y + ztan * normalizedNormal.z);
+	   
+	worldTangent = (world * vec4(worldTangent, 1.0)).xyz;
+    worldBinormal = (world * vec4(worldBinormal, 1.0)).xyz;
+	vec3 worldNormal = normalize(cross(worldTangent, worldBinormal));
+
+	tangentSpace[0] = worldTangent;
+    tangentSpace[1] = worldBinormal;
+    tangentSpace[2] = worldNormal;
+#endif
+
+	// Clip plane
+#ifdef CLIPPLANE
+	fClipDistance = dot(worldPos, vClipPlane);
+#endif
+
+	// Fog
+#ifdef FOG
+	fFogDistance = (view * worldPos).z;
+#endif
+
+	// Shadows
+#ifdef SHADOWS
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
+	vPositionFromLight0 = lightMatrix0 * worldPos;
+#endif
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
+	vPositionFromLight1 = lightMatrix1 * worldPos;
+#endif
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
+	vPositionFromLight2 = lightMatrix2 * worldPos;
+#endif
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
+	vPositionFromLight3 = lightMatrix3 * worldPos;
+#endif
+#endif
+
+	// Vertex color
+#ifdef VERTEXCOLOR
+	vColor = color;
+#endif
+
+	// Point size
+#ifdef POINTSIZE
+	gl_PointSize = pointSize;
+#endif
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 695 - 693
materialsLibrary/materials/water/water.fragment.fx


+ 71 - 61
materialsLibrary/test/add/addpbr.js

@@ -1,29 +1,30 @@
 window.preparePBR = function() {
 window.preparePBR = function() {
 	var pbr = new BABYLON.PBRMaterial("pbr", scene);
 	var pbr = new BABYLON.PBRMaterial("pbr", scene);
-	pbr.diffuseTexture = new BABYLON.Texture("textures/amiga.jpg", scene);
-	pbr.diffuseTexture.uScale = 5;
-	pbr.diffuseTexture.vScale = 5;
+	pbr.albedoTexture = new BABYLON.Texture("textures/amiga.jpg", scene);
+	pbr.albedoTexture.uScale = 5;
+	pbr.albedoTexture.vScale = 5;
 	pbr.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/TropicalSunnyDay", scene);	
 	pbr.reflectionTexture = new BABYLON.CubeTexture("textures/skybox/TropicalSunnyDay", scene);	
-	pbr.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3);
-	pbr.glossiness = 0.9;
+	pbr.reflectivityColor = new BABYLON.Color3(0.3, 0.3, 0.3);
+	pbr.microSurface = 0.9;
 	
 	
 	registerButtonUI("pbr", "Default", function() {
 	registerButtonUI("pbr", "Default", function() {
 		setRangeValues({
 		setRangeValues({
 		  "directIntensity": 1,
 		  "directIntensity": 1,
 		  "emissiveIntensity": 1,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 1,
 		  "environmentIntensity": 1,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "cameraExposure": 1,
 		  "cameraExposure": 1,
 		  "cameraContrast": 1,
 		  "cameraContrast": 1,
-		  "glossiness": 0.9,
-		  "specularColorR": 0.3,
-		  "specularColorG": 0.3,
-		  "specularColorB": 0.3,
-		  "diffuseColorR": 1,
-		  "diffuseColorG": 1,
-		  "diffuseColorB": 1,
-		  "diffuseColorLevel": 0
+		  "microSurface": 0.9,
+		  "reflectivityColorR": 0.3,
+		  "reflectivityColorG": 0.3,
+		  "reflectivityColorB": 0.3,
+		  "albedoColorR": 1,
+		  "albedoColorG": 1,
+		  "albedoColorB": 1,
+		  "albedoColorLevel": 0
 		});
 		});
 	});
 	});
 	registerButtonUI("pbr", "Rough Gold", function() {
 	registerButtonUI("pbr", "Rough Gold", function() {
@@ -31,18 +32,19 @@ window.preparePBR = function() {
 		  "directIntensity": 1.3439461727881254,
 		  "directIntensity": 1.3439461727881254,
 		  "emissiveIntensity": 1,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 0.3685013699580344,
 		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "cameraExposure": 0.7153261887420668,
 		  "cameraExposure": 0.7153261887420668,
 		  "cameraContrast": 1.6474178892241538,
 		  "cameraContrast": 1.6474178892241538,
-		  "glossiness": 0.42269274789303946,
-		  "specularColorR": 1,
-		  "specularColorG": 0.8453854957860789,
-		  "specularColorB": 0.5093989525890475,
-		  "diffuseColorR": 0,
-		  "diffuseColorG": 0,
-		  "diffuseColorB": 0,
-		  "diffuseColorLevel": 1
+		  "microSurface": 0.42269274789303946,
+		  "reflectivityColorR": 1,
+		  "reflectivityColorG": 0.8453854957860789,
+		  "reflectivityColorB": 0.5093989525890475,
+		  "albedoColorR": 0,
+		  "albedoColorG": 0,
+		  "albedoColorB": 0,
+		  "albedoColorLevel": 1
 		});
 		});
 	});
 	});
 	registerButtonUI("pbr", "Plastic", function() {
 	registerButtonUI("pbr", "Plastic", function() {
@@ -50,18 +52,19 @@ window.preparePBR = function() {
 		  "directIntensity": 0.9971213540040931,
 		  "directIntensity": 0.9971213540040931,
 		  "emissiveIntensity": 1,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 0.3685013699580344,
 		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 0.975444802830091,
 		  "ShadowIntensity": 0.975444802830091,
 		  "ShadeIntensity": 0.8020323934380749,
 		  "ShadeIntensity": 0.8020323934380749,
 		  "cameraExposure": 0.7586792910900708,
 		  "cameraExposure": 0.7586792910900708,
 		  "cameraContrast": 1.5823882357021477,
 		  "cameraContrast": 1.5823882357021477,
-		  "glossiness": 0.8562237713730799,
-		  "specularColorR": 0.05,
-		  "specularColorG": 0.05,
-		  "specularColorB": 0.05,
-		  "diffuseColorR": 0.20592723615301922,
-		  "diffuseColorG": 0.942929976069088,
-		  "diffuseColorB": 1,
-		  "diffuseColorLevel": 1
+		  "microSurface": 0.8562237713730799,
+		  "reflectivityColorR": 0.05,
+		  "reflectivityColorG": 0.05,
+		  "reflectivityColorB": 0.05,
+		  "albedoColorR": 0.20592723615301922,
+		  "albedoColorG": 0.942929976069088,
+		  "albedoColorB": 1,
+		  "albedoColorLevel": 1
 		});
 		});
 	});
 	});
 	registerButtonUI("pbr", "Shiny Copper", function() {
 	registerButtonUI("pbr", "Shiny Copper", function() {
@@ -69,18 +72,19 @@ window.preparePBR = function() {
 		  "directIntensity": 1.2355634169181153,
 		  "directIntensity": 1.2355634169181153,
 		  "emissiveIntensity": 0.910415149308085,
 		  "emissiveIntensity": 0.910415149308085,
 		  "environmentIntensity": 0.21676551174002023,
 		  "environmentIntensity": 0.21676551174002023,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1.018797905178095,
 		  "ShadowIntensity": 1.018797905178095,
 		  "ShadeIntensity": 0.975444802830091,
 		  "ShadeIntensity": 0.975444802830091,
 		  "cameraExposure": 1.0621510075260991,
 		  "cameraExposure": 1.0621510075260991,
 		  "cameraContrast": 1.0404744563520971,
 		  "cameraContrast": 1.0404744563520971,
-		  "glossiness": 0.888738598134083,
-		  "specularColorR": 0.98,
-		  "specularColorG": 0.78,
-		  "specularColorB": 0.706,
-		  "diffuseColorR": 0.1,
-		  "diffuseColorG": 0.1,
-		  "diffuseColorB": 0.1,
-		  "diffuseColorLevel": 1
+		  "microSurface": 0.888738598134083,
+		  "reflectivityColorR": 0.98,
+		  "reflectivityColorG": 0.78,
+		  "reflectivityColorB": 0.706,
+		  "albedoColorR": 0.1,
+		  "albedoColorG": 0.1,
+		  "albedoColorB": 0.1,
+		  "albedoColorLevel": 1
 		});
 		});
 	});
 	});
 
 
@@ -101,6 +105,12 @@ window.preparePBR = function() {
 	}, function() {
 	}, function() {
 		return pbr.environmentIntensity;
 		return pbr.environmentIntensity;
 	});
 	});
+
+	registerRangeUI("pbr", "specularIntensity", 0, 2, function(value) {
+		pbr.specularIntensity = value;
+	}, function() {
+		return pbr.specularIntensity;
+	});
 	
 	
 	registerRangeUI("pbr", "ShadowIntensity", 0, 2, function(value) {
 	registerRangeUI("pbr", "ShadowIntensity", 0, 2, function(value) {
 		pbr.overloadedShadowIntensity = value;
 		pbr.overloadedShadowIntensity = value;
@@ -126,52 +136,52 @@ window.preparePBR = function() {
 		return pbr.cameraContrast;
 		return pbr.cameraContrast;
 	});
 	});
 	
 	
-	registerRangeUI("pbr", "glossiness", 0, 1, function(value) {
-		pbr.glossiness = value;
+	registerRangeUI("pbr", "microSurface", 0, 1, function(value) {
+		pbr.microSurface = value;
 	}, function() {
 	}, function() {
-		return pbr.glossiness;
+		return pbr.microSurface;
 	});
 	});
 
 
-	registerRangeUI("pbr", "specularColorR", 0, 1, function(value) {
-		pbr.specularColor.r = value;
+	registerRangeUI("pbr", "reflectivityColorR", 0, 1, function(value) {
+		pbr.reflectivityColor.r = value;
 	}, function() {
 	}, function() {
-		return pbr.specularColor.r;
+		return pbr.reflectivityColor.r;
 	});
 	});
 
 
-	registerRangeUI("pbr", "specularColorG", 0, 1, function(value) {
-		pbr.specularColor.g = value;
+	registerRangeUI("pbr", "reflectivityColorG", 0, 1, function(value) {
+		pbr.reflectivityColor.g = value;
 	}, function() {
 	}, function() {
-		return pbr.specularColor.g;
+		return pbr.reflectivityColor.g;
 	});
 	});
 
 
-	registerRangeUI("pbr", "specularColorB", 0, 1, function(value) {
-		pbr.specularColor.b = value;
+	registerRangeUI("pbr", "reflectivityColorB", 0, 1, function(value) {
+		pbr.reflectivityColor.b = value;
 	}, function() {
 	}, function() {
-		return pbr.specularColor.b;
+		return pbr.reflectivityColor.b;
 	});
 	});
 
 
-	registerRangeUI("pbr", "diffuseColorR", 0, 1, function(value) {
-		pbr.overloadedDiffuse.r = value;
+	registerRangeUI("pbr", "albedoColorR", 0, 1, function(value) {
+		pbr.overloadedAlbedo.r = value;
 	}, function() {
 	}, function() {
-		return pbr.overloadedDiffuse.r;
+		return pbr.overloadedAlbedo.r;
 	});
 	});
 
 
-	registerRangeUI("pbr", "diffuseColorG", 0, 1, function(value) {
-		pbr.overloadedDiffuse.g = value;
+	registerRangeUI("pbr", "albedoColorG", 0, 1, function(value) {
+		pbr.overloadedAlbedo.g = value;
 	}, function() {
 	}, function() {
-		return pbr.overloadedDiffuse.g;
+		return pbr.overloadedAlbedo.g;
 	});
 	});
 
 
-	registerRangeUI("pbr", "diffuseColorB", 0, 1, function(value) {
-		pbr.overloadedDiffuse.b = value;
+	registerRangeUI("pbr", "albedoColorB", 0, 1, function(value) {
+		pbr.overloadedAlbedo.b = value;
 	}, function() {
 	}, function() {
-		return pbr.overloadedDiffuse.b;
+		return pbr.overloadedAlbedo.b;
 	});
 	});
 
 
-	registerRangeUI("pbr", "diffuseColorLevel", 0, 1, function(value) {
-		pbr.overloadedDiffuseIntensity = value;
+	registerRangeUI("pbr", "albedoColorLevel", 0, 1, function(value) {
+		pbr.overloadedAlbedoIntensity = value;
 	}, function() {
 	}, function() {
-		return pbr.overloadedDiffuseIntensity;
+		return pbr.overloadedAlbedoIntensity;
 	});
 	});
 
 
 	return pbr;
 	return pbr;

+ 19 - 0
materialsLibrary/test/add/addtriplanar.js

@@ -0,0 +1,19 @@
+window.prepareTriPlanar = function() {
+    var triPlanar = new BABYLON.TriPlanarMaterial("triplanar", scene);
+    triPlanar.diffuseTextureX = new BABYLON.Texture("textures/rock.png", scene);
+    triPlanar.diffuseTextureY = new BABYLON.Texture("textures/grass.png", scene);
+    triPlanar.diffuseTextureZ = triPlanar.diffuseTextureX;
+    triPlanar.normalTextureX = new BABYLON.Texture("textures/rockn.png", scene);
+    triPlanar.normalTextureY = new BABYLON.Texture("textures/grassn.png", scene);
+    triPlanar.normalTextureZ = triPlanar.normalTextureX;
+    triPlanar.specularPower = 64;
+    triPlanar.tileSize = 1.5;
+    
+    registerRangeUI("triPlanar", "tileSize", 0, 20, function(value) {
+		triPlanar.tileSize = value;
+	}, function() {
+		return triPlanar.tileSize;
+	});
+    
+    return triPlanar;
+};

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 252 - 146
materialsLibrary/test/babylon.max.js


+ 14 - 5
materialsLibrary/test/index.html

@@ -12,6 +12,7 @@
 	<script src="../dist/babylon.terrainMaterial.js"></script>
 	<script src="../dist/babylon.terrainMaterial.js"></script>
 	<script src="../dist/babylon.pbrMaterial.js"></script>
 	<script src="../dist/babylon.pbrMaterial.js"></script>
 	<script src="../dist/babylon.furMaterial.js"></script>
 	<script src="../dist/babylon.furMaterial.js"></script>
+	<script src="../dist/babylon.triPlanarMaterial.js"></script>
 
 
 	<style>
 	<style>
 		html, body {
 		html, body {
@@ -53,6 +54,7 @@
 	<script src="add/addfur.js"></script>
 	<script src="add/addfur.js"></script>
 	<script src="add/addterrain.js"></script>
 	<script src="add/addterrain.js"></script>
 	<script src="add/addfire.js"></script>
 	<script src="add/addfire.js"></script>
+	<script src="add/addtriplanar.js"></script>
 	
 	
 	<script>
 	<script>
 		if (BABYLON.Engine.isSupported()) {
 		if (BABYLON.Engine.isSupported()) {
@@ -64,6 +66,7 @@
 
 
 			var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 6, 50, BABYLON.Vector3.Zero(), scene);
 			var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 6, 50, BABYLON.Vector3.Zero(), scene);
 			camera.attachControl(canvas, true);
 			camera.attachControl(canvas, true);
+			camera.minZ = 0.1;
 
 
 			// Lights
 			// Lights
 			var hemisphericLight = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
 			var hemisphericLight = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
@@ -75,7 +78,7 @@
 			spotLight.setEnabled(false);
 			spotLight.setEnabled(false);
 
 
 			// Create meshes
 			// Create meshes
-			var sphere = BABYLON.Mesh.CreateSphere("sphere", 32, 30.0, scene);
+			var sphere = BABYLON.Mesh.CreateSphere("sphere", 48, 30.0, scene);
 			
 			
 			var plane = BABYLON.MeshBuilder.CreateBox("plane", { width: 30, height: 1, depth:30 }, scene);
 			var plane = BABYLON.MeshBuilder.CreateBox("plane", { width: 30, height: 1, depth:30 }, scene);
 			plane.setEnabled(false);
 			plane.setEnabled(false);
@@ -135,7 +138,8 @@
 				
 				
 				var shadowGenerator3 = new BABYLON.ShadowGenerator(1024, pointLight);
 				var shadowGenerator3 = new BABYLON.ShadowGenerator(1024, pointLight);
 				shadowGenerator3.getShadowMap().renderList.push(shadowCaster3);
 				shadowGenerator3.getShadowMap().renderList.push(shadowCaster3);
-				shadowGenerator3.usePoissonSampling = true;
+				shadowGenerator3.usePoissonSampling = false;
+				shadowGenerator3.bias = 0;
 
 
 				// Register a render loop to repeatedly render the scene
 				// Register a render loop to repeatedly render the scene
 				engine.runRenderLoop(function () {
 				engine.runRenderLoop(function () {
@@ -190,13 +194,15 @@
 				var terrain = prepareTerrain();
 				var terrain = prepareTerrain();
 				
 				
 				var pbr = preparePBR();
 				var pbr = preparePBR();
-								
+				
+				var triPlanar = prepareTriPlanar();
+				
 				// Default to std
 				// Default to std
 				var currentMaterial = std;
 				var currentMaterial = std;
 				sphere.material = std;				
 				sphere.material = std;				
 				sphere.receiveShadows = true;
 				sphere.receiveShadows = true;
 
 
-				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur']).onFinishChange(function () {
+				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur', 'triPlanar']).onFinishChange(function () {
 					water.enableRenderTargets(false);
 					water.enableRenderTargets(false);
 					
 					
 					switch (options.material) {
 					switch (options.material) {
@@ -225,7 +231,10 @@
 							break;
 							break;
 						case "fur":
 						case "fur":
 							currentMaterial = fur;
 							currentMaterial = fur;
-							break;														
+							break;
+						case "triPlanar":
+							currentMaterial = triPlanar;
+							break;
 						default:
 						default:
 							currentMaterial = std;
 							currentMaterial = std;
 							break;
 							break;

+ 1 - 1
readme.md

@@ -35,7 +35,7 @@ You can help by testing or contributing to the next version.
  - FBX command line [exporter](https://github.com/BabylonJS/Babylon.js/tree/master/Exporters/FBX) can be used to generate a .babylon file from .FBX file (animations are supported)
  - FBX command line [exporter](https://github.com/BabylonJS/Babylon.js/tree/master/Exporters/FBX) can be used to generate a .babylon file from .FBX file (animations are supported)
 
 
 ## Features
 ## Features
-To get a complete list of supported features, please visit our [website](babylonjs.com/#specifications).
+To get a complete list of supported features, please visit our [website](http://www.babylonjs.com/#specifications).
 
 
 ## Apache License 2.0 (Apache)
 ## Apache License 2.0 (Apache)
 
 

+ 4 - 0
src/Animations/babylon.animation.js

@@ -424,6 +424,7 @@ var BABYLON;
                     case Animation.ANIMATIONTYPE_QUATERNION:
                     case Animation.ANIMATIONTYPE_QUATERNION:
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     case Animation.ANIMATIONTYPE_VECTOR3:
+                    case Animation.ANIMATIONTYPE_COLOR3:
                         key.values = animationKey.value.asArray();
                         key.values = animationKey.value.asArray();
                         break;
                         break;
                 }
                 }
@@ -511,6 +512,9 @@ var BABYLON;
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_MATRIX:
                         data = BABYLON.Matrix.FromArray(key.values);
                         data = BABYLON.Matrix.FromArray(key.values);
                         break;
                         break;
+                    case Animation.ANIMATIONTYPE_COLOR3:
+                        data = BABYLON.Color3.FromArray(key.values);
+                        break;
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     default:
                     default:
                         data = BABYLON.Vector3.FromArray(key.values);
                         data = BABYLON.Vector3.FromArray(key.values);

+ 4 - 0
src/Animations/babylon.animation.ts

@@ -491,6 +491,7 @@
                     case Animation.ANIMATIONTYPE_QUATERNION:
                     case Animation.ANIMATIONTYPE_QUATERNION:
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     case Animation.ANIMATIONTYPE_VECTOR3:
+                    case Animation.ANIMATIONTYPE_COLOR3:
                         key.values = animationKey.value.asArray();
                         key.values = animationKey.value.asArray();
                         break;
                         break;
                 }
                 }
@@ -568,6 +569,9 @@
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_MATRIX:
                         data = Matrix.FromArray(key.values);
                         data = Matrix.FromArray(key.values);
                         break;
                         break;
+                    case Animation.ANIMATIONTYPE_COLOR3:
+                        data = Color3.FromArray(key.values);
+                        break;
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     default:
                     default:
                         data = Vector3.FromArray(key.values);
                         data = Vector3.FromArray(key.values);

+ 10 - 3
src/Lights/Shadows/babylon.shadowGenerator.js

@@ -66,6 +66,10 @@ var BABYLON;
                     mesh._bind(subMesh, _this._effect, BABYLON.Material.TriangleFillMode);
                     mesh._bind(subMesh, _this._effect, BABYLON.Material.TriangleFillMode);
                     var material = subMesh.getMaterial();
                     var material = subMesh.getMaterial();
                     _this._effect.setMatrix("viewProjection", _this.getTransformMatrix());
                     _this._effect.setMatrix("viewProjection", _this.getTransformMatrix());
+                    _this._effect.setVector3("lightPosition", _this.getLight().position);
+                    if (_this.getLight().needCube()) {
+                        _this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    }
                     // Alpha test
                     // Alpha test
                     if (material && material.needAlphaTesting()) {
                     if (material && material.needAlphaTesting()) {
                         var alphaTexture = material.getAlphaTestTexture();
                         var alphaTexture = material.getAlphaTestTexture();
@@ -225,6 +229,9 @@ var BABYLON;
             if (this.useVarianceShadowMap || this.useBlurVarianceShadowMap) {
             if (this.useVarianceShadowMap || this.useBlurVarianceShadowMap) {
                 defines.push("#define VSM");
                 defines.push("#define VSM");
             }
             }
+            if (this.getLight().needCube()) {
+                defines.push("#define CUBEMAP");
+            }
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
             var material = subMesh.getMaterial();
             var material = subMesh.getMaterial();
@@ -266,7 +273,7 @@ var BABYLON;
             var join = defines.join("\n");
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
                 this._cachedDefines = join;
-                this._effect = this._scene.getEngine().createEffect("shadowMap", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix"], ["diffuseSampler"], join);
+                this._effect = this._scene.getEngine().createEffect("shadowMap", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "lightPosition", "depthValues"], ["diffuseSampler"], join);
             }
             }
             return this._effect.isReady();
             return this._effect.isReady();
         };
         };
@@ -293,7 +300,7 @@ var BABYLON;
             var lightPosition = this._light.position;
             var lightPosition = this._light.position;
             BABYLON.Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
             BABYLON.Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
             if (Math.abs(BABYLON.Vector3.Dot(this._lightDirection, BABYLON.Vector3.Up())) === 1.0) {
             if (Math.abs(BABYLON.Vector3.Dot(this._lightDirection, BABYLON.Vector3.Up())) === 1.0) {
-                this._lightDirection.z = 0.0000000000001; // Need to avoid perfectly perpendicular light
+                this._lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light
             }
             }
             if (this._light.computeTransformedPosition()) {
             if (this._light.computeTransformedPosition()) {
                 lightPosition = this._light.transformedPosition;
                 lightPosition = this._light.transformedPosition;
@@ -301,7 +308,7 @@ var BABYLON;
             if (this._light.needRefreshPerFrame() || !this._cachedPosition || !this._cachedDirection || !lightPosition.equals(this._cachedPosition) || !this._lightDirection.equals(this._cachedDirection)) {
             if (this._light.needRefreshPerFrame() || !this._cachedPosition || !this._cachedDirection || !lightPosition.equals(this._cachedPosition) || !this._lightDirection.equals(this._cachedDirection)) {
                 this._cachedPosition = lightPosition.clone();
                 this._cachedPosition = lightPosition.clone();
                 this._cachedDirection = this._lightDirection.clone();
                 this._cachedDirection = this._lightDirection.clone();
-                BABYLON.Matrix.LookAtLHToRef(lightPosition, this._light.position.add(this._lightDirection), BABYLON.Vector3.Up(), this._viewMatrix);
+                BABYLON.Matrix.LookAtLHToRef(lightPosition, lightPosition.add(this._lightDirection), BABYLON.Vector3.Up(), this._viewMatrix);
                 this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
                 this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
                 this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
                 this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
             }
             }

+ 12 - 3
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -190,6 +190,11 @@
                     var material = subMesh.getMaterial();
                     var material = subMesh.getMaterial();
 
 
                     this._effect.setMatrix("viewProjection", this.getTransformMatrix());
                     this._effect.setMatrix("viewProjection", this.getTransformMatrix());
+                    this._effect.setVector3("lightPosition", this.getLight().position);
+
+                    if (this.getLight().needCube()) {
+                        this._effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                    }
 
 
                     // Alpha test
                     // Alpha test
                     if (material && material.needAlphaTesting()) {
                     if (material && material.needAlphaTesting()) {
@@ -246,6 +251,10 @@
                 defines.push("#define VSM");
                 defines.push("#define VSM");
             }
             }
 
 
+            if (this.getLight().needCube()) {
+                defines.push("#define CUBEMAP");
+            }
+
             var attribs = [VertexBuffer.PositionKind];
             var attribs = [VertexBuffer.PositionKind];
 
 
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
@@ -293,7 +302,7 @@
                 this._cachedDefines = join;
                 this._cachedDefines = join;
                 this._effect = this._scene.getEngine().createEffect("shadowMap",
                 this._effect = this._scene.getEngine().createEffect("shadowMap",
                     attribs,
                     attribs,
-                    ["world", "mBones", "viewProjection", "diffuseMatrix"],
+                    ["world", "mBones", "viewProjection", "diffuseMatrix", "lightPosition", "depthValues"],
                     ["diffuseSampler"], join);
                     ["diffuseSampler"], join);
             }
             }
 
 
@@ -330,7 +339,7 @@
             Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
             Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
 
 
             if (Math.abs(Vector3.Dot(this._lightDirection, Vector3.Up())) === 1.0) {
             if (Math.abs(Vector3.Dot(this._lightDirection, Vector3.Up())) === 1.0) {
-                this._lightDirection.z = 0.0000000000001; // Need to avoid perfectly perpendicular light
+                this._lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light
             }
             }
 
 
             if (this._light.computeTransformedPosition()) {
             if (this._light.computeTransformedPosition()) {
@@ -342,7 +351,7 @@
                 this._cachedPosition = lightPosition.clone();
                 this._cachedPosition = lightPosition.clone();
                 this._cachedDirection = this._lightDirection.clone();
                 this._cachedDirection = this._lightDirection.clone();
 
 
-                Matrix.LookAtLHToRef(lightPosition, this._light.position.add(this._lightDirection), Vector3.Up(), this._viewMatrix);
+                Matrix.LookAtLHToRef(lightPosition, lightPosition.add(this._lightDirection), Vector3.Up(), this._viewMatrix);
 
 
                 this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
                 this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
 
 

+ 1 - 1
src/Lights/babylon.spotLight.ts

@@ -34,7 +34,7 @@
         public getShadowDirection(faceIndex?: number): Vector3 {
         public getShadowDirection(faceIndex?: number): Vector3 {
             return this.direction;
             return this.direction;
         }
         }
-
+        
         public setDirectionToTarget(target: Vector3): Vector3 {
         public setDirectionToTarget(target: Vector3): Vector3 {
             this.direction = Vector3.Normalize(target.subtract(this.position));
             this.direction = Vector3.Normalize(target.subtract(this.position));
             return this.direction;
             return this.direction;

+ 8 - 1
src/Materials/babylon.standardMaterial.js

@@ -268,6 +268,7 @@ var BABYLON;
         };
         };
         StandardMaterial.BindLights = function (scene, mesh, effect, defines) {
         StandardMaterial.BindLights = function (scene, mesh, effect, defines) {
             var lightIndex = 0;
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
                 var light = scene.lights[index];
                 if (!light.isEnabled()) {
                 if (!light.isEnabled()) {
@@ -305,6 +306,12 @@ var BABYLON;
                         if (!light.needCube()) {
                         if (!light.needCube()) {
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                         }
                         }
+                        else {
+                            if (!depthValuesAlreadySet) {
+                                depthValuesAlreadySet = true;
+                                effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                            }
+                        }
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                     }
                     }
@@ -640,7 +647,7 @@ var BABYLON;
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
                     "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
                     "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
-                    "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
+                    "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues",
                     "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
                     "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
                     "logarithmicDepthConstant"
                     "logarithmicDepthConstant"
                 ], ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
                 ], ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",

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

@@ -318,6 +318,7 @@
         private static _scaledSpecular = new Color3();
         private static _scaledSpecular = new Color3();
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
                 var light = scene.lights[index];
 
 
@@ -356,6 +357,11 @@
                     if (mesh.receiveShadows && shadowGenerator) {
                     if (mesh.receiveShadows && shadowGenerator) {
                         if (!(<any>light).needCube()) {
                         if (!(<any>light).needCube()) {
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                             effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
+                        } else {
+                            if (!depthValuesAlreadySet) {
+                                depthValuesAlreadySet = true;
+                                effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
+                            }
                         }
                         }
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
@@ -755,7 +761,7 @@
                         "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
                         "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
                         "mBones",
                         "mBones",
                         "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
                         "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "lightmapMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues", 
                         "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
                         "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor",
                         "logarithmicDepthConstant"
                         "logarithmicDepthConstant"
                     ],
                     ],

+ 6 - 3
src/Shaders/default.fragment.fx

@@ -287,14 +287,17 @@ float unpack(vec4 color)
 }
 }
 
 
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+uniform vec2 depthValues;
+
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	vec3 directionToLight = vPositionW - lightPosition;
 	float depth = length(directionToLight);
 	float depth = length(directionToLight);
+	depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
+	depth = clamp(depth, 0., 1.0);
 
 
-	depth = clamp(depth, 0., 1.);
-
-	directionToLight.y = 1.0 - directionToLight.y;
+	directionToLight = normalize(directionToLight);
+	directionToLight.y = - directionToLight.y;
 
 
 	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 
 

+ 14 - 0
src/Shaders/shadowMap.fragment.fx

@@ -27,14 +27,28 @@ varying vec2 vUV;
 uniform sampler2D diffuseSampler;
 uniform sampler2D diffuseSampler;
 #endif
 #endif
 
 
+#ifdef CUBEMAP
+uniform vec3 lightPosition;
+uniform vec2 depthValues;
+#endif
+
 void main(void)
 void main(void)
 {
 {
 #ifdef ALPHATEST
 #ifdef ALPHATEST
 	if (texture2D(diffuseSampler, vUV).a < 0.4)
 	if (texture2D(diffuseSampler, vUV).a < 0.4)
 		discard;
 		discard;
 #endif
 #endif
+
+#ifdef CUBEMAP
+	vec3 directionToLight = vPosition.xyz - lightPosition;
+	
+	float depth = length(directionToLight);
+	depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
+	depth = clamp(depth, 0., 1.0);
+#else
 	float depth = vPosition.z / vPosition.w;
 	float depth = vPosition.z / vPosition.w;
 	depth = depth * 0.5 + 0.5;
 	depth = depth * 0.5 + 0.5;
+#endif
 
 
 #ifdef VSM
 #ifdef VSM
 	float moment1 = depth;
 	float moment1 = depth;

+ 7 - 1
src/Shaders/shadowMap.vertex.fx

@@ -77,8 +77,14 @@ void main(void)
 
 
 	finalWorld = finalWorld * influence;
 	finalWorld = finalWorld * influence;
 #endif
 #endif
-	vPosition = viewProjection * finalWorld * vec4(position, 1.0);
+
+#ifdef CUBEMAP
+	vPosition = finalWorld * vec4(position, 1.0);
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+#else
+	vPosition = viewProjection * finalWorld * vec4(position, 1.0)
 	gl_Position = vPosition;
 	gl_Position = vPosition;
+#endif
 
 
 #ifdef ALPHATEST
 #ifdef ALPHATEST
 #ifdef UV1
 #ifdef UV1