浏览代码

Merge pull request #4 from BabylonJS/master

get from main repo
Etienne Margraff 9 年之前
父节点
当前提交
e7f7bf40af
共有 61 个文件被更改,包括 7142 次插入4426 次删除
  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 = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (3, 0, 6),
+    'version': (4, 0, 0),
     'blender': (2, 75, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -38,9 +38,9 @@ if __name__ == '__main__':
 # output related constants
 MAX_VERTEX_ELEMENTS = 65535
 MAX_VERTEX_ELEMENTS_32Bit = 16777216
-VERTEX_OUTPUT_PER_LINE = 1000
+VERTEX_OUTPUT_PER_LINE = 100
 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
 #FOGMODE_NONE = 0
@@ -110,6 +110,8 @@ CUBIC_MODE = 3
 #PROJECTION_MODE = 4
 #SKYBOX_MODE = 5
 
+DEFAULT_MATERIAL_NAMESPACE = 'Same as Filename'
+
 # passed to Animation constructor from animatable objects, defined in BABYLON.Animation
 #ANIMATIONTYPE_FLOAT = 0
 ANIMATIONTYPE_VECTOR3 = 1
@@ -134,9 +136,9 @@ class ExporterSettingsPanel(bpy.types.Panel):
         description="Export only selected layers",
         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,
         )        
     bpy.types.Scene.attachedSound = bpy.props.StringProperty(
@@ -165,7 +167,7 @@ class ExporterSettingsPanel(bpy.types.Panel):
 
         scene = context.scene
         layout.prop(scene, "export_onlySelectedLayer")
-        layout.prop(scene, "export_noVertexOpt")
+        layout.prop(scene, "export_flatshadeScene")
         layout.prop(scene, "inlineTextures")
 
         box = layout.box()
@@ -238,6 +240,10 @@ class Main(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
                 bpy.ops.object.mode_set(mode = 'OBJECT')
 
             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)
 
             bpy.ops.screen.animation_cancel()
@@ -591,8 +597,8 @@ class Mesh(FCurveAnimatable):
         self.name = object.name + str(nameID)
         Main.log('processing begun of mesh:  ' + self.name)
         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.receiveShadows = object.data.receiveShadows
         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
                 material = exporter.getMaterial(slot.name)
                 if (material != None):
-                    material.numOfUsers = material.numOfUsers + 1
                     Main.log('registered as also a user of material:  ' + slot.name, 2)
                 else:
                     material = StdMaterial(slot, exporter, object)
@@ -749,8 +754,10 @@ class Mesh(FCurveAnimatable):
             Colormap = mesh.tessface_vertex_colors.active.data
 
         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
         alreadySavedVertices = []
@@ -759,6 +766,8 @@ class Mesh(FCurveAnimatable):
         vertices_UV2s = []
         vertices_Colors = []
         vertices_indices = []
+        vertices_sk_weights = []
+        vertices_sk_indices = []
 
         self.offsetFace = 0
 
@@ -769,11 +778,12 @@ class Mesh(FCurveAnimatable):
             vertices_UV2s.append([])
             vertices_Colors.append([])
             vertices_indices.append([])
+            vertices_sk_weights.append([])
+            vertices_sk_indices.append([])
 
         materialsCount = 1 if recipe.needsBaking else max(1, len(object.material_slots))
         verticesCount = 0
         indicesCount = 0
-        maxInfluencersExceeded = 0
 
         for materialIndex in range(materialsCount):
             if self.offsetFace != 0:
@@ -797,38 +807,22 @@ class Mesh(FCurveAnimatable):
 
                     vertex = mesh.vertices[vertex_index]
                     position = vertex.co
+                    normal = face.normal if useFlatShading else vertex.normal
                     
-                    if (scene.export_noVertexOpt):
-                        normal = face.normal
-                    else:
-                        normal = vertex.normal
-
                     #skeletons
                     if hasSkeleton:
                         matricesWeights = []
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesWeights.append(0.0)
-                        matricesIndicesCompressed = 0
+                        matricesIndices = []
 
                         # Getting influences
-                        i = 0
-                        offset = 0
                         for group in vertex.groups:
                             index = group.group
                             weight = group.weight
 
                             for boneIndex, bone in enumerate(objArmature.pose.bones):
                                 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
                     if hasUV:
@@ -847,7 +841,7 @@ class Mesh(FCurveAnimatable):
                             vertex_Color = Colormap[face.index].color3
 
                     # 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:
                         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):
                                     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:
                                 alreadySaved = True
                                 break
@@ -905,11 +905,13 @@ class Mesh(FCurveAnimatable):
                             self.colors.append(vertex_Color.b)
                             self.colors.append(1.0)
                         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)
 
@@ -922,11 +924,8 @@ class Mesh(FCurveAnimatable):
             self.subMeshes.append(SubMesh(materialIndex, subMeshVerticesStart, subMeshIndexStart, verticesCount - subMeshVerticesStart, indicesCount - subMeshIndexStart))
 
         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)
 
         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 colors         :  ' + str(len(self.colors   )), 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()
         if numZeroAreaFaces > 0:
@@ -969,6 +988,85 @@ class Mesh(FCurveAnimatable):
         except:
             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):
         file_handler.write('{')
         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, 'freezeWorldMatrix', self.freezeWorldMatrix)
         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, 'receiveShadows', self.receiveShadows)
 
@@ -999,7 +1096,10 @@ class Mesh(FCurveAnimatable):
             write_float(file_handler, 'physicsRestitution', self.physicsRestitution)
 
         # 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, 'normals'  , self.normals  )
 
@@ -1014,7 +1114,11 @@ class Mesh(FCurveAnimatable):
 
         if hasattr(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)
 
@@ -1135,7 +1239,7 @@ class SubMesh:
 #===============================================================================
 class Bone:
     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.index = index
 
@@ -1153,7 +1257,7 @@ class Bone:
 
         #animation
         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')
 
             start_frame = scene.frame_start
@@ -1668,7 +1772,7 @@ class BakingRecipe:
                         continue
                     
                     # 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.texture_coords == 'REFLECTION':
                                 nReflectionImages += 1
@@ -1739,10 +1843,8 @@ class BakingRecipe:
 #===============================================================================
 # Not intended to be instanced directly
 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
         self.textures = []
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1757,8 +1859,7 @@ class Material:
         write_float(file_handler, 'specularPower', self.specularPower)
         write_float(file_handler, 'alpha', self.alpha)
         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:
             texSlot.to_scene_file(file_handler)
 
@@ -1766,8 +1867,10 @@ class Material:
 #===============================================================================
 class StdMaterial(Material):
     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)
 
         # 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.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))
                 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))
 
             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))
 
             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:
-                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))
 
             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))
 
             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))
 #===============================================================================
 class BakedMaterial(Material):
     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)
 
         # 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
         # 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:
             mesh.data.uv_textures.new('BakingUV')
@@ -1883,25 +1987,25 @@ class BakedMaterial(Material):
 
         # now go thru all the textures that need to be baked
         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:
-            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
-            self.bake('opacityTexture', None, 'ALPHA', image, mesh, exporter, recipe)
+            self.bake('opacityTexture', None, 'ALPHA', image, mesh, uv, exporter, recipe)
 
         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:
-            self.bake('emissiveTexture', 'EMIT', 'EMIT', image, mesh, exporter, recipe)
+            self.bake('emissiveTexture', 'EMIT', 'EMIT', image, mesh, uv, exporter, recipe)
 
         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:
-            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
         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
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    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 cycles_type is None:
                 return
-            self.bakeCycles(cycles_type, image, recipe.nodeTrees)
+            self.bakeCycles(cycles_type, image, uv, recipe.nodeTrees)
         else:
-            self.bakeInternal(internal_type, image)
+            self.bakeInternal(internal_type, image, uv)
 
         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.render.engine = 'BLENDER_RENDER'
@@ -1946,9 +2052,10 @@ class BakedMaterial(Material):
 
         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.render.engine = 'CYCLES'
@@ -2199,6 +2306,13 @@ def scale_vector(vector, mult, xOffset = 0):
 
 def same_vertex(vertA, vertB):
     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
 #===============================================================================
@@ -2250,7 +2364,7 @@ bpy.types.Mesh.autoAnimate = bpy.props.BoolProperty(
 )
 bpy.types.Mesh.useFlatShading = bpy.props.BoolProperty(
     name='Use Flat Shading',
-    description='',
+    description='Use face normals.  Increases vertices.',
     default = False
 )
 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(
     name='Quality 1-100',
     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(
     name='Freeze World Matrix',
     description='Indicate the position, rotation, & scale do not change for performance reasons',
     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(
     name='Sound',
     description='',
@@ -2303,6 +2432,11 @@ bpy.types.Mesh.maxSoundDistance = bpy.props.FloatProperty(
     description='',
     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(
     name='Auto launch animations',
@@ -2417,22 +2551,31 @@ class ObjectPanel(bpy.types.Panel):
         isLight = isinstance(ob.data, bpy.types.Lamp)
 
         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.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, 'bakeQuality')
 
-            layout.prop(ob.data, 'freezeWorldMatrix')
-
             box = layout.box()
             box.prop(ob.data, 'attachedSound')
             box.prop(ob.data, 'autoPlaySound')
@@ -2463,4 +2606,3 @@ class ObjectPanel(bpy.types.Panel):
             box.prop(ob.data, 'shadowBlurBoxOffset')
 
             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
 * **Materials**
  * Name
+ * Name space
  * Ambient color
  * Diffuse color
  * Specular color
@@ -46,6 +47,7 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Bump texture
  * Procedural Texture Baking
  * Cycles Render Baking
+ * Check Ready Only Once
 * **Multi-materials**
  * Name
  * Child materials
@@ -71,10 +73,12 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Texture coordinates (2 channels)
  * Vertex colors
  * Visibility
+ * Load disabled
  * Check collisions
  * Billboard
  * Receive and cast shadows
  * Bones (armatures) and bones' animations
+ 	* Variable Max Bone Influencers / vertex
  * Animations
 
 

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


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


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


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


文件差异内容过多而无法显示
+ 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:
 
 ```
-<script src="babylon.2.1.js"></script>
+<script src="babylon.2.2.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
-* Load scenes (SceneLoader.Load)
+* Load scenes (SceneLoader.Load and SceneLoader.Append)
+* Support of ImportMesh function
 * Import geometries
     * From binary files
     * From base64 buffers
@@ -34,8 +43,5 @@ BABYLON.SceneLoader.Load("./", "duck.gltf", engine, function (scene) {
     * Bones import
 * Handle dummy nodes (empty nodes)
 
-## Unsupported features
-* ImportMesh function
-
 ## To improve
 * Test on more models

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

@@ -447,8 +447,13 @@ var BABYLON;
     /**
     * 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
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
         var buffer = getBufferFromAccessor(gltfRuntime, accessor);
@@ -533,9 +538,14 @@ var BABYLON;
     /**
     * 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);
         newMesh.material = multiMat;
         var vertexData = new BABYLON.VertexData();
@@ -555,7 +565,7 @@ var BABYLON;
                 // Temporary vertex data
                 var tempVertexData = new BABYLON.VertexData();
                 var primitive = mesh.primitives[i];
-                if (primitive.primitive !== 4) {
+                if (primitive.mode !== 4) {
                 }
                 var attributes = primitive.attributes;
                 var accessor = null;
@@ -639,7 +649,7 @@ var BABYLON;
                 continue;
             }
             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);
                 index++;
@@ -687,14 +697,22 @@ var BABYLON;
     */
     var importNode = function (gltfRuntime, node, id) {
         var lastNode = null;
+        if (gltfRuntime.importOnlyMeshes && (node.skin || node.meshes)) {
+            if (gltfRuntime.importMeshesNames.length > 0 && gltfRuntime.importMeshesNames.indexOf(node.name) === -1) {
+                return null;
+            }
+        }
         // Meshes
         if (node.skin) {
             if (node.meshes) {
                 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);
                 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) {
                     newMesh.useBones = true;
@@ -706,10 +724,10 @@ var BABYLON;
             /**
             * 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;
         }
-        else if (node.light) {
+        else if (node.light && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var light = gltfRuntime.lights[node.light];
             if (light) {
                 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];
             if (camera) {
                 if (camera.type === "orthographic") {
@@ -784,9 +802,15 @@ var BABYLON;
             }
         }
         // 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 (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));
             }
             lastNode.updateCache(true);
+            node.babylonNode = 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 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.id = id;
-            newNode.parent = parent;
+            if (newNode !== null) {
+                newNode.id = id;
+                newNode.parent = parent;
+            }
         }
         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
         */
         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;
         };
         /**
@@ -1213,6 +1299,23 @@ var BABYLON;
         */
         GLTFFileLoader.prototype.load = function (scene, data, rootUrl) {
             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 = {
                 accessors: {},
                 buffers: {},
@@ -1293,10 +1396,7 @@ var BABYLON;
             if (parsedData.scene && parsedData.scenes) {
                 gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
             }
-            // Load shaders and buffers
-            load(gltfRuntime);
-            // Finish
-            return true;
+            return gltfRuntime;
         };
         return GLTFFileLoader;
     })();

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

@@ -493,8 +493,15 @@
     /**
     * 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
         var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
@@ -600,9 +607,15 @@
     /**
     * 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);
         newMesh.material = multiMat;
@@ -629,7 +642,7 @@
                 var tempVertexData = new VertexData();
 
                 var primitive = mesh.primitives[i];
-                if (primitive.primitive !== 4) {
+                if (primitive.mode !== 4) {
                     //continue;
                 }
 
@@ -728,7 +741,7 @@
             }
 
             for (var i = 0; i < mesh.primitives.length; i++) {
-                if (mesh.primitives[i].primitive !== 4) {
+                if (mesh.primitives[i].mode !== 4) {
                     //continue;
                 }
 
@@ -786,16 +799,26 @@
     var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string): Node => {
         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
         if (node.skin) {
             if (node.meshes) {
                 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);
 
                 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) {
@@ -809,11 +832,11 @@
             /**
             * 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;
         }
         // Lights
-        else if (node.light) {
+        else if (node.light && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var light = gltfRuntime.lights[node.light];
 
             if (light) {
@@ -872,7 +895,7 @@
             }
         }
         // Cameras
-        else if (node.camera) {
+        else if (node.camera && !node.babylonNode && !gltfRuntime.importOnlyMeshes) {
             var camera: IGLTFCamera = gltfRuntime.cameras[node.camera];
 
             if (camera) {
@@ -908,9 +931,15 @@
         }
 
         // 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) {
@@ -922,24 +951,59 @@
             }
 
             lastNode.updateCache(true);
+
+            node.babylonNode = 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;
 
-        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.id = id;
-            newNode.parent = parent;
+
+            if (newNode !== null) {
+                newNode.id = id;
+                newNode.parent = parent;
+            }
         }
 
         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
         */
         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;
         }
 
@@ -1418,7 +1523,29 @@
         */
         public load(scene: Scene, data: string, rootUrl: string): boolean {
             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 = {
                 accessors: {},
                 buffers: {},
@@ -1521,11 +1648,7 @@
                 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;
         material: string;
 
-        primitive?: number;
+        mode?: number;
     }
 
     export interface IGLTFMesh extends IGLTFChildRootProperty {
@@ -206,6 +206,8 @@
         bindShapeMatrix: number[];
         inverseBindMatrices: string;
         jointNames: string[];
+
+        babylonSkeleton?: Skeleton;
     }
 
     export interface IGLTFNode extends IGLTFChildRootProperty {
@@ -220,6 +222,9 @@
         rotation?: number[];
         scale?: number[];
         translation?: number[];
+
+        // Babylon.js values (optimize)
+        babylonNode?: Node;
     }
 
     export interface IGLTFScene extends IGLTFChildRootProperty {
@@ -258,6 +263,7 @@
         arrayBuffers: Object;
 
         importOnlyMeshes: boolean;
+        importMeshesNames?: string[];
 
         dummyNodes: Node[];
     }

+ 8 - 0
materialsLibrary/config.json

@@ -65,6 +65,14 @@
         "materials/terrain/terrain.fragment.fx"
       ],
       "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": {

文件差异内容过多而无法显示
+ 2 - 2
materialsLibrary/dist/babylon.fireMaterial.js


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


文件差异内容过多而无法显示
+ 13 - 3
materialsLibrary/dist/babylon.lavaMaterial.js


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


文件差异内容过多而无法显示
+ 13 - 4
materialsLibrary/dist/babylon.normalMaterial.js


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


文件差异内容过多而无法显示
+ 147 - 137
materialsLibrary/dist/babylon.pbrMaterial.js


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


文件差异内容过多而无法显示
+ 13 - 4
materialsLibrary/dist/babylon.simpleMaterial.js


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


文件差异内容过多而无法显示
+ 2 - 2
materialsLibrary/dist/babylon.terrainMaterial.js


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


文件差异内容过多而无法显示
+ 509 - 0
materialsLibrary/dist/babylon.triPlanarMaterial.js


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


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


文件差异内容过多而无法显示
+ 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;
         emissiveIntensity: number;
         environmentIntensity: number;
+        specularIntensity: number;
         private _lightingInfos;
         overloadedShadowIntensity: number;
         overloadedShadeIntensity: number;
@@ -12,43 +13,43 @@ declare module BABYLON {
         cameraContrast: number;
         private _cameraInfos;
         overloadedAmbientIntensity: number;
-        overloadedDiffuseIntensity: number;
-        overloadedSpecularIntensity: number;
+        overloadedAlbedoIntensity: number;
+        overloadedReflectivityIntensity: number;
         overloadedEmissiveIntensity: number;
         private _overloadedIntensity;
         overloadedAmbient: Color3;
-        overloadedDiffuse: Color3;
-        overloadedSpecular: Color3;
+        overloadedAlbedo: Color3;
+        overloadedReflectivity: Color3;
         overloadedEmissive: Color3;
         overloadedReflection: Color3;
-        overloadedGlossiness: number;
-        overloadedGlossinessIntensity: number;
+        overloadedMicroSurface: number;
+        overloadedMicroSurfaceIntensity: number;
         overloadedReflectionIntensity: number;
-        private _overloadedGlossiness;
+        private _overloadedMicroSurface;
         disableBumpMap: boolean;
-        diffuseTexture: BaseTexture;
+        albedoTexture: BaseTexture;
         ambientTexture: BaseTexture;
         opacityTexture: BaseTexture;
         reflectionTexture: BaseTexture;
         emissiveTexture: BaseTexture;
-        specularTexture: BaseTexture;
+        reflectivityTexture: BaseTexture;
         bumpTexture: BaseTexture;
         lightmapTexture: BaseTexture;
         ambientColor: Color3;
-        diffuseColor: Color3;
-        specularColor: Color3;
+        albedoColor: Color3;
+        reflectivityColor: Color3;
         reflectionColor: Color3;
-        glossiness: number;
+        microSurface: number;
         emissiveColor: Color3;
-        useAlphaFromDiffuseTexture: boolean;
+        useAlphaFromAlbedoTexture: boolean;
         useEmissiveAsIllumination: boolean;
-        linkEmissiveWithDiffuse: boolean;
+        linkEmissiveWithAlbedo: boolean;
         useSpecularOverAlpha: boolean;
         disableLighting: boolean;
         useLightmapAsShadowmap: boolean;
         opacityFresnelParameters: FresnelParameters;
         emissiveFresnelParameters: FresnelParameters;
-        useGlossinessFromSpecularMapAlpha: boolean;
+        useMicroSurfaceFromReflectivityMapAlpha: boolean;
         private _renderTargets;
         private _worldViewProjectionMatrix;
         private _globalAmbientColor;
@@ -61,12 +62,12 @@ declare module BABYLON {
         useLogarithmicDepth: boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
-        private _shouldUseAlphaFromDiffuseTexture();
+        private _shouldUseAlphaFromAlbedoTexture();
         getAlphaTestTexture(): BaseTexture;
         private _checkCache(scene, mesh?, useInstances?);
         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 _scaledReflection;
         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",
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3","time", "speed","movingSpeed",
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues",
+                        "time", "speed","movingSpeed",
                         "fogColor","fogDensity", "lowFrequencySpeed"
                     ],
                     ["diffuseSampler",
@@ -437,6 +438,7 @@ module BABYLON {
 
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
 
@@ -469,7 +471,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         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.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)
+uniform vec2 depthValues;
+
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	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;
 
@@ -142,14 +144,16 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 	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;
 	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.;
 
@@ -466,7 +470,7 @@ void main(void) {
 #else
 #ifdef SHADOWPCF0
 	#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
+	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x, shadowsInfo0.y);
 	#else
 	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
 	#endif
@@ -500,7 +504,7 @@ void main(void) {
 #else
 #ifdef SHADOWPCF1
 #if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
+	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x, shadowsInfo1.y);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
 #endif
@@ -534,7 +538,7 @@ void main(void) {
 #else
 #ifdef SHADOWPCF2
 #if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
+	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x, shadowsInfo2.y);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
 #endif
@@ -568,7 +572,7 @@ void main(void) {
 #else
 #ifdef SHADOWPCF3
 #if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x, shadowsInfo3.y);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
 #endif

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

@@ -353,7 +353,7 @@ module BABYLON {
                         "vDiffuseInfos", 
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3"
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                     ],
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -420,6 +420,7 @@ module BABYLON {
 
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
 
@@ -452,7 +453,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         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.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         }

文件差异内容过多而无法显示
+ 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;
 
     class PBRMaterialDefines extends MaterialDefines {
-        public DIFFUSE = false;
+        public ALBEDO = false;
         public AMBIENT = false;
         public OPACITY = false;
         public OPACITYRGB = false;
         public REFLECTION = false;
         public EMISSIVE = false;
-        public SPECULAR = false;
+        public REFLECTIVITY = false;
         public BUMP = false;
         public SPECULAROVERALPHA = false;
         public CLIPPLANE = false;
         public ALPHATEST = false;
-        public ALPHAFROMDIFFUSE = false;
+        public ALPHAFROMALBEDO = false;
         public POINTSIZE = false;
         public FOG = false;
         public LIGHT0 = false;
@@ -63,9 +63,9 @@ module BABYLON {
         public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
-        public GLOSSINESSFROMSPECULARMAP = false;
+        public MICROSURFACEFROMREFLECTIVITYMAP = false;
         public EMISSIVEASILLUMINATION = false;
-        public LINKEMISSIVEWITHDIFFUSE = false;
+        public LINKEMISSIVEWITHALBEDO = false;
         public LIGHTMAP = false;
         public USELIGHTMAPASSHADOWMAP = false;
         public REFLECTIONMAP_3D = false;
@@ -94,7 +94,9 @@ module BABYLON {
         public directIntensity: number = 1.0;
         public emissiveIntensity: 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 overloadedShadeIntensity: number = 1.0;
@@ -105,42 +107,42 @@ module BABYLON {
         private _cameraInfos: Vector4 = new Vector4(1.0, 1.0, 0.0, 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;
-        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 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 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;
-        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 diffuseTexture: BaseTexture;
+        public albedoTexture: BaseTexture;
         public ambientTexture: BaseTexture;
         public opacityTexture: BaseTexture;
         public reflectionTexture: BaseTexture;
         public emissiveTexture: BaseTexture;
-        public specularTexture: BaseTexture;
+        public reflectivityTexture: BaseTexture;
         public bumpTexture: BaseTexture;
         public lightmapTexture: BaseTexture;
 
         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 glossiness = 0.5;
+        public microSurface = 0.5;
         public emissiveColor = new Color3(0, 0, 0);
-        public useAlphaFromDiffuseTexture = false;
+        public useAlphaFromAlbedoTexture = false;
         public useEmissiveAsIllumination = false;
-        public linkEmissiveWithDiffuse = false;
+        public linkEmissiveWithAlbedo = false;
         public useSpecularOverAlpha = true;
         public disableLighting = false;
 
@@ -149,7 +151,7 @@ module BABYLON {
         public opacityFresnelParameters: FresnelParameters;
         public emissiveFresnelParameters: FresnelParameters;
 
-        public useGlossinessFromSpecularMapAlpha = false;
+        public useMicroSurfaceFromReflectivityMapAlpha = false;
 
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _worldViewProjectionMatrix = Matrix.Zero();
@@ -188,19 +190,19 @@ module BABYLON {
         }
 
         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 {
-            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 {
-            return this.diffuseTexture;
+            return this.albedoTexture;
         }
 
         private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
@@ -305,13 +307,14 @@ module BABYLON {
             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 _scaledReflection = new Color3();
 
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
 
@@ -338,15 +341,15 @@ module BABYLON {
                 }
 
                 // 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"]) {
-                    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
@@ -355,6 +358,11 @@ module BABYLON {
                     if (mesh.receiveShadows && shadowGenerator) {
                         if (!(<any>light).needCube()) {
                             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.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
@@ -394,12 +402,12 @@ module BABYLON {
 
             // Textures
             if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
+                if (this.albedoTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    if (!this.albedoTexture.isReady()) {
                         return false;
                     } else {
                         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;
                     } else {
                         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;
             }
 
-            if (this._shouldUseAlphaFromDiffuseTexture()) {
-                this._defines.ALPHAFROMDIFFUSE = true;
+            if (this._shouldUseAlphaFromAlbedoTexture()) {
+                this._defines.ALPHAFROMALBEDO = true;
             }
 
             if (this.useEmissiveAsIllumination) {
                 this._defines.EMISSIVEASILLUMINATION = true;
             }
 
-            if (this.linkEmissiveWithDiffuse) {
-                this._defines.LINKEMISSIVEWITHDIFFUSE = true;
+            if (this.linkEmissiveWithAlbedo) {
+                this._defines.LINKEMISSIVEWITHALBEDO = true;
             }
 
             if (this.useLogarithmicDepth) {
@@ -542,10 +550,10 @@ module BABYLON {
                 this._defines.OVERLOADEDSHADOWVALUES = true;
             }
 
-            if (this.overloadedGlossinessIntensity > 0 ||
+            if (this.overloadedMicroSurfaceIntensity > 0 ||
                 this.overloadedEmissiveIntensity > 0 ||
-                this.overloadedSpecularIntensity > 0 ||
-                this.overloadedDiffuseIntensity > 0 ||
+                this.overloadedReflectivityIntensity > 0 ||
+                this.overloadedAlbedoIntensity > 0 ||
                 this.overloadedAmbientIntensity > 0 ||
                 this.overloadedReflectionIntensity > 0) {
                 this._defines.OVERLOADEDVALUES = true;
@@ -630,8 +638,8 @@ module BABYLON {
                     fallbacks.addFallback(0, "REFLECTION");
                 }
 
-                if (this._defines.SPECULAR) {
-                    fallbacks.addFallback(0, "SPECULAR");
+                if (this._defines.REFLECTIVITY) {
+                    fallbacks.addFallback(0, "REFLECTIVITY");
                 }
 
                 if (this._defines.BUMP) {
@@ -739,21 +747,21 @@ module BABYLON {
                 var join = this._defines.toString();
                 this._effect = scene.getEngine().createEffect(shaderName,
                     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",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                         "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
                         "vFogInfos", "vFogColor", "pointSize",
-                        "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
+                        "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vReflectivityInfos", "vBumpInfos", "vLightmapInfos",
                         "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",
-                        "vLightingIntensity", "vOverloadedShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedDiffuse", "vOverloadedReflection", "vOverloadedSpecular", "vOverloadedEmissive", "vOverloadedGlossiness",
+                        "vLightingIntensity", "vOverloadedShadowIntensity", "vOverloadedIntensity", "vCameraInfos", "vOverloadedAlbedo", "vOverloadedReflection", "vOverloadedReflectivity", "vOverloadedEmissive", "vOverloadedMicroSurface",
                         "logarithmicDepthConstant"
                     ],
-                    ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
+                    ["albedoSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "reflectivitySampler", "bumpSampler", "lightmapSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     ],
                     join, fallbacks, this.onCompiled, this.onError);
@@ -818,11 +826,11 @@ module BABYLON {
                 }
 
                 // 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) {
@@ -864,11 +872,11 @@ module BABYLON {
                     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) {
@@ -895,14 +903,11 @@ module BABYLON {
                 this._myScene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
                 
                 // 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.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.
                 this.emissiveColor.toLinearSpaceToRef(PBRMaterial._scaledEmissive); 
@@ -914,8 +919,8 @@ module BABYLON {
             }
 
             // 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
             if (this._myScene.lightsEnabled && !this.disableLighting) {
@@ -936,6 +941,8 @@ module BABYLON {
             this._lightingInfos.x = this.directIntensity;
             this._lightingInfos.y = this.emissiveIntensity;
             this._lightingInfos.z = this.environmentIntensity;
+            this._lightingInfos.w = this.specularIntensity;
+
             this._effect.setVector4("vLightingIntensity", this._lightingInfos);
 
             this._overloadedShadowInfos.x = this.overloadedShadowIntensity;
@@ -947,26 +954,26 @@ module BABYLON {
             this._effect.setVector4("vCameraInfos", this._cameraInfos);
 
             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._effect.setVector4("vOverloadedIntensity", this._overloadedIntensity);
 
             this.overloadedAmbient.toLinearSpaceToRef(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._effect.setColor3("vOverloadedEmissive", this._tempColor);
             this.overloadedReflection.toLinearSpaceToRef(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
             if (this._defines.LOGARITHMICDEPTH) {
@@ -981,8 +988,8 @@ module BABYLON {
         public getAnimatables(): IAnimatable[] {
             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) {
@@ -1001,8 +1008,8 @@ module BABYLON {
                 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) {
@@ -1013,8 +1020,8 @@ module BABYLON {
         }
 
         public dispose(forceDisposeEffect?: boolean): void {
-            if (this.diffuseTexture) {
-                this.diffuseTexture.dispose();
+            if (this.albedoTexture) {
+                this.albedoTexture.dispose();
             }
 
             if (this.ambientTexture) {
@@ -1033,8 +1040,8 @@ module BABYLON {
                 this.emissiveTexture.dispose();
             }
 
-            if (this.specularTexture) {
-                this.specularTexture.dispose();
+            if (this.reflectivityTexture) {
+                this.reflectivityTexture.dispose();
             }
 
             if (this.bumpTexture) {
@@ -1053,6 +1060,7 @@ module BABYLON {
             newPBRMaterial.directIntensity = this.directIntensity;
             newPBRMaterial.emissiveIntensity = this.emissiveIntensity;
             newPBRMaterial.environmentIntensity = this.environmentIntensity;
+            newPBRMaterial.specularIntensity = this.specularIntensity;
         
             newPBRMaterial.cameraExposure = this.cameraExposure;
             newPBRMaterial.cameraContrast = this.cameraContrast;
@@ -1061,24 +1069,24 @@ module BABYLON {
             newPBRMaterial.overloadedShadeIntensity = this.overloadedShadeIntensity;
         
             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.overloadedAmbient = this.overloadedAmbient;
-            newPBRMaterial.overloadedDiffuse = this.overloadedDiffuse;
-            newPBRMaterial.overloadedSpecular = this.overloadedSpecular;
+            newPBRMaterial.overloadedAlbedo = this.overloadedAlbedo;
+            newPBRMaterial.overloadedReflectivity = this.overloadedReflectivity;
             newPBRMaterial.overloadedEmissive = this.overloadedEmissive;
             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.disableBumpMap = this.disableBumpMap;
 
             // 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) {
                 newPBRMaterial.ambientTexture = this.ambientTexture.clone();
@@ -1092,8 +1100,8 @@ module BABYLON {
             if (this.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) {
                 newPBRMaterial.bumpTexture = this.bumpTexture.clone();
@@ -1104,14 +1112,14 @@ module BABYLON {
             }
 
             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.glossiness = this.glossiness;
+            newPBRMaterial.microSurface = this.microSurface;
             newPBRMaterial.emissiveColor = this.emissiveColor.clone();
-            newPBRMaterial.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
+            newPBRMaterial.useAlphaFromAlbedoTexture = this.useAlphaFromAlbedoTexture;
             newPBRMaterial.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            newPBRMaterial.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
+            newPBRMaterial.useMicroSurfaceFromReflectivityMapAlpha = this.useMicroSurfaceFromReflectivityMapAlpha;
             newPBRMaterial.useSpecularOverAlpha = this.useSpecularOverAlpha;
             
             newPBRMaterial.emissiveFresnelParameters = this.emissiveFresnelParameters.clone();
@@ -1128,6 +1136,7 @@ module BABYLON {
             serializationObject.directIntensity = this.directIntensity;
             serializationObject.emissiveIntensity = this.emissiveIntensity;
             serializationObject.environmentIntensity = this.environmentIntensity;
+            serializationObject.specularIntensity = this.specularIntensity;
         
             serializationObject.cameraExposure = this.cameraExposure;
             serializationObject.cameraContrast = this.cameraContrast;
@@ -1136,24 +1145,24 @@ module BABYLON {
             serializationObject.overloadedShadeIntensity = this.overloadedShadeIntensity;
         
             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.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.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.disableBumpMap = this.disableBumpMap;
 
             // Standard material
-            if (this.diffuseTexture) {
-                serializationObject.diffuseTexture = this.diffuseTexture.serialize();
+            if (this.albedoTexture) {
+                serializationObject.albedoTexture = this.albedoTexture.serialize();
             }
             if (this.ambientTexture) {
                 serializationObject.ambientTexture = this.ambientTexture.serialize();
@@ -1167,8 +1176,8 @@ module BABYLON {
             if (this.emissiveTexture) {
                 serializationObject.emissiveTexture = this.emissiveTexture.serialize();
             }
-            if (this.specularTexture) {
-                serializationObject.specularTexture = this.specularTexture.serialize();
+            if (this.reflectivityTexture) {
+                serializationObject.reflectivityTexture = this.reflectivityTexture.serialize();
             }
             if (this.bumpTexture) {
                 serializationObject.bumpTexture = this.bumpTexture.serialize();
@@ -1179,14 +1188,14 @@ module BABYLON {
             }
 
             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.glossiness = this.glossiness;
+            serializationObject.microSurface = this.microSurface;
             serializationObject.emissiveColor = this.emissiveColor.asArray();
-            serializationObject.useAlphaFromDiffuseTexture = this.useAlphaFromDiffuseTexture;
+            serializationObject.useAlphaFromAlbedoTexture = this.useAlphaFromAlbedoTexture;
             serializationObject.useEmissiveAsIllumination = this.useEmissiveAsIllumination;
-            serializationObject.useGlossinessFromSpecularMapAlpha = this.useGlossinessFromSpecularMapAlpha;
+            serializationObject.useMicroSurfaceFromReflectivityMapAlpha = this.useMicroSurfaceFromReflectivityMapAlpha;
             serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;
             
             serializationObject.emissiveFresnelParameters = this.emissiveFresnelParameters.serialize();
@@ -1216,6 +1225,7 @@ module BABYLON {
             material.directIntensity = source.directIntensity;
             material.emissiveIntensity = source.emissiveIntensity;
             material.environmentIntensity = source.environmentIntensity;
+            material.specularIntensity = source.specularIntensity;
         
             material.cameraExposure = source.cameraExposure;
             material.cameraContrast = source.cameraContrast;
@@ -1224,24 +1234,24 @@ module BABYLON {
             material.overloadedShadeIntensity = source.overloadedShadeIntensity;
         
             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.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.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.disableBumpMap = source.disableBumpMap;
 
             // 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) {
                 material.ambientTexture = Texture.Parse(source.ambientTexture, scene, rootUrl);
@@ -1255,8 +1265,8 @@ module BABYLON {
             if (source.emissiveTexture) {
                 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) {
                 material.bumpTexture = Texture.Parse(source.bumpTexture, scene, rootUrl);
@@ -1267,14 +1277,14 @@ module BABYLON {
             }
 
             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.glossiness = source.glossiness;
+            material.microSurface = source.microSurface;
             material.emissiveColor = Color3.FromArray(source.emissive);
-            material.useAlphaFromDiffuseTexture = source.useAlphaFromDiffuseTexture;
+            material.useAlphaFromAlbedoTexture = source.useAlphaFromAlbedoTexture;
             material.useEmissiveAsIllumination = source.useEmissiveAsIllumination;
-            material.useGlossinessFromSpecularMapAlpha = source.useGlossinessFromSpecularMapAlpha;
+            material.useMicroSurfaceFromReflectivityMapAlpha = source.useMicroSurfaceFromReflectivityMapAlpha;
             material.useSpecularOverAlpha = source.useSpecularOverAlpha;
             
             material.emissiveFresnelParameters = FresnelParameters.Parse(source.emissiveFresnelParameters);

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

@@ -6,7 +6,7 @@
 
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
-uniform vec4 vDiffuseColor;
+uniform vec4 vAlbedoColor;
 uniform vec3 vReflectionColor;
 
 // CUSTOM CONTROLS
@@ -16,11 +16,11 @@ uniform vec4 vCameraInfos;
 #ifdef OVERLOADEDVALUES
 uniform vec4 vOverloadedIntensity;
 uniform vec3 vOverloadedAmbient;
-uniform vec3 vOverloadedDiffuse;
-uniform vec3 vOverloadedSpecular;
+uniform vec3 vOverloadedAlbedo;
+uniform vec3 vOverloadedReflectivity;
 uniform vec3 vOverloadedEmissive;
 uniform vec3 vOverloadedReflection;
-uniform vec3 vOverloadedGlossiness;
+uniform vec3 vOverloadedMicroSurface;
 #endif
 
 #ifdef OVERLOADEDSHADOWVALUES
@@ -113,17 +113,17 @@ float computeDiffuseTerm(float NdotL, float NdotV, float VdotH, float roughness)
     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)
@@ -174,9 +174,7 @@ vec3 toGammaSpace(vec3 color)
 #endif
 // END PBR HELPER METHODS
 
-#ifdef SPECULARTERM
-uniform vec4 vSpecularColor;
-#endif
+uniform vec4 vReflectivityColor;
 uniform vec3 vEmissiveColor;
 
 // Input
@@ -284,10 +282,10 @@ uniform vec3 vLightGround3;
 #endif
 
 // Samplers
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform sampler2D diffuseSampler;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform sampler2D albedoSampler;
+uniform vec2 vAlbedoInfos;
 #endif
 
 #ifdef AMBIENT
@@ -314,10 +312,10 @@ uniform vec2 vLightmapInfos;
 uniform sampler2D lightmapSampler;
 #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
 
 #ifdef CLIPPLANE
@@ -446,13 +444,13 @@ void main(void) {
 
     // Base color
     vec4 baseColor = vec4(1., 1., 1., 1.);
-    vec3 diffuseColor = vDiffuseColor.rgb;
+    vec3 diffuseColor = vAlbedoColor.rgb;
     
     // 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);
 
 #ifdef ALPHATEST
@@ -460,11 +458,11 @@ void main(void) {
         discard;
 #endif
 
-#ifdef ALPHAFROMDIFFUSE
+#ifdef ALPHAFROMALBEDO
     alpha *= baseColor.a;
 #endif
 
-    baseColor.rgb *= vDiffuseInfos.y;
+    baseColor.rgb *= vAlbedoInfos.y;
 #endif
 
 #ifdef VERTEXCOLOR
@@ -472,8 +470,8 @@ void main(void) {
 #endif
 
 #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
 
     // Bump
@@ -493,57 +491,45 @@ void main(void) {
     #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
-        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
     #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
-                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+                reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
         #endif
 
-        #ifdef GLOSSINESSFROMSPECULARMAP
-            glossiness = specularMapColor.a;
+        #ifdef MICROSURFACEFROMREFLECTIVITYMAP
+            microSurface = reflectivityMapColor.a;
         #else
-            glossiness = computeDefaultGlossiness(glossiness, specularColor);
+            microSurface = computeDefaultMicroSurface(microSurface, reflectivityColor);
         #endif
     #endif
 
     #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
 
     // 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;
 
     // Compute Specular Fresnel + Reflectance.
     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.
-    float rough = clamp(1. - glossiness, 0.000001, 1.0);
+    float rough = clamp(1. - microSurface, 0.000001, 1.0);
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
@@ -664,15 +650,15 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
 reflectionColor *= 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
-    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
 
 #ifdef OPACITY
@@ -704,21 +690,21 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 
     // Composition
 #ifdef EMISSIVEASILLUMINATION
-    vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    vec3 finalDiffuse = max(diffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
 
     #ifdef OVERLOADEDSHADOWVALUES
-        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
 #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
-                shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+                shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
     #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
-            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
     #endif
 #endif
@@ -732,7 +718,7 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 
 #ifdef SPECULARTERM
-    vec3 finalSpecular = specularBase * specularColor;
+    vec3 finalSpecular = specularBase * reflectivityColor * vLightingIntensity.w;
 #else
     vec3 finalSpecular = vec3(0.0);
 #endif

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

@@ -29,10 +29,10 @@ uniform mat4 world;
 uniform mat4 view;
 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
 
 #ifdef AMBIENT
@@ -53,10 +53,10 @@ uniform vec2 vEmissiveInfos;
 uniform mat4 emissiveMatrix;
 #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
 
 // Output
@@ -119,14 +119,14 @@ void main(void) {
 	vec2 uv2 = vec2(0., 0.);
 #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
 	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+		vAlbedoUV = vec2(albedoMatrix * vec4(uv2, 1.0, 0.0));
 	}
 #endif
 
@@ -163,14 +163,14 @@ void main(void) {
 	}
 #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
 	{
-		vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
+		vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2, 1.0, 0.0));
 	}
 #endif
 

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

@@ -15,7 +15,7 @@ precision highp float;
 uniform vec3 vEyePosition;
 uniform vec3 vAmbientColor;
 uniform vec3 vReflectionColor;
-uniform vec4 vDiffuseColor;
+uniform vec4 vAlbedoColor;
 
 // CUSTOM CONTROLS
 uniform vec4 vLightingIntensity;
@@ -24,11 +24,11 @@ uniform vec4 vCameraInfos;
 #ifdef OVERLOADEDVALUES
     uniform vec4 vOverloadedIntensity;
     uniform vec3 vOverloadedAmbient;
-    uniform vec3 vOverloadedDiffuse;
-    uniform vec3 vOverloadedSpecular;
+    uniform vec3 vOverloadedAlbedo;
+    uniform vec3 vOverloadedReflectivity;
     uniform vec3 vOverloadedEmissive;
     uniform vec3 vOverloadedReflection;
-    uniform vec3 vOverloadedGlossiness;
+    uniform vec3 vOverloadedMicroSurface;
 #endif
 
 #ifdef OVERLOADEDSHADOWVALUES
@@ -124,15 +124,15 @@ float computeDiffuseTerm(float NdotL, float NdotV, float VdotH, float roughness)
     // 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)
@@ -185,10 +185,8 @@ vec3 toGammaSpace(vec3 color)
 #endif
 // END PBR HELPER METHODS
 
-#ifdef SPECULARTERM
-uniform vec4 vSpecularColor;
-#endif
-uniform vec3 vEmissiveColor;
+    uniform vec4 vReflectivityColor;
+    uniform vec3 vEmissiveColor;
 
 // Input
 varying vec3 vPositionW;
@@ -295,10 +293,10 @@ uniform vec3 vLightGround3;
 #endif
 
 // Samplers
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform sampler2D diffuseSampler;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform sampler2D albedoSampler;
+uniform vec2 vAlbedoInfos;
 #endif
 
 #ifdef AMBIENT
@@ -325,10 +323,10 @@ uniform vec2 vLightmapInfos;
 uniform sampler2D lightmapSampler;
 #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
 
 // Fresnel
@@ -438,16 +436,18 @@ float unpack(vec4 color)
 }
 
 #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+uniform vec2 depthValues;
+
 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)
     {
@@ -462,13 +462,14 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 
 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.;
 
@@ -800,13 +801,13 @@ void main(void) {
 
     // Base color
     vec4 baseColor = vec4(1., 1., 1., 1.);
-    vec3 diffuseColor = vDiffuseColor.rgb;
+    vec3 albedoColor = vAlbedoColor.rgb;
     
     // 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);
 
 #ifdef ALPHATEST
@@ -814,11 +815,11 @@ void main(void) {
         discard;
 #endif
 
-#ifdef ALPHAFROMDIFFUSE
+#ifdef ALPHAFROMALBEDO
     alpha *= baseColor.a;
 #endif
 
-    baseColor.rgb *= vDiffuseInfos.y;
+    baseColor.rgb *= vAlbedoInfos.y;
 #endif
 
 #ifdef VERTEXCOLOR
@@ -826,8 +827,8 @@ void main(void) {
 #endif
 
 #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
 
     // Bump
@@ -854,56 +855,44 @@ void main(void) {
 #endif
 
     // Specular map
-#ifdef SPECULARTERM
-    float glossiness = vSpecularColor.a;
-    vec3 specularColor = vSpecularColor.rgb;
+    float microSurface = vReflectivityColor.a;
+    vec3 reflectivityColor = vReflectivityColor.rgb;
     
     #ifdef OVERLOADEDVALUES
-        specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+        reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
     #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
-                specularColor.rgb = mix(specularColor.rgb, vOverloadedSpecular, vOverloadedIntensity.z);
+                reflectivityColor.rgb = mix(reflectivityColor.rgb, vOverloadedReflectivity, vOverloadedIntensity.z);
         #endif
 
-        #ifdef GLOSSINESSFROMSPECULARMAP
-            glossiness = specularMapColor.a;
+        #ifdef MICROSURFACEFROMREFLECTIVITYMAP
+            microSurface = reflectivityMapColor.a;
         #else
-            glossiness = computeDefaultGlossiness(glossiness, specularColor);
+            microSurface = computeDefaultMicroSurface(microSurface, reflectivityColor);
         #endif
     #endif
 
     #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
 
     // 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;
 
     // Compute Specular Fresnel + Reflectance.
     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.
-    float rough = clamp(1. - glossiness, 0.000001, 1.0);
+    float rough = clamp(1. - microSurface, 0.000001, 1.0);
 
     // Lighting
     vec3 diffuseBase = vec3(0., 0., 0.);
@@ -1104,12 +1093,8 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
     vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
 
     #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 = toLinearSpace(reflectionColor.rgb);
@@ -1134,17 +1119,17 @@ vec3 ambientReflectionColor = vReflectionColor.rgb;
 #endif
 
 #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
 
 reflectionColor *= vLightingIntensity.z;
 ambientReflectionColor *= vLightingIntensity.z;
 
 // Compute reflection specular fresnel
-vec3 specularEnvironmentR0 = specularColor.rgb;
+vec3 specularEnvironmentR0 = reflectivityColor.rgb;
 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;
 
 #ifdef OPACITY
@@ -1188,23 +1173,23 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 
     // Composition
 #ifdef EMISSIVEASILLUMINATION
-    vec3 finalDiffuse = max(diffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+    vec3 finalDiffuse = max(diffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     
     #ifdef OVERLOADEDSHADOWVALUES
-        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+        shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
     #endif
 #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
-            shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max((shadowedOnlyDiffuseBase + emissiveColor) * albedoColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
     #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
-            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
+            shadowedOnlyDiffuseBase = max(shadowedOnlyDiffuseBase * albedoColor + emissiveColor + vAmbientColor, 0.0) * baseColor.rgb;
         #endif
     #endif
 #endif
@@ -1218,7 +1203,7 @@ reflectionColor *= specularEnvironmentReflectanceViewer;
 finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
 
 #ifdef SPECULARTERM
-    vec3 finalSpecular = specularBase * specularColor;
+    vec3 finalSpecular = specularBase * reflectivityColor * vLightingIntensity.w;
 #else
     vec3 finalSpecular = vec3(0.0);
 #endif
@@ -1279,13 +1264,13 @@ finalDiffuse += baseColor.rgb * ambientReflectionColor * 0.2;
     // gl_FragColor = vec4(baseColor.rgb, 1.0);
 
     // 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
-    // gl_FragColor = vec4(specularMapColor.rgb, 1.0);
+    // gl_FragColor = vec4(reflectivityMapColor.rgb, 1.0);
 
     //// Emissive Color
     //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 viewProjection;
 
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform mat4 diffuseMatrix;
-uniform vec2 vDiffuseInfos;
+#ifdef ALBEDO
+varying vec2 vAlbedoUV;
+uniform mat4 albedoMatrix;
+uniform vec2 vAlbedoInfos;
 #endif
 
 #ifdef AMBIENT
@@ -69,10 +69,10 @@ uniform vec2 vLightmapInfos;
 uniform mat4 lightmapMatrix;
 #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
 
 #ifdef BUMP
@@ -199,14 +199,14 @@ void main(void) {
     vec2 uv2 = vec2(0., 0.);
 #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
     {
-        vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+        vAlbedoUV = vec2(albedoMatrix * vec4(uv2, 1.0, 0.0));
     }
 #endif
 
@@ -254,14 +254,14 @@ void main(void) {
     }
 #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
     {
-        vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
+        vReflectivityUV = vec2(reflectivityMatrix * vec4(uv2, 1.0, 0.0));
     }
 #endif
 

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

@@ -353,7 +353,7 @@ module BABYLON {
                         "vDiffuseInfos", 
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
-                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3"
+                        "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                     ],
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
@@ -420,6 +420,7 @@ module BABYLON {
 
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
+                var depthValuesAlreadySet = false;
                 for (var index = 0; index < scene.lights.length; index++) {
                     var light = scene.lights[index];
 
@@ -452,7 +453,14 @@ module BABYLON {
                     if (scene.shadowsEnabled) {
                         var shadowGenerator = light.getShadowGenerator();
                         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.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
                         }

文件差异内容过多而无法显示
+ 560 - 555
materialsLibrary/materials/simple/simple.fragment.fx


文件差异内容过多而无法显示
+ 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
+}

文件差异内容过多而无法显示
+ 695 - 693
materialsLibrary/materials/water/water.fragment.fx


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

@@ -1,29 +1,30 @@
 window.preparePBR = function() {
 	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.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() {
 		setRangeValues({
 		  "directIntensity": 1,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 1,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "cameraExposure": 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() {
@@ -31,18 +32,19 @@ window.preparePBR = function() {
 		  "directIntensity": 1.3439461727881254,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1,
 		  "ShadeIntensity": 1,
 		  "cameraExposure": 0.7153261887420668,
 		  "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() {
@@ -50,18 +52,19 @@ window.preparePBR = function() {
 		  "directIntensity": 0.9971213540040931,
 		  "emissiveIntensity": 1,
 		  "environmentIntensity": 0.3685013699580344,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 0.975444802830091,
 		  "ShadeIntensity": 0.8020323934380749,
 		  "cameraExposure": 0.7586792910900708,
 		  "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() {
@@ -69,18 +72,19 @@ window.preparePBR = function() {
 		  "directIntensity": 1.2355634169181153,
 		  "emissiveIntensity": 0.910415149308085,
 		  "environmentIntensity": 0.21676551174002023,
+		  "specularIntensity": 1,
 		  "ShadowIntensity": 1.018797905178095,
 		  "ShadeIntensity": 0.975444802830091,
 		  "cameraExposure": 1.0621510075260991,
 		  "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() {
 		return pbr.environmentIntensity;
 	});
+
+	registerRangeUI("pbr", "specularIntensity", 0, 2, function(value) {
+		pbr.specularIntensity = value;
+	}, function() {
+		return pbr.specularIntensity;
+	});
 	
 	registerRangeUI("pbr", "ShadowIntensity", 0, 2, function(value) {
 		pbr.overloadedShadowIntensity = value;
@@ -126,52 +136,52 @@ window.preparePBR = function() {
 		return pbr.cameraContrast;
 	});
 	
-	registerRangeUI("pbr", "glossiness", 0, 1, function(value) {
-		pbr.glossiness = value;
+	registerRangeUI("pbr", "microSurface", 0, 1, function(value) {
+		pbr.microSurface = value;
 	}, 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() {
-		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() {
-		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() {
-		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() {
-		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() {
-		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() {
-		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() {
-		return pbr.overloadedDiffuseIntensity;
+		return pbr.overloadedAlbedoIntensity;
 	});
 
 	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;
+};

文件差异内容过多而无法显示
+ 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.pbrMaterial.js"></script>
 	<script src="../dist/babylon.furMaterial.js"></script>
+	<script src="../dist/babylon.triPlanarMaterial.js"></script>
 
 	<style>
 		html, body {
@@ -53,6 +54,7 @@
 	<script src="add/addfur.js"></script>
 	<script src="add/addterrain.js"></script>
 	<script src="add/addfire.js"></script>
+	<script src="add/addtriplanar.js"></script>
 	
 	<script>
 		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);
 			camera.attachControl(canvas, true);
+			camera.minZ = 0.1;
 
 			// Lights
 			var hemisphericLight = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
@@ -75,7 +78,7 @@
 			spotLight.setEnabled(false);
 
 			// 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);
 			plane.setEnabled(false);
@@ -135,7 +138,8 @@
 				
 				var shadowGenerator3 = new BABYLON.ShadowGenerator(1024, pointLight);
 				shadowGenerator3.getShadowMap().renderList.push(shadowCaster3);
-				shadowGenerator3.usePoissonSampling = true;
+				shadowGenerator3.usePoissonSampling = false;
+				shadowGenerator3.bias = 0;
 
 				// Register a render loop to repeatedly render the scene
 				engine.runRenderLoop(function () {
@@ -190,13 +194,15 @@
 				var terrain = prepareTerrain();
 				
 				var pbr = preparePBR();
-								
+				
+				var triPlanar = prepareTriPlanar();
+				
 				// Default to std
 				var currentMaterial = std;
 				sphere.material = std;				
 				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);
 					
 					switch (options.material) {
@@ -225,7 +231,10 @@
 							break;
 						case "fur":
 							currentMaterial = fur;
-							break;														
+							break;
+						case "triPlanar":
+							currentMaterial = triPlanar;
+							break;
 						default:
 							currentMaterial = std;
 							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)
 
 ## 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)
 

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

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

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

@@ -491,6 +491,7 @@
                     case Animation.ANIMATIONTYPE_QUATERNION:
                     case Animation.ANIMATIONTYPE_MATRIX:
                     case Animation.ANIMATIONTYPE_VECTOR3:
+                    case Animation.ANIMATIONTYPE_COLOR3:
                         key.values = animationKey.value.asArray();
                         break;
                 }
@@ -568,6 +569,9 @@
                     case Animation.ANIMATIONTYPE_MATRIX:
                         data = Matrix.FromArray(key.values);
                         break;
+                    case Animation.ANIMATIONTYPE_COLOR3:
+                        data = Color3.FromArray(key.values);
+                        break;
                     case Animation.ANIMATIONTYPE_VECTOR3:
                     default:
                         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);
                     var material = subMesh.getMaterial();
                     _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
                     if (material && material.needAlphaTesting()) {
                         var alphaTexture = material.getAlphaTestTexture();
@@ -225,6 +229,9 @@ var BABYLON;
             if (this.useVarianceShadowMap || this.useBlurVarianceShadowMap) {
                 defines.push("#define VSM");
             }
+            if (this.getLight().needCube()) {
+                defines.push("#define CUBEMAP");
+            }
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var mesh = subMesh.getMesh();
             var material = subMesh.getMaterial();
@@ -266,7 +273,7 @@ var BABYLON;
             var join = defines.join("\n");
             if (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();
         };
@@ -293,7 +300,7 @@ var BABYLON;
             var lightPosition = this._light.position;
             BABYLON.Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
             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()) {
                 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)) {
                 this._cachedPosition = lightPosition.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._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
             }

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

@@ -190,6 +190,11 @@
                     var material = subMesh.getMaterial();
 
                     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
                     if (material && material.needAlphaTesting()) {
@@ -246,6 +251,10 @@
                 defines.push("#define VSM");
             }
 
+            if (this.getLight().needCube()) {
+                defines.push("#define CUBEMAP");
+            }
+
             var attribs = [VertexBuffer.PositionKind];
 
             var mesh = subMesh.getMesh();
@@ -293,7 +302,7 @@
                 this._cachedDefines = join;
                 this._effect = this._scene.getEngine().createEffect("shadowMap",
                     attribs,
-                    ["world", "mBones", "viewProjection", "diffuseMatrix"],
+                    ["world", "mBones", "viewProjection", "diffuseMatrix", "lightPosition", "depthValues"],
                     ["diffuseSampler"], join);
             }
 
@@ -330,7 +339,7 @@
             Vector3.NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
 
             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()) {
@@ -342,7 +351,7 @@
                 this._cachedPosition = lightPosition.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);
 

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

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

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

@@ -268,6 +268,7 @@ var BABYLON;
         };
         StandardMaterial.BindLights = function (scene, mesh, effect, defines) {
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
                 if (!light.isEnabled()) {
@@ -305,6 +306,12 @@ var BABYLON;
                         if (!light.needCube()) {
                             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.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",
                     "mBones",
                     "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",
                     "logarithmicDepthConstant"
                 ], ["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();
         public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: MaterialDefines) {
             var lightIndex = 0;
+            var depthValuesAlreadySet = false;
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
 
@@ -356,6 +357,11 @@
                     if (mesh.receiveShadows && shadowGenerator) {
                         if (!(<any>light).needCube()) {
                             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.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
@@ -755,7 +761,7 @@
                         "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos",
                         "mBones",
                         "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",
                         "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)
+uniform vec2 depthValues;
+
 float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	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;
 

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

@@ -27,14 +27,28 @@ varying vec2 vUV;
 uniform sampler2D diffuseSampler;
 #endif
 
+#ifdef CUBEMAP
+uniform vec3 lightPosition;
+uniform vec2 depthValues;
+#endif
+
 void main(void)
 {
 #ifdef ALPHATEST
 	if (texture2D(diffuseSampler, vUV).a < 0.4)
 		discard;
 #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;
 	depth = depth * 0.5 + 0.5;
+#endif
 
 #ifdef VSM
 	float moment1 = depth;

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

@@ -77,8 +77,14 @@ void main(void)
 
 	finalWorld = finalWorld * influence;
 #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;
+#endif
 
 #ifdef ALPHATEST
 #ifdef UV1