Browse Source

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 8 years ago
parent
commit
c7671c735a
87 changed files with 5499 additions and 5740 deletions
  1. 21 0
      Playground/debug.html
  2. 21 0
      Playground/index-local.html
  3. 64 0
      Playground/index.css
  4. 21 0
      Playground/index.html
  5. 81 10
      Playground/index.js
  6. 1 1
      Playground/package.json
  7. 21 21
      Tools/Gulp/config.json
  8. 187 184
      Tools/Gulp/custom.config.json
  9. 240 0
      Tools/Gulp/profiling.html
  10. 24 24
      dist/preview release/babylon.core.js
  11. 1278 1276
      dist/preview release/babylon.d.ts
  12. 33 33
      dist/preview release/babylon.js
  13. 459 451
      dist/preview release/babylon.max.js
  14. 1278 1276
      dist/preview release/babylon.module.d.ts
  15. 33 33
      dist/preview release/babylon.noworker.js
  16. 2 2
      dist/preview release/inspector/babylon.inspector.bundle.js
  17. 1 4
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  18. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  19. 8 8
      dist/preview release/materialsLibrary/babylon.furMaterial.d.ts
  20. 105 140
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  21. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  22. 5 7
      dist/preview release/materialsLibrary/babylon.gradientMaterial.d.ts
  23. 55 102
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  25. 3 7
      dist/preview release/materialsLibrary/babylon.gridMaterial.d.ts
  26. 37 49
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  27. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  28. 6 7
      dist/preview release/materialsLibrary/babylon.lavaMaterial.d.ts
  29. 83 118
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  31. 7 7
      dist/preview release/materialsLibrary/babylon.normalMaterial.d.ts
  32. 79 112
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  33. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  34. 3 7
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.d.ts
  35. 42 75
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  37. 2 9
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  39. 3 7
      dist/preview release/materialsLibrary/babylon.skyMaterial.d.ts
  40. 40 63
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  41. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.min.js
  42. 12 7
      dist/preview release/materialsLibrary/babylon.terrainMaterial.d.ts
  43. 112 135
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  44. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  45. 17 13
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.d.ts
  46. 112 127
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  47. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  48. 9 7
      dist/preview release/materialsLibrary/babylon.waterMaterial.d.ts
  49. 119 148
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  50. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  51. 5 0
      localDev/src/index.js
  52. 2 6
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  53. 108 156
      materialsLibrary/src/fur/babylon.furMaterial.ts
  54. 5 0
      materialsLibrary/src/fur/fur.fragment.fx
  55. 6 2
      materialsLibrary/src/fur/fur.vertex.fx
  56. 56 117
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  57. 36 52
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  58. 84 132
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  59. 81 126
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  60. 46 85
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  61. 2 10
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  62. 44 71
      materialsLibrary/src/sky/babylon.skyMaterial.ts
  63. 115 156
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts
  64. 116 150
      materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts
  65. 124 167
      materialsLibrary/src/water/babylon.waterMaterial.ts
  66. 0 0
      src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts
  67. 0 0
      src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts
  68. 0 0
      src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts
  69. 0 0
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  70. 0 0
      src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts
  71. 0 0
      src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts
  72. 0 0
      src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts
  73. 0 0
      src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts
  74. 0 0
      src/Cameras/Inputs/babylon.freeCameraMouseInput.ts
  75. 0 0
      src/Cameras/Inputs/babylon.freeCameraTouchInput.ts
  76. 0 0
      src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.ts
  77. 5 0
      src/Materials/babylon.material.ts
  78. 22 11
      src/Materials/babylon.materialHelper.ts
  79. 3 16
      src/Materials/babylon.standardMaterial.ts
  80. 0 0
      src/Tools/HDR/babylon.cubemapToSphericalPolynomial.ts
  81. 0 0
      src/Tools/HDR/babylon.hdr.ts
  82. 0 0
      src/Tools/HDR/babylon.panoramaToCubemap.ts
  83. 0 0
      src/Tools/HDR/babylon.pmremgenerator.ts
  84. 0 0
      src/Tools/babylon.dds.ts
  85. 1 1
      src/Tools/babylon.filesInput.ts
  86. 0 0
      src/Tools/babylon.tga.ts
  87. 2 0
      src/babylon.engine.ts

+ 21 - 0
Playground/debug.html

@@ -95,6 +95,9 @@
                 </a>
                 </a>
                 <ul class="dropdown-menu" id="scriptsList"></ul>
                 <ul class="dropdown-menu" id="scriptsList"></ul>
             </div>
             </div>
+            <div class="save-message" id="saveMessage">
+                This PG has no metadata. Click save to add them.
+            </div>
         </div>
         </div>
     </div>
     </div>
 
 
@@ -125,6 +128,24 @@
         </div>
         </div>
     </div>
     </div>
 
 
+    <div id="saveLayer" class="save-layer">
+        <div class="save-form">
+            <label for="saveFormTitle">TITLE</label>
+            <div class="separator"></div>
+            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+            <label for="saveFormDescription">DESCRIPTION</label>
+            <div class="separator"></div>
+            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+            <label for="saveFormTags">TAGS (separated by comma)</label>
+            <div class="separator"></div>
+            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+            <div class="save-form-buttons">
+                <button class="btn save-form-button" id="saveFormButtonOk">OK</button>
+                <button class="btn save-form-button" id="saveFormButtonCancel">Cancel</button>
+            </div>
+        </div>
+    </div>
+
     <script src="https://code.jquery.com/jquery.js"></script>
     <script src="https://code.jquery.com/jquery.js"></script>
     <script src="bootstrap/js/bootstrap.js"></script>
     <script src="bootstrap/js/bootstrap.js"></script>
     <script src="index.js"></script>
     <script src="index.js"></script>

+ 21 - 0
Playground/index-local.html

@@ -65,6 +65,9 @@
                 <ul class="dropdown-menu" id="scriptsList"></ul>
                 <ul class="dropdown-menu" id="scriptsList"></ul>
             </div>
             </div>
         </div>
         </div>
+        <div class="save-message" id="saveMessage">
+            This PG has no metadata. Click save to add them.
+        </div>
     </div>
     </div>
 
 
     <x-splitbox>
     <x-splitbox>
@@ -94,6 +97,24 @@
         </div>
         </div>
     </div>
     </div>
 
 
+    <div id="saveLayer" class="save-layer">
+        <div class="save-form">
+            <label for="saveFormTitle">TITLE</label>
+            <div class="separator"></div>
+            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+            <label for="saveFormDescription">DESCRIPTION</label>
+            <div class="separator"></div>
+            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+            <label for="saveFormTags">TAGS (separated by comma)</label>
+            <div class="separator"></div>
+            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+            <div class="save-form-buttons">
+                <button class="btn save-form-button" id="saveFormButtonOk">OK</button>
+                <button class="btn save-form-button" id="saveFormButtonCancel">Cancel</button>
+            </div>
+        </div>
+    </div>
+
     <script src="http://code.jquery.com/jquery.js"></script>
     <script src="http://code.jquery.com/jquery.js"></script>
     <script src="bootstrap/js/bootstrap.min.js"></script>
     <script src="bootstrap/js/bootstrap.min.js"></script>
     <script>
     <script>

+ 64 - 0
Playground/index.css

@@ -122,3 +122,67 @@ ul#scriptsList {
 .monaco-editor .invisible {
 .monaco-editor .invisible {
     visibility: visible;
     visibility: visible;
 }
 }
+
+
+/* Save form & co */
+
+.save-message {
+    display: none;
+    float: left;
+    width: 100%;
+    background-color: rgba(0,0,0,.5);
+    text-align: center;
+    color: white;
+    font-size: 1.1em;
+    line-height: 2em;
+}
+
+.save-layer {
+    display: none;
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    background-color: rgba(120,120,120,.5);
+    text-align: center;
+}
+.save-layer .save-form {
+    position: absolute;
+    top: 150px;
+    left: calc(50% - 205px);
+
+    width: 410px;
+    height: 390px;
+    padding-top: 15px;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+
+    background-color: rgba(27,27,27,0.75);/*#1b1b1b;*/
+    background-image: -moz-linear-gradient(top,rgba(34,34,34,.75),rgba(17,17,17,.75));
+    background-image: -webkit-gradient(linear,0 0,0 100%,from(rgba(34,34,34,.75)),to(rgba(17,17,17,.75)));
+    background-image: -webkit-linear-gradient(top,rgba(34,34,34,.75),rgba(17,17,17,.75));
+    background-image: -o-linear-gradient(top,rgba(34,34,34,.75),rgba(17,17,17,.75));
+    background-image: linear-gradient(to bottom,rgba(34,34,34,.75),rgba(17,17,17,.75));
+    background-repeat: repeat-x;
+    border-color: #252525;
+    color: white;
+    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+    font-size: 14px;
+}
+.save-layer .save-form .separator {
+    width: 350px;
+    border-bottom: 1px solid #999;
+    margin: auto;
+    margin-top: -6px;
+    margin-bottom: 10px;
+}
+.save-layer .save-form .save-form-buttons {
+    margin-top: 10px;
+}
+.save-layer .save-form input, .save-layer .save-form textarea {
+    width: 350px;
+}

+ 21 - 0
Playground/index.html

@@ -107,6 +107,9 @@
                 <ul class="dropdown-menu" id="scriptsList"></ul>
                 <ul class="dropdown-menu" id="scriptsList"></ul>
             </div>
             </div>
         </div>
         </div>
+        <div class="save-message" id="saveMessage">
+            This PG has no metadata. Click save to add them.
+        </div>
     </div>
     </div>
 
 
     <x-splitbox>
     <x-splitbox>
@@ -136,6 +139,24 @@
         </div>
         </div>
     </div>
     </div>
 
 
+    <div id="saveLayer" class="save-layer">
+        <div class="save-form">
+            <label for="saveFormTitle">TITLE</label>
+            <div class="separator"></div>
+            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+            <label for="saveFormDescription">DESCRIPTION</label>
+            <div class="separator"></div>
+            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+            <label for="saveFormTags">TAGS (separated by comma)</label>
+            <div class="separator"></div>
+            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+            <div class="save-form-buttons">
+                <button class="btn save-form-button" id="saveFormButtonOk">OK</button>
+                <button class="btn save-form-button" id="saveFormButtonCancel">Cancel</button>
+            </div>
+        </div>
+    </div>
+
     <script src="https://code.jquery.com/jquery.js"></script>
     <script src="https://code.jquery.com/jquery.js"></script>
     <script src="bootstrap/js/bootstrap.min.js"></script>
     <script src="bootstrap/js/bootstrap.min.js"></script>
     <script src="index.js"></script>
     <script src="index.js"></script>

File diff suppressed because it is too large
+ 81 - 10
Playground/index.js


+ 1 - 1
Playground/package.json

@@ -4,7 +4,7 @@
   "description": "Babylon.js is a 3D engine based on webgl and javascript",
   "description": "Babylon.js is a 3D engine based on webgl and javascript",
   "main": "",
   "main": "",
   "repository": { "url": "https://github.com/BabylonJS/Babylon.js/" },
   "repository": { "url": "https://github.com/BabylonJS/Babylon.js/" },
-  "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
+  "readme": "https://github.com/BabylonJS/Babylon.js/blob/master/readme.md",
   "license": "(Apache-2.0)",
   "license": "(Apache-2.0)",
   "devDependencies": {
   "devDependencies": {
     "monaco-editor": "^0.7.0"
     "monaco-editor": "^0.7.0"

+ 21 - 21
Tools/Gulp/config.json

@@ -20,13 +20,14 @@
             "../../src/Tools/babylon.decorators.js",
             "../../src/Tools/babylon.decorators.js",
             "../../src/Tools/babylon.observable.js",
             "../../src/Tools/babylon.observable.js",
             "../../src/Tools/babylon.database.js",
             "../../src/Tools/babylon.database.js",
-            "../../src/Tools/babylon.tools.tga.js",
+            "../../src/Tools/babylon.tga.js",
             "../../src/Tools/babylon.smartArray.js",
             "../../src/Tools/babylon.smartArray.js",
             "../../src/Tools/babylon.stringDictionary.js",
             "../../src/Tools/babylon.stringDictionary.js",
             "../../src/Tools/babylon.tools.js",
             "../../src/Tools/babylon.tools.js",
             "../../src/States/babylon.alphaCullingState.js",
             "../../src/States/babylon.alphaCullingState.js",
             "../../src/States/babylon.depthCullingState.js",
             "../../src/States/babylon.depthCullingState.js",
             "../../src/States/babylon.stencilState.js",
             "../../src/States/babylon.stencilState.js",
+            "../../src/Tools/babylon.loadingScreen.js",
             "../../src/babylon.engine.js",
             "../../src/babylon.engine.js",
             "../../src/babylon.node.js",
             "../../src/babylon.node.js",
             "../../src/Tools/babylon.filesInput.js",
             "../../src/Tools/babylon.filesInput.js",
@@ -47,16 +48,16 @@
             "../../src/Collisions/babylon.collisionCoordinator.js",
             "../../src/Collisions/babylon.collisionCoordinator.js",
             "../../src/Cameras/babylon.camera.js",
             "../../src/Cameras/babylon.camera.js",
             "../../src/Cameras/babylon.cameraInputsManager.js",
             "../../src/Cameras/babylon.cameraInputsManager.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.mouse.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.keyboard.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.touch.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.deviceorientation.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.gamepad.js",
-            "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.keyboard.js",
-            "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.js",
-            "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js",
-            "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.js",
-            "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.vrdeviceorientation.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraMouseInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraTouchInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraGamepadInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.js",
             "../../src/Cameras/babylon.targetCamera.js",
             "../../src/Cameras/babylon.targetCamera.js",
             "../../src/Cameras/babylon.freeCamera.js",
             "../../src/Cameras/babylon.freeCamera.js",
             "../../src/Cameras/babylon.freeCameraInputsManager.js",
             "../../src/Cameras/babylon.freeCameraInputsManager.js",
@@ -66,6 +67,9 @@
             "../../src/Cameras/babylon.arcRotateCameraInputsManager.js",
             "../../src/Cameras/babylon.arcRotateCameraInputsManager.js",
             "../../src/Rendering/babylon.renderingManager.js",
             "../../src/Rendering/babylon.renderingManager.js",
             "../../src/Rendering/babylon.renderingGroup.js",
             "../../src/Rendering/babylon.renderingGroup.js",
+            "../../src/PostProcess/babylon.postProcessManager.js",
+            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js",
+            "../../src/Rendering/babylon.boundingBoxRenderer.js",
             "../../src/babylon.scene.js",
             "../../src/babylon.scene.js",
             "../../src/Mesh/babylon.buffer.js",
             "../../src/Mesh/babylon.buffer.js",
             "../../src/Mesh/babylon.vertexBuffer.js",
             "../../src/Mesh/babylon.vertexBuffer.js",
@@ -105,7 +109,6 @@
             "../../src/Bones/babylon.boneLookController.js",
             "../../src/Bones/babylon.boneLookController.js",
             "../../src/Bones/babylon.skeleton.js",
             "../../src/Bones/babylon.skeleton.js",
             "../../src/PostProcess/babylon.postProcess.js",
             "../../src/PostProcess/babylon.postProcess.js",
-            "../../src/PostProcess/babylon.postProcessManager.js",
             "../../src/PostProcess/babylon.passPostProcess.js",
             "../../src/PostProcess/babylon.passPostProcess.js",
             "../../src/Physics/babylon.physicsJoint.js",
             "../../src/Physics/babylon.physicsJoint.js",
             "../../src/Physics/babylon.physicsImpostor.js",
             "../../src/Physics/babylon.physicsImpostor.js",
@@ -116,8 +119,6 @@
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js",
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js",
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js",
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js",
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js",
             "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js",
-            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js",
-            "../../src/Rendering/babylon.boundingBoxRenderer.js",
             "../../src/Actions/babylon.condition.js",
             "../../src/Actions/babylon.condition.js",
             "../../src/Actions/babylon.action.js",
             "../../src/Actions/babylon.action.js",
             "../../src/Actions/babylon.actionManager.js",
             "../../src/Actions/babylon.actionManager.js",
@@ -127,7 +128,6 @@
             "../../src/Mesh/babylon.groundMesh.js",
             "../../src/Mesh/babylon.groundMesh.js",
             "../../src/Mesh/babylon.instancedMesh.js",
             "../../src/Mesh/babylon.instancedMesh.js",
             "../../src/Mesh/babylon.linesMesh.js",
             "../../src/Mesh/babylon.linesMesh.js",
-            "../../src/Tools/babylon.loadingScreen.js",
             "../../src/Audio/babylon.audioEngine.js",
             "../../src/Audio/babylon.audioEngine.js",
             "../../src/Audio/babylon.sound.js",
             "../../src/Audio/babylon.sound.js",
             "../../src/Audio/babylon.soundtrack.js",
             "../../src/Audio/babylon.soundtrack.js",
@@ -164,7 +164,7 @@
             "../../src/Tools/babylon.dynamicFloatArray.js",
             "../../src/Tools/babylon.dynamicFloatArray.js",
             "../../src/Materials/Textures/babylon.mapTexture.js",
             "../../src/Materials/Textures/babylon.mapTexture.js",
             "../../src/Materials/babylon.shaderMaterial.js",
             "../../src/Materials/babylon.shaderMaterial.js",
-            "../../src/Tools/babylon.tools.dds.js",
+            "../../src/Tools/babylon.dds.js",
             "../../src/Tools/babylon.khronosTextureContainer.js",
             "../../src/Tools/babylon.khronosTextureContainer.js",
             "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",
             "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",
             "../../src/Physics/Plugins/babylon.oimoJSPlugin.js",
             "../../src/Physics/Plugins/babylon.oimoJSPlugin.js",
@@ -176,7 +176,7 @@
             "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
             "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
             "../../src/Tools/babylon.virtualJoystick.js",
             "../../src/Tools/babylon.virtualJoystick.js",
             "../../src/Cameras/babylon.virtualJoysticksCamera.js",
             "../../src/Cameras/babylon.virtualJoysticksCamera.js",
-            "../../src/Cameras/Inputs/babylon.freecamera.input.virtualjoystick.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.js",
             "../../src/PostProcess/babylon.anaglyphPostProcess.js",
             "../../src/PostProcess/babylon.anaglyphPostProcess.js",
             "../../src/Rendering/babylon.outlineRenderer.js",
             "../../src/Rendering/babylon.outlineRenderer.js",
             "../../src/Tools/babylon.assetsManager.js",
             "../../src/Tools/babylon.assetsManager.js",
@@ -216,10 +216,10 @@
             "../../src/Probes/babylon.reflectionProbe.js",
             "../../src/Probes/babylon.reflectionProbe.js",
             "../../src/Particles/babylon.solidParticle.js",
             "../../src/Particles/babylon.solidParticle.js",
             "../../src/Particles/babylon.solidParticleSystem.js",
             "../../src/Particles/babylon.solidParticleSystem.js",
-            "../../src/Tools/HDR/babylon.tools.cubemapToSphericalPolynomial.js",
-            "../../src/Tools/HDR/babylon.tools.panoramaToCubemap.js",
-            "../../src/Tools/HDR/babylon.tools.hdr.js",
-            "../../src/Tools/HDR/babylon.tools.pmremgenerator.js",
+            "../../src/Tools/HDR/babylon.cubemapToSphericalPolynomial.js",
+            "../../src/Tools/HDR/babylon.panoramaToCubemap.js",
+            "../../src/Tools/HDR/babylon.hdr.js",
+            "../../src/Tools/HDR/babylon.pmremgenerator.js",
             "../../src/Materials/Textures/babylon.hdrCubeTexture.js",
             "../../src/Materials/Textures/babylon.hdrCubeTexture.js",
             "../../src/Debug/babylon.skeletonViewer.js",
             "../../src/Debug/babylon.skeletonViewer.js",
             "../../src/Debug/babylon.axesViewer.js",
             "../../src/Debug/babylon.axesViewer.js",

+ 187 - 184
Tools/Gulp/custom.config.json

@@ -11,190 +11,193 @@
       "!../../src/**/*.d.ts"
       "!../../src/**/*.d.ts"
     ],
     ],
     "files": [
     "files": [
-      "../../src/Math/babylon.math.js",
-      "../../src/babylon.mixins.js",
-      "../../src/Tools/babylon.decorators.js",
-      "../../src/Tools/babylon.observable.js",
-      "../../src/Tools/babylon.database.js",
-      "../../src/Tools/babylon.tools.tga.js",
-      "../../src/Tools/babylon.smartArray.js",
-      "../../src/Tools/babylon.stringDictionary.js",
-      "../../src/Tools/babylon.tools.js",
-      "../../src/States/babylon.alphaCullingState.js",
-      "../../src/States/babylon.depthCullingState.js",
-      "../../src/States/babylon.stencilState.js",
-      "../../src/babylon.engine.js",
-      "../../src/babylon.node.js",
-      "../../src/Tools/babylon.filesInput.js",
-      "../../src/Collisions/babylon.pickingInfo.js",
-      "../../src/Culling/babylon.boundingSphere.js",
-      "../../src/Culling/babylon.boundingBox.js",
-      "../../src/Culling/babylon.boundingInfo.js",
-      "../../src/Culling/babylon.ray.js",
-      "../../src/Mesh/babylon.abstractMesh.js",
-      "../../src/Lights/babylon.light.js",
-      "../../src/Lights/babylon.pointLight.js",
-      "../../src/Lights/babylon.spotLight.js",
-      "../../src/Lights/babylon.hemisphericLight.js",
-      "../../src/Lights/babylon.directionalLight.js",
-      "../../src/Lights/Shadows/babylon.shadowGenerator.js",
-      "../../src/Collisions/babylon.collider.js",
-      "../../src/Collisions/babylon.collisionCoordinator.js",
-      "../../src/Cameras/babylon.camera.js",
-      "../../src/Cameras/babylon.cameraInputsManager.js",
-      "../../src/Cameras/Inputs/babylon.freecamera.input.mouse.js",
-      "../../src/Cameras/Inputs/babylon.freecamera.input.keyboard.js",
-      "../../src/Cameras/Inputs/babylon.freecamera.input.touch.js",
-      "../../src/Cameras/Inputs/babylon.freecamera.input.deviceorientation.js",
-      "../../src/Cameras/Inputs/babylon.freecamera.input.gamepad.js",
-      "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.keyboard.js",
-      "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.js",
-      "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.js",
-      "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.js",
-      "../../src/Cameras/Inputs/babylon.arcrotatecamera.input.vrdeviceorientation.js",
-      "../../src/Cameras/babylon.targetCamera.js",
-      "../../src/Cameras/babylon.freeCamera.js",
-      "../../src/Cameras/babylon.freeCameraInputsManager.js",
-      "../../src/Cameras/babylon.followCamera.js",
-      "../../src/Cameras/babylon.touchCamera.js",
-      "../../src/Cameras/babylon.arcRotateCamera.js",
-      "../../src/Cameras/babylon.arcRotateCameraInputsManager.js",
-      "../../src/Rendering/babylon.renderingManager.js",
-      "../../src/Rendering/babylon.renderingGroup.js",
-      "../../src/babylon.scene.js",
-      "../../src/Mesh/babylon.buffer.js",
-      "../../src/Mesh/babylon.vertexBuffer.js",
-      "../../src/Mesh/babylon.instancedMesh.js",
-      "../../src/Mesh/babylon.mesh.js",
-      "../../src/Mesh/babylon.subMesh.js",
-      "../../src/Mesh/babylon.meshBuilder.js",
-      "../../src/Materials/Textures/babylon.baseTexture.js",
-      "../../src/Materials/Textures/babylon.texture.js",
-      "../../src/Materials/Textures/babylon.cubeTexture.js",
-      "../../src/Materials/Textures/babylon.renderTargetTexture.js",
-      "../../src/Materials/Textures/Procedurals/babylon.proceduralTexture.js",
-      "../../src/Materials/Textures/babylon.mirrorTexture.js",
-      "../../src/Materials/Textures/babylon.refractionTexture.js",
-      "../../src/Materials/Textures/babylon.dynamicTexture.js",
-      "../../src/Materials/Textures/babylon.videoTexture.js",
-      "../../src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js",
-      "../../src/Materials/babylon.effect.js",
-      "../../src/Materials/babylon.materialHelper.js",
-      "../../src/Materials/babylon.fresnelParameters.js",
-      "../../src/Materials/babylon.material.js",
-      "../../src/Materials/babylon.pushMaterial.js",
-      "../../src/Materials/babylon.standardMaterial.js",
-      "../../src/Materials/babylon.multiMaterial.js",
-      "../../src/Loading/babylon.sceneLoader.js",
-      "../../src/Loading/Plugins/babylon.babylonFileLoader.js",
-      "../../src/Sprites/babylon.spriteManager.js",
-      "../../src/Sprites/babylon.sprite.js",
-      "../../src/Layer/babylon.layer.js",
-      "../../src/Particles/babylon.particle.js",
-      "../../src/Particles/babylon.particleSystem.js",
-      "../../src/Animations/babylon.animation.js",
-      "../../src/Animations/babylon.animatable.js",
-      "../../src/Animations/babylon.easing.js",
-      "../../src/Bones/babylon.bone.js",
-      "../../src/Bones/babylon.boneIKController.js",
-      "../../src/Bones/babylon.boneLookController.js",
-      "../../src/Bones/babylon.skeleton.js",
-      "../../src/PostProcess/babylon.postProcess.js",
-      "../../src/PostProcess/babylon.postProcessManager.js",
-      "../../src/PostProcess/babylon.passPostProcess.js",
-      "../../src/Physics/babylon.physicsJoint.js",
-      "../../src/Physics/babylon.physicsImpostor.js",
-      "../../src/Physics/babylon.physicsEngine.js",
-      "../../src/Mesh/babylon.mesh.vertexData.js",
-      "../../src/Tools/babylon.tags.js",
-      "../../src/Tools/babylon.andOrNotEvaluator.js",
-      "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js",
-      "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js",
-      "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js",
-      "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js",
-      "../../src/Rendering/babylon.boundingBoxRenderer.js",
-      "../../src/Actions/babylon.condition.js",
-      "../../src/Actions/babylon.action.js",
-      "../../src/Actions/babylon.actionManager.js",
-      "../../src/Actions/babylon.interpolateValueAction.js",
-      "../../src/Actions/babylon.directActions.js",
-      "../../src/Mesh/babylon.geometry.js",
-      "../../src/Mesh/babylon.groundMesh.js",
-      "../../src/Mesh/babylon.instancedMesh.js",
-      "../../src/Mesh/babylon.linesMesh.js",
-      "../../src/Tools/babylon.loadingScreen.js",
-      "../../src/Audio/babylon.audioEngine.js",
-      "../../src/Audio/babylon.sound.js",
-      "../../src/Audio/babylon.soundtrack.js",
-      "../../src/Layer/babylon.highlightlayer.js",
-      "../../src/Math/babylon.math.SIMD.js",
-      "../../src/Tools/babylon.rectPackingMap.js",
-      "../../src/Tools/babylon.dynamicFloatArray.js",
-      "../../src/Materials/Textures/babylon.mapTexture.js",
-      "../../src/Materials/babylon.shaderMaterial.js",
-      "../../src/Tools/babylon.tools.dds.js",
-      "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",
-      "../../src/Physics/Plugins/babylon.oimoJSPlugin.js",
-      "../../src/PostProcess/babylon.displayPassPostProcess.js",
-      "../../src/Mesh/babylon.meshSimplification.js",
-      "../../src/Tools/babylon.sceneSerializer.js",
-      "../../src/Tools/babylon.earcut.js",
-      "../../src/Mesh/babylon.csg.js",
-      "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
-      "../../src/Tools/babylon.virtualJoystick.js",
-      "../../src/Cameras/babylon.virtualJoysticksCamera.js",      
-      "../../src/Cameras/Inputs/babylon.freecamera.input.virtualjoystick.js",
-      "../../src/PostProcess/babylon.anaglyphPostProcess.js",
-      "../../src/Rendering/babylon.outlineRenderer.js",
-      "../../src/Tools/babylon.assetsManager.js",
-      "../../src/Cameras/VR/babylon.vrCameraMetrics.js",
-      "../../src/Cameras/VR/babylon.webVRCamera.js",
-      "../../src/Tools/babylon.sceneOptimizer.js",
-      "../../src/Mesh/babylon.meshLODLevel.js",
-      "../../src/Materials/Textures/babylon.rawTexture.js",
-      "../../src/Mesh/babylon.polygonMesh.js",
-      "../../src/Culling/Octrees/babylon.octree.js",
-      "../../src/Culling/Octrees/babylon.octreeBlock.js",
-      "../../src/PostProcess/babylon.blurPostProcess.js",
-      "../../src/PostProcess/babylon.refractionPostProcess.js",
-      "../../src/PostProcess/babylon.blackAndWhitePostProcess.js",
-      "../../src/PostProcess/babylon.convolutionPostProcess.js",
-      "../../src/PostProcess/babylon.filterPostProcess.js",
-      "../../src/PostProcess/babylon.fxaaPostProcess.js",
-      "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
-      "../../src/LensFlare/babylon.lensFlare.js",
-      "../../src/LensFlare/babylon.lensFlareSystem.js",
-      "../../src/Cameras/babylon.deviceOrientationCamera.js",
-      "../../src/Cameras/VR/babylon.vrDeviceOrientationCamera.js",
-      "../../src/Cameras/babylon.universalCamera.js",
-      "../../src/Tools/babylon.gamepads.js",
-      "../../src/Cameras/babylon.gamepadCamera.js",
-      "../../src/Audio/babylon.analyser.js",
-      "../../src/Rendering/babylon.depthRenderer.js",
-      "../../src/PostProcess/babylon.ssaoRenderingPipeline.js",
-      "../../src/PostProcess/babylon.volumetricLightScatteringPostProcess.js",
-      "../../src/PostProcess/babylon.lensRenderingPipeline.js",
-      "../../src/PostProcess/babylon.colorCorrectionPostProcess.js",
-      "../../src/Cameras/babylon.stereoscopicCameras.js",
-      "../../src/PostProcess/babylon.hdrRenderingPipeline.js",
-      "../../src/Rendering/babylon.edgesRenderer.js",
-      "../../src/PostProcess/babylon.tonemapPostProcess.js",
-      "../../src/Probes/babylon.reflectionProbe.js",
-      "../../src/Particles/babylon.solidParticle.js",
-      "../../src/Particles/babylon.solidParticleSystem.js",
-      "../../src/Tools/HDR/babylon.tools.cubemapToSphericalPolynomial.js",
-      "../../src/Tools/HDR/babylon.tools.panoramaToCubemap.js",
-      "../../src/Tools/HDR/babylon.tools.hdr.js",
-      "../../src/Tools/HDR/babylon.tools.pmremgenerator.js",
-      "../../src/Materials/Textures/babylon.hdrCubeTexture.js",
-      "../../src/Debug/babylon.skeletonViewer.js",
-      "../../src/Debug/babylon.axesViewer.js",
-      "../../src/Debug/babylon.boneAxesViewer.js",
-      "../../src/Materials/Textures/babylon.colorGradingTexture.js",
-      "../../src/Materials/babylon.colorCurves.js",
-      "../../src/Materials/babylon.pbrMaterial.js",      
-      "../../src/Debug/babylon.debugLayer.js",
-      "../../src/PostProcess/babylon.standardRenderingPipeline.js"
+            "../../src/Math/babylon.math.js",
+            "../../src/babylon.mixins.js",
+            "../../src/Tools/babylon.decorators.js",
+            "../../src/Tools/babylon.observable.js",
+            "../../src/Tools/babylon.database.js",
+            "../../src/Tools/babylon.tga.js",
+            "../../src/Tools/babylon.smartArray.js",
+            "../../src/Tools/babylon.stringDictionary.js",
+            "../../src/Tools/babylon.tools.js",
+            "../../src/States/babylon.alphaCullingState.js",
+            "../../src/States/babylon.depthCullingState.js",
+            "../../src/States/babylon.stencilState.js",
+            "../../src/Tools/babylon.loadingScreen.js",
+            "../../src/babylon.engine.js",
+            "../../src/babylon.node.js",
+            "../../src/Tools/babylon.filesInput.js",
+            "../../src/Collisions/babylon.pickingInfo.js",
+            "../../src/Culling/babylon.boundingSphere.js",
+            "../../src/Culling/babylon.boundingBox.js",
+            "../../src/Culling/babylon.boundingInfo.js",
+            "../../src/Culling/babylon.ray.js",
+            "../../src/Debug/babylon.rayHelper.js",
+            "../../src/Mesh/babylon.abstractMesh.js",
+            "../../src/Lights/babylon.light.js",
+            "../../src/Lights/babylon.pointLight.js",
+            "../../src/Lights/babylon.spotLight.js",
+            "../../src/Lights/babylon.hemisphericLight.js",
+            "../../src/Lights/babylon.directionalLight.js",
+            "../../src/Lights/Shadows/babylon.shadowGenerator.js",
+            "../../src/Collisions/babylon.collider.js",
+            "../../src/Collisions/babylon.collisionCoordinator.js",
+            "../../src/Cameras/babylon.camera.js",
+            "../../src/Cameras/babylon.cameraInputsManager.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraMouseInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraTouchInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraGamepadInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.js",
+            "../../src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.js",
+            "../../src/Cameras/babylon.targetCamera.js",
+            "../../src/Cameras/babylon.freeCamera.js",
+            "../../src/Cameras/babylon.freeCameraInputsManager.js",
+            "../../src/Cameras/babylon.followCamera.js",
+            "../../src/Cameras/babylon.touchCamera.js",
+            "../../src/Cameras/babylon.arcRotateCamera.js",
+            "../../src/Cameras/babylon.arcRotateCameraInputsManager.js",
+            "../../src/Rendering/babylon.renderingManager.js",
+            "../../src/Rendering/babylon.renderingGroup.js",
+            "../../src/PostProcess/babylon.postProcessManager.js",
+            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js",
+            "../../src/Rendering/babylon.boundingBoxRenderer.js",
+            "../../src/babylon.scene.js",
+            "../../src/Mesh/babylon.buffer.js",
+            "../../src/Mesh/babylon.vertexBuffer.js",
+            "../../src/Mesh/babylon.instancedMesh.js",
+            "../../src/Mesh/babylon.mesh.js",
+            "../../src/Mesh/babylon.subMesh.js",
+            "../../src/Mesh/babylon.meshBuilder.js",
+            "../../src/Materials/Textures/babylon.baseTexture.js",
+            "../../src/Materials/Textures/babylon.texture.js",
+            "../../src/Materials/Textures/babylon.cubeTexture.js",
+            "../../src/Materials/Textures/babylon.renderTargetTexture.js",
+            "../../src/Materials/Textures/Procedurals/babylon.proceduralTexture.js",
+            "../../src/Materials/Textures/babylon.mirrorTexture.js",
+            "../../src/Materials/Textures/babylon.refractionTexture.js",
+            "../../src/Materials/Textures/babylon.dynamicTexture.js",
+            "../../src/Materials/Textures/babylon.videoTexture.js",
+            "../../src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js",
+            "../../src/Materials/babylon.effect.js",
+            "../../src/Materials/babylon.materialHelper.js",
+            "../../src/Materials/babylon.fresnelParameters.js",
+            "../../src/Materials/babylon.material.js",
+            "../../src/Materials/babylon.pushMaterial.js",
+            "../../src/Materials/babylon.standardMaterial.js",
+            "../../src/Materials/babylon.multiMaterial.js",
+            "../../src/Loading/babylon.sceneLoader.js",
+            "../../src/Loading/Plugins/babylon.babylonFileLoader.js",
+            "../../src/Sprites/babylon.spriteManager.js",
+            "../../src/Sprites/babylon.sprite.js",
+            "../../src/Layer/babylon.layer.js",
+            "../../src/Particles/babylon.particle.js",
+            "../../src/Particles/babylon.particleSystem.js",
+            "../../src/Animations/babylon.animation.js",
+            "../../src/Animations/babylon.animatable.js",
+            "../../src/Animations/babylon.easing.js",
+            "../../src/Bones/babylon.bone.js",
+            "../../src/Bones/babylon.boneIKController.js",
+            "../../src/Bones/babylon.boneLookController.js",
+            "../../src/Bones/babylon.skeleton.js",
+            "../../src/PostProcess/babylon.postProcess.js",
+            "../../src/PostProcess/babylon.passPostProcess.js",
+            "../../src/Physics/babylon.physicsJoint.js",
+            "../../src/Physics/babylon.physicsImpostor.js",
+            "../../src/Physics/babylon.physicsEngine.js",
+            "../../src/Mesh/babylon.mesh.vertexData.js",
+            "../../src/Tools/babylon.tags.js",
+            "../../src/Tools/babylon.andOrNotEvaluator.js",
+            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js",
+            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js",
+            "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js",
+            "../../src/Actions/babylon.condition.js",
+            "../../src/Actions/babylon.action.js",
+            "../../src/Actions/babylon.actionManager.js",
+            "../../src/Actions/babylon.interpolateValueAction.js",
+            "../../src/Actions/babylon.directActions.js",
+            "../../src/Mesh/babylon.geometry.js",
+            "../../src/Mesh/babylon.groundMesh.js",
+            "../../src/Mesh/babylon.instancedMesh.js",
+            "../../src/Mesh/babylon.linesMesh.js",
+            "../../src/Audio/babylon.audioEngine.js",
+            "../../src/Audio/babylon.sound.js",
+            "../../src/Audio/babylon.soundtrack.js",
+            "../../src/Layer/babylon.highlightlayer.js",
+            "../../src/Math/babylon.math.SIMD.js",
+            "../../src/Tools/babylon.rectPackingMap.js",
+            "../../src/Tools/babylon.dynamicFloatArray.js",
+            "../../src/Materials/Textures/babylon.mapTexture.js",
+            "../../src/Materials/babylon.shaderMaterial.js",
+            "../../src/Tools/babylon.dds.js",
+            "../../src/Tools/babylon.khronosTextureContainer.js",
+            "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",
+            "../../src/Physics/Plugins/babylon.oimoJSPlugin.js",
+            "../../src/PostProcess/babylon.displayPassPostProcess.js",
+            "../../src/Mesh/babylon.meshSimplification.js",
+            "../../src/Tools/babylon.sceneSerializer.js",
+            "../../src/Tools/babylon.earcut.js",
+            "../../src/Mesh/babylon.csg.js",
+            "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
+            "../../src/Tools/babylon.virtualJoystick.js",
+            "../../src/Cameras/babylon.virtualJoysticksCamera.js",
+            "../../src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.js",
+            "../../src/PostProcess/babylon.anaglyphPostProcess.js",
+            "../../src/Rendering/babylon.outlineRenderer.js",
+            "../../src/Tools/babylon.assetsManager.js",
+            "../../src/Cameras/VR/babylon.vrCameraMetrics.js",
+            "../../src/Cameras/VR/babylon.webVRCamera.js",
+            "../../src/Tools/babylon.sceneOptimizer.js",
+            "../../src/Mesh/babylon.meshLODLevel.js",
+            "../../src/Materials/Textures/babylon.rawTexture.js",
+            "../../src/Mesh/babylon.polygonMesh.js",
+            "../../src/Culling/Octrees/babylon.octree.js",
+            "../../src/Culling/Octrees/babylon.octreeBlock.js",
+            "../../src/PostProcess/babylon.blurPostProcess.js",
+            "../../src/PostProcess/babylon.refractionPostProcess.js",
+            "../../src/PostProcess/babylon.blackAndWhitePostProcess.js",
+            "../../src/PostProcess/babylon.convolutionPostProcess.js",
+            "../../src/PostProcess/babylon.filterPostProcess.js",
+            "../../src/PostProcess/babylon.fxaaPostProcess.js",
+            "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
+            "../../src/LensFlare/babylon.lensFlare.js",
+            "../../src/LensFlare/babylon.lensFlareSystem.js",
+            "../../src/Cameras/babylon.deviceOrientationCamera.js",
+            "../../src/Cameras/VR/babylon.vrDeviceOrientationCamera.js",
+            "../../src/Cameras/babylon.universalCamera.js",
+            "../../src/Tools/babylon.gamepads.js",
+            "../../src/Tools/babylon.extendedGamepad.js",
+            "../../src/Cameras/babylon.gamepadCamera.js",
+            "../../src/Audio/babylon.analyser.js",
+            "../../src/Rendering/babylon.depthRenderer.js",
+            "../../src/PostProcess/babylon.ssaoRenderingPipeline.js",
+            "../../src/PostProcess/babylon.volumetricLightScatteringPostProcess.js",
+            "../../src/PostProcess/babylon.lensRenderingPipeline.js",
+            "../../src/PostProcess/babylon.colorCorrectionPostProcess.js",
+            "../../src/Cameras/babylon.stereoscopicCameras.js",
+            "../../src/PostProcess/babylon.hdrRenderingPipeline.js",
+            "../../src/Rendering/babylon.edgesRenderer.js",
+            "../../src/PostProcess/babylon.tonemapPostProcess.js",
+            "../../src/Probes/babylon.reflectionProbe.js",
+            "../../src/Particles/babylon.solidParticle.js",
+            "../../src/Particles/babylon.solidParticleSystem.js",
+            "../../src/Tools/HDR/babylon.cubemapToSphericalPolynomial.js",
+            "../../src/Tools/HDR/babylon.panoramaToCubemap.js",
+            "../../src/Tools/HDR/babylon.hdr.js",
+            "../../src/Tools/HDR/babylon.pmremgenerator.js",
+            "../../src/Materials/Textures/babylon.hdrCubeTexture.js",
+            "../../src/Debug/babylon.skeletonViewer.js",
+            "../../src/Debug/babylon.axesViewer.js",
+            "../../src/Debug/babylon.boneAxesViewer.js",
+            "../../src/Materials/Textures/babylon.colorGradingTexture.js",
+            "../../src/Materials/babylon.colorCurves.js",
+            "../../src/Materials/babylon.pbrMaterial.js",
+            "../../src/Debug/babylon.debugLayer.js",
+            "../../src/PostProcess/babylon.standardRenderingPipeline.js"
     ]
     ]
   }
   }
 }
 }

+ 240 - 0
Tools/Gulp/profiling.html

@@ -0,0 +1,240 @@
+<html>
+<head>
+    <title>Customize BJS for a specific Scene</title>
+    <meta charset="UTF-8">
+    <script src="../../dist/preview release/babylon.js"></script>
+    
+</head>
+<body onload="readConfigFile()">
+Obtain a FireFox performance file by:
+<ol>
+	<li>Make sure scene uses Babylon MAX.</li>
+	<li>Load the scene.</li>
+	<li>Turn on performance profiling.</li>
+	<li>Reload the scene (very important if code like sceneLoader runs on page load).</li>
+	<li>Do anything that might call code in babylon.js not yet encountered.</li>
+	<li>Stop recording, and save the data as a file.</li>
+</ol>
+On this page:
+<ol>
+	<li>Select File with 'Browse' button below, and pick the file saved from above.</li>
+	<li>Make any changes of name to babylon file names.</li>
+	<li>Click Generate.</li>
+	<li>Copy the 'custom.cofig.json' file generated in Downloads directory to the Gulp directory.</li>
+	<li>run: 'Gulp build-custom'</li>
+	<li>Copy generated scripts from dist/preview lease to where needed, and test.  Tip: test with the max version</li>
+	<li>If need stuff did not get recorded in performance file, then select file(s) &amp; click Generate again.</li>
+</ol>
+	<form>
+		<input type="radio" name="browser" id="firefox" checked="checked"><label for="firefox"> Firefox</label>
+		<input type="radio" name="browser" id="chrome" disabled data-toggle="tooltip" title="Not yet implemented, Go for it!"><label for="chrome"> Chrome</label>
+		<input type="radio" name="browser" id="edge"   disabled data-toggle="tooltip" title="Not yet implemented, Go for it!"><label for="edge"> Edge</label><br>
+		
+		<label>Profiling file: <input type="file" id="upload_file" name="upload" accept="text/*" multiple="" onchange="assignProfile(this.files[0])"/></label><br><br>
+		
+		Filename: <input type="text" id="filename" maxlength="32" value="babylon.custom.max.js">         
+		minFilename: <input type="text" id="minFilename" maxlength="32" value="babylon.custom.js"><br>         
+        Files Not In Recording: (Select those to still keep)
+			<input type="button" value="Generate" onclick="generate()"><br>
+        <select id="discards" multiple size="30">
+        </select>
+
+	</form>
+	<script>
+	    //  each "File" is a: [keep: boolean, fullPath: string, search]
+	    //  search is initially the file name without the .js.  
+	    var files;
+    	var reg = new RegExp('babylon\\.\\w+');
+	
+	    var FIRE_FOX = 0;
+	    var CHROME   = 1;
+	    var EDGE     = 3;
+	    
+	    function readConfigFile() {
+	    	// read the regular config file, not custom, in-case custom has already been reduced
+	    	// the regular config file has files in 2 separate sections
+	        BABYLON.Tools.LoadFile("./config.json",
+	                function(data){
+	        	        var startInd = data.indexOf('"files": [') + 11; // 11 for "files": [
+	        	        var endInd = data.indexOf(']', startInd);
+	        	        var fileNames = data.substring(startInd, endInd);
+	        	        fileNames += ","; // for spliting once glued to part 2
+	        	        
+	        	        var extras = data.indexOf('"extras"');
+	        	        startInd = data.indexOf('"files": [', extras) + 11; // 11 for "files": [
+	        	        endInd = data.indexOf(']', startInd);
+	        	        fileNames += data.substring(startInd, endInd);
+	        	        
+	        	        fileNames = fileNames.replace(/(\r\n|\n|\r)/gm,""); // strip all line breaks
+	        	        fileNames = fileNames.replace(/\s+/g, ""); // strip all whitespace
+	        	        fileNames = fileNames.split(',');
+
+	        	        var len = fileNames.length;
+                        files = new Array(len);
+                        for (var i = 0; i < len; i++) {
+                        	var name = fileNames[i].match(reg)[0].substring(8);  // remove the babylon.
+                        	files[i] = [false, fileNames[i], name];
+                        }
+						appendSecondarySearches("math.js", "mathtools|color3|color4|vector2|vector3|vector4|size|quaternion|matrix|plane|viewport|frustum|bezierCurve"); // got tired
+
+						// force stuff to always be added
+						appendSecondarySearches("decorators.js", "engine"); //needed for Serialize
+						appendSecondarySearches("stringDictionary.js", "engine"); //needed in Engine Constructor
+						appendSecondarySearches("loadingScreen.js", "engine"); //needed in Engine Constructor		
+						appendSecondarySearches("postProcessRenderPipelineManager.js", "scene"); //needed in Scene Constructor		
+						appendSecondarySearches("boundingBoxRenderer.js", "scene"); //needed in Scene Constructor		
+						appendSecondarySearches("collisionCoordinator.js", "scene"); //needed in Scene Constructor, from a called set of this.workerCollisions = false;
+						appendSecondarySearches("collider.js", "abstractMesh"); // needed in abstractMesh constructor
+						appendSecondarySearches("linesMesh.js", "geometry"); // needed in geometry constructor
+						appendSecondarySearches("multiMaterial.js", "subMesh"); // needed in subMesh.getMaterial()
+						appendSecondarySearches("pointLight.js", "subMesh"); // needed in MaterialHelper.PrepareDefinesForLights
+						appendSecondarySearches("spotLight.js", "subMesh"); // needed in MaterialHelper.PrepareDefinesForLights
+						appendSecondarySearches("hemisphericLight.js", "subMesh"); // needed in MaterialHelper.PrepareDefinesForLights
+						appendSecondarySearches("directionalLight.js", "subMesh"); // needed in MaterialHelper.PrepareDefinesForLights
+						appendSecondarySearches("videoTexture.js", "engine"); //needed in Engine._setTexture()	
+						
+						// there should always some detection of FreeCamera or ArcRotateCamera, but maybe not all inputs got recorded
+						appendSecondarySearches("cameraInputsManager.js", "freeCamera\\w+|arcRotateCamera\\w+");
+						
+						appendSecondarySearches("freeCamera.js", "freeCamera\\w+");
+						appendSecondarySearches("freeCameraInputsManager.js", "freeCamera\\w+");
+						appendSecondarySearches("freeCameraMouseInput.js"            , "freeCamera\\w+");
+						appendSecondarySearches("freeCameraKeyboardMoveInput.js"     , "freeCamera\\w+");
+						appendSecondarySearches("freeCameraTouchInput.js"            , "freeCamera\\w+");
+						appendSecondarySearches("freeCameraDeviceOrientationInput.js", "freeCamera\\w+");
+						appendSecondarySearches("freeCameraGamepadInput.js"          , "freeCamera\\w+");
+						appendSecondarySearches("freeCameraVirtualJoystickInput.js"  , "freeCamera\\w+");
+						
+						appendSecondarySearches("arcRotateCamera.js", "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraInputsManager.js", "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraKeyboardMoveInput.js"       , "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraMouseWheelInput.js"         , "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraPointersInput.js"           , "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraGamepadInput.js"            , "arcRotateCamera\\w+");
+						appendSecondarySearches("arcRotateCameraVRDeviceOrientationInput.js", "arcRotateCamera\\w+");
+						
+						// these are internal classes where class name has a leading '_'
+						appendSecondarySearches("alphaCullingState.js"   , "engine");
+						appendSecondarySearches("depthCullingState.js"   , "_depthCullingState");
+						appendSecondarySearches("stencilState.js"        , "_stencilState");
+						
+						// dependencies with few / no methods, so no performance to record.
+						appendSecondarySearches("pushMaterial.js", "standardMaterial");
+                        
+	                }, null, true
+	        );
+	    }
+	    
+	    // add addition conditions to match a file to.
+	    // additionals is a string with all separated with a '|'
+	    function appendSecondarySearches(baseFilename, additionals) {
+	    	for (var i = 0, len = files.length; i < len; i++) {
+	    		if (files[i][1].indexOf(baseFilename) !== -1) {
+	    			files[i][2] += "|" + additionals;
+	    			return;
+	    		}
+	    	}
+	    	throw "'" + baseFilename + "' not found as a base file name";
+	    }
+	
+	    function assignProfile(file) {
+	        BABYLON.Tools.ReadFile(file, analyse, null, false);
+	    }
+	    
+	    function analyse(data){
+	    	// make sure max was used
+	    	if (!data.match('\\.max\\.js')) {
+	    		alert('babylon.max not detected. File rejected');
+	    		return;
+	    	}
+	    	var browser;
+	    	if (document.getElementById("firefox").checked) browser = FIRE_FOX;
+	    	if (document.getElementById("chrome" ).checked) browser = CHROME;
+	    	if (document.getElementById("edge"   ).checked) browser = EDGE;
+	    	
+			var discards = document.getElementById("discards");
+			discards.options.length = 0;
+	    	
+	    	for (var i = 0, len = files.length; i < len; i++) {
+	    		files[i][0] = false; // clean out boolean for additional runs
+    			switch(browser) {
+    			case FIRE_FOX:
+	     			var exp = new RegExp('"(' + files[i][2] + ')(\\.prototype|\\.\\w)', 'i');
+    				if (data.match(exp) ) {
+    					files[i][0] = true;
+    				}
+    				break;
+    			case CHROME:
+    			case EDGE:
+    				window.alert("Code from your PR goes here!");
+    				return;
+    			}
+	    		
+	    		// add onto the discard select when not found
+	    		if (!files[i][0]){
+	    			var option = document.createElement("option");
+	    			option.text = files[i][1];
+	    			discards.add(option);
+	    		}
+	    	}
+	    }
+	    
+	    function generate() {
+	    	// get all the ones from select
+			var discards = document.getElementById("discards");
+			var opt;
+			var asText = "";
+			for (var i = 0, len = discards.options.length; i < len; i++) {
+				opt = discards.options[i];
+                if (opt.selected) {	
+                	asText += opt.text;
+                }
+			}
+
+			var filename    = document.getElementById("filename"   ).value;
+			var minFilename = document.getElementById("minFilename").value;
+	    	var out = '';
+	    	out += '{\n';
+	    	out += '  "build": {\n';
+	    	out += '	    "filename": "' + filename + '",\n';
+	    	out += '	    "minFilename": "' + minFilename + '",\n';
+	    	out += '	    "outputDirectory": "../../dist/preview release",\n';
+	    	out += '	    "srcOutputDirectory": "../../src/"\n';
+	    	out += '	  },\n';
+	    	out += '	  "core": {\n';
+	    	out += '	    "typescript": [\n';
+	    	out += '	      "../../src/**/*.ts",\n';
+	    	out += '	      "!../../src/**/*.d.ts"\n';
+	    	out += '	    ],\n';
+	    	out += '	    "files": [\n';
+	    		
+	    	var isFirst = true;
+		    for (var i = 0, len = files.length; i < len; i++) {
+		    	if (files[i][0] || asText.indexOf(files[i][1]) !== -1) {
+		    		if (!isFirst) {
+		    			out += ',';
+		    		}
+	    			isFirst = false;
+		    		out += '\n      ' + files[i][1];
+		    	}
+		    }
+		    out += '\n    ]\n';
+		    out += '  }\n';
+		    out += '}\n';
+		    
+            var blob = new Blob ( [ out ], { type : 'text/plain;charset=utf-8' } );
+
+            // turn blob into an object URL;
+            var objectUrl = (window.webkitURL || window.URL).createObjectURL(blob);
+
+            var link = window.document.createElement("a");
+            link.href = objectUrl;
+            link.download = "custom.config.json";
+            var click = document.createEvent("MouseEvents");
+            click.initEvent("click", true, false);
+            link.dispatchEvent(click);	            
+	    }
+
+	</script>
+</body>
+</html>

File diff suppressed because it is too large
+ 24 - 24
dist/preview release/babylon.core.js


File diff suppressed because it is too large
+ 1278 - 1276
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 33 - 33
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 459 - 451
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1278 - 1276
dist/preview release/babylon.module.d.ts


File diff suppressed because it is too large
+ 33 - 33
dist/preview release/babylon.noworker.js


+ 2 - 2
dist/preview release/inspector/babylon.inspector.bundle.js

@@ -65,8 +65,8 @@ var INSPECTOR =
 	if(false) {
 	if(false) {
 		// When the styles change, update the <style> tags
 		// When the styles change, update the <style> tags
 		if(!content.locals) {
 		if(!content.locals) {
-			module.hot.accept("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
-				var newContent = require("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
+			module.hot.accept("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
+				var newContent = require("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
 				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
 				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
 				update(newContent);
 				update(newContent);
 			});
 			});

+ 1 - 4
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -86,19 +86,16 @@ var BABYLON;
                         defines.DIFFUSE = true;
                         defines.DIFFUSE = true;
                     }
                     }
                 }
                 }
-                defines._areTexturesDirty = false;
             }
             }
             // Misc.
             // Misc.
             if (defines._areMiscDirty) {
             if (defines._areMiscDirty) {
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
-                defines._areMiscDirty = false;
             }
             }
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
             BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
-            defines._areAttributesDirty = false;
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {
                 defines.markAsProcessed();
                 defines.markAsProcessed();

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 8 - 8
dist/preview release/materialsLibrary/babylon.furMaterial.d.ts

@@ -1,7 +1,9 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class FurMaterial extends Material {
+    class FurMaterial extends PushMaterial {
+        private _diffuseTexture;
         diffuseTexture: BaseTexture;
         diffuseTexture: BaseTexture;
+        private _heightTexture;
         heightTexture: BaseTexture;
         heightTexture: BaseTexture;
         diffuseColor: Color3;
         diffuseColor: Color3;
         furLength: number;
         furLength: number;
@@ -13,25 +15,23 @@ declare module BABYLON {
         furSpeed: number;
         furSpeed: number;
         furDensity: number;
         furDensity: number;
         furTexture: DynamicTexture;
         furTexture: DynamicTexture;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
-        highLevelFur: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         maxSimultaneousLights: number;
+        highLevelFur: boolean;
         _meshes: AbstractMesh[];
         _meshes: AbstractMesh[];
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _renderId;
         private _renderId;
         private _furTime;
         private _furTime;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         furTime: number;
         furTime: number;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
         updateFur(): void;
         updateFur(): void;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): FurMaterial;
         clone(name: string): FurMaterial;

File diff suppressed because it is too large
+ 105 - 140
dist/preview release/materialsLibrary/babylon.furMaterial.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 5 - 7
dist/preview release/materialsLibrary/babylon.gradientMaterial.d.ts

@@ -1,6 +1,8 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class GradientMaterial extends Material {
+    class GradientMaterial extends PushMaterial {
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
         topColor: Color3;
         topColor: Color3;
         topColorAlpha: number;
         topColorAlpha: number;
         bottomColor: Color3;
         bottomColor: Color3;
@@ -11,16 +13,12 @@ declare module BABYLON {
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _scaledDiffuse;
         private _scaledDiffuse;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): GradientMaterial;
         clone(name: string): GradientMaterial;

+ 55 - 102
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -17,7 +17,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 };
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
-    var maxSimultaneousLights = 4;
     var GradientMaterialDefines = (function (_super) {
     var GradientMaterialDefines = (function (_super) {
         __extends(GradientMaterialDefines, _super);
         __extends(GradientMaterialDefines, _super);
         function GradientMaterialDefines() {
         function GradientMaterialDefines() {
@@ -77,6 +76,7 @@ var BABYLON;
         __extends(GradientMaterial, _super);
         __extends(GradientMaterial, _super);
         function GradientMaterial(name, scene) {
         function GradientMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
             var _this = _super.call(this, name, scene) || this;
+            _this._maxSimultaneousLights = 4;
             // The gradient top color, red by default
             // The gradient top color, red by default
             _this.topColor = new BABYLON.Color3(1, 0, 0);
             _this.topColor = new BABYLON.Color3(1, 0, 0);
             _this.topColorAlpha = 1.0;
             _this.topColorAlpha = 1.0;
@@ -89,9 +89,6 @@ var BABYLON;
             _this.disableLighting = false;
             _this.disableLighting = false;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._scaledDiffuse = new BABYLON.Color3();
             _this._scaledDiffuse = new BABYLON.Color3();
-            _this._defines = new GradientMaterialDefines();
-            _this._cachedDefines = new GradientMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         GradientMaterial.prototype.needAlphaBlending = function () {
         GradientMaterial.prototype.needAlphaBlending = function () {
@@ -104,114 +101,61 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        GradientMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        GradientMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        GradientMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new GradientMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-            this._defines.reset();
-            // No textures
-            // 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 !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            var lightIndex = 0;
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false);
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                 }
                 }
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "gradient";
                 var shaderName = "gradient";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -223,49 +167,52 @@ var BABYLON;
                     "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues", "topColor", "bottomColor", "offset", "smoothness"
                     "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues", "topColor", "bottomColor", "offset", "smoothness"
                 ], ["diffuseSampler",
                 ], ["diffuseSampler",
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 });
+                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        GradientMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        GradientMaterial.prototype.bind = function (world, mesh) {
+        GradientMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
             BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
             BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
                 BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
                 BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._effect.setColor4("topColor", this.topColor, this.topColorAlpha);
-            this._effect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
-            this._effect.setFloat("offset", this.offset);
-            this._effect.setFloat("smoothness", this.smoothness);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._activeEffect.setColor4("topColor", this.topColor, this.topColorAlpha);
+            this._activeEffect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
+            this._activeEffect.setFloat("offset", this.offset);
+            this._activeEffect.setFloat("smoothness", this.smoothness);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         GradientMaterial.prototype.getAnimatables = function () {
         GradientMaterial.prototype.getAnimatables = function () {
             return [];
             return [];
@@ -287,7 +234,13 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new GradientMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new GradientMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return GradientMaterial;
         return GradientMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
+    __decorate([
+        BABYLON.serialize("maxSimultaneousLights")
+    ], GradientMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
+    ], GradientMaterial.prototype, "maxSimultaneousLights", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
     ], GradientMaterial.prototype, "topColor", void 0);
     ], GradientMaterial.prototype, "topColor", void 0);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 3 - 7
dist/preview release/materialsLibrary/babylon.gridMaterial.d.ts

@@ -4,7 +4,7 @@ declare module BABYLON {
      * The grid materials allows you to wrap any shape with a grid.
      * The grid materials allows you to wrap any shape with a grid.
      * Colors are customizable.
      * Colors are customizable.
      */
      */
-    class GridMaterial extends BABYLON.Material {
+    class GridMaterial extends BABYLON.PushMaterial {
         /**
         /**
          * Main color of the grid (e.g. between lines)
          * Main color of the grid (e.g. between lines)
          */
          */
@@ -31,8 +31,6 @@ declare module BABYLON {
         opacity: number;
         opacity: number;
         private _gridControl;
         private _gridControl;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         /**
         /**
          * constructor
          * constructor
          * @param name The name given to the material in order to identify it afterwards.
          * @param name The name given to the material in order to identify it afterwards.
@@ -43,10 +41,8 @@ declare module BABYLON {
          * Returns wehter or not the grid requires alpha blending.
          * Returns wehter or not the grid requires alpha blending.
          */
          */
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): GridMaterial;
         clone(name: string): GridMaterial;
         serialize(): any;
         serialize(): any;

+ 37 - 49
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -17,16 +17,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 };
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
-    var GRIDMaterialDefines = (function (_super) {
-        __extends(GRIDMaterialDefines, _super);
-        function GRIDMaterialDefines() {
+    var GridMaterialDefines = (function (_super) {
+        __extends(GridMaterialDefines, _super);
+        function GridMaterialDefines() {
             var _this = _super.call(this) || this;
             var _this = _super.call(this) || this;
             _this.TRANSPARENT = false;
             _this.TRANSPARENT = false;
             _this.FOG = false;
             _this.FOG = false;
             _this.rebuild();
             _this.rebuild();
             return _this;
             return _this;
         }
         }
-        return GRIDMaterialDefines;
+        return GridMaterialDefines;
     }(BABYLON.MaterialDefines));
     }(BABYLON.MaterialDefines));
     /**
     /**
      * The grid materials allows you to wrap any shape with a grid.
      * The grid materials allows you to wrap any shape with a grid.
@@ -66,8 +66,6 @@ var BABYLON;
              */
              */
             _this.opacity = 1.0;
             _this.opacity = 1.0;
             _this._gridControl = new BABYLON.Vector4(_this.gridRatio, _this.majorUnitFrequency, _this.minorUnitVisibility, _this.opacity);
             _this._gridControl = new BABYLON.Vector4(_this.gridRatio, _this.majorUnitFrequency, _this.minorUnitVisibility, _this.opacity);
-            _this._defines = new GRIDMaterialDefines();
-            _this._cachedDefines = new GRIDMaterialDefines();
             return _this;
             return _this;
         }
         }
         /**
         /**
@@ -76,82 +74,72 @@ var BABYLON;
         GridMaterial.prototype.needAlphaBlending = function () {
         GridMaterial.prototype.needAlphaBlending = function () {
             return this.opacity < 1.0;
             return this.opacity < 1.0;
         };
         };
-        GridMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            return false;
-        };
-        GridMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        GridMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new GridMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = true;
-            this._defines.reset();
-            if (this.opacity < 1.0) {
-                this._defines.TRANSPARENT = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
+            if (this.opacity < 1.0 && !defines.TRANSPARENT) {
+                defines.TRANSPARENT = true;
+                defines.markAsUnprocessed();
             }
             }
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
             // Get correct effect      
             // Get correct effect      
-            if (!this._effect || !this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Attributes
                 // Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind, BABYLON.VertexBuffer.NormalKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind, BABYLON.VertexBuffer.NormalKind];
                 // Effect
                 // Effect
                 var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
                 var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
                 // Defines
                 // Defines
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, ["worldViewProjection", "mainColor", "lineColor", "gridControl", "vFogInfos", "vFogColor", "world", "view"], [], join, null, this.onCompiled, this.onError);
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, ["worldViewProjection", "mainColor", "lineColor", "gridControl", "vFogInfos", "vFogColor", "world", "view"], [], join, null, this.onCompiled, this.onError), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        GridMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            var scene = this.getScene();
-            this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
-            this._effect.setMatrix("world", world);
-            this._effect.setMatrix("view", scene.getViewMatrix());
-        };
-        GridMaterial.prototype.bind = function (world, mesh) {
+        GridMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices
             // Matrices
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
+            this._activeEffect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
             // Uniforms
             // Uniforms
-            if (scene.getCachedMaterial() !== this) {
-                this._effect.setColor3("mainColor", this.mainColor);
-                this._effect.setColor3("lineColor", this.lineColor);
+            if (this._mustRebind(scene, effect)) {
+                this._activeEffect.setColor3("mainColor", this.mainColor);
+                this._activeEffect.setColor3("lineColor", this.lineColor);
                 this._gridControl.x = this.gridRatio;
                 this._gridControl.x = this.gridRatio;
                 this._gridControl.y = Math.round(this.majorUnitFrequency);
                 this._gridControl.y = Math.round(this.majorUnitFrequency);
                 this._gridControl.z = this.minorUnitVisibility;
                 this._gridControl.z = this.minorUnitVisibility;
                 this._gridControl.w = this.opacity;
                 this._gridControl.w = this.opacity;
-                this._effect.setVector4("gridControl", this._gridControl);
-            }
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setVector4("gridControl", this._gridControl);
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         GridMaterial.prototype.dispose = function (forceDisposeEffect) {
         GridMaterial.prototype.dispose = function (forceDisposeEffect) {
             _super.prototype.dispose.call(this, forceDisposeEffect);
             _super.prototype.dispose.call(this, forceDisposeEffect);
@@ -169,7 +157,7 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new GridMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new GridMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return GridMaterial;
         return GridMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
     ], GridMaterial.prototype, "mainColor", void 0);
     ], GridMaterial.prototype, "mainColor", void 0);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


+ 6 - 7
dist/preview release/materialsLibrary/babylon.lavaMaterial.d.ts

@@ -1,6 +1,7 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class LavaMaterial extends Material {
+    class LavaMaterial extends PushMaterial {
+        private _diffuseTexture;
         diffuseTexture: BaseTexture;
         diffuseTexture: BaseTexture;
         noiseTexture: BaseTexture;
         noiseTexture: BaseTexture;
         fogColor: Color3;
         fogColor: Color3;
@@ -10,21 +11,19 @@ declare module BABYLON {
         fogDensity: number;
         fogDensity: number;
         private _lastTime;
         private _lastTime;
         diffuseColor: Color3;
         diffuseColor: Color3;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _scaledDiffuse;
         private _scaledDiffuse;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): LavaMaterial;
         clone(name: string): LavaMaterial;

+ 83 - 118
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -82,13 +82,10 @@ var BABYLON;
             _this.fogDensity = 0.15;
             _this.fogDensity = 0.15;
             _this._lastTime = 0;
             _this._lastTime = 0;
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
-            _this.disableLighting = false;
-            _this.maxSimultaneousLights = 4;
+            _this._disableLighting = false;
+            _this._maxSimultaneousLights = 4;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._scaledDiffuse = new BABYLON.Color3();
             _this._scaledDiffuse = new BABYLON.Color3();
-            _this._defines = new LavaMaterialDefines();
-            _this._cachedDefines = new LavaMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         LavaMaterial.prototype.needAlphaBlending = function () {
         LavaMaterial.prototype.needAlphaBlending = function () {
@@ -101,123 +98,79 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        LavaMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        LavaMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        LavaMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new LavaMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needUVs = false;
-            this._defines.reset();
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this._diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
+                        if (!this._diffuseTexture.isReady()) {
+                            return false;
+                        }
+                        else {
+                            defines._needUVs = true;
+                            defines.DIFFUSE = 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 !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false, this.maxSimultaneousLights);
-            }
+            // Misc.
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            // Lights
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+            // Values that need to be evaluated on every frame
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                 }
                 }
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "lava";
                 var shaderName = "lava";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -231,63 +184,66 @@ var BABYLON;
                     "fogColor", "fogDensity", "lowFrequencySpeed"
                     "fogColor", "fogDensity", "lowFrequencySpeed"
                 ], ["diffuseSampler",
                 ], ["diffuseSampler",
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3", "noiseTexture"
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3", "noiseTexture"
-                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
+                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        LavaMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        LavaMaterial.prototype.bind = function (world, mesh) {
+        LavaMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                 if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
+                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
                 }
                 }
                 if (this.noiseTexture) {
                 if (this.noiseTexture) {
-                    this._effect.setTexture("noiseTexture", this.noiseTexture);
+                    this._activeEffect.setTexture("noiseTexture", this.noiseTexture);
                 }
                 }
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             this._lastTime += scene.getEngine().getDeltaTime();
             this._lastTime += scene.getEngine().getDeltaTime();
-            this._effect.setFloat("time", this._lastTime * this.speed / 1000);
+            this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
             if (!this.fogColor) {
             if (!this.fogColor) {
                 this.fogColor = BABYLON.Color3.Black();
                 this.fogColor = BABYLON.Color3.Black();
             }
             }
-            this._effect.setColor3("fogColor", this.fogColor);
-            this._effect.setFloat("fogDensity", this.fogDensity);
-            this._effect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
-            this._effect.setFloat("movingSpeed", this.movingSpeed);
-            this._afterBind(mesh);
+            this._activeEffect.setColor3("fogColor", this.fogColor);
+            this._activeEffect.setFloat("fogDensity", this.fogDensity);
+            this._activeEffect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
+            this._activeEffect.setFloat("movingSpeed", this.movingSpeed);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         LavaMaterial.prototype.getAnimatables = function () {
         LavaMaterial.prototype.getAnimatables = function () {
             var results = [];
             var results = [];
@@ -322,9 +278,12 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new LavaMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new LavaMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return LavaMaterial;
         return LavaMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexture")
+    ], LavaMaterial.prototype, "_diffuseTexture", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], LavaMaterial.prototype, "diffuseTexture", void 0);
     ], LavaMaterial.prototype, "diffuseTexture", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsTexture()
         BABYLON.serializeAsTexture()
@@ -348,10 +307,16 @@ var BABYLON;
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
     ], LavaMaterial.prototype, "diffuseColor", void 0);
     ], LavaMaterial.prototype, "diffuseColor", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("disableLighting")
+    ], LavaMaterial.prototype, "_disableLighting", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], LavaMaterial.prototype, "disableLighting", void 0);
     ], LavaMaterial.prototype, "disableLighting", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("maxSimultaneousLights")
+    ], LavaMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], LavaMaterial.prototype, "maxSimultaneousLights", void 0);
     ], LavaMaterial.prototype, "maxSimultaneousLights", void 0);
     BABYLON.LavaMaterial = LavaMaterial;
     BABYLON.LavaMaterial = LavaMaterial;
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 7 - 7
dist/preview release/materialsLibrary/babylon.normalMaterial.d.ts

@@ -1,22 +1,22 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class NormalMaterial extends Material {
+    class NormalMaterial extends PushMaterial {
+        private _diffuseTexture;
         diffuseTexture: BaseTexture;
         diffuseTexture: BaseTexture;
         diffuseColor: Color3;
         diffuseColor: Color3;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _scaledDiffuse;
         private _scaledDiffuse;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): NormalMaterial;
         clone(name: string): NormalMaterial;

+ 79 - 112
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -77,12 +77,10 @@ var BABYLON;
         function NormalMaterial(name, scene) {
         function NormalMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
             var _this = _super.call(this, name, scene) || this;
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
-            _this.disableLighting = false;
+            _this._disableLighting = false;
+            _this._maxSimultaneousLights = 4;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._scaledDiffuse = new BABYLON.Color3();
             _this._scaledDiffuse = new BABYLON.Color3();
-            _this._defines = new NormalMaterialDefines();
-            _this._cachedDefines = new NormalMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         NormalMaterial.prototype.needAlphaBlending = function () {
         NormalMaterial.prototype.needAlphaBlending = function () {
@@ -95,124 +93,78 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        NormalMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        NormalMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        NormalMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new NormalMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-            this._defines.reset();
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    }
-                    else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this._diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
+                        if (!this._diffuseTexture.isReady()) {
+                            return false;
+                        }
+                        else {
+                            defines._needUVs = true;
+                            defines.DIFFUSE = 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 !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            var lightIndex = 0;
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false);
-            }
+            // Misc.
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            // Lights
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+            // Values that need to be evaluated on every frame
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                 }
                 }
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 var shaderName = "normal";
                 var shaderName = "normal";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData1", "vLightDiffuse1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
                     "vLightData2", "vLightDiffuse2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -224,52 +176,55 @@ var BABYLON;
                     "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                     "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3", "depthValues"
                 ], ["diffuseSampler",
                 ], ["diffuseSampler",
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
-                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 });
+                ], join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        NormalMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        NormalMaterial.prototype.bind = function (world, mesh) {
+        NormalMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                 if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
+                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
                 }
                 }
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         NormalMaterial.prototype.getAnimatables = function () {
         NormalMaterial.prototype.getAnimatables = function () {
             var results = [];
             var results = [];
@@ -298,16 +253,28 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new NormalMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new NormalMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return NormalMaterial;
         return NormalMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexture")
+    ], NormalMaterial.prototype, "_diffuseTexture", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], NormalMaterial.prototype, "diffuseTexture", void 0);
     ], NormalMaterial.prototype, "diffuseTexture", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
     ], NormalMaterial.prototype, "diffuseColor", void 0);
     ], NormalMaterial.prototype, "diffuseColor", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("disableLighting")
+    ], NormalMaterial.prototype, "_disableLighting", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], NormalMaterial.prototype, "disableLighting", void 0);
     ], NormalMaterial.prototype, "disableLighting", void 0);
+    __decorate([
+        BABYLON.serialize("maxSimultaneousLights")
+    ], NormalMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
+    ], NormalMaterial.prototype, "maxSimultaneousLights", void 0);
     BABYLON.NormalMaterial = NormalMaterial;
     BABYLON.NormalMaterial = NormalMaterial;
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 3 - 7
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.d.ts

@@ -1,19 +1,15 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class ShadowOnlyMaterial extends Material {
+    class ShadowOnlyMaterial extends PushMaterial {
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _scaledDiffuse;
         private _scaledDiffuse;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         clone(name: string): ShadowOnlyMaterial;
         clone(name: string): ShadowOnlyMaterial;
         serialize(): any;
         serialize(): any;
         static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial;
         static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial;

+ 42 - 75
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -39,9 +39,6 @@ var BABYLON;
             var _this = _super.call(this, name, scene) || this;
             var _this = _super.call(this, name, scene) || this;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._scaledDiffuse = new BABYLON.Color3();
             _this._scaledDiffuse = new BABYLON.Color3();
-            _this._defines = new ShadowOnlyMaterialDefines();
-            _this._cachedDefines = new ShadowOnlyMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         ShadowOnlyMaterial.prototype.needAlphaBlending = function () {
         ShadowOnlyMaterial.prototype.needAlphaBlending = function () {
@@ -54,129 +51,99 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        ShadowOnlyMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        ShadowOnlyMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        ShadowOnlyMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new ShadowOnlyMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            this._defines.reset();
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
-            // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
-                this._defines.POINTSIZE = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            if (scene.lightsEnabled) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false, 1);
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, 1);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 var shaderName = "shadowOnly";
                 var shaderName = "shadowOnly";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "mBones",
                     "mBones",
                     "vClipPlane", "depthValues"
                     "vClipPlane", "depthValues"
                 ];
                 ];
                 var samplers = [];
                 var samplers = [];
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, 1);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 1 });
+                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, 1);
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 1 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        ShadowOnlyMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        ShadowOnlyMaterial.prototype.bind = function (world, mesh) {
+        ShadowOnlyMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
             // Lights
             // Lights
             if (scene.lightsEnabled) {
             if (scene.lightsEnabled) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, 1);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         ShadowOnlyMaterial.prototype.clone = function (name) {
         ShadowOnlyMaterial.prototype.clone = function (name) {
             var _this = this;
             var _this = this;
@@ -192,7 +159,7 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new ShadowOnlyMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new ShadowOnlyMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return ShadowOnlyMaterial;
         return ShadowOnlyMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
         BABYLON.serialize()
         BABYLON.serialize()
     ], ShadowOnlyMaterial.prototype, "_worldViewProjectionMatrix", void 0);
     ], ShadowOnlyMaterial.prototype, "_worldViewProjectionMatrix", void 0);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 2 - 9
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -91,22 +91,15 @@ var BABYLON;
                         }
                         }
                     }
                     }
                 }
                 }
-                defines._areTexturesDirty = false;
             }
             }
             // Misc.
             // Misc.
-            if (defines._areMiscDirty) {
-                defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
-                defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
-                defines._areMiscDirty = false;
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-            defines._areLightsDirty = false;
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
             BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
-            defines._areAttributesDirty = false;
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {
                 defines.markAsProcessed();
                 defines.markAsProcessed();

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 3 - 7
dist/preview release/materialsLibrary/babylon.skyMaterial.d.ts

@@ -1,6 +1,6 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class SkyMaterial extends Material {
+    class SkyMaterial extends PushMaterial {
         luminance: number;
         luminance: number;
         turbidity: number;
         turbidity: number;
         rayleigh: number;
         rayleigh: number;
@@ -13,16 +13,12 @@ declare module BABYLON {
         useSunPosition: boolean;
         useSunPosition: boolean;
         private _cameraPosition;
         private _cameraPosition;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): SkyMaterial;
         clone(name: string): SkyMaterial;

+ 40 - 63
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -48,8 +48,6 @@ var BABYLON;
             _this.useSunPosition = false;
             _this.useSunPosition = false;
             // Private members
             // Private members
             _this._cameraPosition = BABYLON.Vector3.Zero();
             _this._cameraPosition = BABYLON.Vector3.Zero();
-            _this._defines = new SkyMaterialDefines();
-            _this._cachedDefines = new SkyMaterialDefines();
             return _this;
             return _this;
         }
         }
         SkyMaterial.prototype.needAlphaBlending = function () {
         SkyMaterial.prototype.needAlphaBlending = function () {
@@ -62,104 +60,83 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        SkyMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            return false;
-        };
-        SkyMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        SkyMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new SkyMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            this._defines.reset();
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
-            // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
-                this._defines.POINTSIZE = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines) || !this._effect) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                // Legacy browser patch
                 var shaderName = "sky";
                 var shaderName = "sky";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, ["world", "viewProjection", "view",
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, ["world", "viewProjection", "view",
                     "vFogInfos", "vFogColor", "pointSize", "vClipPlane",
                     "vFogInfos", "vFogColor", "pointSize", "vClipPlane",
                     "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
                     "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
                     "cameraPosition"
                     "cameraPosition"
-                ], [], join, fallbacks, this.onCompiled, this.onError);
+                ], [], join, fallbacks, this.onCompiled, this.onError), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        SkyMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        SkyMaterial.prototype.bind = function (world, mesh) {
+        SkyMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
-            if (scene.getCachedMaterial() !== this) {
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
                 if (scene.clipPlane) {
                 if (scene.clipPlane) {
                     var clipPlane = scene.clipPlane;
                     var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
+                    this._activeEffect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
                 }
                 }
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             // Sky
             // Sky
             var camera = scene.activeCamera;
             var camera = scene.activeCamera;
             if (camera) {
             if (camera) {
@@ -167,15 +144,15 @@ var BABYLON;
                 this._cameraPosition.x = cameraWorldMatrix.m[12];
                 this._cameraPosition.x = cameraWorldMatrix.m[12];
                 this._cameraPosition.y = cameraWorldMatrix.m[13];
                 this._cameraPosition.y = cameraWorldMatrix.m[13];
                 this._cameraPosition.z = cameraWorldMatrix.m[14];
                 this._cameraPosition.z = cameraWorldMatrix.m[14];
-                this._effect.setVector3("cameraPosition", this._cameraPosition);
+                this._activeEffect.setVector3("cameraPosition", this._cameraPosition);
             }
             }
             if (this.luminance > 0) {
             if (this.luminance > 0) {
-                this._effect.setFloat("luminance", this.luminance);
+                this._activeEffect.setFloat("luminance", this.luminance);
             }
             }
-            this._effect.setFloat("turbidity", this.turbidity);
-            this._effect.setFloat("rayleigh", this.rayleigh);
-            this._effect.setFloat("mieCoefficient", this.mieCoefficient);
-            this._effect.setFloat("mieDirectionalG", this.mieDirectionalG);
+            this._activeEffect.setFloat("turbidity", this.turbidity);
+            this._activeEffect.setFloat("rayleigh", this.rayleigh);
+            this._activeEffect.setFloat("mieCoefficient", this.mieCoefficient);
+            this._activeEffect.setFloat("mieDirectionalG", this.mieDirectionalG);
             if (!this.useSunPosition) {
             if (!this.useSunPosition) {
                 var theta = Math.PI * (this.inclination - 0.5);
                 var theta = Math.PI * (this.inclination - 0.5);
                 var phi = 2 * Math.PI * (this.azimuth - 0.5);
                 var phi = 2 * Math.PI * (this.azimuth - 0.5);
@@ -183,8 +160,8 @@ var BABYLON;
                 this.sunPosition.y = this.distance * Math.sin(phi) * Math.sin(theta);
                 this.sunPosition.y = this.distance * Math.sin(phi) * Math.sin(theta);
                 this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
                 this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
             }
             }
-            this._effect.setVector3("sunPosition", this.sunPosition);
-            this._afterBind(mesh);
+            this._activeEffect.setVector3("sunPosition", this.sunPosition);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         SkyMaterial.prototype.getAnimatables = function () {
         SkyMaterial.prototype.getAnimatables = function () {
             return [];
             return [];
@@ -206,7 +183,7 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new SkyMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new SkyMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return SkyMaterial;
         return SkyMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
         BABYLON.serialize()
         BABYLON.serialize()
     ], SkyMaterial.prototype, "luminance", void 0);
     ], SkyMaterial.prototype, "luminance", void 0);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.min.js


+ 12 - 7
dist/preview release/materialsLibrary/babylon.terrainMaterial.d.ts

@@ -1,30 +1,35 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class TerrainMaterial extends Material {
+    class TerrainMaterial extends PushMaterial {
+        private _mixTexture;
         mixTexture: BaseTexture;
         mixTexture: BaseTexture;
+        private _diffuseTexture1;
         diffuseTexture1: Texture;
         diffuseTexture1: Texture;
+        private _diffuseTexture2;
         diffuseTexture2: Texture;
         diffuseTexture2: Texture;
+        private _diffuseTexture3;
         diffuseTexture3: Texture;
         diffuseTexture3: Texture;
+        private _bumpTexture1;
         bumpTexture1: Texture;
         bumpTexture1: Texture;
+        private _bumpTexture2;
         bumpTexture2: Texture;
         bumpTexture2: Texture;
+        private _bumpTexture3;
         bumpTexture3: Texture;
         bumpTexture3: Texture;
         diffuseColor: Color3;
         diffuseColor: Color3;
         specularColor: Color3;
         specularColor: Color3;
         specularPower: number;
         specularPower: number;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): TerrainMaterial;
         clone(name: string): TerrainMaterial;

+ 112 - 135
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -17,7 +17,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 };
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
-    var maxSimultaneousLights = 4;
     var TerrainMaterialDefines = (function (_super) {
     var TerrainMaterialDefines = (function (_super) {
         __extends(TerrainMaterialDefines, _super);
         __extends(TerrainMaterialDefines, _super);
         function TerrainMaterialDefines() {
         function TerrainMaterialDefines() {
@@ -49,12 +48,9 @@ var BABYLON;
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.specularColor = new BABYLON.Color3(0, 0, 0);
             _this.specularColor = new BABYLON.Color3(0, 0, 0);
             _this.specularPower = 64;
             _this.specularPower = 64;
-            _this.disableLighting = false;
-            _this.maxSimultaneousLights = 4;
+            _this._disableLighting = false;
+            _this._maxSimultaneousLights = 4;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
-            _this._defines = new TerrainMaterialDefines();
-            _this._cachedDefines = new TerrainMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         TerrainMaterial.prototype.needAlphaBlending = function () {
         TerrainMaterial.prototype.needAlphaBlending = function () {
@@ -67,52 +63,23 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        TerrainMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        TerrainMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        TerrainMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new TerrainMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-            this._defines.reset();
-            // 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 !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
-            }
             // Textures
             // Textures
             if (scene.texturesEnabled) {
             if (scene.texturesEnabled) {
                 if (this.mixTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                 if (this.mixTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
@@ -120,76 +87,56 @@ var BABYLON;
                         return false;
                         return false;
                     }
                     }
                     else {
                     else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
                     }
                     }
                 }
                 }
                 if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && BABYLON.StandardMaterial.BumpTextureEnabled) {
                 if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && BABYLON.StandardMaterial.BumpTextureEnabled) {
-                    needUVs = true;
-                    needNormals = true;
-                    this._defines.BUMP = true;
+                    defines._needUVs = true;
+                    defines._needNormals = true;
+                    defines.BUMP = true;
                 }
                 }
             }
             }
+            // Misc.
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            // Lights
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+            // Values that need to be evaluated on every frame
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                 }
                 }
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "terrain";
                 var shaderName = "terrain";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vTextureInfos",
                     "vTextureInfos",
@@ -200,80 +147,83 @@ var BABYLON;
                 var samplers = ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
                 var samplers = ["textureSampler", "diffuse1Sampler", "diffuse2Sampler", "diffuse3Sampler",
                     "bump1Sampler", "bump2Sampler", "bump3Sampler"
                     "bump1Sampler", "bump2Sampler", "bump3Sampler"
                 ];
                 ];
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        TerrainMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        TerrainMaterial.prototype.bind = function (world, mesh) {
+        TerrainMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.mixTexture) {
                 if (this.mixTexture) {
-                    this._effect.setTexture("textureSampler", this.mixTexture);
-                    this._effect.setFloat2("vTextureInfos", this.mixTexture.coordinatesIndex, this.mixTexture.level);
-                    this._effect.setMatrix("textureMatrix", this.mixTexture.getTextureMatrix());
+                    this._activeEffect.setTexture("textureSampler", this._mixTexture);
+                    this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
+                    this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
                     if (BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                     if (BABYLON.StandardMaterial.DiffuseTextureEnabled) {
-                        if (this.diffuseTexture1) {
-                            this._effect.setTexture("diffuse1Sampler", this.diffuseTexture1);
-                            this._effect.setFloat2("diffuse1Infos", this.diffuseTexture1.uScale, this.diffuseTexture1.vScale);
+                        if (this._diffuseTexture1) {
+                            this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
+                            this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
                         }
                         }
-                        if (this.diffuseTexture2) {
-                            this._effect.setTexture("diffuse2Sampler", this.diffuseTexture2);
-                            this._effect.setFloat2("diffuse2Infos", this.diffuseTexture2.uScale, this.diffuseTexture2.vScale);
+                        if (this._diffuseTexture2) {
+                            this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
+                            this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
                         }
                         }
-                        if (this.diffuseTexture3) {
-                            this._effect.setTexture("diffuse3Sampler", this.diffuseTexture3);
-                            this._effect.setFloat2("diffuse3Infos", this.diffuseTexture3.uScale, this.diffuseTexture3.vScale);
+                        if (this._diffuseTexture3) {
+                            this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
+                            this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
                         }
                         }
                     }
                     }
                     if (BABYLON.StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
                     if (BABYLON.StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
-                        if (this.bumpTexture1) {
-                            this._effect.setTexture("bump1Sampler", this.bumpTexture1);
+                        if (this._bumpTexture1) {
+                            this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
                         }
                         }
-                        if (this.bumpTexture2) {
-                            this._effect.setTexture("bump2Sampler", this.bumpTexture2);
+                        if (this._bumpTexture2) {
+                            this._activeEffect.setTexture("bump2Sampler", this._bumpTexture2);
                         }
                         }
-                        if (this.bumpTexture3) {
-                            this._effect.setTexture("bump3Sampler", this.bumpTexture3);
+                        if (this._bumpTexture3) {
+                            this._activeEffect.setTexture("bump3Sampler", this._bumpTexture3);
                         }
                         }
                     }
                     }
                 }
                 }
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         TerrainMaterial.prototype.getAnimatables = function () {
         TerrainMaterial.prototype.getAnimatables = function () {
             var results = [];
             var results = [];
@@ -302,27 +252,48 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new TerrainMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new TerrainMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return TerrainMaterial;
         return TerrainMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("mixTexture")
+    ], TerrainMaterial.prototype, "_mixTexture", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "mixTexture", void 0);
     ], TerrainMaterial.prototype, "mixTexture", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexture1")
+    ], TerrainMaterial.prototype, "_diffuseTexture1", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "diffuseTexture1", void 0);
     ], TerrainMaterial.prototype, "diffuseTexture1", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexture2")
+    ], TerrainMaterial.prototype, "_diffuseTexture2", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "diffuseTexture2", void 0);
     ], TerrainMaterial.prototype, "diffuseTexture2", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexture3")
+    ], TerrainMaterial.prototype, "_diffuseTexture3", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "diffuseTexture3", void 0);
     ], TerrainMaterial.prototype, "diffuseTexture3", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("bumpTexture1")
+    ], TerrainMaterial.prototype, "_bumpTexture1", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "bumpTexture1", void 0);
     ], TerrainMaterial.prototype, "bumpTexture1", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("bumpTexture2")
+    ], TerrainMaterial.prototype, "_bumpTexture2", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "bumpTexture2", void 0);
     ], TerrainMaterial.prototype, "bumpTexture2", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("bumpTexture3")
+    ], TerrainMaterial.prototype, "_bumpTexture3", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TerrainMaterial.prototype, "bumpTexture3", void 0);
     ], TerrainMaterial.prototype, "bumpTexture3", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
@@ -334,10 +305,16 @@ var BABYLON;
         BABYLON.serialize()
         BABYLON.serialize()
     ], TerrainMaterial.prototype, "specularPower", void 0);
     ], TerrainMaterial.prototype, "specularPower", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("disableLighting")
+    ], TerrainMaterial.prototype, "_disableLighting", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], TerrainMaterial.prototype, "disableLighting", void 0);
     ], TerrainMaterial.prototype, "disableLighting", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("maxSimultaneousLights")
+    ], TerrainMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], TerrainMaterial.prototype, "maxSimultaneousLights", void 0);
     ], TerrainMaterial.prototype, "maxSimultaneousLights", void 0);
     BABYLON.TerrainMaterial = TerrainMaterial;
     BABYLON.TerrainMaterial = TerrainMaterial;
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 17 - 13
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.d.ts

@@ -1,31 +1,35 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class TriPlanarMaterial extends Material {
+    class TriPlanarMaterial extends PushMaterial {
         mixTexture: BaseTexture;
         mixTexture: BaseTexture;
-        diffuseTextureX: Texture;
-        diffuseTextureY: Texture;
-        diffuseTextureZ: Texture;
-        normalTextureX: Texture;
-        normalTextureY: Texture;
-        normalTextureZ: Texture;
+        private _diffuseTextureX;
+        diffuseTextureX: BaseTexture;
+        private _diffuseTextureY;
+        diffuseTextureY: BaseTexture;
+        private _diffuseTextureZ;
+        diffuseTextureZ: BaseTexture;
+        private _normalTextureX;
+        normalTextureX: BaseTexture;
+        private _normalTextureY;
+        normalTextureY: BaseTexture;
+        private _normalTextureZ;
+        normalTextureZ: BaseTexture;
         tileSize: number;
         tileSize: number;
         diffuseColor: Color3;
         diffuseColor: Color3;
         specularColor: Color3;
         specularColor: Color3;
         specularPower: number;
         specularPower: number;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         maxSimultaneousLights: number;
         private _worldViewProjectionMatrix;
         private _worldViewProjectionMatrix;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): TriPlanarMaterial;
         clone(name: string): TriPlanarMaterial;

+ 112 - 127
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -17,7 +17,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 };
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
-    var maxSimultaneousLights = 4;
     var TriPlanarMaterialDefines = (function (_super) {
     var TriPlanarMaterialDefines = (function (_super) {
         __extends(TriPlanarMaterialDefines, _super);
         __extends(TriPlanarMaterialDefines, _super);
         function TriPlanarMaterialDefines() {
         function TriPlanarMaterialDefines() {
@@ -52,12 +51,9 @@ var BABYLON;
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.specularColor = new BABYLON.Color3(0.2, 0.2, 0.2);
             _this.specularColor = new BABYLON.Color3(0.2, 0.2, 0.2);
             _this.specularPower = 64;
             _this.specularPower = 64;
-            _this.disableLighting = false;
-            _this.maxSimultaneousLights = 4;
+            _this._disableLighting = false;
+            _this._maxSimultaneousLights = 4;
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
             _this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
-            _this._defines = new TriPlanarMaterialDefines();
-            _this._cachedDefines = new TriPlanarMaterialDefines();
-            _this._cachedDefines.BonesPerMesh = -1;
             return _this;
             return _this;
         }
         }
         TriPlanarMaterial.prototype.needAlphaBlending = function () {
         TriPlanarMaterial.prototype.needAlphaBlending = function () {
@@ -70,128 +66,90 @@ var BABYLON;
             return null;
             return null;
         };
         };
         // Methods   
         // Methods   
-        TriPlanarMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        TriPlanarMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        TriPlanarMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new TriPlanarMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            this._defines.reset();
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (BABYLON.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 (defines._areTexturesDirty) {
+                if (scene.texturesEnabled) {
+                    if (BABYLON.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 {
+                                    defines[textureDefines[i]] = true;
+                                }
                             }
                             }
                         }
                         }
                     }
                     }
-                }
-                if (BABYLON.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;
+                    if (BABYLON.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 {
+                                    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 !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
+            // Misc.
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             // Lights
             // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
-            }
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
+            // Values that need to be evaluated on every frame
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "triplanar";
                 var shaderName = "triplanar";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "mBones",
                     "mBones",
@@ -201,69 +159,72 @@ var BABYLON;
                 var samplers = ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
                 var samplers = ["diffuseSamplerX", "diffuseSamplerY", "diffuseSamplerZ",
                     "normalSamplerX", "normalSamplerY", "normalSamplerZ"
                     "normalSamplerX", "normalSamplerY", "normalSamplerZ"
                 ];
                 ];
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        TriPlanarMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        TriPlanarMaterial.prototype.bind = function (world, mesh) {
+        TriPlanarMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            this._effect.setFloat("tileSize", this.tileSize);
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            this._activeEffect.setFloat("tileSize", this.tileSize);
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTextureX) {
                 if (this.diffuseTextureX) {
-                    this._effect.setTexture("diffuseSamplerX", this.diffuseTextureX);
+                    this._activeEffect.setTexture("diffuseSamplerX", this.diffuseTextureX);
                 }
                 }
                 if (this.diffuseTextureY) {
                 if (this.diffuseTextureY) {
-                    this._effect.setTexture("diffuseSamplerY", this.diffuseTextureY);
+                    this._activeEffect.setTexture("diffuseSamplerY", this.diffuseTextureY);
                 }
                 }
                 if (this.diffuseTextureZ) {
                 if (this.diffuseTextureZ) {
-                    this._effect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
+                    this._activeEffect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
                 }
                 }
                 if (this.normalTextureX) {
                 if (this.normalTextureX) {
-                    this._effect.setTexture("normalSamplerX", this.normalTextureX);
+                    this._activeEffect.setTexture("normalSamplerX", this.normalTextureX);
                 }
                 }
                 if (this.normalTextureY) {
                 if (this.normalTextureY) {
-                    this._effect.setTexture("normalSamplerY", this.normalTextureY);
+                    this._activeEffect.setTexture("normalSamplerY", this.normalTextureY);
                 }
                 }
                 if (this.normalTextureZ) {
                 if (this.normalTextureZ) {
-                    this._effect.setTexture("normalSamplerZ", this.normalTextureZ);
+                    this._activeEffect.setTexture("normalSamplerZ", this.normalTextureZ);
                 }
                 }
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
-            this._afterBind(mesh);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         TriPlanarMaterial.prototype.getAnimatables = function () {
         TriPlanarMaterial.prototype.getAnimatables = function () {
             var results = [];
             var results = [];
@@ -292,27 +253,45 @@ var BABYLON;
             return BABYLON.SerializationHelper.Parse(function () { return new TriPlanarMaterial(source.name, scene); }, source, scene, rootUrl);
             return BABYLON.SerializationHelper.Parse(function () { return new TriPlanarMaterial(source.name, scene); }, source, scene, rootUrl);
         };
         };
         return TriPlanarMaterial;
         return TriPlanarMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
     __decorate([
     __decorate([
         BABYLON.serializeAsTexture()
         BABYLON.serializeAsTexture()
     ], TriPlanarMaterial.prototype, "mixTexture", void 0);
     ], TriPlanarMaterial.prototype, "mixTexture", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTextureX")
+    ], TriPlanarMaterial.prototype, "_diffuseTextureX", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "diffuseTextureX", void 0);
     ], TriPlanarMaterial.prototype, "diffuseTextureX", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTexturY")
+    ], TriPlanarMaterial.prototype, "_diffuseTextureY", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "diffuseTextureY", void 0);
     ], TriPlanarMaterial.prototype, "diffuseTextureY", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("diffuseTextureZ")
+    ], TriPlanarMaterial.prototype, "_diffuseTextureZ", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "diffuseTextureZ", void 0);
     ], TriPlanarMaterial.prototype, "diffuseTextureZ", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("normalTextureX")
+    ], TriPlanarMaterial.prototype, "_normalTextureX", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "normalTextureX", void 0);
     ], TriPlanarMaterial.prototype, "normalTextureX", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("normalTextureY")
+    ], TriPlanarMaterial.prototype, "_normalTextureY", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "normalTextureY", void 0);
     ], TriPlanarMaterial.prototype, "normalTextureY", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.serializeAsTexture("normalTextureZ")
+    ], TriPlanarMaterial.prototype, "_normalTextureZ", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], TriPlanarMaterial.prototype, "normalTextureZ", void 0);
     ], TriPlanarMaterial.prototype, "normalTextureZ", void 0);
     __decorate([
     __decorate([
         BABYLON.serialize()
         BABYLON.serialize()
@@ -327,10 +306,16 @@ var BABYLON;
         BABYLON.serialize()
         BABYLON.serialize()
     ], TriPlanarMaterial.prototype, "specularPower", void 0);
     ], TriPlanarMaterial.prototype, "specularPower", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("disableLighting")
+    ], TriPlanarMaterial.prototype, "_disableLighting", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], TriPlanarMaterial.prototype, "disableLighting", void 0);
     ], TriPlanarMaterial.prototype, "disableLighting", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("maxSimultaneousLights")
+    ], TriPlanarMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], TriPlanarMaterial.prototype, "maxSimultaneousLights", void 0);
     ], TriPlanarMaterial.prototype, "maxSimultaneousLights", void 0);
     BABYLON.TriPlanarMaterial = TriPlanarMaterial;
     BABYLON.TriPlanarMaterial = TriPlanarMaterial;
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 9 - 7
dist/preview release/materialsLibrary/babylon.waterMaterial.d.ts

@@ -1,12 +1,15 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
 declare module BABYLON {
 declare module BABYLON {
-    class WaterMaterial extends Material {
+    class WaterMaterial extends PushMaterial {
         renderTargetSize: Vector2;
         renderTargetSize: Vector2;
+        private _bumpTexture;
         bumpTexture: BaseTexture;
         bumpTexture: BaseTexture;
         diffuseColor: Color3;
         diffuseColor: Color3;
         specularColor: Color3;
         specularColor: Color3;
         specularPower: number;
         specularPower: number;
+        private _disableLighting;
         disableLighting: boolean;
         disableLighting: boolean;
+        private _maxSimultaneousLights;
         maxSimultaneousLights: number;
         maxSimultaneousLights: number;
         /**
         /**
         * @param {number}: Represents the wind force
         * @param {number}: Represents the wind force
@@ -27,14 +30,17 @@ declare module BABYLON {
         /**
         /**
          * @param {boolean}: Add a smaller moving bump to less steady waves.
          * @param {boolean}: Add a smaller moving bump to less steady waves.
          */
          */
+        private _bumpSuperimpose;
         bumpSuperimpose: boolean;
         bumpSuperimpose: boolean;
         /**
         /**
          * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
          * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
          */
          */
+        private _fresnelSeparate;
         fresnelSeparate: boolean;
         fresnelSeparate: boolean;
         /**
         /**
          * @param {boolean}: bump Waves modify the reflection.
          * @param {boolean}: bump Waves modify the reflection.
          */
          */
+        private _bumpAffectsReflection;
         bumpAffectsReflection: boolean;
         bumpAffectsReflection: boolean;
         /**
         /**
         * @param {number}: The water color blended with the refraction (near)
         * @param {number}: The water color blended with the refraction (near)
@@ -67,8 +73,6 @@ declare module BABYLON {
         private _reflectionTransform;
         private _reflectionTransform;
         private _lastTime;
         private _lastTime;
         private _renderId;
         private _renderId;
-        private _defines;
-        private _cachedDefines;
         private _useLogarithmicDepth;
         private _useLogarithmicDepth;
         /**
         /**
         * Constructor
         * Constructor
@@ -84,10 +88,8 @@ declare module BABYLON {
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): BaseTexture;
         getAlphaTestTexture(): BaseTexture;
-        private _checkCache(scene, mesh?, useInstances?);
-        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
-        bindOnlyWorldMatrix(world: Matrix): void;
-        bind(world: Matrix, mesh?: Mesh): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         private _createRenderTargets(scene, renderTargetSize);
         private _createRenderTargets(scene, renderTargetSize);
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;

+ 119 - 148
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -57,8 +57,8 @@ var BABYLON;
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.diffuseColor = new BABYLON.Color3(1, 1, 1);
             _this.specularColor = new BABYLON.Color3(0, 0, 0);
             _this.specularColor = new BABYLON.Color3(0, 0, 0);
             _this.specularPower = 64;
             _this.specularPower = 64;
-            _this.disableLighting = false;
-            _this.maxSimultaneousLights = 4;
+            _this._disableLighting = false;
+            _this._maxSimultaneousLights = 4;
             /**
             /**
             * @param {number}: Represents the wind force
             * @param {number}: Represents the wind force
             */
             */
@@ -78,15 +78,15 @@ var BABYLON;
             /**
             /**
              * @param {boolean}: Add a smaller moving bump to less steady waves.
              * @param {boolean}: Add a smaller moving bump to less steady waves.
              */
              */
-            _this.bumpSuperimpose = false;
+            _this._bumpSuperimpose = false;
             /**
             /**
              * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
              * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
              */
              */
-            _this.fresnelSeparate = false;
+            _this._fresnelSeparate = false;
             /**
             /**
              * @param {boolean}: bump Waves modify the reflection.
              * @param {boolean}: bump Waves modify the reflection.
              */
              */
-            _this.bumpAffectsReflection = false;
+            _this._bumpAffectsReflection = false;
             /**
             /**
             * @param {number}: The water color blended with the refraction (near)
             * @param {number}: The water color blended with the refraction (near)
             */
             */
@@ -117,8 +117,6 @@ var BABYLON;
             _this._mesh = null;
             _this._mesh = null;
             _this._reflectionTransform = BABYLON.Matrix.Zero();
             _this._reflectionTransform = BABYLON.Matrix.Zero();
             _this._lastTime = 0;
             _this._lastTime = 0;
-            _this._defines = new WaterMaterialDefines();
-            _this._cachedDefines = new WaterMaterialDefines();
             // Create render targets
             // Create render targets
             _this._createRenderTargets(scene, renderTargetSize);
             _this._createRenderTargets(scene, renderTargetSize);
             return _this;
             return _this;
@@ -129,6 +127,7 @@ var BABYLON;
             },
             },
             set: function (value) {
             set: function (value) {
                 this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
                 this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+                this._markAllSubMeshesAsMiscDirty();
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -177,143 +176,94 @@ var BABYLON;
         WaterMaterial.prototype.getAlphaTestTexture = function () {
         WaterMaterial.prototype.getAlphaTestTexture = function () {
             return null;
             return null;
         };
         };
-        WaterMaterial.prototype._checkCache = function (scene, mesh, useInstances) {
-            if (!mesh) {
-                return true;
-            }
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-            return false;
-        };
-        WaterMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        WaterMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new WaterMaterialDefines();
+            }
+            var defines = subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-            this._defines.reset();
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
-                    if (!this.bumpTexture.isReady()) {
-                        return false;
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
+                        if (!this.bumpTexture.isReady()) {
+                            return false;
+                        }
+                        else {
+                            defines._needUVs = true;
+                            defines.BUMP = true;
+                        }
                     }
                     }
-                    else {
-                        needUVs = true;
-                        this._defines.BUMP = true;
+                    if (BABYLON.StandardMaterial.ReflectionTextureEnabled) {
+                        defines.REFLECTION = true;
                     }
                     }
                 }
                 }
-                if (BABYLON.StandardMaterial.ReflectionTextureEnabled) {
-                    this._defines.REFLECTION = 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;
-            }
-            if (this.useLogarithmicDepth) {
-                this._defines.LOGARITHMICDEPTH = true;
-            }
-            if (this.fresnelSeparate) {
-                this._defines.FRESNELSEPARATE = true;
-            }
-            if (this.bumpSuperimpose) {
-                this._defines.BUMPSUPERIMPOSE = true;
-            }
-            if (this.bumpAffectsReflection) {
-                this._defines.BUMPAFFECTSREFLECTION = true;
-            }
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
             }
             }
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = true;
-                    }
-                }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            if (defines._areMiscDirty) {
+                if (this._fresnelSeparate) {
+                    defines.FRESNELSEPARATE = true;
                 }
                 }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                if (this._bumpSuperimpose) {
+                    defines.BUMPSUPERIMPOSE = true;
                 }
                 }
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
+                if (this._bumpAffectsReflection) {
+                    defines.BUMPAFFECTSREFLECTION = true;
                 }
                 }
             }
             }
+            // Lights
+            defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
+            // Attribs
+            BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             this._mesh = mesh;
             this._mesh = mesh;
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new BABYLON.EffectFallbacks();
                 var fallbacks = new BABYLON.EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                if (this._defines.LOGARITHMICDEPTH) {
+                if (defines.LOGARITHMICDEPTH) {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
                 }
-                BABYLON.MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                BABYLON.MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
                 //Attributes
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                     attribs.push(BABYLON.VertexBuffer.NormalKind);
                 }
                 }
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                 }
                 }
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                 }
                 }
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
                 }
-                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                BABYLON.MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                BABYLON.MaterialHelper.PrepareAttributesForInstances(attribs, defines);
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "water";
                 var shaderName = "water";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vNormalInfos",
                     "vNormalInfos",
@@ -328,76 +278,79 @@ var BABYLON;
                     // Water
                     // Water
                     "refractionSampler", "reflectionSampler"
                     "refractionSampler", "reflectionSampler"
                 ];
                 ];
-                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
-                this._effect = scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                BABYLON.MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
             return true;
             return true;
         };
         };
-        WaterMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            this._effect.setMatrix("world", world);
-        };
-        WaterMaterial.prototype.bind = function (world, mesh) {
+        WaterMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
             var scene = this.getScene();
             var scene = this.getScene();
+            var defines = subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
-            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
-            if (scene.getCachedMaterial() !== this) {
+            BABYLON.MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
                 if (this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
-                    this._effect.setTexture("normalSampler", this.bumpTexture);
-                    this._effect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
-                    this._effect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
+                    this._activeEffect.setTexture("normalSampler", this.bumpTexture);
+                    this._activeEffect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
+                    this._activeEffect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
                 }
                 }
                 // Clip plane
                 // Clip plane
-                BABYLON.MaterialHelper.BindClipPlane(this._effect, scene);
+                BABYLON.MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                BABYLON.MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                BABYLON.MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             // Fog
             // Fog
-            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            BABYLON.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             // Log. depth
             // Log. depth
-            BABYLON.MaterialHelper.BindLogDepth(this._defines, this._effect, scene);
+            BABYLON.MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
             // Water
             // Water
             if (BABYLON.StandardMaterial.ReflectionTextureEnabled) {
             if (BABYLON.StandardMaterial.ReflectionTextureEnabled) {
-                this._effect.setTexture("refractionSampler", this._refractionRTT);
-                this._effect.setTexture("reflectionSampler", this._reflectionRTT);
+                this._activeEffect.setTexture("refractionSampler", this._refractionRTT);
+                this._activeEffect.setTexture("reflectionSampler", this._reflectionRTT);
             }
             }
             var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
             var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
             this._lastTime += scene.getEngine().getDeltaTime();
             this._lastTime += scene.getEngine().getDeltaTime();
-            this._effect.setMatrix("worldReflectionViewProjection", wrvp);
-            this._effect.setVector2("windDirection", this.windDirection);
-            this._effect.setFloat("waveLength", this.waveLength);
-            this._effect.setFloat("time", this._lastTime / 100000);
-            this._effect.setFloat("windForce", this.windForce);
-            this._effect.setFloat("waveHeight", this.waveHeight);
-            this._effect.setFloat("bumpHeight", this.bumpHeight);
-            this._effect.setColor4("waterColor", this.waterColor, 1.0);
-            this._effect.setFloat("colorBlendFactor", this.colorBlendFactor);
-            this._effect.setColor4("waterColor2", this.waterColor2, 1.0);
-            this._effect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
-            this._effect.setFloat("waveSpeed", this.waveSpeed);
-            this._afterBind(mesh);
+            this._activeEffect.setMatrix("worldReflectionViewProjection", wrvp);
+            this._activeEffect.setVector2("windDirection", this.windDirection);
+            this._activeEffect.setFloat("waveLength", this.waveLength);
+            this._activeEffect.setFloat("time", this._lastTime / 100000);
+            this._activeEffect.setFloat("windForce", this.windForce);
+            this._activeEffect.setFloat("waveHeight", this.waveHeight);
+            this._activeEffect.setFloat("bumpHeight", this.bumpHeight);
+            this._activeEffect.setColor4("waterColor", this.waterColor, 1.0);
+            this._activeEffect.setFloat("colorBlendFactor", this.colorBlendFactor);
+            this._activeEffect.setColor4("waterColor2", this.waterColor2, 1.0);
+            this._activeEffect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
+            this._activeEffect.setFloat("waveSpeed", this.waveSpeed);
+            this._afterBind(mesh, this._activeEffect);
         };
         };
         WaterMaterial.prototype._createRenderTargets = function (scene, renderTargetSize) {
         WaterMaterial.prototype._createRenderTargets = function (scene, renderTargetSize) {
             var _this = this;
             var _this = this;
@@ -514,9 +467,12 @@ var BABYLON;
             return mesh;
             return mesh;
         };
         };
         return WaterMaterial;
         return WaterMaterial;
-    }(BABYLON.Material));
+    }(BABYLON.PushMaterial));
+    __decorate([
+        BABYLON.serializeAsTexture("bumpTexture")
+    ], WaterMaterial.prototype, "_bumpTexture", void 0);
     __decorate([
     __decorate([
-        BABYLON.serializeAsTexture()
+        BABYLON.expandToProperty("_markAllSubMeshesAsTexturesDirty")
     ], WaterMaterial.prototype, "bumpTexture", void 0);
     ], WaterMaterial.prototype, "bumpTexture", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()
@@ -528,10 +484,16 @@ var BABYLON;
         BABYLON.serialize()
         BABYLON.serialize()
     ], WaterMaterial.prototype, "specularPower", void 0);
     ], WaterMaterial.prototype, "specularPower", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("disableLighting")
+    ], WaterMaterial.prototype, "_disableLighting", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], WaterMaterial.prototype, "disableLighting", void 0);
     ], WaterMaterial.prototype, "disableLighting", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("maxSimultaneousLights")
+    ], WaterMaterial.prototype, "_maxSimultaneousLights", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsLightsDirty")
     ], WaterMaterial.prototype, "maxSimultaneousLights", void 0);
     ], WaterMaterial.prototype, "maxSimultaneousLights", void 0);
     __decorate([
     __decorate([
         BABYLON.serialize()
         BABYLON.serialize()
@@ -546,13 +508,22 @@ var BABYLON;
         BABYLON.serialize()
         BABYLON.serialize()
     ], WaterMaterial.prototype, "bumpHeight", void 0);
     ], WaterMaterial.prototype, "bumpHeight", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("bumpSuperimpose")
+    ], WaterMaterial.prototype, "_bumpSuperimpose", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsMiscDirty")
     ], WaterMaterial.prototype, "bumpSuperimpose", void 0);
     ], WaterMaterial.prototype, "bumpSuperimpose", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("fresnelSeparate")
+    ], WaterMaterial.prototype, "_fresnelSeparate", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsMiscDirty")
     ], WaterMaterial.prototype, "fresnelSeparate", void 0);
     ], WaterMaterial.prototype, "fresnelSeparate", void 0);
     __decorate([
     __decorate([
-        BABYLON.serialize()
+        BABYLON.serialize("bumpAffectsReflection")
+    ], WaterMaterial.prototype, "_bumpAffectsReflection", void 0);
+    __decorate([
+        BABYLON.expandToProperty("_markAllSubMeshesAsMiscDirty")
     ], WaterMaterial.prototype, "bumpAffectsReflection", void 0);
     ], WaterMaterial.prototype, "bumpAffectsReflection", void 0);
     __decorate([
     __decorate([
         BABYLON.serializeAsColor3()
         BABYLON.serializeAsColor3()

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 5 - 0
localDev/src/index.js

@@ -0,0 +1,5 @@
+/// <reference path="../../dist/preview release/babylon.d.ts"/>
+
+// Playground like creation of the scene
+var createScene = function () {
+}

+ 2 - 6
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -96,24 +96,20 @@ module BABYLON {
                         defines._needUVs = true;
                         defines._needUVs = true;
                         defines.DIFFUSE = true;
                         defines.DIFFUSE = true;
                     }
                     }
-                }  
-                defines._areTexturesDirty = false;              
+                }              
             }
             }
 
 
             // Misc.
             // Misc.
             if (defines._areMiscDirty) {
             if (defines._areMiscDirty) {
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
-
-                defines._areMiscDirty = false;
             }
             }
             
             
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             
             
             // Attribs
             // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
-            defines._areAttributesDirty = false;
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
 
 
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {

+ 108 - 156
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -1,8 +1,6 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
 module BABYLON {
 module BABYLON {
-    var maxSimultaneousLights = 4;
-
     class FurMaterialDefines extends MaterialDefines {
     class FurMaterialDefines extends MaterialDefines {
         public DIFFUSE = false;
         public DIFFUSE = false;
         public HEIGHTMAP = false;
         public HEIGHTMAP = false;
@@ -26,13 +24,17 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class FurMaterial extends Material {
+    export class FurMaterial extends PushMaterial {
         
         
-        @serializeAsTexture()
+        @serializeAsTexture("diffuseTexture")
+        private _diffuseTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture: BaseTexture;
         public diffuseTexture: BaseTexture;
         
         
-        @serializeAsTexture()
-        public heightTexture: BaseTexture;
+        @serializeAsTexture("heightTexture")
+        private _heightTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public heightTexture: BaseTexture;        
         
         
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
@@ -63,15 +65,20 @@ module BABYLON {
         
         
         public furTexture: DynamicTexture;
         public furTexture: DynamicTexture;
         
         
-        @serialize()
-        public disableLighting = false;
         
         
-        @serialize()
-        public highLevelFur: boolean = true;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;   
         
         
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number; 
         
         
+        @serialize()
+        public highLevelFur: boolean = true;
+               
         public _meshes: AbstractMesh[];
         public _meshes: AbstractMesh[];
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
@@ -79,13 +86,8 @@ module BABYLON {
         
         
         private _furTime: number = 0;
         private _furTime: number = 0;
 
 
-        private _defines = new FurMaterialDefines();
-        private _cachedDefines = new FurMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
         
         
         @serialize()
         @serialize()
@@ -128,165 +130,111 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new FurMaterialDefines();
+            }
+
+            var defines = <FurMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-
-            this._defines.reset();
 
 
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
-                } 
-                if (this.heightTexture) {
-                    if (!this.heightTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.HEIGHTMAP = 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;
+            if (defines._areTexturesDirty) {
+                if (scene.texturesEnabled) {
+                    if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                        if (!this.diffuseTexture.isReady()) {
+                            return false;
+                        } else {
+                            defines._needUVs = true;
+                            defines.DIFFUSE = true;
+                        }
+                    } 
+                    if (this.heightTexture && engine.getCaps().maxVertexTextureImageUnits) {
+                        if (!this.heightTexture.isReady()) {
+                            return false;
+                        } else {
+                            defines._needUVs = true;
+                            defines.HEIGHTMAP = true;
+                        }
+                    }               
+                }
             }
             }
 
 
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            
             // High level
             // High level
-            if (this.highLevelFur) {
-                this._defines.HIGHLEVEL = true;
+            if (this.highLevelFur !== defines.HIGHLEVEL) {
+                defines.HIGHLEVEL = true;
+                defines.markAsUnprocessed();
             }
             }
 
 
+            // Misc.   
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+
             // Lights
             // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false, this.maxSimultaneousLights);
-            }
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
+            // Values that need to be evaluated on every frame
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
 
 
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
              
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "fur";
                 var shaderName = "fur";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vDiffuseInfos", 
                     "vDiffuseInfos", 
@@ -298,13 +246,13 @@ module BABYLON {
                     "heightTexture", "furTexture"
                     "heightTexture", "furTexture"
                 ];
                 ];
                 
                 
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
                 
                 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -314,75 +262,79 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <FurMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
                 // Textures        
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
+                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                    this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
 
 
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                    this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                 }
                 }
                 
                 
-                if (this.heightTexture) {
-                    this._effect.setTexture("heightTexture", this.heightTexture);
+                if (this._heightTexture) {
+                    this._activeEffect.setTexture("heightTexture", this._heightTexture);
                 }
                 }
                 
                 
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             
             
-            this._effect.setFloat("furLength", this.furLength);
-            this._effect.setFloat("furAngle", this.furAngle);
-            this._effect.setColor4("furColor", this.furColor, 1.0);
+            this._activeEffect.setFloat("furLength", this.furLength);
+            this._activeEffect.setFloat("furAngle", this.furAngle);
+            this._activeEffect.setColor4("furColor", this.furColor, 1.0);
             
             
             if (this.highLevelFur) {
             if (this.highLevelFur) {
-                this._effect.setVector3("furGravity", this.furGravity);
-                this._effect.setFloat("furOffset", this.furOffset);
-                this._effect.setFloat("furSpacing", this.furSpacing);
-                this._effect.setFloat("furDensity", this.furDensity);
+                this._activeEffect.setVector3("furGravity", this.furGravity);
+                this._activeEffect.setFloat("furOffset", this.furOffset);
+                this._activeEffect.setFloat("furSpacing", this.furSpacing);
+                this._activeEffect.setFloat("furDensity", this.furDensity);
                 
                 
                 this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
                 this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
-                this._effect.setFloat("furTime", this._furTime);
+                this._activeEffect.setFloat("furTime", this._furTime);
                 
                 
-                this._effect.setTexture("furTexture", this.furTexture);
+                this._activeEffect.setTexture("furTexture", this.furTexture);
             }
             }
  
  
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 5 - 0
materialsLibrary/src/fur/fur.fragment.fx

@@ -97,9 +97,14 @@ void main(void) {
 	// Lighting
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
 	vec3 diffuseBase = vec3(0., 0., 0.);
     lightingInfo info;
     lightingInfo info;
+
 	float shadow = 1.;
 	float shadow = 1.;
 	float glossiness = 0.;
 	float glossiness = 0.;
 
 
+#ifdef SPECULARTERM
+	vec3 specularBase = vec3(0., 0., 0.);
+#endif
+
 	#include<lightFragment>[0..maxSimultaneousLights]
 	#include<lightFragment>[0..maxSimultaneousLights]
 
 
 #ifdef VERTEXALPHA
 #ifdef VERTEXALPHA

+ 6 - 2
materialsLibrary/src/fur/fur.vertex.fx

@@ -76,8 +76,12 @@ void main(void) {
 
 
 //FUR
 //FUR
 float r = Rand(position);
 float r = Rand(position);
-#ifdef HEIGHTMAP	
-	vfur_length = furLength * texture2D(heightTexture, uv).rgb.x;
+#ifdef HEIGHTMAP
+	#if __VERSION__ > 100
+	vfur_length = furLength * texture(heightTexture, uv).x;
+	#else
+	vfur_length = furLength * texture2D(heightTexture, uv).r;
+	#endif
 #else	
 #else	
 	vfur_length = (furLength * r);
 	vfur_length = (furLength * r);
 #endif
 #endif

+ 56 - 117
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -1,8 +1,6 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
 module BABYLON {
 module BABYLON {
-    var maxSimultaneousLights = 4;
-
     class GradientMaterialDefines extends MaterialDefines {
     class GradientMaterialDefines extends MaterialDefines {
         public DIFFUSE = false;
         public DIFFUSE = false;
         public CLIPPLANE = false;
         public CLIPPLANE = false;
@@ -57,7 +55,12 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class GradientMaterial extends Material {
+    export class GradientMaterial extends PushMaterial {
+          
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number;       
 
 
         // The gradient top color, red by default
         // The gradient top color, red by default
         @serializeAsColor3()
         @serializeAsColor3()
@@ -87,13 +90,8 @@ module BABYLON {
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new GradientMaterialDefines();
-        private _cachedDefines = new GradientMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -109,143 +107,82 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new GradientMaterialDefines();
+            }
+
+            var defines = <GradientMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-
-            this._defines.reset();
-
-            // No textures
-
-            // 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;
-            }
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
 
 
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
-            var lightIndex = 0;
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false);
-            }
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
 
 
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;                    
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
 
 
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
              
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "gradient";
                 var shaderName = "gradient";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName,
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                         "vLightData0", "vLightDiffuse0","vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData0", "vLightDiffuse0","vLightDirection0", "vLightGround0", "lightMatrix0",
@@ -261,9 +198,9 @@ module BABYLON {
                     ["diffuseSampler",
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     ],
                     ],
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -273,54 +210,56 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <GradientMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+            
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
             MaterialHelper.BindBonesParameters(mesh, this._effect);
             MaterialHelper.BindBonesParameters(mesh, this._effect);
 
 
-
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
                 MaterialHelper.BindClipPlane(this._effect, scene);
                 MaterialHelper.BindClipPlane(this._effect, scene);
 
 
-
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._effect.setColor4("topColor", this.topColor, this.topColorAlpha);
-            this._effect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
-            this._effect.setFloat("offset", this.offset);
-            this._effect.setFloat("smoothness", this.smoothness);
+            this._activeEffect.setColor4("topColor", this.topColor, this.topColorAlpha);
+            this._activeEffect.setColor4("bottomColor", this.bottomColor, this.bottomColorAlpha);
+            this._activeEffect.setFloat("offset", this.offset);
+            this._activeEffect.setFloat("smoothness", this.smoothness);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 36 - 52
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -1,7 +1,7 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
 module BABYLON {
 module BABYLON {
-    class GRIDMaterialDefines extends MaterialDefines {
+    class GridMaterialDefines extends MaterialDefines {
         public TRANSPARENT = false;
         public TRANSPARENT = false;
 
 
         public FOG = false;
         public FOG = false;
@@ -16,7 +16,7 @@ module BABYLON {
      * The grid materials allows you to wrap any shape with a grid.
      * The grid materials allows you to wrap any shape with a grid.
      * Colors are customizable.
      * Colors are customizable.
      */
      */
-    export class GridMaterial extends BABYLON.Material {
+    export class GridMaterial extends BABYLON.PushMaterial {
 
 
         /**
         /**
          * Main color of the grid (e.g. between lines)
          * Main color of the grid (e.g. between lines)
@@ -57,8 +57,6 @@ module BABYLON {
         private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
         private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
 
 
         private _renderId: number;
         private _renderId: number;
-        private _defines = new GRIDMaterialDefines();
-        private _cachedDefines = new GRIDMaterialDefines();
 
 
         /**
         /**
          * constructor
          * constructor
@@ -76,48 +74,38 @@ module BABYLON {
             return this.opacity < 1.0;
             return this.opacity < 1.0;
         }
         }
 
 
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-            
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new GridMaterialDefines();
+            }
+
+            var defines = <GridMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = true;
 
 
-            this._defines.reset();
-
-            if (this.opacity < 1.0) {
-                this._defines.TRANSPARENT = true;
+            if (this.opacity < 1.0 && !defines.TRANSPARENT) {
+                defines.TRANSPARENT = true;
+                defines.markAsUnprocessed();
             }
             }
 
 
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._effect || !this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Attributes
                 // Attributes
@@ -127,18 +115,18 @@ module BABYLON {
                 var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
                 var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
 
 
                 // Defines
                 // Defines
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName,
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
                     ["worldViewProjection", "mainColor", "lineColor", "gridControl", "vFogInfos", "vFogColor", "world", "view"],
                     ["worldViewProjection", "mainColor", "lineColor", "gridControl", "vFogInfos", "vFogColor", "world", "view"],
                     [],
                     [],
                     join,
                     join,
                     null,
                     null,
                     this.onCompiled,
                     this.onCompiled,
-                    this.onError);
+                    this.onError), defines);
             }
             }
 
 
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -148,41 +136,37 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
-            this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
-            this._effect.setMatrix("world", world);
-            this._effect.setMatrix("view", scene.getViewMatrix());
-        }
+            var defines = <GridMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
 
 
-        public bind(world: Matrix, mesh?: Mesh): void {
-            var scene = this.getScene();
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
 
 
             // Matrices
             // Matrices
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
+            this._activeEffect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
+            this._activeEffect.setMatrix("view", scene.getViewMatrix());
 
 
             // Uniforms
             // Uniforms
-            if (scene.getCachedMaterial() !== (<BABYLON.Material>this)) {
-                this._effect.setColor3("mainColor", this.mainColor);
-                this._effect.setColor3("lineColor", this.lineColor);
+            if (this._mustRebind(scene, effect)) {
+                this._activeEffect.setColor3("mainColor", this.mainColor);
+                this._activeEffect.setColor3("lineColor", this.lineColor);
 
 
                 this._gridControl.x = this.gridRatio;
                 this._gridControl.x = this.gridRatio;
                 this._gridControl.y = Math.round(this.majorUnitFrequency);
                 this._gridControl.y = Math.round(this.majorUnitFrequency);
                 this._gridControl.z = this.minorUnitVisibility;
                 this._gridControl.z = this.minorUnitVisibility;
                 this._gridControl.w = this.opacity;
                 this._gridControl.w = this.opacity;
-                this._effect.setVector4("gridControl", this._gridControl);
+                this._activeEffect.setVector4("gridControl", this._gridControl);
             }
             }
-
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
-            }
-
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {

+ 84 - 132
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -55,8 +55,10 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class LavaMaterial extends Material {
-        @serializeAsTexture()
+    export class LavaMaterial extends PushMaterial {
+        @serializeAsTexture("diffuseTexture")
+        private _diffuseTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture: BaseTexture;
         public diffuseTexture: BaseTexture;
         
         
         @serializeAsTexture()
         @serializeAsTexture()
@@ -82,23 +84,22 @@ module BABYLON {
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
         
         
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;   
 
 
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number; 
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new LavaMaterialDefines();
-        private _cachedDefines = new LavaMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -114,150 +115,98 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new LavaMaterialDefines();
+            }
+
+            var defines = <LavaMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needUVs = false;
-
-            this._defines.reset();
 
 
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
-                    }
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                        if (!this._diffuseTexture.isReady()) {
+                            return false;
+                        } else {
+                            defines._needUVs = true;
+                            defines.DIFFUSE = 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;
-            }
+               // Misc.
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
-            if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false, this.maxSimultaneousLights);
-            }
+            // Lights
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
+            // Values that need to be evaluated on every frame
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            
             // Attribs
             // Attribs
-            if (mesh) {
-                if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();
                 var fallbacks = new EffectFallbacks();
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
 
 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "lava";
                 var shaderName = "lava";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName,
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                         "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
@@ -275,9 +224,9 @@ module BABYLON {
                     ["diffuseSampler",
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3", "noiseTexture"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3", "noiseTexture"
                     ],
                     ],
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights - 1 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -287,73 +236,76 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <LavaMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                 if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
+                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
 
 
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
                 }
                 }
 
 
                 if (this.noiseTexture) {
                 if (this.noiseTexture) {
-                    this._effect.setTexture("noiseTexture", this.noiseTexture);
+                    this._activeEffect.setTexture("noiseTexture", this.noiseTexture);
                 }
                 }
 
 
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
 
 
             this._lastTime += scene.getEngine().getDeltaTime();
             this._lastTime += scene.getEngine().getDeltaTime();
-            this._effect.setFloat("time", this._lastTime * this.speed / 1000);
+            this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
 
 
             if (! this.fogColor) {
             if (! this.fogColor) {
                 this.fogColor = Color3.Black();
                 this.fogColor = Color3.Black();
             }
             }
-            this._effect.setColor3("fogColor", this.fogColor);
-            this._effect.setFloat("fogDensity", this.fogDensity);
-
-            this._effect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
-            this._effect.setFloat("movingSpeed", this.movingSpeed);
+            this._activeEffect.setColor3("fogColor", this.fogColor);
+            this._activeEffect.setFloat("fogDensity", this.fogDensity);
 
 
+            this._activeEffect.setFloat("lowFrequencySpeed", this.lowFrequencySpeed);
+            this._activeEffect.setFloat("movingSpeed", this.movingSpeed);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 81 - 126
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -55,27 +55,31 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class NormalMaterial extends Material {
-        @serializeAsTexture()
+    export class NormalMaterial extends PushMaterial {
+        @serializeAsTexture("diffuseTexture")
+        private _diffuseTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture: BaseTexture;
         public diffuseTexture: BaseTexture;
 
 
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
         
         
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;   
+        
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number; 
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new NormalMaterialDefines();
-        private _cachedDefines = new NormalMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -91,151 +95,98 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new NormalMaterialDefines();
+            }
+
+            var defines = <NormalMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-
-            this._defines.reset();
-
-            // Textures
-            if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    if (!this.diffuseTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = 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;
+             // Textures
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                        if (!this._diffuseTexture.isReady()) {
+                            return false;
+                        } else {
+                            defines._needUVs = true;
+                            defines.DIFFUSE = true;
+                        }
+                    }                
+                }
             }
             }
 
 
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
+            // Misc.
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
-            var lightIndex = 0;
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false);
-            }
+            // Lights
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
+            // Values that need to be evaluated on every frame
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
 
 
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
                 
                 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 var shaderName = "normal";
                 var shaderName = "normal";
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName,
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                         "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData0", "vLightDiffuse0", "vLightDirection0", "vLightGround0", "lightMatrix0",
@@ -251,9 +202,9 @@ module BABYLON {
                     ["diffuseSampler",
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                     ],
                     ],
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: 4 }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -263,55 +214,59 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <NormalMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                 if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
+                    this._activeEffect.setTexture("diffuseSampler", this.diffuseTexture);
 
 
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+                    this._activeEffect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                    this._activeEffect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
                 }
                 }
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);          
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 46 - 85
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -16,20 +16,15 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class ShadowOnlyMaterial extends Material {
+    export class ShadowOnlyMaterial extends PushMaterial {
         @serialize()
         @serialize()
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new ShadowOnlyMaterialDefines();
-        private _cachedDefines = new ShadowOnlyMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -45,105 +40,67 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new ShadowOnlyMaterialDefines();
+            }
+
+            var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
 
 
-            this._defines.reset();
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
 
 
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = true;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
-            // 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;
-            }
-
-            if (scene.lightsEnabled) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, false, 1);
-            }
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
 
 
             // Attribs
             // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
 
 
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, 1);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
                 
                 
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 var shaderName = "shadowOnly";
                 var shaderName = "shadowOnly";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                                 "vFogInfos", "vFogColor", "pointSize",
                                 "vFogInfos", "vFogColor", "pointSize",
                                 "mBones",
                                 "mBones",
@@ -151,13 +108,13 @@ module BABYLON {
                 ];
                 ];
                 var samplers = [];
                 var samplers = [];
                     
                     
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, 1);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, 1);
                 
                 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, {maxSimultaneousLights: 1});
+                    join, fallbacks, this.onCompiled, this.onError, {maxSimultaneousLights: 1}), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -167,46 +124,50 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <ShadowOnlyMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled) {
             if (scene.lightsEnabled) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, 1);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);          
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public clone(name: string): ShadowOnlyMaterial {
         public clone(name: string): ShadowOnlyMaterial {

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

@@ -97,27 +97,19 @@ module BABYLON {
                         }
                         }
                     }                
                     }                
                 }
                 }
-                defines._areTexturesDirty = false;
             }
             }
 
 
             // Misc.
             // Misc.
-            if (defines._areMiscDirty) {
-                defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
-                defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
-
-                defines._areMiscDirty = false;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Lights
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
-            defines._areLightsDirty = false;
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             
             
             // Attribs
             // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
-            defines._areAttributesDirty = false;
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {

+ 44 - 71
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -14,7 +14,7 @@ module BABYLON {
         }
         }
     }
     }
     
     
-    export class SkyMaterial extends Material {
+    export class SkyMaterial extends PushMaterial {
         // Public members
         // Public members
         @serialize()
         @serialize()
         public luminance: number = 1.0;
         public luminance: number = 1.0;
@@ -49,10 +49,7 @@ module BABYLON {
         // Private members
         // Private members
         private _cameraPosition: Vector3 = Vector3.Zero();
         private _cameraPosition: Vector3 = Vector3.Zero();
         
         
-        private _renderId: number;
-        
-        private _defines = new SkyMaterialDefines();
-        private _cachedDefines = new SkyMaterialDefines();
+        private _renderId: number;        
 
 
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
@@ -71,84 +68,56 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new SkyMaterialDefines();
+            }
+
+            var defines = <SkyMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            this._defines.reset();
 
 
-            // Effect
-            if (scene.clipPlane) {
-                this._defines.CLIPPLANE = 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;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             
             
             // Attribs
             // Attribs
-            if (mesh) {
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {
-                    this._defines.VERTEXCOLOR = true;
-
-                    if (mesh.hasVertexAlpha) {
-                        this._defines.VERTEXALPHA = true;
-                    }
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines) || !this._effect) {
-                this._defines.cloneTo(this._cachedDefines);
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 
                 
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
                 
                 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
                 
                 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                // Legacy browser patch
                 var shaderName = "sky";
                 var shaderName = "sky";
                 
                 
-                var join = this._defines.toString();
-                this._effect = scene.getEngine().createEffect(shaderName,
+                var join = defines.toString();
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs,
                     attribs,
                     ["world", "viewProjection", "view",
                     ["world", "viewProjection", "view",
                         "vFogInfos", "vFogColor", "pointSize", "vClipPlane",
                         "vFogInfos", "vFogColor", "pointSize", "vClipPlane",
@@ -156,10 +125,10 @@ module BABYLON {
                         "cameraPosition"
                         "cameraPosition"
                     ],
                     ],
                     [],
                     [],
-                    join, fallbacks, this.onCompiled, this.onError);
+                    join, fallbacks, this.onCompiled, this.onError), defines);
             }
             }
             
             
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -169,37 +138,41 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <SkyMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Clip plane
                 // Clip plane
                 if (scene.clipPlane) {
                 if (scene.clipPlane) {
                     var clipPlane = scene.clipPlane;
                     var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
+                    this._activeEffect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
                 }
                 }
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }               
                 }               
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
             
             
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             
             
             // Sky
             // Sky
             var camera = scene.activeCamera;
             var camera = scene.activeCamera;
@@ -208,17 +181,17 @@ module BABYLON {
                 this._cameraPosition.x = cameraWorldMatrix.m[12];
                 this._cameraPosition.x = cameraWorldMatrix.m[12];
                 this._cameraPosition.y = cameraWorldMatrix.m[13];
                 this._cameraPosition.y = cameraWorldMatrix.m[13];
                 this._cameraPosition.z = cameraWorldMatrix.m[14];
                 this._cameraPosition.z = cameraWorldMatrix.m[14];
-                this._effect.setVector3("cameraPosition", this._cameraPosition);
+                this._activeEffect.setVector3("cameraPosition", this._cameraPosition);
             }
             }
             
             
             if (this.luminance > 0) {
             if (this.luminance > 0) {
-                this._effect.setFloat("luminance", this.luminance);
+                this._activeEffect.setFloat("luminance", this.luminance);
             }
             }
             
             
-			this._effect.setFloat("turbidity", this.turbidity);
-			this._effect.setFloat("rayleigh", this.rayleigh);
-			this._effect.setFloat("mieCoefficient", this.mieCoefficient);
-			this._effect.setFloat("mieDirectionalG", this.mieDirectionalG);
+			this._activeEffect.setFloat("turbidity", this.turbidity);
+			this._activeEffect.setFloat("rayleigh", this.rayleigh);
+			this._activeEffect.setFloat("mieCoefficient", this.mieCoefficient);
+			this._activeEffect.setFloat("mieDirectionalG", this.mieDirectionalG);
             
             
             if (!this.useSunPosition) {
             if (!this.useSunPosition) {
                 var theta = Math.PI * (this.inclination - 0.5);
                 var theta = Math.PI * (this.inclination - 0.5);
@@ -229,9 +202,9 @@ module BABYLON {
                 this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
                 this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
             }
             }
             
             
-			this._effect.setVector3("sunPosition", this.sunPosition);
+			this._activeEffect.setVector3("sunPosition", this.sunPosition);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 115 - 156
materialsLibrary/src/terrain/babylon.terrainMaterial.ts

@@ -1,7 +1,6 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
 module BABYLON {
 module BABYLON {
-    var maxSimultaneousLights = 4;
 
 
     class TerrainMaterialDefines extends MaterialDefines {
     class TerrainMaterialDefines extends MaterialDefines {
         public DIFFUSE = false;
         public DIFFUSE = false;
@@ -26,27 +25,41 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class TerrainMaterial extends Material {
-        @serializeAsTexture()
-        public mixTexture: BaseTexture;
+    export class TerrainMaterial extends PushMaterial {
+        @serializeAsTexture("mixTexture")
+        private _mixTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public mixTexture: BaseTexture;        
         
         
-        @serializeAsTexture()
+        @serializeAsTexture("diffuseTexture1")
+        private _diffuseTexture1: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture1: Texture;
         public diffuseTexture1: Texture;
-        
-        @serializeAsTexture()
+
+        @serializeAsTexture("diffuseTexture2")
+        private _diffuseTexture2: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture2: Texture;
         public diffuseTexture2: Texture;
         
         
-        @serializeAsTexture()
+        @serializeAsTexture("diffuseTexture3")
+        private _diffuseTexture3: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture3: Texture;
         public diffuseTexture3: Texture;
         
         
-        @serializeAsTexture()
-        public bumpTexture1: Texture;
+        @serializeAsTexture("bumpTexture1")
+        private _bumpTexture1: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public bumpTexture1: Texture;        
         
         
-        @serializeAsTexture()
-        public bumpTexture2: Texture;
+        @serializeAsTexture("bumpTexture2")
+        private _bumpTexture2: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public bumpTexture2: Texture;        
         
         
-        @serializeAsTexture()
-        public bumpTexture3: Texture;
+        @serializeAsTexture("bumpTexture3")
+        private _bumpTexture3: Texture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public bumpTexture3: Texture;   
         
         
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
@@ -57,22 +70,21 @@ module BABYLON {
         @serialize()
         @serialize()
         public specularPower = 64;
         public specularPower = 64;
         
         
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;   
         
         
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number; 
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new TerrainMaterialDefines();
-        private _cachedDefines = new TerrainMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -88,156 +100,99 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new TerrainMaterialDefines();
+            }
+
+            var defines = <TerrainMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-
-            this._defines.reset();
-
-            // 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;
-            }
-
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
-            }
-            
             // Textures
             // Textures
             if (scene.texturesEnabled) {
             if (scene.texturesEnabled) {
                 if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
                 if (this.mixTexture && StandardMaterial.DiffuseTextureEnabled) {
                     if (!this.mixTexture.isReady()) {
                     if (!this.mixTexture.isReady()) {
                         return false;
                         return false;
                     } else {
                     } else {
-                        needUVs = true;
-                        this._defines.DIFFUSE = true;
+                        defines._needUVs = true;
+                        defines.DIFFUSE = true;
                     }
                     }
                 }
                 }
                 if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
                 if ((this.bumpTexture1 || this.bumpTexture2 || this.bumpTexture3) && StandardMaterial.BumpTextureEnabled) {
-                    needUVs = true;
-                    needNormals = true;
-                    this._defines.BUMP = true;
+                    defines._needUVs = true;
+                    defines._needNormals = true;
+                    defines.BUMP = true;
                 }
                 }
             }
             }
+            
+            // Misc.
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
-                }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
+            // Lights
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            // Values that need to be evaluated on every frame
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            
+            // Attribs
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
              
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "terrain";
                 var shaderName = "terrain";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vTextureInfos", 
                     "vTextureInfos", 
@@ -250,13 +205,13 @@ module BABYLON {
                     "bump1Sampler", "bump2Sampler", "bump3Sampler"
                     "bump1Sampler", "bump2Sampler", "bump3Sampler"
                 ];
                 ];
                 
                 
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
                 
                 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -266,84 +221,88 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <TerrainMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.mixTexture) {
                 if (this.mixTexture) {
-                    this._effect.setTexture("textureSampler", this.mixTexture);
-                    this._effect.setFloat2("vTextureInfos", this.mixTexture.coordinatesIndex, this.mixTexture.level);
-                    this._effect.setMatrix("textureMatrix", this.mixTexture.getTextureMatrix());
+                    this._activeEffect.setTexture("textureSampler", this._mixTexture);
+                    this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
+                    this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
                     
                     
                     if (StandardMaterial.DiffuseTextureEnabled) {
                     if (StandardMaterial.DiffuseTextureEnabled) {
-                        if (this.diffuseTexture1) {
-                            this._effect.setTexture("diffuse1Sampler", this.diffuseTexture1);
-                            this._effect.setFloat2("diffuse1Infos", this.diffuseTexture1.uScale, this.diffuseTexture1.vScale);
+                        if (this._diffuseTexture1) {
+                            this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
+                            this._activeEffect.setFloat2("diffuse1Infos", this._diffuseTexture1.uScale, this._diffuseTexture1.vScale);
                         }
                         }
-                        if (this.diffuseTexture2) {
-                            this._effect.setTexture("diffuse2Sampler", this.diffuseTexture2);
-                            this._effect.setFloat2("diffuse2Infos", this.diffuseTexture2.uScale, this.diffuseTexture2.vScale);
+                        if (this._diffuseTexture2) {
+                            this._activeEffect.setTexture("diffuse2Sampler", this._diffuseTexture2);
+                            this._activeEffect.setFloat2("diffuse2Infos", this._diffuseTexture2.uScale, this._diffuseTexture2.vScale);
                         }
                         }
-                        if (this.diffuseTexture3) {
-                            this._effect.setTexture("diffuse3Sampler", this.diffuseTexture3);
-                            this._effect.setFloat2("diffuse3Infos", this.diffuseTexture3.uScale, this.diffuseTexture3.vScale);
+                        if (this._diffuseTexture3) {
+                            this._activeEffect.setTexture("diffuse3Sampler", this._diffuseTexture3);
+                            this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
                         }
                         }
                     }
                     }
                     
                     
                     if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
                     if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
-                        if (this.bumpTexture1) {
-                            this._effect.setTexture("bump1Sampler", this.bumpTexture1);
+                        if (this._bumpTexture1) {
+                            this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
                         }
                         }
-                        if (this.bumpTexture2) {
-                            this._effect.setTexture("bump2Sampler", this.bumpTexture2);
+                        if (this._bumpTexture2) {
+                            this._activeEffect.setTexture("bump2Sampler", this._bumpTexture2);
                         }
                         }
-                        if (this.bumpTexture3) {
-                            this._effect.setTexture("bump3Sampler", this.bumpTexture3);
+                        if (this._bumpTexture3) {
+                            this._activeEffect.setTexture("bump3Sampler", this._bumpTexture3);
                         }
                         }
                     }
                     }
                 }
                 }
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 116 - 150
materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts

@@ -1,8 +1,6 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
 module BABYLON {
 module BABYLON {
-    var maxSimultaneousLights = 4;
-
     class TriPlanarMaterialDefines extends MaterialDefines {
     class TriPlanarMaterialDefines extends MaterialDefines {
         public DIFFUSEX = false;
         public DIFFUSEX = false;
         public DIFFUSEY = false;
         public DIFFUSEY = false;
@@ -30,28 +28,40 @@ module BABYLON {
         }
         }
     }
     }
 
 
-    export class TriPlanarMaterial extends Material {
+    export class TriPlanarMaterial extends PushMaterial {
         @serializeAsTexture()
         @serializeAsTexture()
         public mixTexture: BaseTexture;
         public mixTexture: BaseTexture;
         
         
-        @serializeAsTexture()
-        public diffuseTextureX: Texture;
+        @serializeAsTexture("diffuseTextureX")
+        private _diffuseTextureX: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public diffuseTextureX: BaseTexture;
         
         
-        @serializeAsTexture()
-        public diffuseTextureY: Texture;
+        @serializeAsTexture("diffuseTexturY")
+        private _diffuseTextureY: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public diffuseTextureY: BaseTexture;        
         
         
-        @serializeAsTexture()
-        public diffuseTextureZ: Texture;
+        @serializeAsTexture("diffuseTextureZ")
+        private _diffuseTextureZ: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public diffuseTextureZ: BaseTexture;        
         
         
-        @serializeAsTexture()
-        public normalTextureX: Texture;
+        @serializeAsTexture("normalTextureX")
+        private _normalTextureX: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public normalTextureX: BaseTexture;        
         
         
-        @serializeAsTexture()
-        public normalTextureY: Texture;
-        
-        @serializeAsTexture()
-        public normalTextureZ: Texture;
+        @serializeAsTexture("normalTextureY")
+        private _normalTextureY: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public normalTextureY: BaseTexture;        
         
         
+        @serializeAsTexture("normalTextureZ")
+        private _normalTextureZ: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public normalTextureZ: BaseTexture;        
+               
         @serialize()
         @serialize()
         public tileSize: number = 1;
         public tileSize: number = 1;
         
         
@@ -64,22 +74,21 @@ module BABYLON {
         @serialize()
         @serialize()
         public specularPower = 64;
         public specularPower = 64;
         
         
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;   
         
         
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number; 
 
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new TriPlanarMaterialDefines();
-        private _cachedDefines = new TriPlanarMaterialDefines();
-
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
-
-            this._cachedDefines.BonesPerMesh = -1;
         }
         }
 
 
         public needAlphaBlending(): boolean {
         public needAlphaBlending(): boolean {
@@ -95,155 +104,108 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
-
-        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new TriPlanarMaterialDefines();
+            }
+
+            var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-
-            this._defines.reset();
 
 
             // Textures
             // 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 (defines._areTexturesDirty) {                
+                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 {
+                                    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;
+                    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 {
+                                    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;
-            }
+            // Misc.
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Lights
             // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
-            }
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
+            // Values that need to be evaluated on every frame
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            
             // Attribs
             // 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                }
-
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
-                }
-            }
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
              
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "triplanar";
                 var shaderName = "triplanar";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "mBones",
                     "mBones",
@@ -254,13 +216,13 @@ module BABYLON {
                     "normalSamplerX", "normalSamplerY", "normalSamplerZ"
                     "normalSamplerX", "normalSamplerY", "normalSamplerZ"
                 ];
                 ];
                 
                 
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
                 
                 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -270,72 +232,76 @@ module BABYLON {
             return true;
             return true;
         }
         }
 
 
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-
-        public bind(world: Matrix, mesh?: Mesh): void {
+        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <TriPlanarMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
             
             
-            this._effect.setFloat("tileSize", this.tileSize);
+            this._activeEffect.setFloat("tileSize", this.tileSize);
 
 
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
                 // Textures        
                 // Textures        
                 if (this.diffuseTextureX) {
                 if (this.diffuseTextureX) {
-                    this._effect.setTexture("diffuseSamplerX", this.diffuseTextureX);
+                    this._activeEffect.setTexture("diffuseSamplerX", this.diffuseTextureX);
                 }
                 }
                 if (this.diffuseTextureY) {
                 if (this.diffuseTextureY) {
-                    this._effect.setTexture("diffuseSamplerY", this.diffuseTextureY);
+                    this._activeEffect.setTexture("diffuseSamplerY", this.diffuseTextureY);
                 }
                 }
                 if (this.diffuseTextureZ) {
                 if (this.diffuseTextureZ) {
-                    this._effect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
+                    this._activeEffect.setTexture("diffuseSamplerZ", this.diffuseTextureZ);
                 }
                 }
                 if (this.normalTextureX) {
                 if (this.normalTextureX) {
-                    this._effect.setTexture("normalSamplerX", this.normalTextureX);
+                    this._activeEffect.setTexture("normalSamplerX", this.normalTextureX);
                 }
                 }
                 if (this.normalTextureY) {
                 if (this.normalTextureY) {
-                    this._effect.setTexture("normalSamplerY", this.normalTextureY);
+                    this._activeEffect.setTexture("normalSamplerY", this.normalTextureY);
                 }
                 }
                 if (this.normalTextureZ) {
                 if (this.normalTextureZ) {
-                    this._effect.setTexture("normalSamplerZ", this.normalTextureZ);
+                    this._activeEffect.setTexture("normalSamplerZ", this.normalTextureZ);
                 }
                 }
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {

+ 124 - 167
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -29,12 +29,14 @@ module BABYLON {
         }
         }
     }
     }
 	
 	
-	export class WaterMaterial extends Material {
+	export class WaterMaterial extends PushMaterial {
 		/*
 		/*
 		* Public members
 		* Public members
 		*/
 		*/
-        @serializeAsTexture()
-        public bumpTexture: BaseTexture;
+        @serializeAsTexture("bumpTexture")
+        private _bumpTexture: BaseTexture;
+        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+        public bumpTexture: BaseTexture;        
         
         
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
@@ -45,11 +47,15 @@ module BABYLON {
         @serialize()
         @serialize()
         public specularPower = 64;
         public specularPower = 64;
         
         
-        @serialize()
-        public disableLighting = false;
+        @serialize("disableLighting")
+        private _disableLighting = false;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public disableLighting: boolean;
         
         
-        @serialize()
-        public maxSimultaneousLights = 4;
+        @serialize("maxSimultaneousLights")
+        private _maxSimultaneousLights = 4;
+        @expandToProperty("_markAllSubMeshesAsLightsDirty")
+        public maxSimultaneousLights: number;                   
         
         
         /**
         /**
         * @param {number}: Represents the wind force
         * @param {number}: Represents the wind force
@@ -74,18 +80,26 @@ module BABYLON {
         /**
         /**
          * @param {boolean}: Add a smaller moving bump to less steady waves.
          * @param {boolean}: Add a smaller moving bump to less steady waves.
          */
          */
-        @serialize()
-        public bumpSuperimpose = false;
+        @serialize("bumpSuperimpose")
+        private _bumpSuperimpose = false;
+        @expandToProperty("_markAllSubMeshesAsMiscDirty")
+        public bumpSuperimpose: boolean;
+
         /**
         /**
          * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
          * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
          */
          */
-        @serialize()
-        public fresnelSeparate = false;
+        @serialize("fresnelSeparate")
+        private _fresnelSeparate = false;
+        @expandToProperty("_markAllSubMeshesAsMiscDirty")
+        public fresnelSeparate: boolean;
+
         /**
         /**
          * @param {boolean}: bump Waves modify the reflection.
          * @param {boolean}: bump Waves modify the reflection.
          */
          */
-        @serialize()
-        public bumpAffectsReflection = false;
+        @serialize("bumpAffectsReflection")
+        private _bumpAffectsReflection = false;
+        @expandToProperty("_markAllSubMeshesAsMiscDirty")
+        public bumpAffectsReflection: boolean;        
 
 
         /**
         /**
         * @param {number}: The water color blended with the refraction (near)
         * @param {number}: The water color blended with the refraction (near)
@@ -134,9 +148,6 @@ module BABYLON {
         
         
         private _renderId: number;
         private _renderId: number;
 
 
-        private _defines = new WaterMaterialDefines();
-        private _cachedDefines = new WaterMaterialDefines();
-
         private _useLogarithmicDepth: boolean;
         private _useLogarithmicDepth: boolean;
 
 
         /**
         /**
@@ -156,6 +167,7 @@ module BABYLON {
 
 
         public set useLogarithmicDepth(value: boolean) {
         public set useLogarithmicDepth(value: boolean) {
             this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
             this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
+            this._markAllSubMeshesAsMiscDirty();
         }
         }
 
 
         // Get / Set
         // Get / Set
@@ -199,179 +211,120 @@ module BABYLON {
         public getAlphaTestTexture(): BaseTexture {
         public getAlphaTestTexture(): BaseTexture {
             return null;
             return null;
         }
         }
-        
-        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (!mesh) {
-                return true;
-            }
-
-            if (this._defines.INSTANCES !== useInstances) {
-                return false;
-            }
-
-            return false;
-        }
 		
 		
-		public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-			if (this.checkReadyOnlyOnce) {
-                if (this._wasPreviouslyReady) {
+		public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+            if (this.isFrozen) {
+                if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
                 }
                 }
             }
             }
 
 
+            if (!subMesh._materialDefines) {
+                subMesh._materialDefines = new WaterMaterialDefines();
+            }
+
+            var defines = <WaterMaterialDefines>subMesh._materialDefines;
             var scene = this.getScene();
             var scene = this.getScene();
 
 
             if (!this.checkReadyOnEveryCall) {
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
                 if (this._renderId === scene.getRenderId()) {
-                    if (this._checkCache(scene, mesh, useInstances)) {
-                        return true;
-                    }
+                    return true;
                 }
                 }
             }
             }
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            var needNormals = false;
-            var needUVs = false;
-
-            this._defines.reset();
 
 
             // Textures
             // Textures
-            if (scene.texturesEnabled) {
-                if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
-                    if (!this.bumpTexture.isReady()) {
-                        return false;
-                    } else {
-                        needUVs = true;
-                        this._defines.BUMP = true;
+            if (defines._areTexturesDirty) {
+                defines._needUVs = false;
+                if (scene.texturesEnabled) {
+                    if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
+                        if (!this.bumpTexture.isReady()) {
+                            return false;
+                        } else {
+                            defines._needUVs = true;
+                            defines.BUMP = true;
+                        }
+                    }
+                    
+                    if (StandardMaterial.ReflectionTextureEnabled) {
+                        defines.REFLECTION = true;
                     }
                     }
                 }
                 }
-                
-                if (StandardMaterial.ReflectionTextureEnabled) {
-                    this._defines.REFLECTION = 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;
-            }
-
-            if (this.useLogarithmicDepth) {
-                this._defines.LOGARITHMICDEPTH = true;
-            }
-
-            if (this.fresnelSeparate) {
-                this._defines.FRESNELSEPARATE = true;
             }
             }
 
 
-            if (this.bumpSuperimpose) {
-                this._defines.BUMPSUPERIMPOSE = true;
-            }
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
 
 
-            if (this.bumpAffectsReflection) {
-                this._defines.BUMPAFFECTSREFLECTION = true;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
 
 
-            // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
-                this._defines.FOG = true;
-            }
-            
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, this._defines, true, this.maxSimultaneousLights);
-            }
-
-            // Attribs
-            if (mesh) {
-                if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                    this._defines.NORMAL = true;
+            if (defines._areMiscDirty) {
+                if (this._fresnelSeparate) {
+                    defines.FRESNELSEPARATE = true;
                 }
                 }
-                if (needUVs) {
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
-                        this._defines.UV1 = true;
-                    }
-                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
-                        this._defines.UV2 = 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.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
-                    this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
+                if (this._bumpSuperimpose) {
+                    defines.BUMPSUPERIMPOSE = true;
                 }
                 }
 
 
-                // Instances
-                if (useInstances) {
-                    this._defines.INSTANCES = true;
+                if (this._bumpAffectsReflection) {
+                    defines.BUMPAFFECTSREFLECTION = true;
                 }
                 }
             }
             }
+           
+            // Lights
+            defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
+
+            // Attribs
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             
             
             this._mesh = mesh;
             this._mesh = mesh;
 
 
             // Get correct effect      
             // Get correct effect      
-            if (!this._defines.isEqual(this._cachedDefines)) {
-                this._defines.cloneTo(this._cachedDefines);
-
+            if (defines.isDirty) {
+                defines.markAsProcessed();
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();             
                 var fallbacks = new EffectFallbacks();             
-                if (this._defines.FOG) {
+                if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
-                if (this._defines.LOGARITHMICDEPTH) {
+                if (defines.LOGARITHMICDEPTH) {
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                     fallbacks.addFallback(0, "LOGARITHMICDEPTH");
                 }
                 }
 
 
-                MaterialHelper.HandleFallbacksForShadows(this._defines, fallbacks, this.maxSimultaneousLights);
+                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
              
              
-                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
 
 
                 //Attributes
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
                 var attribs = [VertexBuffer.PositionKind];
 
 
-                if (this._defines.NORMAL) {
+                if (defines.NORMAL) {
                     attribs.push(VertexBuffer.NormalKind);
                     attribs.push(VertexBuffer.NormalKind);
                 }
                 }
 
 
-                if (this._defines.UV1) {
+                if (defines.UV1) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                 }
                 }
 
 
-                if (this._defines.UV2) {
+                if (defines.UV2) {
                     attribs.push(VertexBuffer.UV2Kind);
                     attribs.push(VertexBuffer.UV2Kind);
                 }
                 }
 
 
-                if (this._defines.VERTEXCOLOR) {
+                if (defines.VERTEXCOLOR) {
                     attribs.push(VertexBuffer.ColorKind);
                     attribs.push(VertexBuffer.ColorKind);
                 }
                 }
 
 
-                MaterialHelper.PrepareAttributesForBones(attribs, mesh, this._defines, fallbacks);
-                MaterialHelper.PrepareAttributesForInstances(attribs, this._defines);
+                MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
+                MaterialHelper.PrepareAttributesForInstances(attribs, defines);
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "water";
                 var shaderName = "water";
-                var join = this._defines.toString();
+                var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vNormalInfos", 
                     "vNormalInfos", 
@@ -388,13 +341,13 @@ module BABYLON {
                     "refractionSampler", "reflectionSampler"
                     "refractionSampler", "reflectionSampler"
                 ];
                 ];
                 
                 
-                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.PrepareUniformsAndSamplersList(uniforms, samplers, defines, this.maxSimultaneousLights);
                 
                 
-                this._effect = scene.getEngine().createEffect(shaderName,
+                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     attribs, uniforms, samplers,
                     attribs, uniforms, samplers,
-                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights });
+                    join, fallbacks, this.onCompiled, this.onError, { maxSimultaneousLights: this.maxSimultaneousLights }), defines);
             }
             }
-            if (!this._effect.isReady()) {
+            if (!subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -404,83 +357,87 @@ module BABYLON {
             return true;
             return true;
 		}
 		}
         
         
-        public bindOnlyWorldMatrix(world: Matrix): void {
-            this._effect.setMatrix("world", world);
-        }
-		
-		public bind(world: Matrix, mesh?: Mesh): void {
+		public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
             var scene = this.getScene();
 
 
+            var defines = <WaterMaterialDefines>subMesh._materialDefines;
+            if (!defines) {
+                return;
+            }
+
+            var effect = subMesh.effect;
+            this._activeEffect = effect;
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
+            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
-            if (scene.getCachedMaterial() !== this) {
+            if (this._mustRebind(scene, effect)) {
                 // Textures        
                 // Textures        
                 if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
                 if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
-                    this._effect.setTexture("normalSampler", this.bumpTexture);
+                    this._activeEffect.setTexture("normalSampler", this.bumpTexture);
 
 
-                    this._effect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
-                    this._effect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
+                    this._activeEffect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
+                    this._activeEffect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
                 }
                 }
                 // Clip plane
                 // Clip plane
-                MaterialHelper.BindClipPlane(this._effect, scene);
+                MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
                 // Point size
                 // Point size
                 if (this.pointsCloud) {
                 if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
+                    this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
+                this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);                
             }
             }
 
 
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             
             
-            if (this._defines.SPECULARTERM) {
-                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            if (defines.SPECULARTERM) {
+                this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
 
 
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._effect, this._defines, this.maxSimultaneousLights);
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
+                this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
 
 
             // Fog
             // Fog
-            MaterialHelper.BindFogParameters(scene, mesh, this._effect);
+            MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
 
 
             // Log. depth
             // Log. depth
-            MaterialHelper.BindLogDepth(this._defines, this._effect, scene);
+            MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
 
 
             // Water
             // Water
             if (StandardMaterial.ReflectionTextureEnabled) {
             if (StandardMaterial.ReflectionTextureEnabled) {
-                this._effect.setTexture("refractionSampler", this._refractionRTT);
-                this._effect.setTexture("reflectionSampler", this._reflectionRTT);
+                this._activeEffect.setTexture("refractionSampler", this._refractionRTT);
+                this._activeEffect.setTexture("reflectionSampler", this._reflectionRTT);
             }
             }
             
             
 			var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
 			var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
 			this._lastTime += scene.getEngine().getDeltaTime();
 			this._lastTime += scene.getEngine().getDeltaTime();
 			
 			
-			this._effect.setMatrix("worldReflectionViewProjection", wrvp);
-			this._effect.setVector2("windDirection", this.windDirection);
-			this._effect.setFloat("waveLength", this.waveLength);
-			this._effect.setFloat("time", this._lastTime / 100000);
-			this._effect.setFloat("windForce", this.windForce);
-			this._effect.setFloat("waveHeight", this.waveHeight);
-            this._effect.setFloat("bumpHeight", this.bumpHeight);
-			this._effect.setColor4("waterColor", this.waterColor, 1.0);
-			this._effect.setFloat("colorBlendFactor", this.colorBlendFactor);
-            this._effect.setColor4("waterColor2", this.waterColor2, 1.0);
-            this._effect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
-            this._effect.setFloat("waveSpeed", this.waveSpeed);
-
-            this._afterBind(mesh);
+			this._activeEffect.setMatrix("worldReflectionViewProjection", wrvp);
+			this._activeEffect.setVector2("windDirection", this.windDirection);
+			this._activeEffect.setFloat("waveLength", this.waveLength);
+			this._activeEffect.setFloat("time", this._lastTime / 100000);
+			this._activeEffect.setFloat("windForce", this.windForce);
+			this._activeEffect.setFloat("waveHeight", this.waveHeight);
+            this._activeEffect.setFloat("bumpHeight", this.bumpHeight);
+			this._activeEffect.setColor4("waterColor", this.waterColor, 1.0);
+			this._activeEffect.setFloat("colorBlendFactor", this.colorBlendFactor);
+            this._activeEffect.setColor4("waterColor2", this.waterColor2, 1.0);
+            this._activeEffect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
+            this._activeEffect.setFloat("waveSpeed", this.waveSpeed);
+
+            this._afterBind(mesh, this._activeEffect);
 		}
 		}
 		
 		
 		private _createRenderTargets(scene: Scene, renderTargetSize: Vector2): void {
 		private _createRenderTargets(scene: Scene, renderTargetSize: Vector2): void {

src/Cameras/Inputs/babylon.arcrotatecamera.input.gamepad.ts → src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts


src/Cameras/Inputs/babylon.arcrotatecamera.input.keyboard.ts → src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts


src/Cameras/Inputs/babylon.arcrotatecamera.input.mousewheel.ts → src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts


src/Cameras/Inputs/babylon.arcrotatecamera.input.pointers.ts → src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts


src/Cameras/Inputs/babylon.arcrotatecamera.input.vrdeviceorientation.ts → src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts


src/Cameras/Inputs/babylon.freecamera.input.deviceorientation.ts → src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts


src/Cameras/Inputs/babylon.freecamera.input.gamepad.ts → src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts


src/Cameras/Inputs/babylon.freecamera.input.keyboard.ts → src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts


src/Cameras/Inputs/babylon.freecamera.input.mouse.ts → src/Cameras/Inputs/babylon.freeCameraMouseInput.ts


src/Cameras/Inputs/babylon.freecamera.input.touch.ts → src/Cameras/Inputs/babylon.freeCameraTouchInput.ts


src/Cameras/Inputs/babylon.freecamera.input.virtualjoystick.ts → src/Cameras/Inputs/babylon.freeCameraVirtualJoystickInput.ts


+ 5 - 0
src/Materials/babylon.material.ts

@@ -19,6 +19,11 @@
 
 
         public markAsProcessed() {
         public markAsProcessed() {
             this._isDirty = false;
             this._isDirty = false;
+            this._areAttributesDirty = false;
+            this._areTexturesDirty = false;
+            this._areFresnelDirty = false;
+            this._areLightsDirty = false;
+            this._areMiscDirty = false;
         }
         }
 
 
         public markAsUnprocessed() {
         public markAsUnprocessed() {

+ 22 - 11
src/Materials/babylon.materialHelper.ts

@@ -1,6 +1,14 @@
 module BABYLON {
 module BABYLON {
     export class MaterialHelper {
     export class MaterialHelper {
 
 
+        public static PrepareDefinesForMisc(mesh: AbstractMesh, scene: Scene, useLogarithmicDepth: boolean, pointsCloud, fogEnabled: boolean, defines: MaterialDefines): void {
+            if (defines._areMiscDirty) {
+                defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
+                defines["POINTSIZE"] = (pointsCloud || scene.forcePointsCloud);
+                defines["FOG"] = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && fogEnabled);
+            }
+        }
+
         public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: MaterialDefines, useInstances: boolean): void {
         public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: MaterialDefines, useInstances: boolean): void {
             var changed = false;
             var changed = false;
 
 
@@ -24,7 +32,7 @@
             }
             }
         }
         }
 
 
-        public static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useInstances: boolean): void {
+        public static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: MaterialDefines, useVertexColor: boolean, useBones: boolean): void {
             if (!defines._areAttributesDirty) {
             if (!defines._areAttributesDirty) {
                 return;
                 return;
             }
             }
@@ -39,17 +47,20 @@
                 defines["UV2"] = false;
                 defines["UV2"] = false;
             }
             }
 
 
-            defines["VERTEXCOLOR"] = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
-
-            defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
+            if (useVertexColor) {
+                defines["VERTEXCOLOR"] = mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind);
+                defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
+            }
 
 
-            if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
-                defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
-            } else {
-                defines["NUM_BONE_INFLUENCERS"] = 0;
-                defines["BonesPerMesh"] = 0;
-            }           
+            if (useBones) {
+                if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                    defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
+                    defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
+                } else {
+                    defines["NUM_BONE_INFLUENCERS"] = 0;
+                    defines["BonesPerMesh"] = 0;
+                }           
+            }
         }
         }
 
 
         public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, specularSupported: boolean, maxSimultaneousLights = 4, disableLighting = false): boolean {
         public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: MaterialDefines, specularSupported: boolean, maxSimultaneousLights = 4, disableLighting = false): boolean {

+ 3 - 16
src/Materials/babylon.standardMaterial.ts

@@ -168,8 +168,7 @@ module BABYLON {
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;           
-          
+        public disableLighting: boolean;
 
 
         @serialize("useParallax")
         @serialize("useParallax")
         private _useParallax = false;
         private _useParallax = false;
@@ -369,7 +368,6 @@ module BABYLON {
 
 
             // Lights
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
-            defines._areLightsDirty = false;
 
 
             // Textures
             // Textures
             if (defines._areTexturesDirty) {
             if (defines._areTexturesDirty) {
@@ -553,8 +551,6 @@ module BABYLON {
                 defines.LINKEMISSIVEWITHDIFFUSE = this._linkEmissiveWithDiffuse;       
                 defines.LINKEMISSIVEWITHDIFFUSE = this._linkEmissiveWithDiffuse;       
 
 
                 defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
                 defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
-         
-                defines._areTexturesDirty = false;
             } 
             } 
 
 
             if (defines._areFresnelDirty) {
             if (defines._areFresnelDirty) {
@@ -584,22 +580,13 @@ module BABYLON {
                 } else {
                 } else {
                     defines.FRESNEL = false;
                     defines.FRESNEL = false;
                 }
                 }
-
-                defines._areFresnelDirty = false;
             }
             }
 
 
             // Misc.
             // Misc.
-            if (defines._areMiscDirty) {
-                defines.LOGARITHMICDEPTH = this._useLogarithmicDepth;
-                defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
-                defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
-
-                defines._areMiscDirty = false;
-            }
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Attribs
             // Attribs
-            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, useInstances);
-            defines._areAttributesDirty = false;
+            MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
             MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);

src/Tools/HDR/babylon.tools.cubemapToSphericalPolynomial.ts → src/Tools/HDR/babylon.cubemapToSphericalPolynomial.ts


src/Tools/HDR/babylon.tools.hdr.ts → src/Tools/HDR/babylon.hdr.ts


src/Tools/HDR/babylon.tools.panoramaToCubemap.ts → src/Tools/HDR/babylon.panoramaToCubemap.ts


src/Tools/HDR/babylon.tools.pmremgenerator.ts → src/Tools/HDR/babylon.pmremgenerator.ts


src/Tools/babylon.tools.dds.ts → src/Tools/babylon.dds.ts


+ 1 - 1
src/Tools/babylon.filesInput.ts

@@ -91,7 +91,7 @@
                            FilesInput.FilesTextures[name] = this._filesToLoad[i]; 
                            FilesInput.FilesTextures[name] = this._filesToLoad[i]; 
                         }
                         }
                     else {
                     else {
-                        if ((extension === "babylon" || extension === "stl" || extension === "obj") 
+                        if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb") 
                             && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
                             && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
                             this._sceneFileToLoad = this._filesToLoad[i];
                             this._sceneFileToLoad = this._filesToLoad[i];
                         }
                         }

src/Tools/babylon.tools.tga.ts → src/Tools/babylon.tga.ts


+ 2 - 0
src/babylon.engine.ts

@@ -157,6 +157,7 @@
 
 
     export class EngineCapabilities {
     export class EngineCapabilities {
         public maxTexturesImageUnits: number;
         public maxTexturesImageUnits: number;
+        public maxVertexTextureImageUnits: number;
         public maxTextureSize: number;
         public maxTextureSize: number;
         public maxCubemapTextureSize: number;
         public maxCubemapTextureSize: number;
         public maxRenderTextureSize: number;
         public maxRenderTextureSize: number;
@@ -622,6 +623,7 @@
             this._isStencilEnable = options.stencil;
             this._isStencilEnable = options.stencil;
             this._caps = new EngineCapabilities();
             this._caps = new EngineCapabilities();
             this._caps.maxTexturesImageUnits = this._gl.getParameter(this._gl.MAX_TEXTURE_IMAGE_UNITS);
             this._caps.maxTexturesImageUnits = this._gl.getParameter(this._gl.MAX_TEXTURE_IMAGE_UNITS);
+            this._caps.maxVertexTextureImageUnits = this._gl.getParameter(this._gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
             this._caps.maxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
             this._caps.maxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
             this._caps.maxCubemapTextureSize = this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE);
             this._caps.maxCubemapTextureSize = this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE);
             this._caps.maxRenderTextureSize = this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE);
             this._caps.maxRenderTextureSize = this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE);