Sfoglia il codice sorgente

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into WebGPU

Sebastien Vandenberghe 6 anni fa
parent
commit
8a424c8d1f
62 ha cambiato i file con 1142 aggiunte e 353 eliminazioni
  1. 19 3
      Playground/babylon.d.txt
  2. 18 3
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 167 81
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 36 6
      dist/preview release/babylon.module.d.ts
  7. 18 3
      dist/preview release/documentation.d.ts
  8. 1 1
      dist/preview release/glTF2Interface/package.json
  9. 22 1
      dist/preview release/gui/babylon.gui.js
  10. 1 1
      dist/preview release/gui/babylon.gui.js.map
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js
  12. 2 2
      dist/preview release/gui/package.json
  13. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 1 0
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  15. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  16. 7 7
      dist/preview release/inspector/package.json
  17. 3 3
      dist/preview release/loaders/package.json
  18. 2 2
      dist/preview release/materialsLibrary/package.json
  19. 36 4
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  20. 7 7
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  21. 252 88
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  22. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  23. 82 9
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  24. 2 2
      dist/preview release/nodeEditor/package.json
  25. 1 1
      dist/preview release/package.json
  26. 1 1
      dist/preview release/packagesSizeBaseLine.json
  27. 5 5
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js
  28. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js.map
  29. 5 5
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js
  30. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js.map
  31. 5 5
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js
  32. 1 1
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js.map
  33. 9 9
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  34. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js.map
  35. 2 2
      dist/preview release/postProcessesLibrary/package.json
  36. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  37. 3 3
      dist/preview release/serializers/package.json
  38. 36 6
      dist/preview release/viewer/babylon.module.d.ts
  39. 29 29
      dist/preview release/viewer/babylon.viewer.js
  40. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  41. 2 0
      dist/preview release/what's new.md
  42. 26 1
      gui/src/2D/controls/textBlock.ts
  43. 1 0
      inspector/src/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent.tsx
  44. 41 7
      nodeEditor/src/previewManager.ts
  45. 47 0
      nodeEditor/src/components/preview/previewMeshControlComponent.tsx
  46. 6 0
      nodeEditor/src/components/preview/previewMeshType.ts
  47. 38 4
      nodeEditor/src/components/propertyTab/propertyTabComponent.tsx
  48. 13 1
      nodeEditor/src/globalState.ts
  49. 38 17
      nodeEditor/src/graphEditor.tsx
  50. 32 3
      nodeEditor/src/main.scss
  51. 5 0
      nodeEditor/src/nodeLocationInfo.ts
  52. 1 1
      package.json
  53. 10 3
      src/Cameras/deviceOrientationCamera.ts
  54. 4 4
      src/Engines/engine.ts
  55. 5 0
      src/Loading/Plugins/babylonFileLoader.ts
  56. 42 7
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  57. 11 0
      src/Materials/Node/nodeMaterial.ts
  58. 1 0
      src/Materials/Node/nodeMaterialBuildStateSharedData.ts
  59. 1 1
      src/Materials/PBR/pbrBaseMaterial.ts
  60. 3 1
      src/Meshes/mesh.ts
  61. 4 1
      src/Misc/sceneSerializer.ts
  62. 26 0
      src/scene.ts

+ 19 - 3
Playground/babylon.d.txt

@@ -32073,6 +32073,21 @@ declare module BABYLON {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -37523,6 +37538,7 @@ declare module BABYLON {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -37531,9 +37547,9 @@ declare module BABYLON {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
-         */
private _disablePointerInputWhenUsingDeviceOrientation: boolean;
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
+         */
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active

+ 18 - 3
dist/preview release/babylon.d.ts

@@ -32693,6 +32693,21 @@ declare module BABYLON {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -38234,6 +38249,7 @@ declare module BABYLON {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -38242,10 +38258,9 @@ declare module BABYLON {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active

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


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


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


+ 36 - 6
dist/preview release/babylon.module.d.ts

@@ -33633,6 +33633,21 @@ declare module "babylonjs/scene" {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -39427,6 +39442,7 @@ declare module "babylonjs/Cameras/deviceOrientationCamera" {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -39435,10 +39451,9 @@ declare module "babylonjs/Cameras/deviceOrientationCamera" {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active
@@ -96911,6 +96926,21 @@ declare module BABYLON {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -102452,6 +102482,7 @@ declare module BABYLON {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -102460,10 +102491,9 @@ declare module BABYLON {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active

+ 18 - 3
dist/preview release/documentation.d.ts

@@ -32693,6 +32693,21 @@ declare module BABYLON {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -38234,6 +38249,7 @@ declare module BABYLON {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -38242,10 +38258,9 @@ declare module BABYLON {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active

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

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 22 - 1
dist/preview release/gui/babylon.gui.js

@@ -11446,6 +11446,16 @@ var TextBlock = /** @class */ (function (_super) {
                 }
             }
             var newHeight = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length;
+            if (this._lines.length > 0 && this._lineSpacing.internalValue !== 0) {
+                var lineSpacing = 0;
+                if (this._lineSpacing.isPixel) {
+                    lineSpacing = this._lineSpacing.getValue(this._host);
+                }
+                else {
+                    lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                }
+                newHeight += (this._lines.length - 1) * lineSpacing;
+            }
             if (newHeight !== this._height.internalValue) {
                 this._height.updateInPlace(newHeight, _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__["ValueAndUnit"].UNITMODE_PIXEL);
                 this._rebuildLayout = true;
@@ -11595,7 +11605,18 @@ var TextBlock = /** @class */ (function (_super) {
                     this._fontOffset = _control__WEBPACK_IMPORTED_MODULE_3__["Control"]._GetFontOffset(context_1.font);
                 }
                 var lines = this._lines ? this._lines : this._breakLines(this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context_1);
-                return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+                var newHeight = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+                if (this._lines.length > 0 && this._lineSpacing.internalValue !== 0) {
+                    var lineSpacing = 0;
+                    if (this._lineSpacing.isPixel) {
+                        lineSpacing = this._lineSpacing.getValue(this._host);
+                    }
+                    else {
+                        lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                    }
+                    newHeight += (lines.length - 1) * lineSpacing;
+                }
+                return newHeight;
             }
         }
         return 0;

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


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


+ 2 - 2
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

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


+ 1 - 0
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -40545,6 +40545,7 @@ var ScenePropertyGridComponent = /** @class */ (function (_super) {
                 scene.environmentTexture &&
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textureLinkLineComponent__WEBPACK_IMPORTED_MODULE_9__["TextureLinkLineComponent"], { label: "Env. texture", texture: scene.environmentTexture, onSelectionChangedObservable: this.props.onSelectionChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_8__["FileButtonLineComponent"], { label: "Update environment texture", onClick: function (file) { return _this.updateEnvironmentTexture(file); }, accept: ".dds, .env" }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_12__["SliderLineComponent"], { minimum: 0, maximum: 2, step: 0.01, label: "IBL Intensity", target: scene, propertyName: "environmentIntensity", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_fogPropertyGridComponent__WEBPACK_IMPORTED_MODULE_7__["FogPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, scene: scene, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "MATERIAL IMAGE PROCESSING" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_12__["SliderLineComponent"], { minimum: 0, maximum: 4, step: 0.1, label: "Contrast", target: imageProcessing, propertyName: "contrast", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 7 - 7
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,12 +29,12 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12",
-        "babylonjs-gui": "4.1.0-alpha.12",
-        "babylonjs-loaders": "4.1.0-alpha.12",
-        "babylonjs-materials": "4.1.0-alpha.12",
-        "babylonjs-serializers": "4.1.0-alpha.12",
-        "babylonjs-gltf2interface": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13",
+        "babylonjs-gui": "4.1.0-alpha.13",
+        "babylonjs-loaders": "4.1.0-alpha.13",
+        "babylonjs-materials": "4.1.0-alpha.13",
+        "babylonjs-serializers": "4.1.0-alpha.13",
+        "babylonjs-gltf2interface": "4.1.0-alpha.13"
     },
     "devDependencies": {
         "@types/react": "~16.7.3",

+ 3 - 3
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.1.0-alpha.12",
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs-gltf2interface": "4.1.0-alpha.13",
+        "babylonjs": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

+ 2 - 2
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

+ 36 - 4
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts

@@ -286,6 +286,13 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export interface INodeLocationInfo {
+        blockId: number;
+        x: number;
+        y: number;
+    }
+}
+declare module NODEEDITOR {
     interface IPropertyTabComponentProps {
         globalState: GlobalState;
     }
@@ -295,6 +302,7 @@ declare module NODEEDITOR {
         constructor(props: IPropertyTabComponentProps);
         componentWillMount(): void;
         load(file: File): void;
+        save(): void;
         render(): JSX.Element;
     }
 }
@@ -868,21 +876,41 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export enum PreviewMeshType {
+        Sphere = 0,
+        Box = 1,
+        Torus = 2,
+        Cylinder = 3
+    }
+}
+declare module NODEEDITOR {
     export class PreviewManager {
         private _nodeMaterial;
         private _onBuildObserver;
+        private _onPreviewMeshTypeChangedObserver;
         private _engine;
         private _scene;
         private _light;
-        private _dummySphere;
+        private _dummy;
         private _camera;
         private _material;
+        private _globalState;
         constructor(targetCanvas: HTMLCanvasElement, globalState: GlobalState);
+        private _refreshPreviewMesh;
         private _updatePreview;
         dispose(): void;
     }
 }
 declare module NODEEDITOR {
+    interface IPreviewMeshControlComponent {
+        globalState: GlobalState;
+    }
+    export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
+        changeMeshType(newOne: PreviewMeshType): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
     interface IGraphEditorProps {
         globalState: GlobalState;
     }
@@ -915,8 +943,8 @@ declare module NODEEDITOR {
         constructor(props: IGraphEditorProps);
         zoomToFit(retry?: number): void;
         buildMaterial(): void;
-        build(needToWait?: boolean): void;
-        reOrganize(): void;
+        build(needToWait?: boolean, locations?: BABYLON.Nullable<INodeLocationInfo[]>): void;
+        reOrganize(locations?: BABYLON.Nullable<INodeLocationInfo[]>): void;
         onPointerDown(evt: React.PointerEvent<HTMLDivElement>): void;
         onPointerUp(evt: React.PointerEvent<HTMLDivElement>): void;
         resizeColumns(evt: React.PointerEvent<HTMLDivElement>, forLeft?: boolean): void;
@@ -952,12 +980,16 @@ declare module NODEEDITOR {
         hostDocument: HTMLDocument;
         onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<DefaultNodeModel>>;
         onRebuildRequiredObservable: BABYLON.Observable<void>;
-        onResetRequiredObservable: BABYLON.Observable<void>;
+        onResetRequiredObservable: BABYLON.Observable<BABYLON.Nullable<INodeLocationInfo[]>>;
         onUpdateRequiredObservable: BABYLON.Observable<void>;
         onZoomToFitRequiredObservable: BABYLON.Observable<void>;
         onReOrganizedRequiredObservable: BABYLON.Observable<void>;
         onLogRequiredObservable: BABYLON.Observable<LogEntry>;
         onErrorMessageDialogRequiredObservable: BABYLON.Observable<string>;
+        onPreviewMeshTypeChanged: BABYLON.Observable<void>;
+        onGetNodeFromBlock: (block: BABYLON.NodeMaterialBlock) => NodeModel;
+        previewMeshType: PreviewMeshType;
+        constructor();
     }
 }
 declare module NODEEDITOR {

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


File diff suppressed because it is too large
+ 252 - 88
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 82 - 9
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts

@@ -344,6 +344,13 @@ declare module "babylonjs-node-editor/sharedComponents/fileButtonLineComponent"
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-node-editor/nodeLocationInfo" {
+    export interface INodeLocationInfo {
+        blockId: number;
+        x: number;
+        y: number;
+    }
+}
 declare module "babylonjs-node-editor/components/propertyTab/propertyTabComponent" {
     import * as React from "react";
     import { GlobalState } from "babylonjs-node-editor/globalState";
@@ -358,6 +365,7 @@ declare module "babylonjs-node-editor/components/propertyTab/propertyTabComponen
         constructor(props: IPropertyTabComponentProps);
         componentWillMount(): void;
         load(file: File): void;
+        save(): void;
         render(): JSX.Element;
     }
 }
@@ -1031,22 +1039,45 @@ declare module "babylonjs-node-editor/graphHelper" {
         private static _MapEdges;
     }
 }
-declare module "babylonjs-node-editor/previewManager" {
+declare module "babylonjs-node-editor/components/preview/previewMeshType" {
+    export enum PreviewMeshType {
+        Sphere = 0,
+        Box = 1,
+        Torus = 2,
+        Cylinder = 3
+    }
+}
+declare module "babylonjs-node-editor/components/preview/previewManager" {
     import { GlobalState } from "babylonjs-node-editor/globalState";
     export class PreviewManager {
         private _nodeMaterial;
         private _onBuildObserver;
+        private _onPreviewMeshTypeChangedObserver;
         private _engine;
         private _scene;
         private _light;
-        private _dummySphere;
+        private _dummy;
         private _camera;
         private _material;
+        private _globalState;
         constructor(targetCanvas: HTMLCanvasElement, globalState: GlobalState);
+        private _refreshPreviewMesh;
         private _updatePreview;
         dispose(): void;
     }
 }
+declare module "babylonjs-node-editor/components/preview/previewMeshControlComponent" {
+    import * as React from "react";
+    import { GlobalState } from "babylonjs-node-editor/globalState";
+    import { PreviewMeshType } from "babylonjs-node-editor/components/preview/previewMeshType";
+    interface IPreviewMeshControlComponent {
+        globalState: GlobalState;
+    }
+    export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
+        changeMeshType(newOne: PreviewMeshType): void;
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-node-editor/graphEditor" {
     import { LinkModel } from "storm-react-diagrams";
     import * as React from "react";
@@ -1054,6 +1085,8 @@ declare module "babylonjs-node-editor/graphEditor" {
     import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
     import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
     import { DefaultNodeModel } from "babylonjs-node-editor/components/diagram/defaultNodeModel";
+    import { Nullable } from 'babylonjs/types';
+    import { INodeLocationInfo } from "babylonjs-node-editor/nodeLocationInfo";
     interface IGraphEditorProps {
         globalState: GlobalState;
     }
@@ -1086,8 +1119,8 @@ declare module "babylonjs-node-editor/graphEditor" {
         constructor(props: IGraphEditorProps);
         zoomToFit(retry?: number): void;
         buildMaterial(): void;
-        build(needToWait?: boolean): void;
-        reOrganize(): void;
+        build(needToWait?: boolean, locations?: Nullable<INodeLocationInfo[]>): void;
+        reOrganize(locations?: Nullable<INodeLocationInfo[]>): void;
         onPointerDown(evt: React.PointerEvent<HTMLDivElement>): void;
         onPointerUp(evt: React.PointerEvent<HTMLDivElement>): void;
         resizeColumns(evt: React.PointerEvent<HTMLDivElement>, forLeft?: boolean): void;
@@ -1128,18 +1161,26 @@ declare module "babylonjs-node-editor/globalState" {
     import { Observable } from 'babylonjs/Misc/observable';
     import { DefaultNodeModel } from "babylonjs-node-editor/components/diagram/defaultNodeModel";
     import { LogEntry } from "babylonjs-node-editor/components/log/logComponent";
+    import { NodeModel } from 'storm-react-diagrams';
+    import { INodeLocationInfo } from "babylonjs-node-editor/nodeLocationInfo";
+    import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+    import { PreviewMeshType } from "babylonjs-node-editor/components/preview/previewMeshType";
     export class GlobalState {
         nodeMaterial: NodeMaterial;
         hostElement: HTMLElement;
         hostDocument: HTMLDocument;
         onSelectionChangedObservable: Observable<Nullable<DefaultNodeModel>>;
         onRebuildRequiredObservable: Observable<void>;
-        onResetRequiredObservable: Observable<void>;
+        onResetRequiredObservable: Observable<Nullable<INodeLocationInfo[]>>;
         onUpdateRequiredObservable: Observable<void>;
         onZoomToFitRequiredObservable: Observable<void>;
         onReOrganizedRequiredObservable: Observable<void>;
         onLogRequiredObservable: Observable<LogEntry>;
         onErrorMessageDialogRequiredObservable: Observable<string>;
+        onPreviewMeshTypeChanged: Observable<void>;
+        onGetNodeFromBlock: (block: NodeMaterialBlock) => NodeModel;
+        previewMeshType: PreviewMeshType;
+        constructor();
     }
 }
 declare module "babylonjs-node-editor/sharedComponents/popup" {
@@ -1464,6 +1505,13 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export interface INodeLocationInfo {
+        blockId: number;
+        x: number;
+        y: number;
+    }
+}
+declare module NODEEDITOR {
     interface IPropertyTabComponentProps {
         globalState: GlobalState;
     }
@@ -1473,6 +1521,7 @@ declare module NODEEDITOR {
         constructor(props: IPropertyTabComponentProps);
         componentWillMount(): void;
         load(file: File): void;
+        save(): void;
         render(): JSX.Element;
     }
 }
@@ -2046,21 +2095,41 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export enum PreviewMeshType {
+        Sphere = 0,
+        Box = 1,
+        Torus = 2,
+        Cylinder = 3
+    }
+}
+declare module NODEEDITOR {
     export class PreviewManager {
         private _nodeMaterial;
         private _onBuildObserver;
+        private _onPreviewMeshTypeChangedObserver;
         private _engine;
         private _scene;
         private _light;
-        private _dummySphere;
+        private _dummy;
         private _camera;
         private _material;
+        private _globalState;
         constructor(targetCanvas: HTMLCanvasElement, globalState: GlobalState);
+        private _refreshPreviewMesh;
         private _updatePreview;
         dispose(): void;
     }
 }
 declare module NODEEDITOR {
+    interface IPreviewMeshControlComponent {
+        globalState: GlobalState;
+    }
+    export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
+        changeMeshType(newOne: PreviewMeshType): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
     interface IGraphEditorProps {
         globalState: GlobalState;
     }
@@ -2093,8 +2162,8 @@ declare module NODEEDITOR {
         constructor(props: IGraphEditorProps);
         zoomToFit(retry?: number): void;
         buildMaterial(): void;
-        build(needToWait?: boolean): void;
-        reOrganize(): void;
+        build(needToWait?: boolean, locations?: BABYLON.Nullable<INodeLocationInfo[]>): void;
+        reOrganize(locations?: BABYLON.Nullable<INodeLocationInfo[]>): void;
         onPointerDown(evt: React.PointerEvent<HTMLDivElement>): void;
         onPointerUp(evt: React.PointerEvent<HTMLDivElement>): void;
         resizeColumns(evt: React.PointerEvent<HTMLDivElement>, forLeft?: boolean): void;
@@ -2130,12 +2199,16 @@ declare module NODEEDITOR {
         hostDocument: HTMLDocument;
         onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<DefaultNodeModel>>;
         onRebuildRequiredObservable: BABYLON.Observable<void>;
-        onResetRequiredObservable: BABYLON.Observable<void>;
+        onResetRequiredObservable: BABYLON.Observable<BABYLON.Nullable<INodeLocationInfo[]>>;
         onUpdateRequiredObservable: BABYLON.Observable<void>;
         onZoomToFitRequiredObservable: BABYLON.Observable<void>;
         onReOrganizedRequiredObservable: BABYLON.Observable<void>;
         onLogRequiredObservable: BABYLON.Observable<LogEntry>;
         onErrorMessageDialogRequiredObservable: BABYLON.Observable<string>;
+        onPreviewMeshTypeChanged: BABYLON.Observable<void>;
+        onGetNodeFromBlock: (block: BABYLON.NodeMaterialBlock) => NodeModel;
+        previewMeshType: PreviewMeshType;
+        constructor();
     }
 }
 declare module NODEEDITOR {

+ 2 - 2
dist/preview release/nodeEditor/package.json

@@ -4,14 +4,14 @@
     },
     "name": "babylonjs-node-editor",
     "description": "The Babylon.js node material editor.",
-    "version": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13"
     },
     "files": [
         "babylon.nodeEditor.max.js.map",

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

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

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"engineOnly":166820,"sceneOnly":506148,"minGridMaterial":635017,"minStandardMaterial":762298}
+{"engineOnly":166856,"sceneOnly":506490,"minGridMaterial":635391,"minStandardMaterial":762672}

+ 5 - 5
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-post-process"] = factory(require("babylonjs"));
 	else
 		root["POSTPROCESSES"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -368,7 +368,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsciiArtFontTexture", function() { return AsciiArtFontTexture; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsciiArtPostProcess", function() { return AsciiArtPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _asciiart_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./asciiart.fragment */ "./asciiArt/asciiart.fragment.ts");
 
@@ -589,7 +589,7 @@ var AsciiArtPostProcess = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asciiartPixelShader", function() { return asciiartPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'asciiartPixelShader';
@@ -651,14 +651,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/Textures/texture":
+/***/ "babylonjs/Misc/decorators":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js.map


+ 5 - 5
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-post-process"] = factory(require("babylonjs"));
 	else
 		root["POSTPROCESSES"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -368,7 +368,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DigitalRainFontTexture", function() { return DigitalRainFontTexture; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DigitalRainPostProcess", function() { return DigitalRainPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _digitalrain_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./digitalrain.fragment */ "./digitalRain/digitalrain.fragment.ts");
 
@@ -595,7 +595,7 @@ var DigitalRainPostProcess = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "digitalrainPixelShader", function() { return digitalrainPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'digitalrainPixelShader';
@@ -657,14 +657,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/Textures/texture":
+/***/ "babylonjs/Misc/decorators":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js.map


+ 5 - 5
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-post-process"] = factory(require("babylonjs"));
 	else
 		root["POSTPROCESSES"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -412,7 +412,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "oceanPostProcessPixelShader", function() { return oceanPostProcessPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'oceanPostProcessPixelShader';
@@ -435,7 +435,7 @@ var oceanPostProcessPixelShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OceanPostProcess", function() { return OceanPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _oceanPostProcess_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./oceanPostProcess.fragment */ "./ocean/oceanPostProcess.fragment.ts");
 
@@ -639,14 +639,14 @@ var OceanPostProcess = /** @class */ (function (_super) {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/Textures/texture":
+/***/ "babylonjs/Misc/decorators":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js.map


+ 9 - 9
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-post-process"] = factory(require("babylonjs"));
 	else
 		root["POSTPROCESSES"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -368,7 +368,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsciiArtFontTexture", function() { return AsciiArtFontTexture; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsciiArtPostProcess", function() { return AsciiArtPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _asciiart_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./asciiart.fragment */ "./asciiArt/asciiart.fragment.ts");
 
@@ -589,7 +589,7 @@ var AsciiArtPostProcess = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asciiartPixelShader", function() { return asciiartPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'asciiartPixelShader';
@@ -632,7 +632,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DigitalRainFontTexture", function() { return DigitalRainFontTexture; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DigitalRainPostProcess", function() { return DigitalRainPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _digitalrain_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./digitalrain.fragment */ "./digitalRain/digitalrain.fragment.ts");
 
@@ -859,7 +859,7 @@ var DigitalRainPostProcess = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "digitalrainPixelShader", function() { return digitalrainPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'digitalrainPixelShader';
@@ -984,7 +984,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "oceanPostProcessPixelShader", function() { return oceanPostProcessPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'oceanPostProcessPixelShader';
@@ -1007,7 +1007,7 @@ var oceanPostProcessPixelShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OceanPostProcess", function() { return OceanPostProcess; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/decorators");
 /* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _oceanPostProcess_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./oceanPostProcess.fragment */ "./ocean/oceanPostProcess.fragment.ts");
 
@@ -1211,14 +1211,14 @@ var OceanPostProcess = /** @class */ (function (_super) {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/Textures/texture":
+/***/ "babylonjs/Misc/decorators":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_decorators__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js.map


+ 2 - 2
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

+ 2 - 2
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

+ 3 - 3
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": "4.1.0-alpha.12",
+    "version": "4.1.0-alpha.13",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.12",
-        "babylonjs-gltf2interface": "4.1.0-alpha.12"
+        "babylonjs": "4.1.0-alpha.13",
+        "babylonjs-gltf2interface": "4.1.0-alpha.13"
     },
     "engines": {
         "node": "*"

+ 36 - 6
dist/preview release/viewer/babylon.module.d.ts

@@ -33633,6 +33633,21 @@ declare module "babylonjs/scene" {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -39427,6 +39442,7 @@ declare module "babylonjs/Cameras/deviceOrientationCamera" {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -39435,10 +39451,9 @@ declare module "babylonjs/Cameras/deviceOrientationCamera" {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active
@@ -96911,6 +96926,21 @@ declare module BABYLON {
         */
         environmentTexture: Nullable<BaseTexture>;
         /** @hidden */
+        protected _environmentIntensity: number;
+        /**
+         * Intensity of the environment in all pbr material.
+         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
+         */
+        /**
+        * Intensity of the environment in all pbr material.
+        * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+        * As in the majority of the scene they are the same (exception for multi room and so on),
+        * this is easier to set here than in all the materials.
+        */
+        environmentIntensity: number;
+        /** @hidden */
         protected _imageProcessingConfiguration: ImageProcessingConfiguration;
         /**
          * Default image processing configuration used either in the rendering
@@ -102452,6 +102482,7 @@ declare module BABYLON {
         private _initialQuaternion;
         private _quaternionCache;
         private _tmpDragQuaternion;
+        private _disablePointerInputWhenUsingDeviceOrientation;
         /**
          * Creates a new device orientation camera
          * @param name The name of the camera
@@ -102460,10 +102491,9 @@ declare module BABYLON {
          */
         constructor(name: string, position: Vector3, scene: Scene);
         /**
-         * @hidden
-         * Disabled pointer input on first orientation sensor update (Default: true)
+         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
          */
-        _disablePointerInputWhenUsingDeviceOrientation: boolean;
+        disablePointerInputWhenUsingDeviceOrientation: boolean;
         private _dragFactor;
         /**
          * Enabled turning on the y axis when the orientation sensor is active

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


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


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

@@ -78,6 +78,7 @@
 ### Materials
 - Added `ShaderMaterial.setColor4Array` ([JonathanTron](https://github.com/JonathanTron/))
 - Added `ShaderMaterial.setArray4` ([JonathanTron](https://github.com/JonathanTron/))
+- Added `scene.environmentIntensity` to control the IBL strength overall in a scene ([Sebavan](https://github.com/sebavan/))
 
 ### ScreenshotTools
 - Added interface for argument `size` of screenshot methods ([Dok11](https://github.com/Dok11/))
@@ -97,6 +98,7 @@
 - Added a note on shallow bounding of getBoundingInfo ([tibotiber](https://github.com/tibotiber))
 
 ## Bug fixes
+- Fixed Textblock line spacing evaluation when linespacing > 0 ([Deltakosh](https://github.com/deltakosh/))
 - Fixed Xbox One gamepad controller button schemes ([MackeyK24](https://github.com/MackeyK24/))
 - Added support for `AnimationGroup` serialization ([Drigax](https://github.com/drigax/))
 - Removing assetContainer from scene will also remove gui layers ([TrevorDev](https://github.com/TrevorDev))

+ 26 - 1
gui/src/2D/controls/textBlock.ts

@@ -257,6 +257,17 @@ export class TextBlock extends Control {
             }
             let newHeight = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length;
 
+            if (this._lines.length > 0 && this._lineSpacing.internalValue !== 0) {
+                let lineSpacing = 0;
+                if (this._lineSpacing.isPixel) {
+                    lineSpacing = this._lineSpacing.getValue(this._host);
+                } else {
+                    lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                }
+
+                newHeight += (this._lines.length - 1) * lineSpacing;
+            }
+
             if (newHeight !== this._height.internalValue) {
                 this._height.updateInPlace(newHeight, ValueAndUnit.UNITMODE_PIXEL);
                 this._rebuildLayout = true;
@@ -425,7 +436,21 @@ export class TextBlock extends Control {
                 }
                 const lines = this._lines ? this._lines : this._breakLines(
                     this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
-                return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+
+                let newHeight = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+
+                if (this._lines.length > 0 && this._lineSpacing.internalValue !== 0) {
+                    let lineSpacing = 0;
+                    if (this._lineSpacing.isPixel) {
+                        lineSpacing = this._lineSpacing.getValue(this._host);
+                    } else {
+                        lineSpacing = (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
+                    }
+
+                    newHeight += (lines.length - 1) * lineSpacing;
+                }
+
+                return newHeight;
             }
         }
         return 0;

+ 1 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent.tsx

@@ -155,6 +155,7 @@ export class ScenePropertyGridComponent extends React.Component<IScenePropertyGr
                         <TextureLinkLineComponent label="Env. texture" texture={scene.environmentTexture} onSelectionChangedObservable={this.props.onSelectionChangedObservable} />
                     }
                     <FileButtonLineComponent label="Update environment texture" onClick={(file) => this.updateEnvironmentTexture(file)} accept=".dds, .env" />
+                    <SliderLineComponent minimum={0} maximum={2} step={0.01} label="IBL Intensity" target={scene} propertyName="environmentIntensity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FogPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} scene={scene} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} title="MATERIAL IMAGE PROCESSING">

+ 41 - 7
nodeEditor/src/previewManager.ts

@@ -1,4 +1,4 @@
-import { GlobalState } from './globalState';
+import { GlobalState } from '../../globalState';
 import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
@@ -8,37 +8,48 @@ import { Mesh } from 'babylonjs/Meshes/mesh';
 import { Vector3 } from 'babylonjs/Maths/math.vector';
 import { HemisphericLight } from 'babylonjs/Lights/hemisphericLight';
 import { ArcRotateCamera } from 'babylonjs/Cameras/arcRotateCamera';
+import { PreviewMeshType } from './previewMeshType';
 
 export class PreviewManager {
     private _nodeMaterial: NodeMaterial;
-    private _onBuildObserver: Nullable<Observer<NodeMaterial>>;
+    private _onBuildObserver: Nullable<Observer<NodeMaterial>>;    
+    private _onPreviewMeshTypeChangedObserver: Nullable<Observer<void>>;
     private _engine: Engine;
     private _scene: Scene;
     private _light: HemisphericLight;
-    private _dummySphere: Mesh;
+    private _dummy: Mesh;
     private _camera: ArcRotateCamera;
     private _material: NodeMaterial;
+    private _globalState: GlobalState;    
 
     public constructor(targetCanvas: HTMLCanvasElement, globalState: GlobalState) {
         this._nodeMaterial = globalState.nodeMaterial;
+        this._globalState = globalState;
 
         this._onBuildObserver = this._nodeMaterial.onBuildObservable.add((nodeMaterial) => {
             let serializationObject = nodeMaterial.serialize();
             this._updatePreview(serializationObject);
         });
 
+        this._onPreviewMeshTypeChangedObserver = globalState.onPreviewMeshTypeChanged.add(() => {
+            this._refreshPreviewMesh();
+        });
+
         this._engine = new Engine(targetCanvas, true);
         this._scene = new Scene(this._engine);
         this._camera = new ArcRotateCamera("Camera", 0, 0.8, 4, Vector3.Zero(), this._scene);
         this._light = new HemisphericLight("light", new Vector3(0, 1, 0), this._scene);
 
-        this._dummySphere = Mesh.CreateSphere("sphere", 32, 2, this._scene);
 
-        this._camera.lowerRadiusLimit = 2.5;
+        this._camera.lowerRadiusLimit = 3;
         this._camera.upperRadiusLimit = 10;
+        this._camera.wheelPrecision = 10;
         this._camera.attachControl(targetCanvas, false);
 
+        this._refreshPreviewMesh();
+
         this._engine.runRenderLoop(() => {
+            this._engine.resize();
             this._scene.render();
         });
 
@@ -46,6 +57,28 @@ export class PreviewManager {
         this._updatePreview(serializationObject);
     }
 
+    private _refreshPreviewMesh() {    
+        if (this._dummy) {
+            this._dummy.dispose();
+        }
+        
+        switch (this._globalState.previewMeshType) {
+            case PreviewMeshType.Box:
+                this._dummy = Mesh.CreateBox("dummy", 2, this._scene);
+                break;
+            case PreviewMeshType.Sphere:
+                this._dummy = Mesh.CreateSphere("dummy", 32, 2, this._scene);
+                break;
+            case PreviewMeshType.Torus:
+                this._dummy = Mesh.CreateTorus("dummy", 2, 0.5, 32, this._scene);
+                break;
+                case PreviewMeshType.Cylinder:
+                this._dummy = Mesh.CreateCylinder("dummy", 2, 1, 1.2, 32, 1, this._scene);
+                break;                
+        }
+        this._dummy.material = this._material;
+    }
+
     private _updatePreview(serializationObject: any) {
         if (this._material) {
             this._material.dispose();
@@ -53,18 +86,19 @@ export class PreviewManager {
 
         this._material = NodeMaterial.Parse(serializationObject, this._scene);
         this._material.build(true);
-        this._dummySphere.material = this._material;
+        this._dummy.material = this._material;
     }
 
     public dispose() {
         this._nodeMaterial.onBuildObservable.remove(this._onBuildObserver);
+        this._globalState.onPreviewMeshTypeChanged.remove(this._onPreviewMeshTypeChangedObserver);
 
         if (this._material) {
             this._material.dispose();
         }
 
         this._camera.dispose();
-        this._dummySphere.dispose();
+        this._dummy.dispose();
         this._light.dispose();
         this._engine.dispose();
     }

+ 47 - 0
nodeEditor/src/components/preview/previewMeshControlComponent.tsx

@@ -0,0 +1,47 @@
+
+import * as React from "react";
+import { GlobalState } from '../../globalState';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCircle, faRing, faCube, faHockeyPuck } from '@fortawesome/free-solid-svg-icons';
+import { PreviewMeshType } from './previewMeshType';
+import { DataStorage } from '../../dataStorage';
+
+interface IPreviewMeshControlComponent {
+    globalState: GlobalState;
+}
+
+export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
+
+    changeMeshType(newOne: PreviewMeshType) {
+        if (this.props.globalState.previewMeshType === newOne) {
+            return;
+        }
+
+        this.props.globalState.previewMeshType = newOne;
+        this.props.globalState.onPreviewMeshTypeChanged.notifyObservers();
+
+        DataStorage.StoreNumber("PreviewMeshType", newOne);
+
+        this.forceUpdate();
+    }
+
+    render() {
+        return (
+            <div id="preview-mesh-bar">
+                <div onClick={() => this.changeMeshType(PreviewMeshType.Box)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Box ? " selected" : "")}>
+                    <FontAwesomeIcon icon={faCube} />
+                </div>
+                <div onClick={() => this.changeMeshType(PreviewMeshType.Sphere)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Sphere ? " selected" : "")}>
+                    <FontAwesomeIcon icon={faCircle} />
+                </div>
+                <div onClick={() => this.changeMeshType(PreviewMeshType.Torus)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Torus ? " selected" : "")}>
+                    <FontAwesomeIcon icon={faRing} />
+                </div>
+                <div onClick={() => this.changeMeshType(PreviewMeshType.Cylinder)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Cylinder ? " selected" : "")}>
+                    <FontAwesomeIcon icon={faHockeyPuck} />
+                </div>
+            </div>
+        );
+
+    }
+}

+ 6 - 0
nodeEditor/src/components/preview/previewMeshType.ts

@@ -0,0 +1,6 @@
+export enum PreviewMeshType {
+    Sphere,
+    Box, 
+    Torus,
+    Cylinder
+}

+ 38 - 4
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -8,6 +8,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { StringTools } from '../../stringTools';
 import { FileButtonLineComponent } from '../../sharedComponents/fileButtonLineComponent';
 import { Tools } from 'babylonjs/Misc/tools';
+import { INodeLocationInfo } from '../../nodeLocationInfo';
 require("./propertyTab.scss");
 
 interface IPropertyTabComponentProps {
@@ -34,11 +35,45 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
             let serializationObject = JSON.parse(decoder.decode(data));
 
             this.props.globalState.nodeMaterial!.loadFromSerialization(serializationObject, "");
+
+            // Check for id mapping
+            if (serializationObject.locations && serializationObject.map) {
+                let map: {[key: number]: number} = serializationObject.map;
+                let locations: INodeLocationInfo[] = serializationObject.locations;
+
+                for (var location of locations) {
+                    location.blockId = map[location.blockId];
+                }
+            }
             
-            this.props.globalState.onResetRequiredObservable.notifyObservers();
+            this.props.globalState.onResetRequiredObservable.notifyObservers(serializationObject.locations);
         }, undefined, true);
     }
 
+    save() {
+        let material = this.props.globalState.nodeMaterial;
+        let serializationObject = material.serialize();
+
+        // Store node locations
+        for (var block of material.attachedBlocks) {
+            let node = this.props.globalState.onGetNodeFromBlock(block);
+
+            if (!serializationObject.locations) {
+                serializationObject.locations = [];
+            }
+
+            serializationObject.locations.push({
+                blockId: block.uniqueId,
+                x: node.x,
+                y: node.y
+            });
+        }
+
+        // Output
+        let json = JSON.stringify(serializationObject, undefined, 2);
+        StringTools.DownloadAsFile(json, "nodeMaterial.json");
+    }
+
     render() {
         if (this.state.currentNode) {
             return (
@@ -66,7 +101,7 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                     <LineContainerComponent title="GENERAL">
                         <ButtonLineComponent label="Reset to default" onClick={() => {
                             this.props.globalState.nodeMaterial!.setToDefault();
-                            this.props.globalState.onResetRequiredObservable.notifyObservers();
+                            this.props.globalState.onResetRequiredObservable.notifyObservers(null);
                         }} />
                     </LineContainerComponent>
                     <LineContainerComponent title="UI">
@@ -80,8 +115,7 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                     <LineContainerComponent title="FILE">                        
                         <FileButtonLineComponent label="Load" onClick={(file) => this.load(file)} accept=".json" />
                         <ButtonLineComponent label="Save" onClick={() => {
-                            let json = JSON.stringify(this.props.globalState.nodeMaterial!.serialize(), undefined, 2);
-                            StringTools.DownloadAsFile(json, "nodeMaterial.json");
+                            this.save();
                         }} />
                         <ButtonLineComponent label="Export shaders" onClick={() => {
                             StringTools.DownloadAsFile(this.props.globalState.nodeMaterial!.compiledShaders, "shaders.txt");

+ 13 - 1
nodeEditor/src/globalState.ts

@@ -3,6 +3,11 @@ import { Nullable } from "babylonjs/types"
 import { Observable } from 'babylonjs/Misc/observable';
 import { DefaultNodeModel } from './components/diagram/defaultNodeModel';
 import { LogEntry } from './components/log/logComponent';
+import { NodeModel } from 'storm-react-diagrams';
+import { INodeLocationInfo } from './nodeLocationInfo';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { PreviewMeshType } from './components/preview/previewMeshType';
+import { DataStorage } from './dataStorage';
 
 export class GlobalState {
     nodeMaterial: NodeMaterial;
@@ -10,10 +15,17 @@ export class GlobalState {
     hostDocument: HTMLDocument;
     onSelectionChangedObservable = new Observable<Nullable<DefaultNodeModel>>();
     onRebuildRequiredObservable = new Observable<void>();
-    onResetRequiredObservable = new Observable<void>();
+    onResetRequiredObservable = new Observable<Nullable<INodeLocationInfo[]>>();
     onUpdateRequiredObservable = new Observable<void>();
     onZoomToFitRequiredObservable = new Observable<void>();
     onReOrganizedRequiredObservable = new Observable<void>();
     onLogRequiredObservable = new Observable<LogEntry>();
     onErrorMessageDialogRequiredObservable = new Observable<string>();
+    onPreviewMeshTypeChanged = new Observable<void>();
+    onGetNodeFromBlock: (block: NodeMaterialBlock) => NodeModel;
+    previewMeshType: PreviewMeshType;
+
+    public constructor() {
+        this.previewMeshType = DataStorage.ReadNumber("PreviewMeshType", PreviewMeshType.Box);
+    }
 }

+ 38 - 17
nodeEditor/src/graphEditor.tsx

@@ -37,7 +37,9 @@ import { RemapNodeFactory } from './components/diagram/remap/remapNodeFactory';
 import { RemapNodeModel } from './components/diagram/remap/remapNodeModel';
 import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
 import { GraphHelper } from './graphHelper';
-import { PreviewManager } from './previewManager';
+import { PreviewManager } from './components/preview/previewManager';
+import { INodeLocationInfo } from './nodeLocationInfo';
+import { PreviewMeshControlComponent } from './components/preview/previewMeshControlComponent';
 
 require("storm-react-diagrams/dist/style.min.css");
 require("./main.scss");
@@ -164,8 +166,8 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             this.forceUpdate();
         });
 
-        this.props.globalState.onResetRequiredObservable.add(() => {
-            this.build();
+        this.props.globalState.onResetRequiredObservable.add((locations) => {
+            this.build(false, locations);
             if (this.props.globalState.nodeMaterial) {
                 this.buildMaterial();
             }
@@ -181,7 +183,11 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
         this.props.globalState.onReOrganizedRequiredObservable.add(() => {
             this.reOrganize();
-        })
+        });
+
+        this.props.globalState.onGetNodeFromBlock = (block) => {
+            return this._nodes.filter(n => n.block === block)[0];
+        }
 
         this.build(true);
     }
@@ -212,7 +218,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         }
 
         try {
-            this.props.globalState.nodeMaterial.build(true);
+            this.props.globalState.nodeMaterial.build();
             this.props.globalState.onLogRequiredObservable.notifyObservers(new LogEntry("Node material build successful", false));
         }
         catch (err) {
@@ -220,9 +226,11 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         }
     }
 
-    build(needToWait = false) {
+    build(needToWait = false, locations: Nullable<INodeLocationInfo[]> = null) {
         // setup the diagram model
         this._model = new DiagramModel();
+        this._nodes = [];
+        this._blocks = [];
 
         // Listen to events
         this._model.addListener({
@@ -357,23 +365,35 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
             this.forceUpdate();
 
-            this.reOrganize();
+            this.reOrganize(locations);
         }, needToWait ? 500 : 1);
     }
 
-    reOrganize() {
-        let nodes = GraphHelper.DistributeGraph(this._model);
-        nodes.forEach(node => {
-            for (var nodeName in this._model.nodes) {
-                let modelNode = this._model.nodes[nodeName];
+    reOrganize(locations: Nullable<INodeLocationInfo[]> = null) {
+        if (!locations) {
+            let nodes = GraphHelper.DistributeGraph(this._model);
+            nodes.forEach(node => {
+                for (var nodeName in this._model.nodes) {
+                    let modelNode = this._model.nodes[nodeName];
 
-                if (modelNode.id === node.id) {
-                    modelNode.setPosition(node.x - node.width / 2, node.y - node.height / 2);
-                    return;
+                    if (modelNode.id === node.id) {
+                        modelNode.setPosition(node.x - node.width / 2, node.y - node.height / 2);
+                        return;
+                    }
+                }
+            });
+        } else {
+            for (var location of locations) {
+                for (var node of this._nodes) {
+                    if (node.block && node.block.uniqueId === location.blockId) {
+                        node.setPosition(location.x, location.y);
+                        break;
+                    }
                 }
             }
-        });
-        this.forceUpdate();
+        }
+
+        this._engine.repaintCanvas();
     }
 
     onPointerDown(evt: React.PointerEvent<HTMLDivElement>) {
@@ -482,6 +502,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
                     {/* Property tab */}
                     <div className="right-panel">
                         <PropertyTabComponent globalState={this.props.globalState} />
+                        <PreviewMeshControlComponent globalState={this.props.globalState} />
                         <div id="preview" style={{height: this._rightWidth + "px"}}>
                             <canvas id="preview-canvas"/>
                         </div>

+ 32 - 3
nodeEditor/src/main.scss

@@ -41,7 +41,7 @@
     grid-row: 1 / span 2;
     grid-column: 5;
     display: grid;
-    grid-template-rows: 1fr auto;
+    grid-template-rows: 1fr 30px auto;
     grid-template-columns: 100%;
 
     #propertyTab {
@@ -49,14 +49,43 @@
         grid-column: 1;
     }
 
+    #preview-mesh-bar {
+        grid-row: 2;
+        grid-column: 1;
+        display: flex;
+        color: white;
+        align-items: center;
+        font-size: 18px;
+
+        .button {
+            display: grid;
+            justify-content: center;
+            align-content: center;
+            height: 30px;
+            width: calc(100% / 4);
+            cursor: pointer;
+
+            &:hover {
+                background: rgb(51, 122, 183);
+                color: white;
+                opacity: 0.8;
+            }
+
+            &.selected {
+                background: rgb(51, 122, 183);
+                color: white;
+            }
+        }        
+    }
+    
     #preview {
         border-top: 1px solid rgb(85, 85, 85);
-        grid-row: 2;
+        grid-row: 3;
         grid-column: 1;
         width: 100%;
         display: grid;
         outline: 0 !important;
-        
+
         #preview-canvas {
             width: 100%;
             height: 100%;

+ 5 - 0
nodeEditor/src/nodeLocationInfo.ts

@@ -0,0 +1,5 @@
+export interface INodeLocationInfo {
+    blockId: number;
+    x: number;
+    y: number;
+}

+ 1 - 1
package.json

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

+ 10 - 3
src/Cameras/deviceOrientationCamera.ts

@@ -20,6 +20,7 @@ export class DeviceOrientationCamera extends FreeCamera {
     private _initialQuaternion: Quaternion;
     private _quaternionCache: Quaternion;
     private _tmpDragQuaternion = new Quaternion();
+    private _disablePointerInputWhenUsingDeviceOrientation = true;
 
     /**
      * Creates a new device orientation camera
@@ -55,10 +56,16 @@ export class DeviceOrientationCamera extends FreeCamera {
     }
 
     /**
-     * @hidden
-     * Disabled pointer input on first orientation sensor update (Default: true)
+     * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
      */
-    public _disablePointerInputWhenUsingDeviceOrientation = true;
+    public get disablePointerInputWhenUsingDeviceOrientation() {
+        return this._disablePointerInputWhenUsingDeviceOrientation;
+    }
+
+    public set disablePointerInputWhenUsingDeviceOrientation(value: boolean) {
+        this._disablePointerInputWhenUsingDeviceOrientation = value;
+    }
+
     private _dragFactor = 0;
     /**
      * Enabled turning on the y axis when the orientation sensor is active

+ 4 - 4
src/Engines/engine.ts

@@ -513,14 +513,14 @@ export class Engine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.1.0-alpha.12";
+        return "babylonjs@4.1.0-alpha.13";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.1.0-alpha.12";
+        return "4.1.0-alpha.13";
     }
 
     /**
@@ -3426,7 +3426,7 @@ export class Engine {
             if (!this._gl.getShaderParameter(vertexShader, this._gl.COMPILE_STATUS)) {
                 let log = this._gl.getShaderInfoLog(vertexShader);
                 if (log) {
-                    throw new Error(log);
+                    throw new Error("VERTEX SHADER " + log);
                 }
             }
 
@@ -3434,7 +3434,7 @@ export class Engine {
             if (!this._gl.getShaderParameter(fragmentShader, this._gl.COMPILE_STATUS)) {
                 let log = this._gl.getShaderInfoLog(fragmentShader);
                 if (log) {
-                    throw new Error(log);
+                    throw new Error("FRAGMENT SHADER " + log);
                 }
             }
 

+ 5 - 0
src/Loading/Plugins/babylonFileLoader.ts

@@ -149,6 +149,11 @@ var loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError?:
             container.environmentTexture = scene.environmentTexture;
         }
 
+        // Environment Intensity
+        if (parsedData.environmentIntensity !== undefined && parsedData.environmentIntensity !== null) {
+            scene.environmentIntensity = parsedData.environmentIntensity;
+        }
+
         // Lights
         if (parsedData.lights !== undefined && parsedData.lights !== null) {
             for (index = 0, cache = parsedData.lights.length; index < cache; index++) {

+ 42 - 7
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -145,6 +145,26 @@ export class LightBlock extends NodeMaterialBlock {
         let worldPos = this.worldPosition;
         let worldNormal = this.worldNormal;
 
+        let comments = `//${this.name}`;
+
+        // Declaration
+        if (!this.light) { // Emit for all lights
+            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
+                repeatKey: "maxSimultaneousLights"
+            });
+            this._lightId = 0;
+
+            state.sharedData.dynamicUniformBlocks.push(this);
+        } else {
+
+            this._lightId = (state.counters["lightCounter"] !== undefined ? state.counters["lightCounter"] : -1) + 1;
+            state.counters["lightCounter"] = this._lightId;
+
+            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
+                replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }]
+            }, this._lightId.toString());
+        }
+
         // Inject code in vertex
         let worldPosVaryingName = "v_" + worldPos.associatedVariableName;
         state._emitVaryingFromString(worldPosVaryingName, "vec3");
@@ -152,6 +172,20 @@ export class LightBlock extends NodeMaterialBlock {
         let worldNormalVaryingName = "v_" + worldNormal.associatedVariableName;
         state._emitVaryingFromString(worldNormalVaryingName, "vec3");
 
+        if (this.light) {
+            state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
+                replaceStrings: [
+                    { search: /{X}/g, replace: this._lightId.toString() },
+                    { search: /worldPos/g, replace: worldPos.associatedVariableName }
+                ]
+            });
+        } else {
+            state.compilationString += `vec4 worldPos = ${worldPos.associatedVariableName};\r\n`;
+            state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
+                repeatKey: "maxSimultaneousLights"
+            });
+        }
+
         state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName}.xyz;\r\n`;
         state.compilationString += `${worldNormalVaryingName} = ${worldNormal.associatedVariableName}.xyz;\r\n`;
     }
@@ -173,24 +207,25 @@ export class LightBlock extends NodeMaterialBlock {
         let comments = `//${this.name}`;
         let worldPos = this.worldPosition;
 
+        state._emitFunctionFromInclude("helperFunctions", comments);
+
         state._emitFunctionFromInclude("lightsFragmentFunctions", comments, {
             replaceStrings: [
                 { search: /vPositionW/g, replace: "v_" + worldPos.associatedVariableName }
             ]
         });
 
+        state._emitFunctionFromInclude("shadowsFragmentFunctions", comments, {
+            replaceStrings: [
+                { search: /vPositionW/g, replace: "v_" + worldPos.associatedVariableName }
+            ]
+        });
+
         if (!this.light) { // Emit for all lights
             state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                 repeatKey: "maxSimultaneousLights"
             });
-            this._lightId = 0;
-
-            state.sharedData.dynamicUniformBlocks.push(this);
         } else {
-
-            this._lightId = (state.counters["lightCounter"] !== undefined ? state.counters["lightCounter"] : -1) + 1;
-            state.counters["lightCounter"] = this._lightId;
-
             state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                 replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }]
             }, this._lightId.toString());

+ 11 - 0
src/Materials/Node/nodeMaterial.ts

@@ -779,6 +779,10 @@ export class NodeMaterial extends PushMaterial {
             return true;
         }
 
+        if (!this._sharedData) {
+            return false;
+        }
+
         for (var t of this._sharedData.textureBlocks) {
             if (t.texture === texture) {
                 return true;
@@ -995,6 +999,13 @@ export class NodeMaterial extends PushMaterial {
         for (var outputNodeId of source.outputNodes) {
             this.addOutputNode(map[outputNodeId]);
         }
+
+        // Store map for external uses
+        source.map = {};
+
+        for (var key in map) {
+            source.map[key] = map[key].uniqueId;
+        }
     }
 
     /**

+ 1 - 0
src/Materials/Node/nodeMaterialBuildStateSharedData.ts

@@ -113,6 +113,7 @@ export class NodeMaterialBuildStateSharedData {
         this.variableNames["matricesWeightsExtra"] = 0;
         this.variableNames["diffuseBase"] = 0;
         this.variableNames["specularBase"] = 0;
+        this.variableNames["worldPos"] = 0;
 
         // Exclude defines
         this.defineNames["MAINUV0"] = 0;

+ 1 - 1
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1818,7 +1818,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                 // Misc
                 this._lightingInfos.x = this._directIntensity;
                 this._lightingInfos.y = this._emissiveIntensity;
-                this._lightingInfos.z = this._environmentIntensity;
+                this._lightingInfos.z = this._environmentIntensity * scene.environmentIntensity;
                 this._lightingInfos.w = this._specularIntensity;
 
                 ubo.updateVector4("vLightingIntensity", this._lightingInfos);

+ 3 - 1
src/Meshes/mesh.ts

@@ -2851,7 +2851,9 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
         // Material
         if (this.material) {
-            serializationObject.materialId = this.material.id;
+            if (!this.material.doNotSerialize) {
+                serializationObject.materialId = this.material.id;
+            }
         } else {
             this.material = null;
         }

+ 4 - 1
src/Misc/sceneSerializer.ts

@@ -46,7 +46,7 @@ var finalizeSingleMesh = (mesh: Mesh, serializationObject: any) => {
     //only works if the mesh is already loaded
     if (mesh.delayLoadState === Constants.DELAYLOADSTATE_LOADED || mesh.delayLoadState === Constants.DELAYLOADSTATE_NONE) {
         //serialize material
-        if (mesh.material && !mesh.doNotSerialize) {
+        if (mesh.material && !mesh.material.doNotSerialize) {
             if (mesh.material instanceof MultiMaterial) {
                 serializationObject.multiMaterials = serializationObject.multiMaterials || [];
                 serializationObject.materials = serializationObject.materials || [];
@@ -233,6 +233,9 @@ export class SceneSerializer {
             serializationObject.environmentTexture = scene.environmentTexture.name;
         }
 
+        // Environment Intensity
+        serializationObject.environmentIntensity = scene.environmentIntensity;
+
         // Skeletons
         serializationObject.skeletons = [];
         for (index = 0; index < scene.skeletons.length; index++) {

+ 26 - 0
src/scene.ts

@@ -203,6 +203,32 @@ export class Scene extends AbstractScene implements IAnimatable {
     }
 
     /** @hidden */
+    protected _environmentIntensity: number = 1;
+    /**
+     * Intensity of the environment in all pbr material.
+     * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+     * As in the majority of the scene they are the same (exception for multi room and so on),
+     * this is easier to reference from here than from all the materials.
+     */
+    public get environmentIntensity(): number {
+        return this._environmentIntensity;
+    }
+    /**
+     * Intensity of the environment in all pbr material.
+     * This dims or reinforces the IBL lighting overall (reflection and diffuse).
+     * As in the majority of the scene they are the same (exception for multi room and so on),
+     * this is easier to set here than in all the materials.
+     */
+    public set environmentIntensity(value: number) {
+        if (this._environmentIntensity === value) {
+            return;
+        }
+
+        this._environmentIntensity = value;
+        this.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);
+    }
+
+    /** @hidden */
     protected _imageProcessingConfiguration: ImageProcessingConfiguration;
     /**
      * Default image processing configuration used either in the rendering