Selaa lähdekoodia

Merge remote-tracking branch 'refs/remotes/BabylonJS/master' into AddingCellIdToSpriteGui

# Conflicts:
#	dist/preview release/gui/babylon.gui.min.js
DESKTOP-QJU4N0L\mityh 7 vuotta sitten
vanhempi
commit
2fca090f90
58 muutettua tiedostoa jossa 32660 lisäystä ja 29849 poistoa
  1. 17 17
      Playground/package.json
  2. 42 40
      Tools/Gulp/package.json
  3. 4729 2553
      Viewer/dist/viewer.js
  4. 10 10
      Viewer/package.json
  5. 3 1
      Viewer/src/index.ts
  6. 9 5
      Viewer/src/viewer/defaultViewer.ts
  7. 7 1
      Viewer/src/viewer/viewer.ts
  8. 28 0
      Viewer/src/viewer/viewerManager.ts
  9. 7869 7848
      dist/preview release/babylon.d.ts
  10. 48 48
      dist/preview release/babylon.js
  11. 288 60
      dist/preview release/babylon.max.js
  12. 7869 7848
      dist/preview release/babylon.module.d.ts
  13. 47 47
      dist/preview release/babylon.worker.js
  14. 5483 5443
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  15. 49 49
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  16. 132 59
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  17. 5483 5443
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  18. 3 3
      dist/preview release/gui/babylon.gui.min.js
  19. 1 1
      dist/preview release/gui/package.json
  20. 263 263
      dist/preview release/inspector/babylon.inspector.bundle.js
  21. 2 0
      dist/preview release/inspector/babylon.inspector.js
  22. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  23. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  24. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  25. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  26. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  27. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  28. 1 1
      dist/preview release/loaders/package.json
  29. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  30. 2 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  31. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  32. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  33. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  34. 2 1
      dist/preview release/materialsLibrary/babylonjs.materials.js
  35. 5 5
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  36. 1 1
      dist/preview release/materialsLibrary/package.json
  37. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  38. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  39. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  40. 1 1
      dist/preview release/postProcessesLibrary/package.json
  41. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  42. 1 1
      dist/preview release/serializers/package.json
  43. 2 0
      inspector/src/properties.ts
  44. 2 1
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  45. 1 1
      package.json
  46. 3 2
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  47. 16 4
      src/Engine/babylon.engine.ts
  48. 2 0
      src/Engine/babylon.webgl2.ts
  49. 9 9
      src/Loading/babylon.sceneLoader.ts
  50. 49 29
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  51. 4 1
      src/Materials/Textures/babylon.texture.ts
  52. 2 2
      src/Materials/babylon.effect.ts
  53. 15 14
      src/Materials/babylon.materialHelper.ts
  54. 132 7
      src/Particles/babylon.gpuParticleSystem.ts
  55. 3 3
      src/Shaders/pbr.fragment.fx
  56. 2 2
      src/Shaders/pbr.vertex.fx
  57. 1 1
      src/Tools/babylon.observable.ts
  58. 0 1
      src/babylon.scene.ts

+ 17 - 17
Playground/package.json

@@ -1,17 +1,17 @@
-{
-  "name": "babylonjsplayground",
-  "version": "3.0.0",
-  "description": "Babylon.js is a 3D engine based on webgl and javascript",
-  "main": "",
-  "repository": {
-    "url": "https://github.com/BabylonJS/Babylon.js/"
-  },
-  "readme": "https://github.com/BabylonJS/Babylon.js/blob/master/readme.md",
-  "license": "(Apache-2.0)",
-  "devDependencies": {
-    "monaco-editor": "~0.10.0"
-  },
-  "scripts": {
-    "test": "browser-sync start --server --files **/* --no-inject-changes --startPath index.html"
-  }
-}
+{
+  "name": "babylonjsplayground",
+  "version": "3.0.0",
+  "description": "Babylon.js is a 3D engine based on webgl and javascript",
+  "main": "",
+  "repository": {
+    "url": "https://github.com/BabylonJS/Babylon.js/"
+  },
+  "readme": "https://github.com/BabylonJS/Babylon.js/blob/master/readme.md",
+  "license": "(Apache-2.0)",
+  "devDependencies": {
+    "monaco-editor": "~0.10.0"
+  },
+  "scripts": {
+    "test": "browser-sync start --server --files **/* --no-inject-changes --startPath index.html"
+  }
+}

+ 42 - 40
Tools/Gulp/package.json

@@ -1,40 +1,42 @@
-{
-  "name": "BabylonJS",
-  "version": "3.0.0",
-  "description": "Babylon.js is a 3D engine based on webgl and javascript",
-  "main": "",
-  "repository": { "url": "https://github.com/BabylonJS/Babylon.js/" },
-  "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
-  "license": "(Apache-2.0)",
-  "devDependencies": {
-    "gulp": "^3.8.11",
-    "gulp-uglify": "^2.1.2",
-    "gulp-sourcemaps": "~1.9.1",
-    "typescript": "~2.5.3",
-    "gulp-typescript": "^3.2.2",
-    "through2": "~0.6.5",
-    "gulp-util": "~3.0.4",
-    "gulp-concat": "~2.5.2",
-    "merge2": "~0.3.5",
-    "gulp-rename": "~1.2.2",
-    "gulp-clean-ts-extends": "~0.1.1",
-    "gulp-changed-in-place": "2.0.3",
-    "run-sequence": "~1.1.0",
-    "gulp-replace": "~0.5.3",
-    "gulp-content-to-variable": "^0.1.0",
-    "gulp-expect-file": "^0.0.7",
-    "gulp-optimize-js": "^1.0.2",
-    "gulp-webserver": "^0.9.1",
-    "gulp-debug": "^3.0.0",
-    "gulp-sass": "2.3.2",
-    "webpack-stream": "^3.2.0",
-    "css-loader": "^0.25.0",
-    "style-loader": "^0.13.1",
-    "exports-loader": "^0.6.3",
-    "imports-loader": "^0.7.0",
-    "del": "2.2.2"
-  },
-  "scripts": {
-    "install": "npm --prefix ../../Playground/ install ../../Playground/ && gulp typescript-compile && gulp typescript-libraries && gulp deployLocalDev"
-  }
-}
+{
+  "name": "BabylonJS",
+  "version": "3.0.0",
+  "description": "Babylon.js is a 3D engine based on webgl and javascript",
+  "main": "",
+  "repository": {
+    "url": "https://github.com/BabylonJS/Babylon.js/"
+  },
+  "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
+  "license": "(Apache-2.0)",
+  "devDependencies": {
+    "gulp": "^3.8.11",
+    "gulp-uglify": "^2.1.2",
+    "gulp-sourcemaps": "~1.9.1",
+    "typescript": "~2.5.3",
+    "gulp-typescript": "^3.2.2",
+    "through2": "~0.6.5",
+    "gulp-util": "~3.0.4",
+    "gulp-concat": "~2.5.2",
+    "merge2": "~0.3.5",
+    "gulp-rename": "~1.2.2",
+    "gulp-clean-ts-extends": "~0.1.1",
+    "gulp-changed-in-place": "2.0.3",
+    "run-sequence": "~1.1.0",
+    "gulp-replace": "~0.5.3",
+    "gulp-content-to-variable": "^0.1.0",
+    "gulp-expect-file": "^0.0.7",
+    "gulp-optimize-js": "^1.0.2",
+    "gulp-webserver": "^0.9.1",
+    "gulp-debug": "^3.0.0",
+    "gulp-sass": "3.1.0",
+    "webpack-stream": "^3.2.0",
+    "css-loader": "^0.25.0",
+    "style-loader": "^0.13.1",
+    "exports-loader": "^0.6.3",
+    "imports-loader": "^0.7.0",
+    "del": "2.2.2"
+  },
+  "scripts": {
+    "install": "npm --prefix ../../Playground/ install ../../Playground/ && gulp typescript-compile && gulp typescript-libraries && gulp deployLocalDev"
+  }
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4729 - 2553
Viewer/dist/viewer.js


+ 10 - 10
Viewer/package.json

@@ -23,26 +23,26 @@
     },
     "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
     "devDependencies": {
-        "@types/node": "^8.0.44",
+        "@types/node": "^8.0.47",
         "base64-image-loader": "^1.2.0",
         "html-loader": "^0.5.1",
         "json-loader": "^0.5.7",
         "ts-loader": "^2.3.7",
-        "typescript": "^2.5.3",
-        "uglifyjs-webpack-plugin": "^1.0.0-beta.3",
+        "typescript": "^2.6.1",
+        "uglifyjs-webpack-plugin": "^1.0.1",
         "webpack": "^3.8.1",
-        "webpack-dev-server": "^2.9.2"
+        "webpack-dev-server": "^2.9.4"
     },
     "dependencies": {
-        "babylonjs": "^3.1.0-alpha3.6",
-        "babylonjs-loaders": "^3.1.0-alpha3.6",
-        "babylonjs-materials": "^3.1.0-alpha3.6",
-        "babylonjs-post-process": "^3.1.0-alpha3.6",
-        "babylonjs-procedural-textures": "^3.1.0-alpha3.6",
+        "babylonjs": "^3.1.0-alpha3.7",
+        "babylonjs-loaders": "^3.1.0-alpha3.7",
+        "babylonjs-materials": "^3.1.0-alpha3.7",
+        "babylonjs-post-process": "^3.1.0-alpha3.7",
+        "babylonjs-procedural-textures": "^3.1.0-alpha3.7",
         "es6-promise": "^4.1.1",
         "handlebars": "^4.0.11",
         "lodash": "^4.17.4",
         "lodash.merge": "^4.6.0",
         "promise-polyfill": "^6.0.2"
     }
-}
+}

+ 3 - 1
Viewer/src/index.ts

@@ -1,3 +1,5 @@
+import { viewerManager } from './viewer/viewerManager';
+import { DefaultViewer } from './viewer/defaultViewer';
 import { AbstractViewer } from './viewer/viewer';
 
 /**
@@ -25,4 +27,4 @@ setTimeout(() => {
 });
 
 // public API for initialization
-export { InitTags };
+export { InitTags, DefaultViewer, AbstractViewer, viewerManager };

+ 9 - 5
Viewer/src/viewer/defaultViewer.ts

@@ -9,7 +9,7 @@ window['BABYLON'] = BABYLON;
 
 export class DefaultViewer extends AbstractViewer {
 
-    private camera: ArcRotateCamera;
+    public camera: ArcRotateCamera;
 
     public initScene(): Promise<Scene> {
         return super.initScene().then(() => {
@@ -199,12 +199,12 @@ export class DefaultViewer extends AbstractViewer {
             if (texture) {
                 this.extendClassWithConfig(texture, this.configuration.skybox.cubeTexture);
 
-                let scale = this.configuration.skybox.scale || (this.scene.activeCamera.maxZ - this.scene.activeCamera.minZ) / 2;
+                let scale = this.configuration.skybox.scale || this.scene.activeCamera && (this.scene.activeCamera.maxZ - this.scene.activeCamera.minZ) / 2 || 1;
 
                 let box = this.scene.createDefaultSkybox(texture, this.configuration.skybox.pbr, scale, this.configuration.skybox.blur);
 
                 // before extending, set the material's imageprocessing configuration object, if needed:
-                if (this.configuration.skybox.material && this.configuration.skybox.material.imageProcessingConfiguration) {
+                if (this.configuration.skybox.material && this.configuration.skybox.material.imageProcessingConfiguration && box) {
                     (<StandardMaterial>box.material).imageProcessingConfiguration = new ImageProcessingConfiguration();
                 }
 
@@ -335,6 +335,7 @@ export class DefaultViewer extends AbstractViewer {
                 let lightConfig = this.configuration.lights && this.configuration.lights[name] || { name: name, type: 0 };
                 lightConfig.name = name;
                 let constructor = Light.GetConstructorFromName(lightConfig.type, lightConfig.name, this.scene);
+                if (!constructor) return;
                 let light = constructor();
 
                 //enabled
@@ -347,11 +348,14 @@ export class DefaultViewer extends AbstractViewer {
                 //position. Some lights don't support shadows
                 if (light instanceof ShadowLight) {
                     if (lightConfig.shadowEnabled) {
-                        var shadowGenerator = new BABYLON.ShadowGenerator(512, light)
+                        var shadowGenerator = new BABYLON.ShadowGenerator(512, light);
                         this.extendClassWithConfig(shadowGenerator, lightConfig.shadowConfig || {});
                         // add the focues meshes to the shadow list
+                        let shadownMap = shadowGenerator.getShadowMap();
+                        if (!shadownMap) return;
+                        let renderList = shadownMap.renderList;
                         for (var index = 0; index < focusMeshes.length; index++) {
-                            shadowGenerator.getShadowMap().renderList.push(focusMeshes[index]);
+                            renderList && renderList.push(focusMeshes[index]);
                         }
                     }
                 }

+ 7 - 1
Viewer/src/viewer/viewer.ts

@@ -1,3 +1,4 @@
+import { viewerManager } from './viewerManager';
 import { TemplateManager } from './../templateManager';
 import configurationLoader from './../configuration/loader';
 import { Observable, Engine, Scene, ArcRotateCamera, Vector3, SceneLoader, AbstractMesh, Mesh, HemisphericLight } from 'babylonjs';
@@ -21,6 +22,10 @@ export abstract class AbstractViewer {
             this.baseId = containerElement.id = 'bjs' + Math.random().toString(32).substr(2, 8);
         }
 
+        // add this viewer to the viewer manager
+        viewerManager.addViewer(this);
+
+        // create a new template manager. TODO - singleton?
         this.templateManager = new TemplateManager(containerElement);
 
         this.prepareContainerElement();
@@ -110,6 +115,7 @@ export abstract class AbstractViewer {
         let parts = modelUrl.split('/');
         let filename = parts.pop();
         let base = parts.join('/') + '/';
+        let plugin = (typeof model === 'string') ? undefined : model.loader;
 
         return Promise.resolve().then(() => {
             if (!this.scene || clearScene) return this.initScene();
@@ -121,7 +127,7 @@ export abstract class AbstractViewer {
                 }, undefined, (e, m, exception) => {
                     console.log(m, exception);
                     reject(m);
-                });
+                }, plugin);
             });
         }).then((meshes: Array<AbstractMesh>) => {
             return this.onModelLoaded(meshes);

+ 28 - 0
Viewer/src/viewer/viewerManager.ts

@@ -0,0 +1,28 @@
+import { AbstractViewer } from './viewer';
+
+class ViewerManager {
+
+    private viewers: { [key: string]: AbstractViewer };
+
+    constructor() {
+        this.viewers = {};
+    }
+
+    public addViewer(viewer: AbstractViewer) {
+        this.viewers[viewer.getBaseId()] = viewer;
+    }
+
+    public getViewerById(id: string): AbstractViewer {
+        return this.viewers[id];
+    }
+
+    public getViewerByHTMLElement(element: HTMLElement) {
+        for (let id in this.viewers) {
+            if (this.viewers[id].containerElement === element) {
+                return this.getViewerById(id);
+            }
+        }
+    }
+}
+
+export let viewerManager = new ViewerManager();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 7869 - 7848
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 48 - 48
dist/preview release/babylon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 288 - 60
dist/preview release/babylon.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 7869 - 7848
dist/preview release/babylon.module.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 47 - 47
dist/preview release/babylon.worker.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5483 - 5443
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 49 - 49
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 132 - 59
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5483 - 5443
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 263 - 263
dist/preview release/inspector/babylon.inspector.bundle.js


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

@@ -467,6 +467,8 @@ var INSPECTOR;
                 'radius',
                 'angularSensibilityX',
                 'angularSensibilityY',
+                'angularTouchSensibilityX',
+                'angularTouchSensibilityY',
                 'target',
                 'lowerAlphaLimit',
                 'lowerBetaLimit',

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


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

@@ -142,7 +142,8 @@ var BABYLON;
                     onCompiled: this.onCompiled,
                     onError: this.onError,
                     indexParameters: null,
-                    maxSimultaneousLights: 4
+                    maxSimultaneousLights: 4,
+                    transformFeedbackVaryings: null
                 }, engine), defines);
             }
             if (!subMesh.effect || !subMesh.effect.isReady()) {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 2 - 1
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -2154,7 +2154,8 @@ var BABYLON;
                     onCompiled: this.onCompiled,
                     onError: this.onError,
                     indexParameters: null,
-                    maxSimultaneousLights: 4
+                    maxSimultaneousLights: 4,
+                    transformFeedbackVaryings: null
                 }, engine), defines);
             }
             if (!subMesh.effect || !subMesh.effect.isReady()) {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5 - 5
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.1.0-alpha3.4",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 0
inspector/src/properties.ts

@@ -116,6 +116,8 @@ module INSPECTOR {
                 'radius',
                 'angularSensibilityX',
                 'angularSensibilityY',
+                'angularTouchSensibilityX',
+                'angularTouchSensibilityY',
                 'target',
                 'lowerAlphaLimit',
                 'lowerBetaLimit',

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

@@ -167,7 +167,8 @@ module BABYLON {
                         onCompiled: this.onCompiled,
                         onError: this.onError,
                         indexParameters: null,
-                        maxSimultaneousLights: 4
+                        maxSimultaneousLights: 4,
+                        transformFeedbackVaryings: null
                     }, engine), defines);
             }
             

+ 1 - 1
package.json

@@ -8,7 +8,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.1.0-alpha3.6",
+    "version": "3.1.0-alpha3.7",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 3 - 2
src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts

@@ -54,7 +54,8 @@ module BABYLON {
 
             this._pointerInput = (p, s) => {
                 var evt = <PointerEvent>p.event;
-
+                let isTouch = (<any>p.event).pointerType === "touch";
+                
                 if (engine.isInVRExclusivePointerMode) {
                     return;
                 }
@@ -105,7 +106,7 @@ module BABYLON {
                     twoFingerActivityCount = 0;
                     initialDistance = 0;
 
-                    if ((<any>p.event).pointerType !== "touch") {
+                    if (!isTouch) {
                         pointB = null; // Mouse and pen are mono pointer
                     }
 

+ 16 - 4
src/Engine/babylon.engine.ts

@@ -1447,6 +1447,14 @@
             }
         }
 
+        public setRasterizerState(value: boolean): void {
+            if (value) {
+                this._gl.disable(this._gl.RASTERIZER_DISCARD);
+            } else {
+                this._gl.enable(this._gl.RASTERIZER_DISCARD);
+            }
+        }        
+
         /**
          * stop executing a render loop function and remove it from the execution array
          * @param {Function} [renderFunction] the function to be removed. If not provided all functions will be removed.
@@ -2470,13 +2478,13 @@
                 ["diffuseSampler"].concat(samplers), defines, fallbacks, onCompiled, onError);
         }
 
-        public createRawShaderProgram(vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext): WebGLProgram {
+        public createRawShaderProgram(vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
             context = context || this._gl;
 
             var vertexShader = compileRawShader(context, vertexCode, "vertex");
             var fragmentShader = compileRawShader(context, fragmentCode, "fragment");
 
-            return this._createShaderProgram(vertexShader, fragmentShader, context);
+            return this._createShaderProgram(vertexShader, fragmentShader, context, transformFeedbackVaryings);
         }
 
         public createShaderProgram(vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
@@ -5281,8 +5289,8 @@
             this._gl.bindTransformFeedback(this._gl.TRANSFORM_FEEDBACK, value);
         }
 
-        public beginTransformFeedback(): void {
-            this._gl.beginTransformFeedback(this._gl.TRIANGLES);
+        public beginTransformFeedback(usePoints: boolean = true): void {
+            this._gl.beginTransformFeedback(usePoints ? this._gl.POINTS : this._gl.TRIANGLES);
         }
 
         public endTransformFeedback(): void {
@@ -5293,6 +5301,10 @@
             this._gl.transformFeedbackVaryings(program, value, this._gl.INTERLEAVED_ATTRIBS);
         }
 
+        public bindTransformFeedbackBuffer(value: Nullable<WebGLBuffer>): void {
+            this._gl.bindBufferBase(this._gl.TRANSFORM_FEEDBACK_BUFFER, 0, value);
+        }
+
         // Statics
         public static isSupported(): boolean {
             try {

+ 2 - 0
src/Engine/babylon.webgl2.ts

@@ -4,6 +4,7 @@
 // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
 
 interface WebGLRenderingContext {
+    readonly RASTERIZER_DISCARD: number;
     readonly TEXTURE_3D: number;
     readonly TEXTURE_2D_ARRAY: number;
     readonly TEXTURE_WRAP_R: number;
@@ -16,6 +17,7 @@ interface WebGLRenderingContext {
 
     readonly TRANSFORM_FEEDBACK: number;
     readonly INTERLEAVED_ATTRIBS: number;
+    readonly TRANSFORM_FEEDBACK_BUFFER: number;
     createTransformFeedback(): WebGLTransformFeedback;
     deleteTransformFeedback(transformFeedbac: WebGLTransformFeedback): void;
     bindTransformFeedback(target: number, transformFeedback: Nullable<WebGLTransformFeedback>): void;

+ 9 - 9
src/Loading/babylon.sceneLoader.ts

@@ -138,9 +138,9 @@
             return null;
         }
 
-        private static _loadData(rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: (plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync, data: any) => void, onProgress: (event: ProgressEvent) => void, onError: (message: Nullable<string>, exception?: any) => void): void {
+        private static _loadData(rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: (plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync, data: any) => void, onProgress: (event: ProgressEvent) => void, onError: (message: Nullable<string>, exception?: any) => void, pluginExtension?: string): void {
             var directLoad = SceneLoader._getDirectLoad(sceneFilename);
-            var registeredPlugin = directLoad ? SceneLoader._getPluginForDirectLoad(sceneFilename) : SceneLoader._getPluginForFilename(sceneFilename);
+            var registeredPlugin = pluginExtension ? SceneLoader._getPluginForExtension(pluginExtension) : (directLoad ? SceneLoader._getPluginForDirectLoad(sceneFilename) : SceneLoader._getPluginForFilename(sceneFilename));
             var plugin = registeredPlugin.plugin;
             var useArrayBuffer = registeredPlugin.isBinary;
             var database: Database;
@@ -187,7 +187,7 @@
             }
             // Loading file from disk via input file or drag'n'drop
             else {
-                var fileOrString = <any> sceneFilename;
+                var fileOrString = <any>sceneFilename;
 
                 if (fileOrString.name) { // File
                     Tools.ReadFile(fileOrString, dataCallback, onProgress, useArrayBuffer);
@@ -234,7 +234,7 @@
         * @param onProgress a callback with a progress event for each file being loaded
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
-        public static ImportMesh(meshNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: Nullable<(meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void> = null, onProgress: Nullable<(event: ProgressEvent) => void> = null, onError: Nullable<(scene: Scene, message: string, exception?: any) => void> = null): void {
+        public static ImportMesh(meshNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: Nullable<(meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void> = null, onProgress: Nullable<(event: ProgressEvent) => void> = null, onError: Nullable<(scene: Scene, message: string, exception?: any) => void> = null, pluginExtension?: string): void {
             if (sceneFilename.substr && sceneFilename.substr(0, 1) === "/") {
                 Tools.Error("Wrong sceneFilename parameter");
                 return;
@@ -297,7 +297,7 @@
                         }
                     }, progressHandler, errorHandler);
                 }
-            }, progressHandler, errorHandler);
+            }, progressHandler, errorHandler, pluginExtension);
         }
 
         /**
@@ -309,8 +309,8 @@
         * @param onProgress a callback with a progress event for each file being loaded
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
-        public static Load(rootUrl: string, sceneFilename: any, engine: Engine, onSuccess?: (scene: Scene) => void, onProgress?: (event: ProgressEvent) => void, onError?: (scene: Scene, message: string, exception?: any) => void): void {
-            SceneLoader.Append(rootUrl, sceneFilename, new Scene(engine), onSuccess, onProgress, onError);
+        public static Load(rootUrl: string, sceneFilename: any, engine: Engine, onSuccess?: (scene: Scene) => void, onProgress?: (event: ProgressEvent) => void, onError?: (scene: Scene, message: string, exception?: any) => void, pluginExtension?: string): void {
+            SceneLoader.Append(rootUrl, sceneFilename, new Scene(engine), onSuccess, onProgress, onError, pluginExtension);
         }
 
         /**
@@ -322,7 +322,7 @@
         * @param onProgress a callback with a progress event for each file being loaded
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
-        public static Append(rootUrl: string, sceneFilename: any, scene: Scene, onSuccess?: (scene: Scene) => void, onProgress?: (event: ProgressEvent) => void, onError?: (scene: Scene, message: string, exception?: any) => void): void {
+        public static Append(rootUrl: string, sceneFilename: any, scene: Scene, onSuccess?: (scene: Scene) => void, onProgress?: (event: ProgressEvent) => void, onError?: (scene: Scene, message: string, exception?: any) => void, pluginExtension?: string): void {
             if (sceneFilename.substr && sceneFilename.substr(0, 1) === "/") {
                 Tools.Error("Wrong sceneFilename parameter");
                 return;
@@ -387,7 +387,7 @@
                         scene.getEngine().hideLoadingUI();
                     });
                 }
-            }, progressHandler, errorHandler);
+            }, progressHandler, errorHandler, pluginExtension);
         }
     };
 }

+ 49 - 29
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -74,7 +74,7 @@
         public REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
         public INVERTCUBICMAP = false;
         public USESPHERICALFROMREFLECTIONMAP = false;
-        public USESPHERICALINFRAGMENT = false;
+        public USESPHERICALINVERTEX = false;
         public REFLECTIONMAP_OPPOSITEZ = false;
         public LODINREFLECTIONALPHA = false;
         public GAMMAREFLECTION = false;
@@ -632,7 +632,10 @@
                             if (reflectionTexture.sphericalPolynomial) {
                                 defines.USESPHERICALFROMREFLECTIONMAP = true;
                                 if (this._forceIrradianceInFragment || scene.getEngine().getCaps().maxVaryingVectors <= 8) {
-                                    defines.USESPHERICALINFRAGMENT = true;
+                                    defines.USESPHERICALINVERTEX = false;
+                                }
+                                else {
+                                    defines.USESPHERICALINVERTEX = true;
                                 }
                             }
                         }
@@ -650,7 +653,7 @@
                         defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
                         defines.INVERTCUBICMAP = false;
                         defines.USESPHERICALFROMREFLECTIONMAP = false;
-                        defines.USESPHERICALINFRAGMENT = false;
+                        defines.USESPHERICALINVERTEX = false;
                         defines.REFLECTIONMAP_OPPOSITEZ = false;
                         defines.LODINREFLECTIONALPHA = false;
                         defines.GAMMAREFLECTION = false;
@@ -831,58 +834,75 @@
 
                 // Fallbacks
                 var fallbacks = new EffectFallbacks();
-                if (defines.ENVIRONMENTBRDF) {
-                    fallbacks.addFallback(0, "ENVIRONMENTBRDF");
+                var fallbackRank = 0;
+                if (defines.USESPHERICALINVERTEX) {
+                    fallbacks.addFallback(fallbackRank++, "USESPHERICALINVERTEX");
                 }
 
-                if (defines.REFLECTION) {
-                    fallbacks.addFallback(0, "REFLECTION");
+                if (defines.FOG) {
+                    fallbacks.addFallback(fallbackRank, "FOG");
+                }
+                if (defines.POINTSIZE) {
+                    fallbacks.addFallback(fallbackRank, "POINTSIZE");
+                }
+                if (defines.LOGARITHMICDEPTH) {
+                    fallbacks.addFallback(fallbackRank, "LOGARITHMICDEPTH");
+                }
+                if (defines.PARALLAX) {
+                    fallbacks.addFallback(fallbackRank, "PARALLAX");
+                }
+                if (defines.PARALLAXOCCLUSION) {
+                    fallbacks.addFallback(fallbackRank++, "PARALLAXOCCLUSION");
                 }
 
-                if (defines.REFRACTION) {
-                    fallbacks.addFallback(0, "REFRACTION");
+                if (defines.ENVIRONMENTBRDF) {
+                    fallbacks.addFallback(fallbackRank++, "ENVIRONMENTBRDF");
                 }
 
-                if (defines.REFLECTIVITY) {
-                    fallbacks.addFallback(0, "REFLECTIVITY");
+                if (defines.TANGENT) {
+                    fallbacks.addFallback(fallbackRank++, "TANGENT");
                 }
 
                 if (defines.BUMP) {
-                    fallbacks.addFallback(0, "BUMP");
+                    fallbacks.addFallback(fallbackRank++, "BUMP");
                 }
 
-                if (defines.PARALLAX) {
-                    fallbacks.addFallback(1, "PARALLAX");
-                }
+                fallbackRank = MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank++);
 
-                if (defines.PARALLAXOCCLUSION) {
-                    fallbacks.addFallback(0, "PARALLAXOCCLUSION");
+                if (defines.SPECULARTERM) {
+                    fallbacks.addFallback(fallbackRank++, "SPECULARTERM");
                 }
 
-                if (defines.SPECULAROVERALPHA) {
-                    fallbacks.addFallback(0, "SPECULAROVERALPHA");
+                if (defines.USESPHERICALFROMREFLECTIONMAP) {
+                    fallbacks.addFallback(fallbackRank++, "USESPHERICALFROMREFLECTIONMAP");
                 }
 
-                if (defines.FOG) {
-                    fallbacks.addFallback(1, "FOG");
+                if (defines.LIGHTMAP) {
+                    fallbacks.addFallback(fallbackRank++, "LIGHTMAP");
                 }
 
-                if (defines.POINTSIZE) {
-                    fallbacks.addFallback(0, "POINTSIZE");
+                if (defines.NORMAL) {
+                    fallbacks.addFallback(fallbackRank++, "NORMAL");
                 }
 
-                if (defines.LOGARITHMICDEPTH) {
-                    fallbacks.addFallback(0, "LOGARITHMICDEPTH");
+                if (defines.AMBIENT) {
+                    fallbacks.addFallback(fallbackRank++, "AMBIENT");
                 }
 
-                MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);
+                if (defines.EMISSIVE) {
+                    fallbacks.addFallback(fallbackRank++, "EMISSIVE");
+                }
 
-                if (defines.SPECULARTERM) {
-                    fallbacks.addFallback(0, "SPECULARTERM");
+                if (defines.VERTEXCOLOR) {
+                    fallbacks.addFallback(fallbackRank++, "VERTEXCOLOR");
                 }
 
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
-                    fallbacks.addCPUSkinningFallback(0, mesh);
+                    fallbacks.addCPUSkinningFallback(fallbackRank++, mesh);
+                }
+
+                if (defines.MORPHTARGETS) {
+                    fallbacks.addFallback(fallbackRank++, "MORPHTARGETS");
                 }
 
                 //Attributes

+ 4 - 1
src/Materials/Textures/babylon.texture.ts

@@ -316,9 +316,12 @@
 
             if (!this._cachedTextureMatrix) {
                 this._cachedTextureMatrix = Matrix.Zero();
+            }
+            
+            if (!this._projectionModeMatrix) {
                 this._projectionModeMatrix = Matrix.Zero();
             }
-
+            
             this._cachedUOffset = this.uOffset;
             this._cachedVOffset = this.vOffset;
             this._cachedUScale = this.uScale;

+ 2 - 2
src/Materials/babylon.effect.ts

@@ -558,10 +558,10 @@
                 var engine = this._engine;
 
                 if (this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride) {
-                    this._program = engine.createRawShaderProgram(this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride);
+                    this._program = engine.createRawShaderProgram(this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, undefined, this._transformFeedbackVaryings);
                 }
                 else {
-                    this._program = engine.createShaderProgram(this._vertexSourceCode, this._fragmentSourceCode, defines);
+                    this._program = engine.createShaderProgram(this._vertexSourceCode, this._fragmentSourceCode, defines, undefined, this._transformFeedbackVaryings);
                 }
                 this._program.__SPECTOR_rebuildProgram = this._rebuildProgram.bind(this);
 

+ 15 - 14
src/Materials/babylon.materialHelper.ts

@@ -277,32 +277,33 @@
             }
         }
 
-        public static HandleFallbacksForShadows(defines: any, fallbacks: EffectFallbacks, maxSimultaneousLights = 4): void {
-            if (!defines["SHADOWS"]) {
-                return;
-            }
-
+        public static HandleFallbacksForShadows(defines: any, fallbacks: EffectFallbacks, maxSimultaneousLights = 4, rank = 0): number {
+            let lightFallbackRank = 0;
             for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
                 if (!defines["LIGHT" + lightIndex]) {
                     break;
                 }
 
                 if (lightIndex > 0) {
-                    fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
+                    lightFallbackRank = rank + lightIndex;
+                    fallbacks.addFallback(lightFallbackRank, "LIGHT" + lightIndex);
                 }
 
-                if (defines["SHADOW" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOW" + lightIndex);
-                }
+                if (!defines["SHADOWS"]) {
+                    if (defines["SHADOW" + lightIndex]) {
+                        fallbacks.addFallback(rank, "SHADOW" + lightIndex);
+                    }
 
-                if (defines["SHADOWPCF" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
-                }
+                    if (defines["SHADOWPCF" + lightIndex]) {
+                        fallbacks.addFallback(rank, "SHADOWPCF" + lightIndex);
+                    }
 
-                if (defines["SHADOWESM" + lightIndex]) {
-                    fallbacks.addFallback(0, "SHADOWESM" + lightIndex);
+                    if (defines["SHADOWESM" + lightIndex]) {
+                        fallbacks.addFallback(rank, "SHADOWESM" + lightIndex);
+                    }
                 }
             }
+            return lightFallbackRank++;
         }
 
         public static PrepareAttributesForMorphTargets(attribs: string[], mesh: AbstractMesh, defines: any): void {

+ 132 - 7
src/Particles/babylon.gpuParticleSystem.ts

@@ -4,11 +4,28 @@
         public id: string;
         public emitter: Nullable<AbstractMesh | Vector3> = null;       
         public renderingGroupId = 0;        
-        public layerMask: number = 0x0FFFFFFF;
-        private _renderingEffect: Effect;
+        public layerMask: number = 0x0FFFFFFF; // TODO
+        private _capacity: number;
+        private _renderEffect: Effect;
         private _updateEffect: Effect;
 
+        private _updateBuffer: Buffer;
+        private _updateVAO: WebGLVertexArrayObject;
+        private _updateVertexBuffers: {[key: string]: VertexBuffer} = {};
+        private _renderBuffer: Buffer;
+        private _renderVAO: WebGLVertexArrayObject;
+        private _renderVertexBuffers: {[key: string]: VertexBuffer} = {};
+
+        private _sourceVAO: WebGLVertexArrayObject;
+        private _targetVAO: WebGLVertexArrayObject;
+        private _sourceBuffer: Buffer;
+        private _targetBuffer: Buffer;
+
         private _scene: Scene;
+        private _engine: Engine;
+
+        private _currentRenderId = -1;    
+        private _started = true;    
 
         /**
         * An event triggered when the system is disposed.
@@ -16,18 +33,27 @@
         */
         public onDisposeObservable = new Observable<GPUParticleSystem>();
 
-
         public isStarted(): boolean {
-            return false;
+            return this._started;
+        }     
+
+        public start(): void {
+            this._started = true;
+        }
+
+        public stop(): void {
+            this._started = false;
         }        
 
         constructor(public name: string, capacity: number, scene: Scene) {
             this.id = name;
             this._scene = scene || Engine.LastCreatedScene;
+            this._capacity = capacity;
+            this._engine = this._scene.getEngine();
 
             this._scene.particleSystems.push(this);
 
-            this._renderingEffect = new Effect("gpuRenderParticles", ["position", "age", "life", "velocity"], [], [], this._scene.getEngine());
+            this._renderEffect = new Effect("gpuRenderParticles", ["position", "age", "life", "velocity"], [], [], this._scene.getEngine());
 
             let updateEffectOptions: EffectCreationOptions = {
                 attributes: ["position", "age", "life", "velocity"],
@@ -43,15 +69,112 @@
                 transformFeedbackVaryings: ["outPosition", "outAge", "outLife", "outVelocity"]
             };
 
-            this._updateEffect = new Effect("gpuUpdateParticles", updateEffectOptions, this._scene.getEngine());
-                                            
+            this._updateEffect = new Effect("gpuUpdateParticles", updateEffectOptions, this._scene.getEngine());   
         }
 
         public animate(): void {
+            // Do nothing
+        }
+        
+        private _initialize(): void {
+            if (this._renderVAO) {
+                return;
+            }
+
+            var data = new Array<float>();
+            for (var particleIndex = 0; particleIndex < this._capacity; particleIndex++) {
+              // position
+              data.push(0.0);
+              data.push(0.0);
+              data.push(0.0);
+          
+              var life = 1 + Math.random() * 10; // TODO: var
+              data.push(life + 1); // create the particle as a dead one to create a new one at start
+              data.push(life);
+          
+              // velocity
+              data.push(0.0);
+              data.push(0.0);
+              data.push(0.0);
+            }
 
+            // Update VAO
+            this._updateBuffer = new Buffer(this._scene.getEngine(), data, false, 0);
+            this._updateVertexBuffers["position"] = this._updateBuffer.createVertexBuffer("position", 0, 3, 3);
+            this._updateVertexBuffers["age"] = this._updateBuffer.createVertexBuffer("age", 3, 1, 1);
+            this._updateVertexBuffers["life"] = this._updateBuffer.createVertexBuffer("life", 4, 1, 1);
+            this._updateVertexBuffers["velocity"] = this._updateBuffer.createVertexBuffer("velocity", 5, 3, 3);
+           
+            this._updateVAO = this._engine.recordVertexArrayObject(this._updateVertexBuffers, null, this._updateEffect);
+            this._engine.bindArrayBuffer(null);
+
+            // Render VAO
+            this._renderBuffer = new Buffer(this._scene.getEngine(), data, false, 0);
+            this._renderVertexBuffers["position"] = this._renderBuffer.createVertexBuffer("position", 0, 3, 3);
+            this._renderVertexBuffers["age"] = this._renderBuffer.createVertexBuffer("age", 3, 1, 1);
+            this._renderVertexBuffers["life"] = this._renderBuffer.createVertexBuffer("life", 4, 1, 1);
+            this._renderVertexBuffers["velocity"] = this._renderBuffer.createVertexBuffer("velocity", 5, 3, 3);
+           
+            this._renderVAO = this._engine.recordVertexArrayObject(this._renderVertexBuffers, null, this._renderEffect);  
+            this._engine.bindArrayBuffer(null);          
+
+            // Links
+            this._sourceVAO = this._updateVAO;
+            this._targetVAO = this._renderVAO;
+
+            this._sourceBuffer = this._updateBuffer;
+            this._targetBuffer = this._renderBuffer;
         }
 
         public render(): number {
+            if (!this.emitter || !this._updateEffect.isReady() || !this._renderEffect.isReady() ) {
+                return 0;
+            }
+
+            // Get everything ready to render
+            this. _initialize();
+            
+            if (this._currentRenderId === this._scene.getRenderId()) {
+                return 0;
+            }
+
+            this._currentRenderId = this._scene.getRenderId();            
+
+            // Enable update effect
+            this._engine.enableEffect(this._updateEffect);
+            this._engine.setState(false);            
+
+            // Bind source VAO
+            this._engine.bindVertexArrayObject(this._sourceVAO, null);
+
+            // Update
+            this._engine.bindTransformFeedbackBuffer(this._targetBuffer.getBuffer());
+            this._engine.setRasterizerState(false);
+            this._engine.beginTransformFeedback();
+            this._engine.drawPointClouds(0, this._capacity);
+            this._engine.endTransformFeedback();
+            this._engine.setRasterizerState(true);
+            this._engine.bindTransformFeedbackBuffer(null);
+
+            // Enable render effect
+            this._engine.enableEffect(this._renderEffect);
+
+            // Bind source VAO
+            this._engine.bindVertexArrayObject(this._targetVAO, null);
+
+            // Render
+            this._engine.drawPointClouds(0, this._capacity);            
+
+            // Switch VAOs
+            let tmpVAO = this._sourceVAO;
+            this._sourceVAO = this._targetVAO;
+            this._targetVAO = tmpVAO;
+
+            // Switch buffers
+            let tmpBuffer = this._sourceBuffer;
+            this._sourceBuffer = this._targetBuffer;
+            this._targetBuffer = tmpBuffer;            
+
             return 0;
         }
 
@@ -65,6 +188,8 @@
                 this._scene.particleSystems.splice(index, 1);
             }
 
+            //TODO: this._dataBuffer.dispose();
+
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();

+ 3 - 3
src/Shaders/pbr.fragment.fx

@@ -26,12 +26,12 @@ varying vec3 vPositionW;
 #endif 
 
 #ifdef MAINUV2 
-	varying vec2 vMainUV2; 
+	varying vec2 vMainUV2;
 #endif 
 
 #ifdef NORMAL
 	varying vec3 vNormalW;
-	#if defined(USESPHERICALFROMREFLECTIONMAP) && !defined(USESPHERICALINFRAGMENT)
+	#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)
 		varying vec3 vEnvironmentIrradiance;
 	#endif
 #endif
@@ -565,7 +565,7 @@ void main(void) {
 
 	// _____________________________ Irradiance ________________________________
 	#ifdef USESPHERICALFROMREFLECTIONMAP
-		#if defined(NORMAL) && !defined(USESPHERICALINFRAGMENT)
+		#if defined(NORMAL) && defined(USESPHERICALINVERTEX)
 			environmentIrradiance = vEnvironmentIrradiance;
 		#else
 			vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;

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

@@ -68,7 +68,7 @@ varying vec2 vBumpUV;
 varying vec3 vPositionW;
 #ifdef NORMAL
     varying vec3 vNormalW;
-    #if defined(USESPHERICALFROMREFLECTIONMAP) && !defined(USESPHERICALINFRAGMENT)
+    #if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)
         varying vec3 vEnvironmentIrradiance;
         
         #include<harmonicsFunctions>
@@ -129,7 +129,7 @@ void main(void) {
 
 	vNormalW = normalize(normalWorld * normalUpdated);
 
-    #if defined(USESPHERICALFROMREFLECTIONMAP) && !defined(USESPHERICALINFRAGMENT)
+    #if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)
         vec3 reflectionVector = vec3(reflectionMatrix * vec4(vNormalW, 0)).xyz;
         #ifdef REFLECTIONMAP_OPPOSITEZ
             reflectionVector.z *= -1.0;

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

@@ -178,7 +178,7 @@
          */
         public notifyObservers(eventData: Nullable<T>, mask: number = -1, target?: any, currentTarget?: any): boolean {
             if (!this._observers.length) {
-                return false;
+                return true;
             }
 
             let state = this._eventState;

+ 0 - 1
src/babylon.scene.ts

@@ -1624,7 +1624,6 @@
                 this._meshPickProceed = false;
 
                 this._updatePointerPosition(evt);      
-
                 this._initClickEvent(this.onPrePointerObservable, this.onPointerObservable, evt, (clickInfo: ClickInfo, pickResult: Nullable<PickingInfo>) => {
                     // PreObservable support
                     if (this.onPrePointerObservable.hasObservers()) {