Kaynağa Gözat

Merge branch 'viewer-changes-new' of https://github.com/RaananW/Babylon.js into viewer-changes-new

# Conflicts:
#	Viewer/dist/viewer.js
#	Viewer/dist/viewer.min.js
Raanan Weber 7 yıl önce
ebeveyn
işleme
b426153470
51 değiştirilmiş dosya ile 29645 ekleme ve 29089 silme
  1. 13727 13679
      Playground/babylon.d.txt
  2. 19 1
      Viewer/dist/viewer.js
  3. 19 1
      Viewer/dist/viewer.min.js
  4. 12771 12723
      dist/preview release/babylon.d.ts
  5. 50 50
      dist/preview release/babylon.js
  6. 188 72
      dist/preview release/babylon.max.js
  7. 51 51
      dist/preview release/babylon.worker.js
  8. 1114 1066
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  9. 55 55
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  10. 188 72
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  11. 188 72
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  12. 188 72
      dist/preview release/es6.js
  13. 3 3
      dist/preview release/gui/babylon.gui.min.js
  14. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  15. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  16. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  17. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  18. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  19. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  20. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  21. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  22. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  23. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  24. 3 3
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  25. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  26. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  27. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  28. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  29. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  30. 2 571
      dist/preview release/typedocValidationBaseline.json
  31. 63 63
      dist/preview release/viewer/babylon.viewer.js
  32. 4 4
      dist/preview release/what's new.md
  33. 445 378
      serializers/src/glTF/2.0/babylon.glTFExporter.ts
  34. 1 1
      serializers/src/glTF/2.0/babylon.glTFMaterial.ts
  35. 14 5
      src/Engine/babylon.engine.ts
  36. 23 4
      src/Lights/babylon.shadowLight.ts
  37. 111 65
      src/Lights/babylon.spotLight.ts
  38. 10 0
      src/Loading/babylon.sceneLoader.ts
  39. 2 1
      src/Materials/babylon.materialHelper.ts
  40. 16 2
      src/Mesh/babylon.transformNode.ts
  41. 84 4
      src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts
  42. 18 2
      src/PostProcess/babylon.blurPostProcess.ts
  43. 27 27
      src/PostProcess/babylon.depthOfFieldEffect.ts
  44. 143 5
      src/PostProcess/babylon.postProcess.ts
  45. 34 0
      src/PostProcess/babylon.postProcessManager.ts
  46. 1 1
      src/Shaders/ShadersInclude/lightFragment.fx
  47. 6 5
      src/Shaders/ShadersInclude/lightsFragmentFunctions.fx
  48. 10 3
      src/Tools/babylon.promise.ts
  49. 12 2
      src/Tools/babylon.tools.ts
  50. 24 0
      tests/unit/babylon/promises/babylon.promises.tests.ts
  51. 5 0
      tests/validation/integration.js

Dosya farkı çok büyük olduğundan ihmal edildi
+ 13727 - 13679
Playground/babylon.d.txt


Dosya farkı çok büyük olduğundan ihmal edildi
+ 19 - 1
Viewer/dist/viewer.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 19 - 1
Viewer/dist/viewer.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 12771 - 12723
dist/preview release/babylon.d.ts


Dosya farkı çok büyük olduğundan ihmal edildi
+ 50 - 50
dist/preview release/babylon.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 188 - 72
dist/preview release/babylon.max.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 51 - 51
dist/preview release/babylon.worker.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1114 - 1066
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Dosya farkı çok büyük olduğundan ihmal edildi
+ 55 - 55
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 188 - 72
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 188 - 72
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 188 - 72
dist/preview release/es6.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 3 - 3
dist/preview release/materialsLibrary/babylonjs.materials.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


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

@@ -1,7 +1,7 @@
 {
-  "errors": 8288,
+  "errors": 8179,
   "babylon.typedoc.json": {
-    "errors": 8288,
+    "errors": 8179,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -4774,20 +4774,6 @@
         }
       }
     },
-    "BlurPostProcess": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Property": {
-        "direction": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      }
-    },
     "Bone": {
       "Class": {
         "Comments": {
@@ -8913,173 +8899,45 @@
       }
     },
     "DefaultRenderingPipeline": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
       "Property": {
         "BlurXPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "BlurYPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "CopyBackPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "FinalMergePostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "FxaaPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "HighLightsPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "ImageProcessingPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
           }
         },
         "PassPostProcessId": {
           "Naming": {
             "NotCamelCase": true
-          },
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "animations": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "bloomEnabled": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "bloomScale": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "bloomWeight": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "blurX": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "blurY": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "copyBack": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "finalMerge": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "fxaa": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "fxaaEnabled": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "highlights": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "imageProcessing": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "imageProcessingEnabled": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "pass": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      },
-      "Method": {
-        "serialize": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "Parse": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "source": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "rootUrl": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
           }
         }
       }
@@ -25995,433 +25853,6 @@
         }
       }
     },
-    "PostProcess": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Constructor": {
-        "new PostProcess": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "name": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "fragmentUrl": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "parameters": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplers": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "options": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "camera": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplingMode": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "engine": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "reusable": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "defines": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "textureType": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "vertexUrl": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "indexParameters": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "blockCompilation": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      },
-      "Property": {
-        "_currentRenderTextureInd": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "_textures": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "adaptScaleToCurrentViewport": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "alphaConstants": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "alphaMode": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "alwaysForcePOT": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "animations": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "aspectRatio": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "autoClear": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "clearColor": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "enablePixelPerfectMode": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "height": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "isSupported": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "name": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "onActivate": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "onAfterRender": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "onApply": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "onBeforeRender": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "onSizeChanged": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "outputTexture": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "renderTargetSamplingMode": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "samples": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "scaleMode": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "texelSize": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "width": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      },
-      "Method": {
-        "activate": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "camera": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "sourceTexture": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "forceDepthStencil": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "apply": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "dispose": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "camera": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "getCamera": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "getEffect": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "getEngine": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "isReusable": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "shareOutputWith": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "postProcess": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "updateEffect": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "defines": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "uniforms": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "samplers": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "indexParameters": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "onCompiled": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "onError": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      }
-    },
-    "PostProcessManager": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Constructor": {
-        "new PostProcessManager": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      },
-      "Method": {
-        "_finalizeFrame": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "doNotPresent": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "targetTexture": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "faceIndex": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "postProcesses": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "forceFullscreenViewport": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "_prepareFrame": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "sourceTexture": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "postProcesses": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "_rebuild": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "directRender": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "postProcesses": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "targetTexture": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "forceFullscreenViewport": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "dispose": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      }
-    },
     "PostProcessRenderPipeline": {
       "Class": {
         "Comments": {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 63 - 63
dist/preview release/viewer/babylon.viewer.js


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

@@ -7,12 +7,12 @@
 - `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
 - New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
 - Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
-- Introduced Projection Texture on SpotLight (`spotLight.projectedLightTexture`). ([lostink](https://github.com/lostink))
+- Introduced Projection Texture on SpotLight (`spotLight.projectedLightTexture`) ([lostink](https://github.com/lostink))
 
 ## Updates
 - Tons of functions and classes received the code comments they deserved (All the community)
 - Added support for all RGBA orders (BGR, RGB, etc..) for the DDS loader ([deltakosh](https://github.com/deltakosh))
-- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adapatability ([deltakosh](https://github.com/deltakosh))
+- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adaptability ([deltakosh](https://github.com/deltakosh))
 - Improved `scene.isReady()` function which now takes in account shadows and LOD ([deltakosh](https://github.com/deltakosh))
 - New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
 - Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
@@ -41,8 +41,8 @@
 - Gulp process now supports multiple outputs when using webpack. ([RaananW](https://github.com/RaananW))
 - (Viewer) Scene Optimizer intergrated in viewer. ([RaananW](https://github.com/RaananW))
 - (Viewer) The viewer supports custom shaders in the configuration. ([RaananW](https://github.com/RaananW))
-- Documented PostProcessRenderEffect class ([trevordev](https://github.com/trevordev))
-- SPS internal storage of each solid particle rotation matrix ([jbousquie](https://github.com/jbousquie))
+- Documented PostProcessRenderEffect, DefaultRenderingPipeline, BlurPostProcess, DepthOfFieldEffect, PostProcess, PostProcessManager classes ([trevordev](https://github.com/trevordev))
+- SPS internal storage of each solid particle rotation matrix ([jbousquie](https://github.com/jbousquie)) 
 - (Viewer) Introducing the viewer labs - testing new features. ([RaananW](https://github.com/RaananW))
 
 ## Bug fixes

Dosya farkı çok büyük olduğundan ihmal edildi
+ 445 - 378
serializers/src/glTF/2.0/babylon.glTFExporter.ts


+ 1 - 1
serializers/src/glTF/2.0/babylon.glTFMaterial.ts

@@ -100,7 +100,7 @@ module BABYLON.GLTF2 {
             const diffuse = babylonSpecularGlossiness.diffuse;
             const opacity = babylonSpecularGlossiness.opacity;
             const specular = babylonSpecularGlossiness.specular;
-            const glossiness = babylonSpecularGlossiness.glossiness;
+            const glossiness = BABYLON.Scalar.Clamp(babylonSpecularGlossiness.glossiness);
             
             const oneMinusSpecularStrength = 1 - Math.max(specular.r, Math.max(specular.g, specular.b));
             const diffusePerceivedBrightness = _GLTFMaterial.PerceivedBrightness(diffuse);

+ 14 - 5
src/Engine/babylon.engine.ts

@@ -283,6 +283,7 @@
             { key: "Chrome/63.0", capture: "63\\.0\\.3239\\.(\\d+)", captureConstraint: 108, targets: ["uniformBuffer"] },
             { key: "Firefox/58", capture: null, captureConstraint: null, targets: ["uniformBuffer"] },
             { key: "Macintosh", capture: null, captureConstraint: null, targets: ["textureBindingOptimization"] },
+            { key: "iPhone", capture: null, captureConstraint: null, targets: ["textureBindingOptimization"] },
         ];
 
         public static Instances = new Array<Engine>();
@@ -1347,15 +1348,19 @@
         public resetTextureCache() {
             for (var key in this._boundTexturesCache) {
                 let boundTexture = this._boundTexturesCache[key];
-                if (!this.disableTextureBindingOptimization && boundTexture) {
+                if (boundTexture) {
                     this._removeDesignatedSlot(boundTexture);
                 }
                 this._boundTexturesCache[key] = null;
             }
-            this._nextFreeTextureSlots = [];
-            for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {
-                this._nextFreeTextureSlots.push(slot);
+
+            if (!this.disableTextureBindingOptimization) {
+                this._nextFreeTextureSlots = [];
+                for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {
+                    this._nextFreeTextureSlots.push(slot);
+                }
             }
+
             this._currentTextureChannel = -1;
         }
 
@@ -4805,6 +4810,10 @@
 
             internalTexture._designatedSlot = -1;
 
+            if (this.disableTextureBindingOptimization) {
+                return -1;
+            }
+            
             // Remove from bound list
             this._linkTrackers(internalTexture.previous, internalTexture.next);
 
@@ -4831,7 +4840,7 @@
             let isTextureForRendering = texture && texture._initialSlot > -1;
 
             if (currentTextureBound !== texture) {
-                if (currentTextureBound && !this.disableTextureBindingOptimization) {
+                if (currentTextureBound) {
                     this._removeDesignatedSlot(currentTextureBound);
                 }
 

+ 23 - 4
src/Lights/babylon.shadowLight.ts

@@ -118,25 +118,44 @@
 
         protected abstract _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
 
+        protected _position: Vector3;
+        protected _setPosition(value: Vector3) {
+            this._position = value;
+        }
         /**
-         * The position the shdow will be casted from.
+         * Sets the position the shadow will be casted from. Also use as the light position for both 
+         * point and spot lights.
          */
         @serializeAsVector3()
-        public position: Vector3;
+        public get position(): Vector3 {
+            return this._position;
+        }
+        /**
+         * Sets the position the shadow will be casted from. Also use as the light position for both 
+         * point and spot lights.
+         */
+        public set position(value: Vector3) {
+            this._setPosition(value);
+        }
 
         protected _direction: Vector3;
-        @serializeAsVector3()
+        protected _setDirection(value: Vector3) {
+            this._direction = value;
+        }
         /**
          * In 2d mode (needCube being false), gets the direction used to cast the shadow.
+         * Also use as the light direction on spot and directional lights.
          */
+        @serializeAsVector3()
         public get direction(): Vector3 {
             return this._direction;
         }
         /**
          * In 2d mode (needCube being false), sets the direction used to cast the shadow.
+         * Also use as the light direction on spot and directional lights.
          */
         public set direction(value: Vector3) {
-            this._direction = value;
+            this._setDirection(value);
         }
 
         private _shadowMinZ: number;

+ 111 - 65
src/Lights/babylon.spotLight.ts

@@ -13,23 +13,18 @@
             
             Also we have the following rules always holds:
             direction cross up   = right
-            right cross dirction = up
+            right cross direction = up
             up cross right       = forward
 
             light_near and light_far will control the range of the texture projection. If a plane is 
             out of the range in spot light space, there is no texture projection.
-
-            Warning:
-            Change the angle of the Spotlight, direction of the SpotLight will not re-compute the 
-            projection matrix. Need to call computeTextureMatrix() to recompute manually. Add inheritance
-            to the setting function of the 2 attributes will solve the problem.
         */
 
         private _angle: number;
-        @serialize()
         /**
          * Gets the cone angle of the spot light in Radians.
          */
+        @serialize()
         public get angle(): number {
             return this._angle
         }
@@ -38,14 +33,15 @@
          */
         public set angle(value: number) {
             this._angle = value;
+            this._projectionTextureProjectionLightDirty = true;
             this.forceProjectionMatrixCompute();
         }
 
         private _shadowAngleScale: number;
-        @serialize()
         /**
          * Allows scaling the angle of the light for shadow generation only.
          */
+        @serialize()
         public get shadowAngleScale(): number {
             return this._shadowAngleScale
         }
@@ -63,70 +59,89 @@
         @serialize()
         public exponent: number;
 
-        private _textureProjectionMatrix = Matrix.Zero();
-        @serialize()
+        private _projectionTextureMatrix = Matrix.Zero();
         /**
         * Allows reading the projecton texture
         */
-        public get textureMatrix(): Matrix{
-            return this._textureProjectionMatrix;
-        }
-        /**
-        * Allows setting the value of projection texture
-        */
-        public set textureMatrix(value: Matrix) {
-            this._textureProjectionMatrix = value;
+        public get projectionTextureMatrix(): Matrix{
+            return this._projectionTextureMatrix;
         }
 
-        protected _light_near :number;
-        @serialize()
+        protected _projectionTextureLightNear : number = 1e-6;;
         /**
          * Gets the near clip of the Spotlight for texture projection.
          */
-        public get light_near(): number {
-            return this._light_near;
+        @serialize()
+        public get projectionTextureLightNear(): number {
+            return this._projectionTextureLightNear;
         }
         /**
          * Sets the near clip of the Spotlight for texture projection.
          */
-        public set light_near(value: number) {
-            this._light_near = value;
-            this._computeTextureMatrix();
+        public set projectionTextureLightNear(value: number) {
+            this._projectionTextureLightNear = value;
+            this._projectionTextureProjectionLightDirty = true;
         }
 
-        protected _light_far  :number;
+        protected _projectionTextureLightFar : number = 1000.0;
         /**
          * Gets the far clip of the Spotlight for texture projection.
          */
         @serialize()
-        public get light_far(): number {
-            return this._light_far;
+        public get projectionTextureLightFar(): number {
+            return this._projectionTextureLightFar;
         }
         /**
          * Sets the far clip of the Spotlight for texture projection.
          */
-        public set light_far(value: number) {
-            this._light_far = value;
+        public set projectionTextureLightFar(value: number) {
+            this._projectionTextureLightFar = value;
+            this._projectionTextureProjectionLightDirty = true;
+        }
+
+        protected _projectionTextureUpDirection: Vector3 = Vector3.Up();
+        /**
+         * Gets the Up vector of the Spotlight for texture projection.
+         */
+        @serialize()
+        public get projectionTextureUpDirection(): Vector3 {
+            return this._projectionTextureUpDirection;
+        }
+        /**
+         * Sets the Up vector of the Spotlight for texture projection.
+         */
+        public set projectionTextureUpDirection(value: Vector3) {
+            this._projectionTextureUpDirection = value;
+            this._projectionTextureProjectionLightDirty = true;
         }
 
         @serializeAsTexture("projectedLightTexture")
-        private _projectedLightTexture: Nullable<BaseTexture>;;
+        private _projectionTexture: Nullable<BaseTexture>;;
         /** 
          * Gets the projection texture of the light.
         */
-        public get projectedLightTexture(): Nullable<BaseTexture> {
-            return this._projectedLightTexture;
+        public get projectionTexture(): Nullable<BaseTexture> {
+            return this._projectionTexture;
         }
         /**
         * Sets the projection texture of the light.
         */
-        public set projectedLightTexture(value: Nullable<BaseTexture>) {
-            this._projectedLightTexture = value;
-            this._light_far = 1000.0;
-            this._light_near = 1e-6;
-            this._computeTextureMatrix();
+        public set projectionTexture(value: Nullable<BaseTexture>) {
+            this._projectionTexture = value;
+            this._projectionTextureDirty = true;
         }
 
+        private _projectionTextureViewLightDirty = true;
+        private _projectionTextureProjectionLightDirty = true;
+        private _projectionTextureDirty = true;
+        private _projectionTextureViewTargetVector = Vector3.Zero();
+        private _projectionTextureViewLightMatrix = Matrix.Zero();
+        private _projectionTextureProjectionLightMatrix = Matrix.Zero();
+        private _projectionTextureScalingMatrix = Matrix.FromValues(0.5, 0.0, 0.0, 0.0,
+            0.0, 0.5, 0.0, 0.0,
+            0.0, 0.0, 0.5, 0.0,
+            0.5, 0.5, 0.5, 1.0);
+
         /**
          * Creates a SpotLight object in the scene. A spot light is a simply light oriented cone.
          * It can cast shadows.
@@ -164,6 +179,22 @@
         }
 
         /**
+         * Overrides the direction setter to recompute the projection texture view light Matrix.
+         */
+        protected _setDirection(value: Vector3) {
+            super._setDirection(value);
+            this._projectionTextureViewLightDirty = true;
+        }
+
+        /**
+         * Overrides the position setter to recompute the projection texture view light Matrix.
+         */
+        protected _setPosition(value: Vector3) {
+            super._setPosition(value);
+            this._projectionTextureViewLightDirty = true;
+        }
+
+        /**
          * Sets the passed matrix "matrix" as perspective projection matrix for the shadows and the passed view matrix with the fov equal to the SpotLight angle and and aspect ratio of 1.0.  
          * Returns the SpotLight.  
          */
@@ -181,37 +212,43 @@
             this.getDepthMinZ(activeCamera), this.getDepthMaxZ(activeCamera), matrix);
         }
 
-        /**
-         * Main function for light texture projection matrix computing.
-         */
-        protected _computeTextureMatrix(): void {
+        protected _computeProjectionTextureViewLightMatrix(): void {
+            this._projectionTextureViewLightDirty = false;
+            this._projectionTextureDirty = true;
+            
+            this.position.addToRef(this.direction, this._projectionTextureViewTargetVector);
+            Matrix.LookAtLHToRef(this.position, 
+                this._projectionTextureViewTargetVector, 
+                this._projectionTextureUpDirection, 
+                this._projectionTextureViewLightMatrix);
+        }
 
-            var viewLightMatrix = Matrix.Zero();
-            Matrix.LookAtLHToRef(this.position, this.position.add(this.direction), Vector3.Up(), viewLightMatrix);
+        protected _computeProjectionTextureProjectionLightMatrix(): void {
+            this._projectionTextureProjectionLightDirty = false;
+            this._projectionTextureDirty = true;
 
-            var light_far = this.light_far;
-            var light_near = this.light_near;
+            var light_far = this.projectionTextureLightFar;
+            var light_near = this.projectionTextureLightNear;
 
             var P = light_far / (light_far - light_near);
             var Q = - P * light_near;
             var S = 1.0 / Math.tan(this._angle / 2.0);
             var A = 1.0;
-            
-            var projectionLightMatrix = Matrix.Zero();
-            Matrix.FromValuesToRef(S/A, 0.0, 0.0, 0.0,
+
+            Matrix.FromValuesToRef(S / A, 0.0, 0.0, 0.0,
                 0.0, S, 0.0, 0.0,
                 0.0, 0.0, P, 1.0,
-                0.0, 0.0, Q, 0.0, projectionLightMatrix);
-
-            var scaleMatrix = Matrix.Zero();
-            Matrix.FromValuesToRef(0.5, 0.0, 0.0, 0.0,
-                0.0, 0.5, 0.0, 0.0,
-                0.0, 0.0, 0.5, 0.0,
-                0.5, 0.5, 0.5, 1.0, scaleMatrix);
-                
-            this._textureProjectionMatrix.copyFrom(viewLightMatrix);
-            this._textureProjectionMatrix.multiplyToRef(projectionLightMatrix, this._textureProjectionMatrix);
-            this._textureProjectionMatrix.multiplyToRef(scaleMatrix, this._textureProjectionMatrix);
+                0.0, 0.0, Q, 0.0, this._projectionTextureProjectionLightMatrix);
+        }
+
+        /**
+         * Main function for light texture projection matrix computing.
+         */
+        protected _computeProjectionTextureMatrix(): void {
+            this._projectionTextureDirty = false;
+
+            this._projectionTextureViewLightMatrix.multiplyToRef(this._projectionTextureProjectionLightMatrix, this._projectionTextureMatrix);
+            this._projectionTextureMatrix.multiplyToRef(this._projectionTextureScalingMatrix, this._projectionTextureMatrix);
         }
 
         protected _buildUniformLayout(): void {
@@ -260,9 +297,18 @@
                 Math.cos(this.angle * 0.5),
                 lightIndex);
 
-            effect.setMatrix("textureProjectionMatrix" + lightIndex, this._textureProjectionMatrix);
-            if (this.projectedLightTexture){
-                effect.setTexture("projectionLightSampler" + lightIndex, this.projectedLightTexture);
+            if (this.projectionTexture && this.projectionTexture.isReady()) {
+                if (this._projectionTextureViewLightDirty) {
+                    this._computeProjectionTextureViewLightMatrix();
+                }
+                if (this._projectionTextureProjectionLightDirty) {
+                    this._computeProjectionTextureProjectionLightMatrix();
+                }
+                if (this._projectionTextureDirty) {
+                    this._computeProjectionTextureMatrix();
+                }
+                effect.setMatrix("textureProjectionMatrix" + lightIndex, this._projectionTextureMatrix);
+                effect.setTexture("projectionLightSampler" + lightIndex, this.projectionTexture);
             }
             return this;
         }
@@ -272,8 +318,8 @@
          */
         public dispose() : void {
             super.dispose();
-            if (this._projectedLightTexture){
-                this._projectedLightTexture.dispose();
+            if (this._projectionTexture){
+                this._projectionTexture.dispose();
             }
         }
     }

+ 10 - 0
src/Loading/babylon.sceneLoader.ts

@@ -336,6 +336,12 @@
                     rootUrl = plugin.rewriteRootURL(rootUrl, responseURL);
                 }
 
+                if (sceneFilename === "") {
+                    if (sceneFilename === "") {
+                        rootUrl = Tools.GetFolderPath(rootUrl, true);
+                    }
+                }
+
                 if ((<any>plugin).importMesh) {
                     var syncedPlugin = <ISceneLoaderPlugin>plugin;
                     var meshes = new Array<AbstractMesh>();
@@ -434,6 +440,10 @@
             };
 
             return SceneLoader._loadData(rootUrl, sceneFilename, scene, (plugin, data, responseURL) => {
+                if (sceneFilename === "") {
+                    rootUrl = Tools.GetFolderPath(rootUrl, true);
+                }
+
                 if ((<any>plugin).load) {
                     var syncedPlugin = <ISceneLoaderPlugin>plugin;
                     if (!syncedPlugin.load(scene, data, rootUrl, errorHandler)) {

+ 2 - 1
src/Materials/babylon.materialHelper.ts

@@ -214,7 +214,8 @@ module BABYLON {
                     var type;
                     if (light.getTypeID() === Light.LIGHTTYPEID_SPOTLIGHT) {
                         type = "SPOTLIGHT" + lightIndex;
-                        defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = (light as SpotLight).projectedLightTexture ? true : false;
+                        let spotLight = light as SpotLight;
+                        defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = spotLight.projectionTexture ? spotLight.projectionTexture.isReady() : false;
                     } else if (light.getTypeID() === Light.LIGHTTYPEID_HEMISPHERICLIGHT) {
                         type = "HEMILIGHT" + lightIndex;
                     } else if (light.getTypeID() === Light.LIGHTTYPEID_POINTLIGHT) {

+ 16 - 2
src/Mesh/babylon.transformNode.ts

@@ -216,9 +216,12 @@ module BABYLON {
             this._cache.pivotMatrixUpdated = true;
             this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;
 
-            if (this._postMultiplyPivotMatrix) {
-                this._pivotMatrixInverse = Matrix.Invert(matrix);
+            if(!this._pivotMatrixInverse){
+                this._pivotMatrixInverse = Matrix.Invert(this._pivotMatrix);
+            } else {
+                this._pivotMatrix.invertToRef(this._pivotMatrixInverse);
             }
+
             return this;
         }
 
@@ -407,6 +410,13 @@ module BABYLON {
             this._pivotMatrix.m[12] = -point.x;
             this._pivotMatrix.m[13] = -point.y;
             this._pivotMatrix.m[14] = -point.z;
+
+            if(!this._pivotMatrixInverse){
+                this._pivotMatrixInverse = Matrix.Invert(this._pivotMatrix);
+            } else {
+                this._pivotMatrix.invertToRef(this._pivotMatrixInverse);
+            }
+            
             this._cache.pivotMatrixUpdated = true;
             return this;
         }
@@ -825,6 +835,10 @@ module BABYLON {
             // Absolute position
             this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
 
+            if(this._pivotMatrixInverse){
+                Vector3.TransformCoordinatesToRef(this._absolutePosition, this._pivotMatrixInverse, this._absolutePosition);
+            }
+
             // Callbacks
             this.onAfterWorldMatrixUpdateObservable.notifyObservers(this);
 

+ 84 - 4
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -1,31 +1,85 @@
 module BABYLON {
+    /**
+	 * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
+     * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
+     */
     export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
         private _scene: Scene;
 
+        /**
+		 * ID of the pass post process used for bloom,
+		 */
         readonly PassPostProcessId: string = "PassPostProcessEffect";
+        /**
+		 * ID of the highlight post process used for bloom,
+		 */
         readonly HighLightsPostProcessId: string = "HighLightsPostProcessEffect";
+        /**
+		 * ID of the blurX post process used for bloom,
+		 */
         readonly BlurXPostProcessId: string = "BlurXPostProcessEffect";
+        /**
+		 * ID of the blurY post process used for bloom,
+		 */
         readonly BlurYPostProcessId: string = "BlurYPostProcessEffect";
+        /**
+		 * ID of the copy back post process used for bloom,
+		 */
         readonly CopyBackPostProcessId: string = "CopyBackPostProcessEffect";
+        /**
+		 * ID of the image processing post process;
+		 */
         readonly ImageProcessingPostProcessId: string = "ImageProcessingPostProcessEffect";
+        /**
+		 * ID of the Fast Approximate Anti-Aliasing post process;
+		 */
         readonly FxaaPostProcessId: string = "FxaaPostProcessEffect";
+        /**
+		 * ID of the final merge post process;
+		 */
         readonly FinalMergePostProcessId: string = "FinalMergePostProcessEffect";
 
         // Post-processes
+        /**
+		 * First pass of bloom to capture the original image texture for later use.
+		 */
         public pass: PassPostProcess;
+        /**
+		 * Second pass of bloom used to brighten bright portions of the image.
+		 */
         public highlights: HighlightsPostProcess;
+        /**
+		 * BlurX post process used in coordination with blurY to guassian blur the highlighted image.
+		 */
         public blurX: BlurPostProcess;
+        /**
+		 * BlurY post process used in coordination with blurX to guassian blur the highlighted image.
+		 */
         public blurY: BlurPostProcess;
+        /**
+		 * Final pass run for bloom to copy the resulting bloom texture back to screen.
+		 */
         public copyBack: PassPostProcess;
         /**
          * Depth of field effect, applies a blur based on how far away objects are from the focus distance.
          */
         public depthOfField: DepthOfFieldEffect;
+        /**
+         * The Fast Approximate Anti-Aliasing post process which attemps to remove aliasing from an image.
+         */
         public fxaa: FxaaPostProcess;
+        /**
+         * Image post processing pass used to perform operations such as tone mapping or color grading.
+         */
         public imageProcessing: ImageProcessingPostProcess;
+        /**
+         * Final post process to merge results of all previous passes
+         */
         public finalMerge: PassPostProcess;
 
-        // IAnimatable
+        /**
+         * Animations which can be used to tweak settings over a period of time
+         */
         public animations: Animation[] = [];
 
         // Values       
@@ -53,6 +107,9 @@
         @serialize()
         private _hdr: boolean;
 
+        /**
+         * The strength of the bloom.
+         */
         public set bloomWeight(value: number) {
             if (this._bloomWeight === value) {
                 return;
@@ -69,6 +126,9 @@
             return this._bloomWeight;
         }
 
+        /**
+         * The scale of the bloom, lower value will provide better performance.
+         */
         public set bloomScale(value: number) {
             if (this._bloomScale === value) {
                 return;
@@ -83,6 +143,9 @@
             return this._bloomScale;
         }
 
+        /**
+         * Enable or disable the bloom from the pipeline
+         */
         public set bloomEnabled(enabled: boolean) {
             if (this._bloomEnabled === enabled) {
                 return;
@@ -114,6 +177,9 @@
             this._buildPipeline();
         }
 
+        /**
+         * If the anti aliasing is enabled.
+         */
         public set fxaaEnabled(enabled: boolean) {
             if (this._fxaaEnabled === enabled) {
                 return;
@@ -128,6 +194,9 @@
             return this._fxaaEnabled;
         }
 
+        /**
+         * If image processing is enabled.
+         */
         public set imageProcessingEnabled(enabled: boolean) {
             if (this._imageProcessingEnabled === enabled) {
                 return;
@@ -347,7 +416,9 @@
             (<any>this.depthOfField) = null;
         }
 
-        // Dispose
+        /**
+         * Dispose of the pipeline and stop all post processes
+         */
         public dispose(): void {
             this._disposePostProcesses();
 
@@ -356,7 +427,10 @@
             super.dispose();
         }
 
-        // Serialize rendering pipeline
+        /**
+         * Serialize the rendering pipeline (Used when exporting)
+         * @returns the serialized object
+         */
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "DefaultRenderingPipeline";
@@ -364,7 +438,13 @@
             return serializationObject;
         }
 
-        // Parse serialized pipeline
+        /**
+         * Parse the serialized pipeline
+         * @param source Source pipeline.
+         * @param scene The scene to load the pipeline to.
+         * @param rootUrl The URL of the serialized pipeline.
+         * @returns An instantiated pipeline from the serialized object.
+         */
         public static Parse(source: any, scene: Scene, rootUrl: string): DefaultRenderingPipeline {
             return SerializationHelper.Parse(() => new DefaultRenderingPipeline(source._name, source._name._hdr, scene), source, scene, rootUrl);
         }

+ 18 - 2
src/PostProcess/babylon.blurPostProcess.ts

@@ -1,4 +1,8 @@
 module BABYLON {
+	/**
+	 * The Blur Post Process which blurs an image based on a kernel and direction. 
+	 * Can be used twice in x and y directions to perform a guassian blur in two passes.
+     */
     export class BlurPostProcess extends PostProcess {
 		protected _kernel: number;
 		protected _idealKernel: number;
@@ -43,8 +47,20 @@
 			return this._packedFloat;
 		}
 
-        constructor(name: string, public direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
-            super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
+		/**
+         * Creates a new instance of @see BlurPostProcess
+         * @param name The name of the effect.
+         * @param direction The direction in which to blur the image.
+		 * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        constructor(name: string, /** The direction in which to blur the image. */ public direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+			super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
 			
 			this.onApplyObservable.add((effect: Effect) => {
 				effect.setFloat2('delta', (1 / this.width) * this.direction.x, (1 / this.height) * this.direction.y);

+ 27 - 27
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -4,57 +4,57 @@ module BABYLON {
      * The depth of field effect applies a blur to objects that are closer or further from where the camera is focusing.
      */
     export class DepthOfFieldEffect extends PostProcessRenderEffect{
-        private depthOfFieldPass: PassPostProcess;
-        private circleOfConfusion: CircleOfConfusionPostProcess;
-        private depthOfFieldBlurX: DepthOfFieldBlurPostProcess;
-        private depthOfFieldBlurY: DepthOfFieldBlurPostProcess;
-        private depthOfFieldMerge: DepthOfFieldMergePostProcess;
+        private _depthOfFieldPass: PassPostProcess;
+        private _circleOfConfusion: CircleOfConfusionPostProcess;
+        private _depthOfFieldBlurX: DepthOfFieldBlurPostProcess;
+        private _depthOfFieldBlurY: DepthOfFieldBlurPostProcess;
+        private _depthOfFieldMerge: DepthOfFieldMergePostProcess;
 
         /**
          * The size of the kernel to be used for the blur
          */
         public set kernelSize(value: number){
-            this.depthOfFieldBlurX.kernel = value;
-            this.depthOfFieldBlurY.kernel = value;
+            this._depthOfFieldBlurX.kernel = value;
+            this._depthOfFieldBlurY.kernel = value;
         }
         public get kernelSize(){
-            return this.depthOfFieldBlurX.kernel;
+            return this._depthOfFieldBlurX.kernel;
         }
         /**
          * The focal the length of the camera used in the effect
          */
         public set focalLength(value: number){
-            this.circleOfConfusion.focalLength = value;
+            this._circleOfConfusion.focalLength = value;
         }
         public get focalLength(){
-            return this.circleOfConfusion.focalLength;
+            return this._circleOfConfusion.focalLength;
         }
         /**
          * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
          */
         public set fStop(value: number){
-            this.circleOfConfusion.fStop = value;
+            this._circleOfConfusion.fStop = value;
         }
         public get fStop(){
-            return this.circleOfConfusion.fStop;
+            return this._circleOfConfusion.fStop;
         }
         /**
          * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
          */
         public set focusDistance(value: number){
-            this.circleOfConfusion.focusDistance = value;
+            this._circleOfConfusion.focusDistance = value;
         }
         public get focusDistance(){
-            return this.circleOfConfusion.focusDistance;
+            return this._circleOfConfusion.focusDistance;
         }
         /**
          * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
          */
         public set lensSize(value: number){
-            this.circleOfConfusion.lensSize = value;
+            this._circleOfConfusion.lensSize = value;
         }
         public get lensSize(){
-            return this.circleOfConfusion.lensSize;
+            return this._circleOfConfusion.lensSize;
         }
 
         /**
@@ -63,19 +63,19 @@ module BABYLON {
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          */
         constructor(scene: Scene, pipelineTextureType = 0) {
-            super(scene.getEngine(), "depth of field", ()=>{return [this.circleOfConfusion, this.depthOfFieldPass, this.depthOfFieldBlurY, this.depthOfFieldBlurX, this.depthOfFieldMerge]}, true);
+            super(scene.getEngine(), "depth of field", ()=>{return [this._circleOfConfusion, this._depthOfFieldPass, this._depthOfFieldBlurY, this._depthOfFieldBlurX, this._depthOfFieldMerge]}, true);
             // Enable and get current depth map
             var depthMap = scene.enableDepthRenderer().getDepthMap();
             // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-            this.circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Capture circle of confusion texture
-            this.depthOfFieldPass = new PassPostProcess("depthOfFieldPass", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            this._depthOfFieldPass = new PassPostProcess("depthOfFieldPass", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
             // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-            this.depthOfFieldBlurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), 15, 1.0, null, depthMap, this.circleOfConfusion, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-            this.depthOfFieldBlurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), 15, 1.0, null,  depthMap, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            this._depthOfFieldBlurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), 15, 1.0, null, depthMap, this._circleOfConfusion, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            this._depthOfFieldBlurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), 15, 1.0, null,  depthMap, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Merge blurred images with original image based on circleOfConfusion
-            this.depthOfFieldMerge = new DepthOfFieldMergePostProcess("depthOfFieldMerge", this.circleOfConfusion, this.depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            this._depthOfFieldMerge = new DepthOfFieldMergePostProcess("depthOfFieldMerge", this._circleOfConfusion, this._depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
         }
 
         /**
@@ -83,11 +83,11 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          */
         public disposeEffects(camera:Camera){
-            this.depthOfFieldPass.dispose(camera);
-            this.circleOfConfusion.dispose(camera);
-            this.depthOfFieldBlurX.dispose(camera);
-            this.depthOfFieldBlurY.dispose(camera);
-            this.depthOfFieldMerge.dispose(camera);
+            this._depthOfFieldPass.dispose(camera);
+            this._circleOfConfusion.dispose(camera);
+            this._depthOfFieldBlurX.dispose(camera);
+            this._depthOfFieldBlurY.dispose(camera);
+            this._depthOfFieldMerge.dispose(camera);
         }
     }
 }

+ 143 - 5
src/PostProcess/babylon.postProcess.ts

@@ -1,25 +1,67 @@
 module BABYLON {
     export type PostProcessOptions = { width: number, height: number };
 
+    /**
+	 * PostProcess can be used to apply a shader to a texture after it has been rendered
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     export class PostProcess {
+        /**
+        * Width of the texture to apply the post process on
+        */
         public width = -1;
+        /**
+        * Height of the texture to apply the post process on
+        */
         public height = -1;
+        /**
+        * Sampling mode used by the shader
+        * See https://doc.babylonjs.com/classes/3.1/texture
+        */
         public renderTargetSamplingMode: number;
+        /**
+        * Clear color to use when screen clearing
+        */
         public clearColor: Color4;
+        /**
+        * If the buffer needs to be cleared before applying the post process. (default: true)
+        * Should be set to false if shader will overwrite all previous pixels.
+        */
         public autoClear = true;
+        /**
+        * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
+        */
         public alphaMode = Engine.ALPHA_DISABLE;
+        /**
+        * Sets the setAlphaBlendConstants of the babylon engine
+        */
         public alphaConstants: Color4;
+        /**
+        * Animations to be used for the post processing 
+        */
         public animations = new Array<Animation>();
 
-        /*
-            Enable Pixel Perfect mode where texture is not scaled to be power of 2.
-            Can only be used on a single postprocess or on the last one of a chain.
-        */
+        /**
+         * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+         * Can only be used on a single postprocess or on the last one of a chain. (default: false)
+         */
         public enablePixelPerfectMode = false;
 
+        /**
+        * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+        */
         public scaleMode = Engine.SCALEMODE_FLOOR;
+        /**
+        * Force textures to be a power of two (default: false)
+        */
         public alwaysForcePOT = false;
+        /**
+        * Number of sample textures (default: 1)
+        */
         public samples = 1;
+        /**
+        * Modify the scale of the post process to be the same as the viewport (default: false)
+        */
         public adaptScaleToCurrentViewport = false;
 
         private _camera: Camera;
@@ -28,7 +70,13 @@
         private _options: number | PostProcessOptions;
         private _reusable = false;
         private _textureType: number;
+        /**
+        * Smart array of input and output textures for the post process.
+        */
         public _textures = new SmartArray<InternalTexture>(2);
+        /**
+        * The index in _textures that corresponds to the output texture.
+        */
         public _currentRenderTextureInd = 0;
         private _effect: Effect;
         private _samplers: string[];
@@ -50,6 +98,9 @@
         public onActivateObservable = new Observable<Camera>();
 
         private _onActivateObserver: Nullable<Observer<Camera>>;
+        /**
+        * A function that is added to the onActivateObservable
+        */
         public set onActivate(callback: Nullable<(camera: Camera) => void>) {
             if (this._onActivateObserver) {
                 this.onActivateObservable.remove(this._onActivateObserver);
@@ -66,6 +117,9 @@
         public onSizeChangedObservable = new Observable<PostProcess>();
 
         private _onSizeChangedObserver: Nullable<Observer<PostProcess>>;
+        /**
+        * A function that is added to the onSizeChangedObservable
+        */
         public set onSizeChanged(callback: (postProcess: PostProcess) => void) {
             if (this._onSizeChangedObserver) {
                 this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
@@ -80,6 +134,9 @@
         public onApplyObservable = new Observable<Effect>();
 
         private _onApplyObserver: Nullable<Observer<Effect>>;
+        /**
+        * A function that is added to the onApplyObservable
+        */
         public set onApply(callback: (effect: Effect) => void) {
             if (this._onApplyObserver) {
                 this.onApplyObservable.remove(this._onApplyObserver);
@@ -94,6 +151,9 @@
         public onBeforeRenderObservable = new Observable<Effect>();
 
         private _onBeforeRenderObserver: Nullable<Observer<Effect>>;
+        /**
+        * A function that is added to the onBeforeRenderObservable
+        */
         public set onBeforeRender(callback: (effect: Effect) => void) {
             if (this._onBeforeRenderObserver) {
                 this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
@@ -108,6 +168,9 @@
         public onAfterRenderObservable = new Observable<Effect>();
 
         private _onAfterRenderObserver: Nullable<Observer<Effect>>;
+        /**
+        * A function that is added to the onAfterRenderObservable
+        */
         public set onAfterRender(callback: (efect: Effect) => void) {
             if (this._onAfterRenderObserver) {
                 this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
@@ -115,6 +178,9 @@
             this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
         }
 
+        /**
+        * The resulting output of the post process.
+        */
         public get outputTexture(): InternalTexture {
             return this._textures.data[this._currentRenderTextureInd];
         }
@@ -123,10 +189,18 @@
             this._forcedOutputTexture = value;
         }
 
+        /**
+        * Gets the camera which post process is applied to.
+        * @returns The camera the post process is applied to.
+        */
         public getCamera(): Camera {
             return this._camera;
         }
 
+        /**
+        * Gets the texel size of the postprocess.
+        * See https://en.wikipedia.org/wiki/Texel_(graphics)
+        */
         public get texelSize(): Vector2 {
             if (this._shareOutputWithPostProcess) {
                 return this._shareOutputWithPostProcess.texelSize;
@@ -139,7 +213,24 @@
             return this._texelSize;
         }
 
-        constructor(public name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>,
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param name The name of the PostProcess.
+         * @param fragmentUrl The url of the fragment shader to be used.
+		 * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
+         * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param defines String of defines that will be set when running the fragment shader. (default: null)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param blockCompilation If the shader should be compiled imediatly. (default: false) 
+         */
+        constructor(/** Name of the PostProcess. */public name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>,
             samplingMode: number = Texture.NEAREST_SAMPLINGMODE, engine?: Engine, reusable?: boolean, defines: Nullable<string> = null, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, vertexUrl: string = "postprocess", indexParameters?: any, blockCompilation = false) {
             if (camera != null) {
                 this._camera = camera;
@@ -175,14 +266,27 @@
             }
         }
 
+        /**
+         * Gets the engine which this post process belongs to.
+         * @returns The engine the post process was enabled with.
+         */
         public getEngine(): Engine {
             return this._engine;
         }
 
+        /**
+         * The effect that is created when initializing the post process.
+         * @returns The created effect corrisponding the the postprocess.
+         */
         public getEffect(): Effect {
             return this._effect;
         }
 
+        /**
+         * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
+         * @param postProcess The post process to share the output with.
+         * @returns This post process.
+         */
         public shareOutputWith(postProcess: PostProcess): PostProcess {
             this._disposeTextures();
 
@@ -191,6 +295,15 @@
             return this;
         }
 
+        /**
+         * Updates the effect with the current post process compile time values and recompiles the shader.
+         * @param defines Define statements that should be added at the beginning of the shader. (default: null)
+         * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
+         * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param onCompiled Called when the shader has been compiled.
+         * @param onError Called if there is an error when compiling a shader.
+         */
         public updateEffect(defines: Nullable<string> = null, uniforms: Nullable<string[]> = null, samplers: Nullable<string[]> = null, indexParameters?: any,
             onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void) {
             this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl },
@@ -205,6 +318,10 @@
             );
         }
 
+        /**
+         * The post process is reusable if it can be used multiple times within one frame.
+         * @returns If the post process is reusable
+         */
         public isReusable(): boolean {
             return this._reusable;
         }
@@ -214,6 +331,12 @@
             this.width = -1;
         }
 
+        /**
+         * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
+         * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
+         * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
+         * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
+         */
         public activate(camera: Nullable<Camera>, sourceTexture: Nullable<InternalTexture> = null, forceDepthStencil?: boolean): void {
             camera = camera || this._camera;
 
@@ -319,10 +442,17 @@
             }
         }
 
+
+        /**
+         * If the post process is supported.
+         */
         public get isSupported(): boolean {
             return this._effect.isSupported;
         }
 
+        /**
+         * The aspect ratio of the output texture.
+         */
         public get aspectRatio(): number {
             if (this._shareOutputWithPostProcess) {
                 return this._shareOutputWithPostProcess.aspectRatio;
@@ -342,6 +472,10 @@
             return this._effect && this._effect.isReady();
         }
 
+        /**
+         * Binds all textures and uniforms to the shader, this will be run on every pass.
+         * @returns the effect corrisponding to this post process. Null if not compiled or not ready.
+         */
         public apply(): Nullable<Effect> {
             // Check
             if (!this._effect || !this._effect.isReady())
@@ -390,6 +524,10 @@
             this._textures.dispose();
         }
 
+        /**
+         * Disposes the post process.
+         * @param camera The camera to dispose the post process on.
+         */
         public dispose(camera?: Camera): void {
             camera = camera || this._camera;
 

+ 34 - 0
src/PostProcess/babylon.postProcessManager.ts

@@ -1,9 +1,17 @@
 module BABYLON {
+    /**
+	 * PostProcessManager is used to manage one or more post processes or post process pipelines
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     export class PostProcessManager {
         private _scene: Scene;
         private _indexBuffer: Nullable<WebGLBuffer>;
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
 
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param scene The scene that the post process is associated with.
+         */
         constructor(scene: Scene) {
             this._scene = scene;
         }
@@ -39,6 +47,9 @@
             this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
         }
 
+        /**
+         * Rebuilds the vertex buffers of the manager.
+         */
         public _rebuild(): void {
             let vb = this._vertexBuffers[VertexBuffer.PositionKind];
 
@@ -50,6 +61,12 @@
         }
 
         // Methods
+        /**
+         * Prepares a frame to be run through a post process.
+         * @param sourceTexture The input texture to the post procesess. (default: null)
+         * @param postProcesses An array of post processes to be run. (default: null)
+         * @returns True if the post processes were able to be run.
+         */
         public _prepareFrame(sourceTexture: Nullable<InternalTexture> = null, postProcesses: Nullable<PostProcess[]> = null): boolean {
             let camera = this._scene.activeCamera;
             if (!camera) {
@@ -66,6 +83,12 @@
             return true;
         }
 
+        /**
+         * Manually render a set of post processes to a texture.
+         * @param postProcesses An array of post processes to be run.
+         * @param targetTexture The target texture to render to.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
+         */
         public directRender(postProcesses: PostProcess[], targetTexture: Nullable<InternalTexture> = null, forceFullscreenViewport = false): void {
             var engine = this._scene.getEngine();
 
@@ -102,6 +125,14 @@
             engine.setDepthWrite(true);
         }
 
+        /**
+         * Finalize the result of the output of the postprocesses.
+         * @param doNotPresent If true the result will not be displayed to the screen.
+         * @param targetTexture The target texture to render to.
+         * @param faceIndex The index of the face to bind the target texture to.
+         * @param postProcesses The array of post processes to render.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
+         */
         public _finalizeFrame(doNotPresent?: boolean, targetTexture?: InternalTexture, faceIndex?: number, postProcesses?: PostProcess[], forceFullscreenViewport = false): void {
             let camera = this._scene.activeCamera;
 
@@ -153,6 +184,9 @@
             engine.setAlphaMode(Engine.ALPHA_DISABLE);
         }
 
+        /**
+         * Disposes of the post process manager.
+         */
         public dispose(): void {
             var buffer = this._vertexBuffers[VertexBuffer.PositionKind];
             if (buffer) {

+ 1 - 1
src/Shaders/ShadersInclude/lightFragment.fx

@@ -24,7 +24,7 @@
 			#endif
 		#endif
 		#ifdef PROJECTEDLIGHTTEXTURE{X}
-			info = computeProjectionTexture(info,projectionLightSampler{X},textureProjectionMatrix{X});
+			info.diffuse *= computeProjectionTextureDiffuseLighting(projectionLightSampler{X}, textureProjectionMatrix{X});
 		#endif
     #endif
 	#ifdef SHADOW{X}

+ 6 - 5
src/Shaders/ShadersInclude/lightsFragmentFunctions.fx

@@ -109,11 +109,12 @@ lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4
 		return result;
 }
 
-lightingInfo computeProjectionTexture(lightingInfo origin,sampler2D projectionLightSampler, mat4 textureProjectionMatrix){
-	lightingInfo result = origin;
+vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, mat4 textureProjectionMatrix){
 	vec4 strq = textureProjectionMatrix * vec4(vPositionW, 1.0);
 	strq /= strq.w;
-	vec4 textureColor = texture2D(projectionLightSampler, strq.xy);
-	result.diffuse *= vec3(textureColor);
-	return result;
+	vec3 textureColor = texture2D(projectionLightSampler, strq.xy).rgb;
+#ifdef PBR
+	textureColor = toLinearSpace(textureColor);
+#endif
+	return textureColor;
 }

+ 10 - 3
src/Tools/babylon.promise.ts

@@ -106,7 +106,7 @@ module BABYLON {
         }       
 
         private _moveChildren(children: InternalPromise<T>[]): void {
-            this._children = children.splice(0, children.length);
+            this._children.push(...children.splice(0, children.length));
 
             if (this.isFulfilled) {
                 for (var child of this._children) {
@@ -135,6 +135,8 @@ module BABYLON {
                         let returnedPromise = returnedValue as InternalPromise<T>;
                         
                         returnedPromise._moveChildren(this._children);
+                    } else {
+                        value = <T>returnedValue;
                     }
                 }
 
@@ -198,10 +200,15 @@ module BABYLON {
             agregator.target = promises.length;
             agregator.rootPromise = newPromise;
 
-            for(var index = 0; index < promises.length; index++) {
-                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+            if (promises.length) {
+                for(var index = 0; index < promises.length; index++) {
+                    InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+                }
+            } else {
+                newPromise._resolve([]);
             }
 
+
             return newPromise;
         }
     }

+ 12 - 2
src/Tools/babylon.tools.ts

@@ -212,10 +212,20 @@
             return path.substring(index + 1);
         }
 
-        public static GetFolderPath(uri: string): string {
+        /**
+         * Extracts the "folder" part of a path (everything before the filename).
+         * @param uri The URI to extract the info from
+         * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
+         * @returns The "folder" part of the path
+         */
+        public static GetFolderPath(uri: string, returnUnchangedIfNoSlash = false): string {
             var index = uri.lastIndexOf("/");
-            if (index < 0)
+            if (index < 0) {
+                if (returnUnchangedIfNoSlash) {
+                    return uri;
+                }
                 return "";
+            }
 
             return uri.substring(0, index + 1);
         }

+ 24 - 0
tests/unit/babylon/promises/babylon.promises.tests.ts

@@ -175,4 +175,28 @@ describe('Babylon.Promise', () => {
             });
         });
     });     
+
+    describe('#All and then', () => {
+        it('should correctly handle chaining a returning then after a all', (done) => {
+            mocha.timeout(10000);
+            var delayAsync = function (timeout) {
+                return new Promise(function (resolve) {
+                    setTimeout(function () {
+                        resolve(1);
+                    }, timeout);
+                });
+            };
+            
+            var promise = Promise.all([delayAsync(100), delayAsync(200)]).then(function () {
+                return 2;
+            });
+            
+            promise.then(function (value) {
+                value.should.be.equal(2);
+                done();
+            }); 
+        });
+    });      
+
+
 });

+ 5 - 0
tests/validation/integration.js

@@ -21,6 +21,11 @@ xhr.addEventListener("load", function () {
                         var info = engine.getGlInfo();
                         console.log("Webgl Version: " + info.version);
                         console.log("Webgl Vendor: " + info.vendor);
+                        // Reduces error ratio on Embedded Firefox for travis.
+                        if (info.vendor === "VMware, Inc.") {
+                            errorRatio = 5;
+                        }
+
                         console.log("Webgl Renderer: " + info.renderer);
                         done();
                     });