Преглед изворни кода

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

Guide пре 6 година
родитељ
комит
c18700bfd9
55 измењених фајлова са 3595 додато и 2475 уклоњено
  1. 335 279
      Playground/babylon.d.txt
  2. 337 280
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 318 114
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 704 584
      dist/preview release/babylon.module.d.ts
  7. 337 280
      dist/preview release/documentation.d.ts
  8. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  9. 119 32
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  10. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  11. 18 1
      dist/preview release/inspector/babylon.inspector.d.ts
  12. 43 2
      dist/preview release/inspector/babylon.inspector.module.d.ts
  13. 2 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  14. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  15. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  16. 2 1
      dist/preview release/loaders/babylon.glTFFileLoader.js
  17. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  18. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  19. 2 1
      dist/preview release/loaders/babylonjs.loaders.js
  20. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  21. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  22. 3 2
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  23. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  24. 86 69
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  25. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  26. 7 4
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  27. 1 1
      dist/preview release/packagesSizeBaseLine.json
  28. 704 584
      dist/preview release/viewer/babylon.module.d.ts
  29. 20 16
      dist/preview release/viewer/babylon.viewer.js
  30. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  31. 12 0
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  32. 64 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent.tsx
  33. 41 8
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx
  34. 9 1
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  35. 1 1
      inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx
  36. 1 1
      inspector/src/tools.ts
  37. 2 1
      loaders/src/glTF/2.0/glTFLoader.ts
  38. 3 0
      nodeEditor/src/blockTools.ts
  39. 46 26
      nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx
  40. 1 2
      nodeEditor/src/components/diagram/texture/texturePropertyTabComponent.tsx
  41. 99 95
      nodeEditor/src/components/nodeList/nodeList.scss
  42. 1 1
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  43. 2 2
      nodeEditor/src/components/propertyTab/propertyTabComponent.tsx
  44. 9 5
      nodeEditor/src/sharedComponents/optionsLineComponent.tsx
  45. 8 0
      src/Audio/audioSceneComponent.ts
  46. 3 3
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  47. 116 0
      src/Materials/Node/Blocks/Fragment/fresnelBlock.ts
  48. 1 4
      src/Materials/Node/Blocks/Fragment/index.ts
  49. 4 0
      src/Materials/Node/Blocks/colorSplitterBlock.ts
  50. 5 1
      src/Materials/Node/Blocks/index.ts
  51. 36 15
      src/Materials/Node/nodeMaterial.ts
  52. 10 0
      src/Materials/Node/nodeMaterialBuildState.ts
  53. 5 0
      src/Materials/Node/nodeMaterialBuildStateSharedData.ts
  54. 56 36
      src/Materials/effect.ts
  55. 3 3
      src/Meshes/mesh.ts

+ 335 - 279
Playground/babylon.d.txt

@@ -27765,6 +27765,7 @@ declare module BABYLON {
          * @returns if the effect is compiled and prepared.
          */
         isReady(): boolean;
+        private _isReadyInternal;
         /**
          * The engine the effect was initialized with.
          * @returns the engine.
@@ -27840,6 +27841,7 @@ declare module BABYLON {
          * Prepares the effect
          * @hidden
          */
private _prepareEffect(): void;
+        private _processCompilationErrors;
         /**
          * Checks if the effect is supported. (Must be called after compilation)
          */
@@ -50952,6 +50954,117 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Enum used to define well known values e.g. values automatically provided by the system
+     */
+    export enum NodeMaterialWellKnownValues {
+        /** World */
+        World = 1,
+        /** View */
+        View = 2,
+        /** Projection */
+        Projection = 3,
+        /** ViewProjection */
+        ViewProjection = 4,
+        /** WorldView */
+        WorldView = 5,
+        /** WorldViewProjection */
+        WorldViewProjection = 6,
+        /** CameraPosition */
+        CameraPosition = 7,
+        /** Fog Color */
+        FogColor = 8
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to read a reflection texture from a sampler
+     */
+    export class ReflectionTextureBlock extends NodeMaterialBlock {
+        private _define3DName;
+        private _defineCubicName;
+        private _defineExplicitName;
+        private _defineProjectionName;
+        private _defineLocalCubicName;
+        private _defineSphericalName;
+        private _definePlanarName;
+        private _defineEquirectangularName;
+        private _defineMirroredEquirectangularFixedName;
+        private _defineEquirectangularFixedName;
+        private _defineSkyboxName;
+        private _cubeSamplerName;
+        private _2DSamplerName;
+        private _positionUVWName;
+        private _directionWName;
+        private _reflectionCoordsName;
+        private _reflection2DCoordsName;
+        private _reflectionColorName;
+        private _reflectionMatrixName;
+        /**
+         * Gets or sets the texture associated with the node
+         */
+        texture: Nullable<BaseTexture>;
+        /**
+         * Create a new TextureBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly position: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world normal input component
+         */
+        readonly worldNormal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world input component
+         */
+        readonly world: NodeMaterialConnectionPoint;
+        /**
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the view input component
+         */
+        readonly view: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb output component
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r output component
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g output component
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b output component
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        isReady(): boolean;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        private _injectVertexCode;
+        private _writeOutput;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
private _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Interface used to configure the node material editor
      */
     export interface INodeMaterialEditorOptions {
@@ -51080,7 +51193,7 @@ declare module BABYLON {
          * @param name defines the name of the block to retrieve
          * @returns the required block or null if not found
          */
-        getBlockByName(name: string): NodeMaterialBlock | null;
+        getBlockByName(name: string): Nullable<NodeMaterialBlock>;
         /**
          * Gets the list of input blocks attached to this material
          * @returns an array of InputBlocks
@@ -51167,6 +51280,11 @@ declare module BABYLON {
          */
         getActiveTextures(): BaseTexture[];
         /**
+         * Gets the list of texture blocks
+         * @returns an array of texture blocks
+         */
+        getTextureBlocks(): (TextureBlock | ReflectionTextureBlock)[];
+        /**
          * Specifies if the material uses a texture
          * @param texture defines the texture to check against the material
          * @returns a boolean specifying if the material uses the texture
@@ -51201,6 +51319,7 @@ declare module BABYLON {
          * @returns the serialized material object
          */
         serialize(): any;
+        private _restoreConnections;
         /**
          * Clear the current graph and load a new one from a serialization object
          * @param source defines the JSON representation of the material
@@ -51291,121 +51410,14 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Enum used to define well known values e.g. values automatically provided by the system
-     */
-    export enum NodeMaterialWellKnownValues {
-        /** World */
-        World = 1,
-        /** View */
-        View = 2,
-        /** Projection */
-        Projection = 3,
-        /** ViewProjection */
-        ViewProjection = 4,
-        /** WorldView */
-        WorldView = 5,
-        /** WorldViewProjection */
-        WorldViewProjection = 6,
-        /** CameraPosition */
-        CameraPosition = 7,
-        /** Fog Color */
-        FogColor = 8
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to read a reflection texture from a sampler
-     */
-    export class ReflectionTextureBlock extends NodeMaterialBlock {
-        private _define3DName;
-        private _defineCubicName;
-        private _defineExplicitName;
-        private _defineProjectionName;
-        private _defineLocalCubicName;
-        private _defineSphericalName;
-        private _definePlanarName;
-        private _defineEquirectangularName;
-        private _defineMirroredEquirectangularFixedName;
-        private _defineEquirectangularFixedName;
-        private _defineSkyboxName;
-        private _cubeSamplerName;
-        private _2DSamplerName;
-        private _positionUVWName;
-        private _directionWName;
-        private _reflectionCoordsName;
-        private _reflection2DCoordsName;
-        private _reflectionColorName;
-        private _reflectionMatrixName;
-        /**
-         * Gets or sets the texture associated with the node
-         */
-        texture: Nullable<BaseTexture>;
-        /**
-         * Create a new TextureBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the world position input component
-         */
-        readonly position: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world position input component
-         */
-        readonly worldPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world normal input component
-         */
-        readonly worldNormal: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world input component
-         */
-        readonly world: NodeMaterialConnectionPoint;
-        /**
-        * Gets the camera (or eye) position component
-        */
-        readonly cameraPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the view input component
-         */
-        readonly view: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb output component
-         */
-        readonly rgb: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r output component
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g output component
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b output component
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        autoConfigure(): void;
-        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
-        isReady(): boolean;
-        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
-        private _injectVertexCode;
-        private _writeOutput;
-        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
-        serialize(): any;
private _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
-    }
-}
-declare module BABYLON {
-    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
         /**
+        * Gets the list of emitted varyings
+        */
+        temps: string[];
+        /**
          * Gets the list of emitted varyings
          */
         varyings: string[];
@@ -51420,7 +51432,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
+        textureBlocks: (ReflectionTextureBlock | TextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -51573,6 +51585,7 @@ declare module BABYLON {
                 replace: string;
             }[];
         }, storeKey?: string): void;
+        /** @hidden */
private _registerTempVariable(name: string): boolean;
         /** @hidden */
private _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
private _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -51770,7 +51783,7 @@ declare module BABYLON {
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
          * @returns a copy of the current block
          */
-        clone(scene: Scene, rootUrl?: string): NodeMaterialBlock | null;
+        clone(scene: Scene, rootUrl?: string): Nullable<NodeMaterialBlock>;
         /**
          * Serializes this block in a JSON representation
          * @returns the serialized block object
@@ -52196,11 +52209,11 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     * Block used to compute fresnel value
      */
-    export class ColorMergerBlock extends NodeMaterialBlock {
+    export class FresnelBlock extends NodeMaterialBlock {
         /**
-         * Create a new ColorMergerBlock
+         * Create a new FresnelBlock
          * @param name defines the block name
          */
         constructor(name: string);
@@ -52210,176 +52223,31 @@ declare module BABYLON {
          */
         getClassName(): string;
         /**
-         * Gets the r component (input)
+         * Gets the world position input component
          */
-        readonly r: NodeMaterialConnectionPoint;
+        readonly worldPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the g component (input)
+         * Gets the world normal input component
          */
-        readonly g: NodeMaterialConnectionPoint;
+        readonly worldNormal: NodeMaterialConnectionPoint;
         /**
-         * Gets the b component (input)
-         */
-        readonly b: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the a component (input)
-         */
-        readonly a: NodeMaterialConnectionPoint;
+        * Gets the bias input component
+        */
+        readonly bias: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgba component (output)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly power: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgb component (output)
+         * Gets the fresnel output component
          */
-        readonly rgb: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
-     */
-    export class VectorMergerBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorMergerBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the x component (input)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (input)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (input)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (input)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyzw component (output)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyz: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xy: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Color3/4 into 4 outputs (one for each component)
-     */
-    export class ColorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new ColorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the rgba component (input)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (input)
-         */
-        readonly rgbIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (output)
-         */
-        readonly rgbOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r component (output)
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g component (output)
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b component (output)
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        /**
-         * Gets the a component (output)
-         */
-        readonly a: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
-     */
-    export class VectorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the xyzw component (input)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (input)
-         */
-        readonly xyzIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (input)
-         */
-        readonly xyIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyzOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xyOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the x component (output)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (output)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (output)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (output)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
+        readonly fresnel: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
     }
 }
 declare module BABYLON {
@@ -52791,6 +52659,194 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     */
+    export class ColorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the r component (input)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (input)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (input)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (input)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgba component (output)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
+     */
+    export class VectorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the x component (input)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (input)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (input)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (input)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyzw component (output)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyz: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Color3/4 into 4 outputs (one for each component)
+     */
+    export class ColorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the rgba component (input)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (input)
+         */
+        readonly rgbIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgbOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r component (output)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (output)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (output)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (output)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
+     */
+    export class VectorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the xyzw component (input)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (input)
+         */
+        readonly xyzIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (input)
+         */
+        readonly xyIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyzOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xyOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the x component (output)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (output)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (output)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (output)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

+ 337 - 280
dist/preview release/babylon.d.ts

@@ -28306,6 +28306,7 @@ declare module BABYLON {
          * @returns if the effect is compiled and prepared.
          */
         isReady(): boolean;
+        private _isReadyInternal;
         /**
          * The engine the effect was initialized with.
          * @returns the engine.
@@ -28386,6 +28387,7 @@ declare module BABYLON {
          * @hidden
          */
         _prepareEffect(): void;
+        private _processCompilationErrors;
         /**
          * Checks if the effect is supported. (Must be called after compilation)
          */
@@ -51731,6 +51733,118 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Enum used to define well known values e.g. values automatically provided by the system
+     */
+    export enum NodeMaterialWellKnownValues {
+        /** World */
+        World = 1,
+        /** View */
+        View = 2,
+        /** Projection */
+        Projection = 3,
+        /** ViewProjection */
+        ViewProjection = 4,
+        /** WorldView */
+        WorldView = 5,
+        /** WorldViewProjection */
+        WorldViewProjection = 6,
+        /** CameraPosition */
+        CameraPosition = 7,
+        /** Fog Color */
+        FogColor = 8
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to read a reflection texture from a sampler
+     */
+    export class ReflectionTextureBlock extends NodeMaterialBlock {
+        private _define3DName;
+        private _defineCubicName;
+        private _defineExplicitName;
+        private _defineProjectionName;
+        private _defineLocalCubicName;
+        private _defineSphericalName;
+        private _definePlanarName;
+        private _defineEquirectangularName;
+        private _defineMirroredEquirectangularFixedName;
+        private _defineEquirectangularFixedName;
+        private _defineSkyboxName;
+        private _cubeSamplerName;
+        private _2DSamplerName;
+        private _positionUVWName;
+        private _directionWName;
+        private _reflectionCoordsName;
+        private _reflection2DCoordsName;
+        private _reflectionColorName;
+        private _reflectionMatrixName;
+        /**
+         * Gets or sets the texture associated with the node
+         */
+        texture: Nullable<BaseTexture>;
+        /**
+         * Create a new TextureBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly position: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world normal input component
+         */
+        readonly worldNormal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world input component
+         */
+        readonly world: NodeMaterialConnectionPoint;
+        /**
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the view input component
+         */
+        readonly view: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb output component
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r output component
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g output component
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b output component
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        isReady(): boolean;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        private _injectVertexCode;
+        private _writeOutput;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Interface used to configure the node material editor
      */
     export interface INodeMaterialEditorOptions {
@@ -51861,7 +51975,7 @@ declare module BABYLON {
          * @param name defines the name of the block to retrieve
          * @returns the required block or null if not found
          */
-        getBlockByName(name: string): NodeMaterialBlock | null;
+        getBlockByName(name: string): Nullable<NodeMaterialBlock>;
         /**
          * Gets the list of input blocks attached to this material
          * @returns an array of InputBlocks
@@ -51948,6 +52062,11 @@ declare module BABYLON {
          */
         getActiveTextures(): BaseTexture[];
         /**
+         * Gets the list of texture blocks
+         * @returns an array of texture blocks
+         */
+        getTextureBlocks(): (TextureBlock | ReflectionTextureBlock)[];
+        /**
          * Specifies if the material uses a texture
          * @param texture defines the texture to check against the material
          * @returns a boolean specifying if the material uses the texture
@@ -51982,6 +52101,7 @@ declare module BABYLON {
          * @returns the serialized material object
          */
         serialize(): any;
+        private _restoreConnections;
         /**
          * Clear the current graph and load a new one from a serialization object
          * @param source defines the JSON representation of the material
@@ -52073,122 +52193,14 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Enum used to define well known values e.g. values automatically provided by the system
-     */
-    export enum NodeMaterialWellKnownValues {
-        /** World */
-        World = 1,
-        /** View */
-        View = 2,
-        /** Projection */
-        Projection = 3,
-        /** ViewProjection */
-        ViewProjection = 4,
-        /** WorldView */
-        WorldView = 5,
-        /** WorldViewProjection */
-        WorldViewProjection = 6,
-        /** CameraPosition */
-        CameraPosition = 7,
-        /** Fog Color */
-        FogColor = 8
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to read a reflection texture from a sampler
-     */
-    export class ReflectionTextureBlock extends NodeMaterialBlock {
-        private _define3DName;
-        private _defineCubicName;
-        private _defineExplicitName;
-        private _defineProjectionName;
-        private _defineLocalCubicName;
-        private _defineSphericalName;
-        private _definePlanarName;
-        private _defineEquirectangularName;
-        private _defineMirroredEquirectangularFixedName;
-        private _defineEquirectangularFixedName;
-        private _defineSkyboxName;
-        private _cubeSamplerName;
-        private _2DSamplerName;
-        private _positionUVWName;
-        private _directionWName;
-        private _reflectionCoordsName;
-        private _reflection2DCoordsName;
-        private _reflectionColorName;
-        private _reflectionMatrixName;
-        /**
-         * Gets or sets the texture associated with the node
-         */
-        texture: Nullable<BaseTexture>;
-        /**
-         * Create a new TextureBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the world position input component
-         */
-        readonly position: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world position input component
-         */
-        readonly worldPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world normal input component
-         */
-        readonly worldNormal: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world input component
-         */
-        readonly world: NodeMaterialConnectionPoint;
-        /**
-        * Gets the camera (or eye) position component
-        */
-        readonly cameraPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the view input component
-         */
-        readonly view: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb output component
-         */
-        readonly rgb: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r output component
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g output component
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b output component
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        autoConfigure(): void;
-        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
-        isReady(): boolean;
-        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
-        private _injectVertexCode;
-        private _writeOutput;
-        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
-        serialize(): any;
-        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
-    }
-}
-declare module BABYLON {
-    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
         /**
+        * Gets the list of emitted varyings
+        */
+        temps: string[];
+        /**
          * Gets the list of emitted varyings
          */
         varyings: string[];
@@ -52203,7 +52215,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
+        textureBlocks: (ReflectionTextureBlock | TextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -52371,6 +52383,8 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
+        _registerTempVariable(name: string): boolean;
+        /** @hidden */
         _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
@@ -52571,7 +52585,7 @@ declare module BABYLON {
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
          * @returns a copy of the current block
          */
-        clone(scene: Scene, rootUrl?: string): NodeMaterialBlock | null;
+        clone(scene: Scene, rootUrl?: string): Nullable<NodeMaterialBlock>;
         /**
          * Serializes this block in a JSON representation
          * @returns the serialized block object
@@ -53006,11 +53020,11 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     * Block used to compute fresnel value
      */
-    export class ColorMergerBlock extends NodeMaterialBlock {
+    export class FresnelBlock extends NodeMaterialBlock {
         /**
-         * Create a new ColorMergerBlock
+         * Create a new FresnelBlock
          * @param name defines the block name
          */
         constructor(name: string);
@@ -53020,176 +53034,31 @@ declare module BABYLON {
          */
         getClassName(): string;
         /**
-         * Gets the r component (input)
+         * Gets the world position input component
          */
-        readonly r: NodeMaterialConnectionPoint;
+        readonly worldPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the g component (input)
+         * Gets the world normal input component
          */
-        readonly g: NodeMaterialConnectionPoint;
+        readonly worldNormal: NodeMaterialConnectionPoint;
         /**
-         * Gets the b component (input)
-         */
-        readonly b: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the a component (input)
-         */
-        readonly a: NodeMaterialConnectionPoint;
+        * Gets the bias input component
+        */
+        readonly bias: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgba component (output)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly power: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgb component (output)
+         * Gets the fresnel output component
          */
-        readonly rgb: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
-     */
-    export class VectorMergerBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorMergerBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the x component (input)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (input)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (input)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (input)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyzw component (output)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyz: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xy: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Color3/4 into 4 outputs (one for each component)
-     */
-    export class ColorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new ColorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the rgba component (input)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (input)
-         */
-        readonly rgbIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (output)
-         */
-        readonly rgbOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r component (output)
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g component (output)
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b component (output)
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        /**
-         * Gets the a component (output)
-         */
-        readonly a: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
-     */
-    export class VectorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the xyzw component (input)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (input)
-         */
-        readonly xyzIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (input)
-         */
-        readonly xyIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyzOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xyOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the x component (output)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (output)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (output)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (output)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
+        readonly fresnel: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
     }
 }
 declare module BABYLON {
@@ -53602,6 +53471,194 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     */
+    export class ColorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the r component (input)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (input)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (input)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (input)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgba component (output)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
+     */
+    export class VectorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the x component (input)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (input)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (input)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (input)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyzw component (output)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyz: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Color3/4 into 4 outputs (one for each component)
+     */
+    export class ColorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the rgba component (input)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (input)
+         */
+        readonly rgbIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgbOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r component (output)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (output)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (output)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (output)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
+     */
+    export class VectorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the xyzw component (input)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (input)
+         */
+        readonly xyzIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (input)
+         */
+        readonly xyIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyzOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xyOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the x component (output)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (output)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (output)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (output)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 318 - 114
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.max.js.map


Разлика између датотеке није приказан због своје велике величине
+ 704 - 584
dist/preview release/babylon.module.d.ts


+ 337 - 280
dist/preview release/documentation.d.ts

@@ -28306,6 +28306,7 @@ declare module BABYLON {
          * @returns if the effect is compiled and prepared.
          */
         isReady(): boolean;
+        private _isReadyInternal;
         /**
          * The engine the effect was initialized with.
          * @returns the engine.
@@ -28386,6 +28387,7 @@ declare module BABYLON {
          * @hidden
          */
         _prepareEffect(): void;
+        private _processCompilationErrors;
         /**
          * Checks if the effect is supported. (Must be called after compilation)
          */
@@ -51731,6 +51733,118 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Enum used to define well known values e.g. values automatically provided by the system
+     */
+    export enum NodeMaterialWellKnownValues {
+        /** World */
+        World = 1,
+        /** View */
+        View = 2,
+        /** Projection */
+        Projection = 3,
+        /** ViewProjection */
+        ViewProjection = 4,
+        /** WorldView */
+        WorldView = 5,
+        /** WorldViewProjection */
+        WorldViewProjection = 6,
+        /** CameraPosition */
+        CameraPosition = 7,
+        /** Fog Color */
+        FogColor = 8
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to read a reflection texture from a sampler
+     */
+    export class ReflectionTextureBlock extends NodeMaterialBlock {
+        private _define3DName;
+        private _defineCubicName;
+        private _defineExplicitName;
+        private _defineProjectionName;
+        private _defineLocalCubicName;
+        private _defineSphericalName;
+        private _definePlanarName;
+        private _defineEquirectangularName;
+        private _defineMirroredEquirectangularFixedName;
+        private _defineEquirectangularFixedName;
+        private _defineSkyboxName;
+        private _cubeSamplerName;
+        private _2DSamplerName;
+        private _positionUVWName;
+        private _directionWName;
+        private _reflectionCoordsName;
+        private _reflection2DCoordsName;
+        private _reflectionColorName;
+        private _reflectionMatrixName;
+        /**
+         * Gets or sets the texture associated with the node
+         */
+        texture: Nullable<BaseTexture>;
+        /**
+         * Create a new TextureBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly position: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world normal input component
+         */
+        readonly worldNormal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the world input component
+         */
+        readonly world: NodeMaterialConnectionPoint;
+        /**
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the view input component
+         */
+        readonly view: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb output component
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r output component
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g output component
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b output component
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        isReady(): boolean;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        private _injectVertexCode;
+        private _writeOutput;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Interface used to configure the node material editor
      */
     export interface INodeMaterialEditorOptions {
@@ -51861,7 +51975,7 @@ declare module BABYLON {
          * @param name defines the name of the block to retrieve
          * @returns the required block or null if not found
          */
-        getBlockByName(name: string): NodeMaterialBlock | null;
+        getBlockByName(name: string): Nullable<NodeMaterialBlock>;
         /**
          * Gets the list of input blocks attached to this material
          * @returns an array of InputBlocks
@@ -51948,6 +52062,11 @@ declare module BABYLON {
          */
         getActiveTextures(): BaseTexture[];
         /**
+         * Gets the list of texture blocks
+         * @returns an array of texture blocks
+         */
+        getTextureBlocks(): (TextureBlock | ReflectionTextureBlock)[];
+        /**
          * Specifies if the material uses a texture
          * @param texture defines the texture to check against the material
          * @returns a boolean specifying if the material uses the texture
@@ -51982,6 +52101,7 @@ declare module BABYLON {
          * @returns the serialized material object
          */
         serialize(): any;
+        private _restoreConnections;
         /**
          * Clear the current graph and load a new one from a serialization object
          * @param source defines the JSON representation of the material
@@ -52073,122 +52193,14 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Enum used to define well known values e.g. values automatically provided by the system
-     */
-    export enum NodeMaterialWellKnownValues {
-        /** World */
-        World = 1,
-        /** View */
-        View = 2,
-        /** Projection */
-        Projection = 3,
-        /** ViewProjection */
-        ViewProjection = 4,
-        /** WorldView */
-        WorldView = 5,
-        /** WorldViewProjection */
-        WorldViewProjection = 6,
-        /** CameraPosition */
-        CameraPosition = 7,
-        /** Fog Color */
-        FogColor = 8
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to read a reflection texture from a sampler
-     */
-    export class ReflectionTextureBlock extends NodeMaterialBlock {
-        private _define3DName;
-        private _defineCubicName;
-        private _defineExplicitName;
-        private _defineProjectionName;
-        private _defineLocalCubicName;
-        private _defineSphericalName;
-        private _definePlanarName;
-        private _defineEquirectangularName;
-        private _defineMirroredEquirectangularFixedName;
-        private _defineEquirectangularFixedName;
-        private _defineSkyboxName;
-        private _cubeSamplerName;
-        private _2DSamplerName;
-        private _positionUVWName;
-        private _directionWName;
-        private _reflectionCoordsName;
-        private _reflection2DCoordsName;
-        private _reflectionColorName;
-        private _reflectionMatrixName;
-        /**
-         * Gets or sets the texture associated with the node
-         */
-        texture: Nullable<BaseTexture>;
-        /**
-         * Create a new TextureBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the world position input component
-         */
-        readonly position: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world position input component
-         */
-        readonly worldPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world normal input component
-         */
-        readonly worldNormal: NodeMaterialConnectionPoint;
-        /**
-         * Gets the world input component
-         */
-        readonly world: NodeMaterialConnectionPoint;
-        /**
-        * Gets the camera (or eye) position component
-        */
-        readonly cameraPosition: NodeMaterialConnectionPoint;
-        /**
-         * Gets the view input component
-         */
-        readonly view: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb output component
-         */
-        readonly rgb: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r output component
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g output component
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b output component
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        autoConfigure(): void;
-        prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
-        isReady(): boolean;
-        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
-        private _injectVertexCode;
-        private _writeOutput;
-        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
-        serialize(): any;
-        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
-    }
-}
-declare module BABYLON {
-    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
         /**
+        * Gets the list of emitted varyings
+        */
+        temps: string[];
+        /**
          * Gets the list of emitted varyings
          */
         varyings: string[];
@@ -52203,7 +52215,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
+        textureBlocks: (ReflectionTextureBlock | TextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -52371,6 +52383,8 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
+        _registerTempVariable(name: string): boolean;
+        /** @hidden */
         _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
@@ -52571,7 +52585,7 @@ declare module BABYLON {
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
          * @returns a copy of the current block
          */
-        clone(scene: Scene, rootUrl?: string): NodeMaterialBlock | null;
+        clone(scene: Scene, rootUrl?: string): Nullable<NodeMaterialBlock>;
         /**
          * Serializes this block in a JSON representation
          * @returns the serialized block object
@@ -53006,11 +53020,11 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     * Block used to compute fresnel value
      */
-    export class ColorMergerBlock extends NodeMaterialBlock {
+    export class FresnelBlock extends NodeMaterialBlock {
         /**
-         * Create a new ColorMergerBlock
+         * Create a new FresnelBlock
          * @param name defines the block name
          */
         constructor(name: string);
@@ -53020,176 +53034,31 @@ declare module BABYLON {
          */
         getClassName(): string;
         /**
-         * Gets the r component (input)
+         * Gets the world position input component
          */
-        readonly r: NodeMaterialConnectionPoint;
+        readonly worldPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the g component (input)
+         * Gets the world normal input component
          */
-        readonly g: NodeMaterialConnectionPoint;
+        readonly worldNormal: NodeMaterialConnectionPoint;
         /**
-         * Gets the b component (input)
-         */
-        readonly b: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly cameraPosition: NodeMaterialConnectionPoint;
         /**
-         * Gets the a component (input)
-         */
-        readonly a: NodeMaterialConnectionPoint;
+        * Gets the bias input component
+        */
+        readonly bias: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgba component (output)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
+        * Gets the camera (or eye) position component
+        */
+        readonly power: NodeMaterialConnectionPoint;
         /**
-         * Gets the rgb component (output)
+         * Gets the fresnel output component
          */
-        readonly rgb: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
-     */
-    export class VectorMergerBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorMergerBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the x component (input)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (input)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (input)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (input)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyzw component (output)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyz: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xy: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Color3/4 into 4 outputs (one for each component)
-     */
-    export class ColorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new ColorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the rgba component (input)
-         */
-        readonly rgba: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (input)
-         */
-        readonly rgbIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the rgb component (output)
-         */
-        readonly rgbOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the r component (output)
-         */
-        readonly r: NodeMaterialConnectionPoint;
-        /**
-         * Gets the g component (output)
-         */
-        readonly g: NodeMaterialConnectionPoint;
-        /**
-         * Gets the b component (output)
-         */
-        readonly b: NodeMaterialConnectionPoint;
-        /**
-         * Gets the a component (output)
-         */
-        readonly a: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
-     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
-     */
-    export class VectorSplitterBlock extends NodeMaterialBlock {
-        /**
-         * Create a new VectorSplitterBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the xyzw component (input)
-         */
-        readonly xyzw: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (input)
-         */
-        readonly xyzIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (input)
-         */
-        readonly xyIn: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xyz component (output)
-         */
-        readonly xyzOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the xy component (output)
-         */
-        readonly xyOut: NodeMaterialConnectionPoint;
-        /**
-         * Gets the x component (output)
-         */
-        readonly x: NodeMaterialConnectionPoint;
-        /**
-         * Gets the y component (output)
-         */
-        readonly y: NodeMaterialConnectionPoint;
-        /**
-         * Gets the z component (output)
-         */
-        readonly z: NodeMaterialConnectionPoint;
-        /**
-         * Gets the w component (output)
-         */
-        readonly w: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
+        readonly fresnel: NodeMaterialConnectionPoint;
+        autoConfigure(): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
     }
 }
 declare module BABYLON {
@@ -53602,6 +53471,194 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to create a Color3/4 out of individual inputs (one for each component)
+     */
+    export class ColorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the r component (input)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (input)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (input)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (input)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgba component (output)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgb: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
+     */
+    export class VectorMergerBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorMergerBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the x component (input)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (input)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (input)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (input)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyzw component (output)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyz: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Color3/4 into 4 outputs (one for each component)
+     */
+    export class ColorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new ColorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the rgba component (input)
+         */
+        readonly rgba: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (input)
+         */
+        readonly rgbIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the rgb component (output)
+         */
+        readonly rgbOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the r component (output)
+         */
+        readonly r: NodeMaterialConnectionPoint;
+        /**
+         * Gets the g component (output)
+         */
+        readonly g: NodeMaterialConnectionPoint;
+        /**
+         * Gets the b component (output)
+         */
+        readonly b: NodeMaterialConnectionPoint;
+        /**
+         * Gets the a component (output)
+         */
+        readonly a: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to expand a Vector3/4 into 4 outputs (one for each component)
+     */
+    export class VectorSplitterBlock extends NodeMaterialBlock {
+        /**
+         * Create a new VectorSplitterBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the xyzw component (input)
+         */
+        readonly xyzw: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (input)
+         */
+        readonly xyzIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (input)
+         */
+        readonly xyIn: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xyz component (output)
+         */
+        readonly xyzOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the xy component (output)
+         */
+        readonly xyOut: NodeMaterialConnectionPoint;
+        /**
+         * Gets the x component (output)
+         */
+        readonly x: NodeMaterialConnectionPoint;
+        /**
+         * Gets the y component (output)
+         */
+        readonly y: NodeMaterialConnectionPoint;
+        /**
+         * Gets the z component (output)
+         */
+        readonly z: NodeMaterialConnectionPoint;
+        /**
+         * Gets the w component (output)
+         */
+        readonly w: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

Разлика између датотеке није приказан због своје велике величине
+ 6 - 6
dist/preview release/inspector/babylon.inspector.bundle.js


+ 119 - 32
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -36514,6 +36514,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _propertyGrids_lights_spotLightPropertyGridComponent__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./propertyGrids/lights/spotLightPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/lights/spotLightPropertyGridComponent.tsx");
 /* harmony import */ var _propertyGrids_postProcesses_lensRenderingPipelinePropertyGridComponent__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ./propertyGrids/postProcesses/lensRenderingPipelinePropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/postProcesses/lensRenderingPipelinePropertyGridComponent.tsx");
 /* harmony import */ var _propertyGrids_materials_nodeMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ./propertyGrids/materials/nodeMaterialPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx");
+/* harmony import */ var _propertyGrids_materials_multiMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ./propertyGrids/materials/multiMaterialPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent.tsx");
+
 
 
 
@@ -36624,6 +36626,10 @@ var PropertyGridTabComponent = /** @class */ (function (_super) {
                 var transformNode = entity;
                 return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyGrids_meshes_transformNodePropertyGridComponent__WEBPACK_IMPORTED_MODULE_13__["TransformNodePropertyGridComponent"], { transformNode: transformNode, globalState: this.props.globalState, lockObject: this._lockObject, onPropertyChangedObservable: this.props.onPropertyChangedObservable }));
             }
+            if (className === "MultiMaterial") {
+                var material = entity;
+                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyGrids_materials_multiMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_45__["MultiMaterialPropertyGridComponent"], { globalState: this.props.globalState, material: material, lockObject: this._lockObject, onSelectionChangedObservable: this.props.onSelectionChangedObservable, onPropertyChangedObservable: this.props.onPropertyChangedObservable }));
+            }
             if (className === "StandardMaterial") {
                 var material = entity;
                 return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyGrids_materials_standardMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_4__["StandardMaterialPropertyGridComponent"], { globalState: this.props.globalState, material: material, lockObject: this._lockObject, onSelectionChangedObservable: this.props.onSelectionChangedObservable, onPropertyChangedObservable: this.props.onPropertyChangedObservable }));
@@ -38814,6 +38820,61 @@ var MaterialPropertyGridComponent = /** @class */ (function (_super) {
 
 /***/ }),
 
+/***/ "./components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent.tsx":
+/*!***************************************************************************************************!*\
+  !*** ./components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent.tsx ***!
+  \***************************************************************************************************/
+/*! exports provided: MultiMaterialPropertyGridComponent */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiMaterialPropertyGridComponent", function() { return MultiMaterialPropertyGridComponent; });
+/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
+/* harmony import */ var _commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./commonMaterialPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx");
+/* harmony import */ var _lines_textLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../lines/textLineComponent */ "./components/actionTabs/lines/textLineComponent.tsx");
+
+
+
+
+
+var MultiMaterialPropertyGridComponent = /** @class */ (function (_super) {
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MultiMaterialPropertyGridComponent, _super);
+    function MultiMaterialPropertyGridComponent(props) {
+        return _super.call(this, props) || this;
+    }
+    MultiMaterialPropertyGridComponent.prototype.onMaterialLink = function (mat) {
+        if (!this.props.onSelectionChangedObservable) {
+            return;
+        }
+        this.props.onSelectionChangedObservable.notifyObservers(mat);
+    };
+    MultiMaterialPropertyGridComponent.prototype.renderChildMaterial = function () {
+        var _this = this;
+        var material = this.props.material;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "CHILDREN" }, material.subMaterials.map(function (mat, i) {
+            if (mat) {
+                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_4__["TextLineComponent"], { key: "Material #" + i, label: "Material #" + i, value: mat.name, onLink: function () { return _this.onMaterialLink(mat); } }));
+            }
+            return null;
+        })));
+    };
+    MultiMaterialPropertyGridComponent.prototype.render = function () {
+        var material = this.props.material;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "pane" },
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_3__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+            this.renderChildMaterial()));
+    };
+    return MultiMaterialPropertyGridComponent;
+}(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
+
+
+
+/***/ }),
+
 /***/ "./components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx":
 /*!**************************************************************************************************!*\
   !*** ./components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx ***!
@@ -38827,17 +38888,20 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
-/* harmony import */ var _commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./commonMaterialPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx");
-/* harmony import */ var _lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../lines/buttonLineComponent */ "./components/actionTabs/lines/buttonLineComponent.tsx");
-/* harmony import */ var _lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/checkBoxLineComponent */ "./components/actionTabs/lines/checkBoxLineComponent.tsx");
-/* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
-/* harmony import */ var _lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../lines/color3LineComponent */ "./components/actionTabs/lines/color3LineComponent.tsx");
-/* harmony import */ var _lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../lines/vector3LineComponent */ "./components/actionTabs/lines/vector3LineComponent.tsx");
-/* harmony import */ var _lines_vector4LineComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../lines/vector4LineComponent */ "./components/actionTabs/lines/vector4LineComponent.tsx");
-/* harmony import */ var _lines_vector2LineComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../lines/vector2LineComponent */ "./components/actionTabs/lines/vector2LineComponent.tsx");
-/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
-/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__);
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
+/* harmony import */ var _commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./commonMaterialPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx");
+/* harmony import */ var _lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/buttonLineComponent */ "./components/actionTabs/lines/buttonLineComponent.tsx");
+/* harmony import */ var _lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/checkBoxLineComponent */ "./components/actionTabs/lines/checkBoxLineComponent.tsx");
+/* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
+/* harmony import */ var _lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../lines/color3LineComponent */ "./components/actionTabs/lines/color3LineComponent.tsx");
+/* harmony import */ var _lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../lines/vector3LineComponent */ "./components/actionTabs/lines/vector3LineComponent.tsx");
+/* harmony import */ var _lines_vector4LineComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../lines/vector4LineComponent */ "./components/actionTabs/lines/vector4LineComponent.tsx");
+/* harmony import */ var _lines_vector2LineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../lines/vector2LineComponent */ "./components/actionTabs/lines/vector2LineComponent.tsx");
+/* harmony import */ var _lines_textureLinkLineComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../lines/textureLinkLineComponent */ "./components/actionTabs/lines/textureLinkLineComponent.tsx");
+
+
 
 
 
@@ -38853,11 +38917,25 @@ __webpack_require__.r(__webpack_exports__);
 var NodeMaterialPropertyGridComponent = /** @class */ (function (_super) {
     tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NodeMaterialPropertyGridComponent, _super);
     function NodeMaterialPropertyGridComponent(props) {
-        return _super.call(this, props) || this;
+        var _this = _super.call(this, props) || this;
+        _this._onDebugSelectionChangeObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
+        return _this;
     }
     NodeMaterialPropertyGridComponent.prototype.edit = function () {
         this.props.material.edit();
     };
+    NodeMaterialPropertyGridComponent.prototype.renderTextures = function () {
+        var _this = this;
+        var material = this.props.material;
+        var onDebugSelectionChangeObservable = this._onDebugSelectionChangeObservable;
+        var textureBlocks = material.getTextureBlocks();
+        if (!textureBlocks || textureBlocks.length === 0) {
+            return null;
+        }
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "TEXTURES" }, textureBlocks.map(function (textureBlock, i) {
+            return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textureLinkLineComponent__WEBPACK_IMPORTED_MODULE_12__["TextureLinkLineComponent"], { label: textureBlock.name, key: textureBlock.texture.uniqueId + i, texture: textureBlock.texture, material: material, onSelectionChangedObservable: _this.props.onSelectionChangedObservable, onDebugSelectionChangeObservable: onDebugSelectionChangeObservable }));
+        })));
+    };
     NodeMaterialPropertyGridComponent.prototype.renderInputValues = function () {
         var _this = this;
         var configurableInputBlocks = this.props.material.getInputBlocks().filter(function (block) {
@@ -38865,19 +38943,22 @@ var NodeMaterialPropertyGridComponent = /** @class */ (function (_super) {
         }).sort(function (a, b) {
             return a.name.localeCompare(b.name);
         });
-        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](react__WEBPACK_IMPORTED_MODULE_1__["Fragment"], null, configurableInputBlocks.map(function (block) {
+        if (configurableInputBlocks.length === 0) {
+            return null;
+        }
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "INPUTS" }, configurableInputBlocks.map(function (block) {
             switch (block.type) {
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Float:
-                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_6__["FloatLineComponent"], { key: block.name, lockObject: _this.props.lockObject, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Color3:
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Color4:
-                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_7__["Color3LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Vector2:
-                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector2LineComponent__WEBPACK_IMPORTED_MODULE_10__["Vector2LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Vector3:
-                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_8__["Vector3LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
-                case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_11__["NodeMaterialBlockConnectionPointTypes"].Vector4:
-                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector4LineComponent__WEBPACK_IMPORTED_MODULE_9__["Vector4LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float:
+                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_7__["FloatLineComponent"], { key: block.name, lockObject: _this.props.lockObject, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3:
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4:
+                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_8__["Color3LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
+                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector2LineComponent__WEBPACK_IMPORTED_MODULE_11__["Vector2LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3:
+                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector3LineComponent__WEBPACK_IMPORTED_MODULE_9__["Vector3LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
+                case babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4:
+                    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_vector4LineComponent__WEBPACK_IMPORTED_MODULE_10__["Vector4LineComponent"], { key: block.name, label: block.name, target: block, propertyName: "value", onPropertyChangedObservable: _this.props.onPropertyChangedObservable }));
             }
             return null;
         })));
@@ -38886,11 +38967,12 @@ var NodeMaterialPropertyGridComponent = /** @class */ (function (_super) {
         var _this = this;
         var material = this.props.material;
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "pane" },
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_3__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "CONFIGURATION" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_5__["CheckBoxLineComponent"], { label: "Ignore alpha", target: material, propertyName: "ignoreAlpha", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_4__["ButtonLineComponent"], { label: "Edit", onClick: function () { return _this.edit(); } })),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "INPUTS" }, this.renderInputValues())));
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_commonMaterialPropertyGridComponent__WEBPACK_IMPORTED_MODULE_4__["CommonMaterialPropertyGridComponent"], { globalState: this.props.globalState, lockObject: this.props.lockObject, material: material, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { globalState: this.props.globalState, title: "CONFIGURATION" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_6__["CheckBoxLineComponent"], { label: "Ignore alpha", target: material, propertyName: "ignoreAlpha", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_5__["ButtonLineComponent"], { label: "Edit", onClick: function () { return _this.edit(); } })),
+            this.renderInputValues(),
+            this.renderTextures()));
     };
     return NodeMaterialPropertyGridComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -43000,13 +43082,18 @@ var SceneExplorerComponent = /** @class */ (function (_super) {
                 _this.props.globalState.onSelectionChangedObservable.notifyObservers(newFreeCamera);
             }
         });
+        var materials = [];
+        materials.push.apply(materials, scene.materials);
+        if (scene.multiMaterials && scene.multiMaterials.length) {
+            materials.push.apply(materials, scene.multiMaterials);
+        }
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { id: "tree", onContextMenu: function (e) { return e.preventDefault(); } },
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](SceneExplorerFilterComponent, { onFilter: function (filter) { return _this.filterContent(filter); } }),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_entities_sceneTreeItemComponent__WEBPACK_IMPORTED_MODULE_6__["SceneTreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, scene: scene, onRefresh: function () { return _this.forceUpdate(); }, onSelectionChangedObservable: this.props.globalState.onSelectionChangedObservable }),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, contextMenuItems: nodeContextMenus, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.rootNodes, label: "Nodes", offset: 1, filter: this.state.filter }),
             scene.skeletons.length > 0 &&
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.skeletons, label: "Skeletons", offset: 1, filter: this.state.filter }),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.materials, label: "Materials", offset: 1, filter: this.state.filter }),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: materials, label: "Materials", offset: 1, filter: this.state.filter }),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: textures, label: "Textures", offset: 1, filter: this.state.filter }),
             postProcessses.length > 0 &&
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_3__["TreeItemComponent"], { globalState: this.props.globalState, extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: postProcessses, label: "Post-processes", offset: 1, filter: this.state.filter }),
@@ -43339,7 +43426,7 @@ var TreeItemSelectableComponent = /** @class */ (function (_super) {
         };
         var entity = this.props.entity;
         var chevron = this.state.isExpanded ? react__WEBPACK_IMPORTED_MODULE_6__["createElement"](_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_2__["FontAwesomeIcon"], { icon: _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_3__["faMinus"] }) : react__WEBPACK_IMPORTED_MODULE_6__["createElement"](_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_2__["FontAwesomeIcon"], { icon: _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_3__["faPlus"] });
-        var children = _tools__WEBPACK_IMPORTED_MODULE_4__["Tools"].SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
+        var children = entity.getClassName() === "MultiMaterial" ? [] : _tools__WEBPACK_IMPORTED_MODULE_4__["Tools"].SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
         var hasChildren = children.length > 0;
         if (!entity.reservedDataStore) {
             entity.reservedDataStore = {};
@@ -44004,7 +44091,7 @@ var Tools = /** @class */ (function () {
             return true;
         }
         var children = item.getChildren ? item.getChildren() : item.children;
-        if (children) {
+        if (children && item.getClassName() !== "MultiMaterial") {
             for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                 var child = children_1[_i];
                 if (Tools.LookForItem(child, selectedEntity)) {

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 18 - 1
dist/preview release/inspector/babylon.inspector.d.ts

@@ -1291,9 +1291,26 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
     }
     export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
+        private _onDebugSelectionChangeObservable;
         constructor(props: INodeMaterialPropertyGridComponentProps);
         edit(): void;
-        renderInputValues(): JSX.Element;
+        renderTextures(): JSX.Element | null;
+        renderInputValues(): JSX.Element | null;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IMultiMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
+        material: BABYLON.MultiMaterial;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class MultiMaterialPropertyGridComponent extends React.Component<IMultiMaterialPropertyGridComponentProps> {
+        constructor(props: IMultiMaterialPropertyGridComponentProps);
+        onMaterialLink(mat: BABYLON.Material): void;
+        renderChildMaterial(): JSX.Element;
         render(): JSX.Element;
     }
 }

+ 43 - 2
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -1679,9 +1679,33 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
     }
     export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
+        private _onDebugSelectionChangeObservable;
         constructor(props: INodeMaterialPropertyGridComponentProps);
         edit(): void;
-        renderInputValues(): JSX.Element;
+        renderTextures(): JSX.Element | null;
+        renderInputValues(): JSX.Element | null;
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent" {
+    import * as React from "react";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
+    import { GlobalState } from "babylonjs-inspector/components/globalState";
+    import { Material } from 'babylonjs/Materials/material';
+    import { MultiMaterial } from 'babylonjs/Materials/multiMaterial';
+    interface IMultiMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
+        material: MultiMaterial;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: Observable<any>;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    }
+    export class MultiMaterialPropertyGridComponent extends React.Component<IMultiMaterialPropertyGridComponentProps> {
+        constructor(props: IMultiMaterialPropertyGridComponentProps);
+        onMaterialLink(mat: Material): void;
+        renderChildMaterial(): JSX.Element;
         render(): JSX.Element;
     }
 }
@@ -3584,9 +3608,26 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
     }
     export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
+        private _onDebugSelectionChangeObservable;
         constructor(props: INodeMaterialPropertyGridComponentProps);
         edit(): void;
-        renderInputValues(): JSX.Element;
+        renderTextures(): JSX.Element | null;
+        renderInputValues(): JSX.Element | null;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IMultiMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
+        material: BABYLON.MultiMaterial;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class MultiMaterialPropertyGridComponent extends React.Component<IMultiMaterialPropertyGridComponentProps> {
+        constructor(props: IMultiMaterialPropertyGridComponentProps);
+        onMaterialLink(mat: BABYLON.Material): void;
+        renderChildMaterial(): JSX.Element;
         render(): JSX.Element;
     }
 }

+ 2 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -2031,6 +2031,7 @@ var GLTFLoader = /** @class */ (function () {
         else {
             var promises = new Array();
             var babylonMesh_1 = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, this._babylonScene);
+            babylonMesh_1.overrideMaterialSideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh_1);
             promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh_1).then(function (babylonGeometry) {
                 return _this._loadMorphTargetsAsync(context, primitive, babylonMesh_1, babylonGeometry).then(function () {
@@ -2811,7 +2812,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     GLTFLoader.prototype._createDefaultMaterial = function (name, babylonDrawMode) {
         var babylonMaterial = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["PBRMaterial"](name, this._babylonScene);
-        babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
+        // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
         babylonMaterial.fillMode = babylonDrawMode;
         babylonMaterial.enableSpecularAntiAliasing = true;
         babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 2 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -4591,6 +4591,7 @@ var GLTFLoader = /** @class */ (function () {
         else {
             var promises = new Array();
             var babylonMesh_1 = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, this._babylonScene);
+            babylonMesh_1.overrideMaterialSideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh_1);
             promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh_1).then(function (babylonGeometry) {
                 return _this._loadMorphTargetsAsync(context, primitive, babylonMesh_1, babylonGeometry).then(function () {
@@ -5371,7 +5372,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     GLTFLoader.prototype._createDefaultMaterial = function (name, babylonDrawMode) {
         var babylonMaterial = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["PBRMaterial"](name, this._babylonScene);
-        babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
+        // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
         babylonMaterial.fillMode = babylonDrawMode;
         babylonMaterial.enableSpecularAntiAliasing = true;
         babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 2 - 1
dist/preview release/loaders/babylonjs.loaders.js

@@ -5933,6 +5933,7 @@ var GLTFLoader = /** @class */ (function () {
         else {
             var promises = new Array();
             var babylonMesh_1 = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, this._babylonScene);
+            babylonMesh_1.overrideMaterialSideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh_1);
             promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh_1).then(function (babylonGeometry) {
                 return _this._loadMorphTargetsAsync(context, primitive, babylonMesh_1, babylonGeometry).then(function () {
@@ -6713,7 +6714,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     GLTFLoader.prototype._createDefaultMaterial = function (name, babylonDrawMode) {
         var babylonMaterial = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["PBRMaterial"](name, this._babylonScene);
-        babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Material"].ClockWiseSideOrientation;
+        // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
         babylonMaterial.fillMode = babylonDrawMode;
         babylonMaterial.enableSpecularAntiAliasing = true;
         babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


Разлика између датотеке није приказан због своје велике величине
+ 3 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 86 - 69
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -62141,6 +62141,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 var BlockTools = /** @class */ (function () {
     function BlockTools() {
     }
@@ -62196,6 +62197,8 @@ var BlockTools = /** @class */ (function () {
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["RemapBlock"]("Remap");
             case "NormalizeBlock":
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["NormalizeBlock"]("Normalize");
+            case "FresnelBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["FresnelBlock"]("Fresnel");
         }
         return null;
     };
@@ -62697,16 +62700,16 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _propertyTab_properties_vector2PropertyTabComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../propertyTab/properties/vector2PropertyTabComponent */ "./components/propertyTab/properties/vector2PropertyTabComponent.tsx");
 /* harmony import */ var _propertyTab_properties_vector3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../propertyTab/properties/vector3PropertyTabComponent */ "./components/propertyTab/properties/vector3PropertyTabComponent.tsx");
-/* harmony import */ var _sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../sharedComponents/checkBoxLineComponent */ "./sharedComponents/checkBoxLineComponent.tsx");
-/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
-/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var _sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../sharedComponents/optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
-/* harmony import */ var _sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../sharedComponents/textLineComponent */ "./sharedComponents/textLineComponent.tsx");
-/* harmony import */ var _propertyTab_properties_color3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../propertyTab/properties/color3PropertyTabComponent */ "./components/propertyTab/properties/color3PropertyTabComponent.tsx");
-/* harmony import */ var _propertyTab_properties_floatPropertyTabComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../propertyTab/properties/floatPropertyTabComponent */ "./components/propertyTab/properties/floatPropertyTabComponent.tsx");
-/* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
-/* harmony import */ var _stringTools__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../stringTools */ "./stringTools.ts");
-/* harmony import */ var _sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../sharedComponents/textInputLineComponent */ "./sharedComponents/textInputLineComponent.tsx");
+/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
+/* harmony import */ var babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__);
+/* harmony import */ var _sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../sharedComponents/optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
+/* harmony import */ var _sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../sharedComponents/textLineComponent */ "./sharedComponents/textLineComponent.tsx");
+/* harmony import */ var _propertyTab_properties_color3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../propertyTab/properties/color3PropertyTabComponent */ "./components/propertyTab/properties/color3PropertyTabComponent.tsx");
+/* harmony import */ var _propertyTab_properties_floatPropertyTabComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../propertyTab/properties/floatPropertyTabComponent */ "./components/propertyTab/properties/floatPropertyTabComponent.tsx");
+/* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
+/* harmony import */ var _stringTools__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../stringTools */ "./stringTools.ts");
+/* harmony import */ var _sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../sharedComponents/textInputLineComponent */ "./sharedComponents/textInputLineComponent.tsx");
+/* harmony import */ var _sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../sharedComponents/checkBoxLineComponent */ "./sharedComponents/checkBoxLineComponent.tsx");
 
 
 
@@ -62730,14 +62733,14 @@ var InputPropertyTabComponentProps = /** @class */ (function (_super) {
     InputPropertyTabComponentProps.prototype.renderValue = function (globalState) {
         var inputBlock = this.props.inputNode.inputBlock;
         switch (inputBlock.type) {
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Float:
-                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_floatPropertyTabComponent__WEBPACK_IMPORTED_MODULE_9__["FloatPropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Vector2:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Float:
+                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_floatPropertyTabComponent__WEBPACK_IMPORTED_MODULE_8__["FloatPropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                 return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_vector2PropertyTabComponent__WEBPACK_IMPORTED_MODULE_2__["Vector2PropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Color3:
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Color4:
-                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_color3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_8__["Color3PropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Vector3:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Color3:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Color4:
+                return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_color3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_7__["Color3PropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                 return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_propertyTab_properties_vector3PropertyTabComponent__WEBPACK_IMPORTED_MODULE_3__["Vector3PropertyTabComponent"], { globalState: globalState, inputBlock: inputBlock }));
         }
         return null;
@@ -62753,41 +62756,41 @@ var InputPropertyTabComponentProps = /** @class */ (function (_super) {
         var attributeOptions = [];
         var animationOptions = [];
         switch (inputBlock.type) {
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Float:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Float:
                 animationOptions = [
-                    { label: "None", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["AnimatedInputBlockTypes"].None },
-                    { label: "Time", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["AnimatedInputBlockTypes"].Time },
+                    { label: "None", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["AnimatedInputBlockTypes"].None },
+                    { label: "Time", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["AnimatedInputBlockTypes"].Time },
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Matrix:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Matrix:
                 wellKnownOptions = [
-                    { label: "World", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].World },
-                    { label: "WorldxView", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].WorldView },
-                    { label: "WorldxViewxProjection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].WorldViewProjection },
-                    { label: "View", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].View },
-                    { label: "ViewxProjection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].ViewProjection },
-                    { label: "Projection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].Projection }
+                    { label: "World", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].World },
+                    { label: "WorldxView", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].WorldView },
+                    { label: "WorldxViewxProjection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].WorldViewProjection },
+                    { label: "View", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].View },
+                    { label: "ViewxProjection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].ViewProjection },
+                    { label: "Projection", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].Projection }
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Color3:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Color3:
                 wellKnownOptions = [
-                    { label: "Fog color", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].FogColor }
+                    { label: "Fog color", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].FogColor }
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Color3:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Color3:
                 attributeOptions = [
                     { label: "color", value: "color" }
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Vector2:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                 attributeOptions = [
                     { label: "uv", value: "uv" },
                     { label: "uv2", value: "uv2" },
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Vector3:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                 wellKnownOptions = [
-                    { label: "Camera position", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialWellKnownValues"].CameraPosition }
+                    { label: "Camera position", value: babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialWellKnownValues"].CameraPosition }
                 ];
                 attributeOptions = [
                     { label: "position", value: "position" },
@@ -62795,57 +62798,69 @@ var InputPropertyTabComponentProps = /** @class */ (function (_super) {
                     { label: "tangent", value: "tangent" },
                 ];
                 break;
-            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBlockConnectionPointTypes"].Vector4:
+            case babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockConnectionPointTypes"].Vector4:
                 attributeOptions = [
                     { label: "matricesIndices", value: "matricesIndices" },
                     { label: "matricesWeights", value: "matricesWeights" }
                 ];
                 break;
         }
+        var modeOptions = [
+            { label: "User-defined", value: 0 }
+        ];
+        if (attributeOptions.length > 0) {
+            modeOptions.push({ label: "Mesh attribute", value: 1 });
+        }
+        if (wellKnownOptions.length > 0) {
+            modeOptions.push({ label: "Well-known value", value: 2 });
+        }
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", null,
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_10__["LineContainerComponent"], { title: "GENERAL" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_12__["TextInputLineComponent"], { label: "Name", propertyName: "name", target: inputBlock, onChange: function () { return _this.props.globalState.onUpdateRequiredObservable.notifyObservers(); } }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_7__["TextLineComponent"], { label: "Type", value: _stringTools__WEBPACK_IMPORTED_MODULE_11__["StringTools"].GetBaseType(inputBlock.type) })),
-            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_10__["LineContainerComponent"], { title: "PROPERTIES" },
-                attributeOptions.length > 0 &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_4__["CheckBoxLineComponent"], { label: "Is mesh attribute", onSelect: function (value) {
-                            if (!value) {
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_9__["LineContainerComponent"], { title: "GENERAL" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_11__["TextInputLineComponent"], { label: "Name", propertyName: "name", target: inputBlock, onChange: function () { return _this.props.globalState.onUpdateRequiredObservable.notifyObservers(); } }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_6__["TextLineComponent"], { label: "Type", value: _stringTools__WEBPACK_IMPORTED_MODULE_10__["StringTools"].GetBaseType(inputBlock.type) })),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_9__["LineContainerComponent"], { title: "PROPERTIES" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Mode", options: modeOptions, target: inputBlock, noDirectUpdate: true, getSelection: function (block) {
+                        if (block.isAttribute) {
+                            return 1;
+                        }
+                        if (block.isWellKnownValue) {
+                            return 2;
+                        }
+                        return 0;
+                    }, onSelect: function (value) {
+                        switch (value) {
+                            case 0:
                                 inputBlock.isUniform = true;
+                                inputBlock.setAsWellKnownValue(null);
                                 _this.setDefaultValue();
-                            }
-                            else {
+                                break;
+                            case 1:
                                 inputBlock.setAsAttribute(attributeOptions[0].value);
-                            }
-                            _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
-                            _this.forceUpdate();
-                        }, isSelected: function () { return inputBlock.isAttribute; } }),
+                                break;
+                            case 2:
+                                inputBlock.setAsWellKnownValue(wellKnownOptions[0].value);
+                                break;
+                        }
+                        _this.forceUpdate();
+                        _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+                    } }),
                 inputBlock.isAttribute &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_6__["OptionsLineComponent"], { label: "Attribute", valuesAreStrings: true, options: attributeOptions, target: inputBlock, propertyName: "name", onSelect: function (value) {
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Attribute", valuesAreStrings: true, options: attributeOptions, target: inputBlock, propertyName: "name", onSelect: function (value) {
                             inputBlock.setAsAttribute(value);
                             _this.forceUpdate();
                             _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         } }),
-                inputBlock.isUniform && wellKnownOptions.length > 0 &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_4__["CheckBoxLineComponent"], { label: "Is well known value", onSelect: function (value) {
-                            if (value) {
-                                inputBlock.setAsWellKnownValue(wellKnownOptions[0].value);
-                            }
-                            else {
-                                inputBlock.setAsWellKnownValue(null);
-                                _this.setDefaultValue();
-                            }
-                            _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
-                            _this.forceUpdate();
-                        }, isSelected: function () { return inputBlock.isWellKnownValue; } }),
                 inputBlock.isUniform && animationOptions.length > 0 &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_6__["OptionsLineComponent"], { label: "Animation type", options: animationOptions, target: inputBlock, propertyName: "animationType", onSelect: function (value) {
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Animation type", options: animationOptions, target: inputBlock, propertyName: "animationType", onSelect: function (value) {
                             _this.forceUpdate();
                             _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         } }),
-                inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_5__["AnimatedInputBlockTypes"].None &&
+                inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["AnimatedInputBlockTypes"].None &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_12__["CheckBoxLineComponent"], { label: "Visible in the Inspector", target: inputBlock, propertyName: "visibleInInspector" }),
+                inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === babylonjs_Materials_Node_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_4__["AnimatedInputBlockTypes"].None &&
                     this.renderValue(this.props.globalState),
                 inputBlock.isUniform && inputBlock.isWellKnownValue &&
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_6__["OptionsLineComponent"], { label: "Well known value", options: wellKnownOptions, target: inputBlock, propertyName: "wellKnownValue", onSelect: function (value) {
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Well known value", options: wellKnownOptions, target: inputBlock, propertyName: "wellKnownValue", onSelect: function (value) {
                             inputBlock.setAsWellKnownValue(value);
                             _this.forceUpdate();
                             _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
@@ -63945,7 +63960,6 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-
 var TexturePropertyTabComponent = /** @class */ (function (_super) {
     tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TexturePropertyTabComponent, _super);
     function TexturePropertyTabComponent() {
@@ -63966,7 +63980,7 @@ var TexturePropertyTabComponent = /** @class */ (function (_super) {
         }
         var texture = this.props.node.texture;
         if (!texture) {
-            this.props.node.texture = new babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Texture"](null, babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Engine"].LastCreatedScene);
+            this.props.node.texture = new babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Texture"](null, this.props.globalState.nodeMaterial.getScene(), false, false);
             texture = this.props.node.texture;
         }
         babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].ReadFile(file, function (data) {
@@ -64380,7 +64394,7 @@ var NodeListComponent = /** @class */ (function (_super) {
         // Block types used to create the menu from
         var allBlocks = {
             Vertex: ["BonesBlock", "InstancesBlock", "MorphTargetsBlock"],
-            Fragment: ["AlphaTestBlock", "FogBlock", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "TextureBlock"],
+            Fragment: ["AlphaTestBlock", "FogBlock", "Fresnel", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "TextureBlock"],
             Outputs: ["VertexOutputBlock", "FragmentOutputBlock"],
             Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "RemapBlock", "NormalizeBlock", "ScaleBlock", "TransformBlock", "TrigonometryBlock"],
             Conversion: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
@@ -64822,8 +64836,8 @@ var PropertyTabComponent = /** @class */ (function (_super) {
             }
             serializationObject.locations.push({
                 blockId: block.uniqueId,
-                x: node.x,
-                y: node.y
+                x: node ? node.x : 0,
+                y: node ? node.y : 0
             });
         }
         // Output
@@ -66340,7 +66354,10 @@ var OptionsLineComponent = /** @class */ (function (_super) {
         return _this;
     }
     OptionsLineComponent.prototype._getValue = function (props) {
-        return props.target ? props.target[props.propertyName] : props.options[props.defaultIfNull || 0];
+        if (props.getSelection) {
+            return props.getSelection(props.target);
+        }
+        return (props.target && props.propertyName) ? props.target[props.propertyName] : props.options[props.defaultIfNull || 0];
     };
     OptionsLineComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
         if (this._localChange) {

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


Разлика између датотеке није приказан због своје велике величине
+ 7 - 4
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


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

@@ -1 +1 @@
-{"engineOnly":166895,"sceneOnly":507199,"minGridMaterial":636659,"minStandardMaterial":765860}
+{"engineOnly":167205,"sceneOnly":507509,"minGridMaterial":636969,"minStandardMaterial":766170}

Разлика између датотеке није приказан због своје велике величине
+ 704 - 584
dist/preview release/viewer/babylon.module.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 20 - 16
dist/preview release/viewer/babylon.viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 12 - 0
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -87,6 +87,8 @@ import { LensRenderingPipeline } from 'babylonjs/PostProcesses/RenderPipeline/Pi
 import { LensRenderingPipelinePropertyGridComponent } from './propertyGrids/postProcesses/lensRenderingPipelinePropertyGridComponent';
 import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
 import { NodeMaterialPropertyGridComponent } from './propertyGrids/materials/nodeMaterialPropertyGridComponent';
+import { MultiMaterial } from 'babylonjs/Materials/multiMaterial';
+import { MultiMaterialPropertyGridComponent } from './propertyGrids/materials/multiMaterialPropertyGridComponent';
 
 export class PropertyGridTabComponent extends PaneComponent {
     private _timerIntervalId: number;
@@ -205,6 +207,16 @@ export class PropertyGridTabComponent extends PaneComponent {
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
 
+            if (className === "MultiMaterial") {
+                const material = entity as MultiMaterial;
+                return (<MultiMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
+                    material={material}
+                    lockObject={this._lockObject}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
             if (className === "StandardMaterial") {
                 const material = entity as StandardMaterial;
                 return (<StandardMaterialPropertyGridComponent

+ 64 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/multiMaterialPropertyGridComponent.tsx

@@ -0,0 +1,64 @@
+import * as React from "react";
+
+import { Observable } from "babylonjs/Misc/observable";
+
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { CommonMaterialPropertyGridComponent } from "./commonMaterialPropertyGridComponent";
+import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
+import { TextLineComponent } from '../../../lines/textLineComponent';
+import { Material } from 'babylonjs/Materials/material';
+import { MultiMaterial } from 'babylonjs/Materials/multiMaterial';
+
+interface IMultiMaterialPropertyGridComponentProps {
+    globalState: GlobalState;
+    material: MultiMaterial;
+    lockObject: LockObject;
+    onSelectionChangedObservable?: Observable<any>;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+}
+
+export class MultiMaterialPropertyGridComponent extends React.Component<IMultiMaterialPropertyGridComponentProps> {
+    constructor(props: IMultiMaterialPropertyGridComponentProps) {
+        super(props);
+    }
+
+    onMaterialLink(mat: Material) {
+        if (!this.props.onSelectionChangedObservable) {
+            return;
+        }
+
+        this.props.onSelectionChangedObservable.notifyObservers(mat);
+    }
+
+    renderChildMaterial() {
+        const material = this.props.material;
+
+        return (
+            <LineContainerComponent globalState={this.props.globalState} title="CHILDREN">
+                {
+                    material.subMaterials.map((mat, i) => {
+                        if (mat) {
+                            return (
+                                <TextLineComponent key={"Material #" + i} label={"Material #" + i} value={mat.name} onLink={() => this.onMaterialLink(mat)} />
+                            )
+                        }
+                        return null;                        
+                    })
+                }
+            </LineContainerComponent>
+        );
+    }
+
+    render() {
+        const material = this.props.material;
+
+        return (
+            <div className="pane">
+                <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                {this.renderChildMaterial()}
+            </div>
+        );
+    }
+}

+ 41 - 8
inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx

@@ -16,6 +16,8 @@ import { Vector3LineComponent } from '../../../lines/vector3LineComponent';
 import { Vector4LineComponent } from '../../../lines/vector4LineComponent';
 import { Vector2LineComponent } from '../../../lines/vector2LineComponent';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
+import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
+import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
 
 interface INodeMaterialPropertyGridComponentProps {
     globalState: GlobalState;
@@ -26,6 +28,8 @@ interface INodeMaterialPropertyGridComponentProps {
 }
 
 export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
+    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    
     constructor(props: INodeMaterialPropertyGridComponentProps) {
         super(props);
     }
@@ -34,6 +38,30 @@ export class NodeMaterialPropertyGridComponent extends React.Component<INodeMate
         this.props.material.edit();
     }
 
+    renderTextures() {
+        const material = this.props.material;
+
+        const onDebugSelectionChangeObservable = this._onDebugSelectionChangeObservable;
+
+        let textureBlocks = material.getTextureBlocks();
+
+        if (!textureBlocks || textureBlocks.length === 0) {
+            return null;
+        }
+
+        return (
+            <LineContainerComponent globalState={this.props.globalState} title="TEXTURES">
+                {
+                    textureBlocks.map((textureBlock, i) => {
+                        return (
+                            <TextureLinkLineComponent label={textureBlock.name} key={textureBlock.texture!.uniqueId + i} texture={textureBlock.texture} material={material} onSelectionChangedObservable={this.props.onSelectionChangedObservable} onDebugSelectionChangeObservable={onDebugSelectionChangeObservable} />
+                        )
+                    })
+                }
+               </LineContainerComponent>
+        );
+    }
+
     renderInputValues() {
         let configurableInputBlocks = this.props.material.getInputBlocks().filter(block => {
             return block.visibleInInspector && block.isUniform && !block.isWellKnownValue
@@ -41,8 +69,12 @@ export class NodeMaterialPropertyGridComponent extends React.Component<INodeMate
             return a.name.localeCompare(b.name);
         });
 
+        if (configurableInputBlocks.length === 0) {
+            return null;
+        }
+
         return (
-            <>
+            <LineContainerComponent globalState={this.props.globalState} title="INPUTS">
                 {
                     configurableInputBlocks.map(block => {
                         switch (block.type) {
@@ -76,8 +108,8 @@ export class NodeMaterialPropertyGridComponent extends React.Component<INodeMate
                             }
                         return null;
                     })
-                }
-            </>
+                }           
+           </LineContainerComponent>
         );
     }
 
@@ -91,11 +123,12 @@ export class NodeMaterialPropertyGridComponent extends React.Component<INodeMate
                 <CheckBoxLineComponent label="Ignore alpha" target={material} propertyName="ignoreAlpha" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <ButtonLineComponent label="Edit" onClick={() => this.edit()} />
                 </LineContainerComponent>
-                <LineContainerComponent globalState={this.props.globalState} title="INPUTS">
-                    {
-                        this.renderInputValues()
-                    }                    
-                </LineContainerComponent>
+                {
+                    this.renderInputValues()
+                }      
+                {
+                    this.renderTextures()
+                }                  
             </div>
         );
     }

+ 9 - 1
inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx

@@ -292,6 +292,14 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
             }
         });
 
+        let materials = [];
+
+        materials.push(...scene.materials);
+
+        if (scene.multiMaterials && scene.multiMaterials.length) {
+            materials.push(...scene.multiMaterials);
+        }
+
         return (
             <div id="tree" onContextMenu={e => e.preventDefault()}>
                 <SceneExplorerFilterComponent onFilter={(filter) => this.filterContent(filter)} />
@@ -304,7 +312,7 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
                     scene.skeletons.length > 0 &&
                     <TreeItemComponent globalState={this.props.globalState} extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.skeletons} label="Skeletons" offset={1} filter={this.state.filter} />
                 }
-                <TreeItemComponent globalState={this.props.globalState} extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.materials} label="Materials" offset={1} filter={this.state.filter} />
+                <TreeItemComponent globalState={this.props.globalState} extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={materials} label="Materials" offset={1} filter={this.state.filter} />
                 <TreeItemComponent globalState={this.props.globalState} extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={textures} label="Textures" offset={1} filter={this.state.filter} />
                 {
                     postProcessses.length > 0 &&

+ 1 - 1
inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx

@@ -108,7 +108,7 @@ export class TreeItemSelectableComponent extends React.Component<ITreeItemSelect
         const entity = this.props.entity;
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
-        const children = Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
+        const children = entity.getClassName() === "MultiMaterial" ? [] : Tools.SortAndFilter(entity, entity.getChildren ? entity.getChildren() : entity.children);
         const hasChildren = children.length > 0;
 
         if (!entity.reservedDataStore) {

+ 1 - 1
inspector/src/tools.ts

@@ -19,7 +19,7 @@ export class Tools {
         }
 
         const children = item.getChildren ? item.getChildren() : item.children;
-        if (children) {
+        if (children && item.getClassName() !== "MultiMaterial") {
             for (var child of children) {
                 if (Tools.LookForItem(child, selectedEntity)) {
                     return true;

+ 2 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -742,6 +742,7 @@ export class GLTFLoader implements IGLTFLoader {
             const promises = new Array<Promise<any>>();
 
             const babylonMesh = new Mesh(name, this._babylonScene);
+            babylonMesh.overrideMaterialSideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
 
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
             promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then((babylonGeometry) => {
@@ -1644,7 +1645,7 @@ export class GLTFLoader implements IGLTFLoader {
 
     private _createDefaultMaterial(name: string, babylonDrawMode: number): Material {
         const babylonMaterial = new PBRMaterial(name, this._babylonScene);
-        babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
+        // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
         babylonMaterial.fillMode = babylonDrawMode;
         babylonMaterial.enableSpecularAntiAliasing = true;
         babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;

+ 3 - 0
nodeEditor/src/blockTools.ts

@@ -24,6 +24,7 @@ import { DotBlock } from 'babylonjs/Materials/Node/Blocks/dotBlock';
 import { MultiplyBlock } from 'babylonjs/Materials/Node/Blocks/multiplyBlock';
 import { TransformBlock } from 'babylonjs/Materials/Node/Blocks/transformBlock';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
+import { FresnelBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/fresnelBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string) {
@@ -78,6 +79,8 @@ export class BlockTools {
                 return new RemapBlock("Remap");
             case "NormalizeBlock":
                 return new NormalizeBlock("Normalize");
+            case "FresnelBlock":
+                return new FresnelBlock("Fresnel");
         }
 
         return null;

+ 46 - 26
nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx

@@ -2,7 +2,6 @@
 import * as React from "react";
 import { Vector2PropertyTabComponent } from '../../propertyTab/properties/vector2PropertyTabComponent';
 import { Vector3PropertyTabComponent } from '../../propertyTab/properties/vector3PropertyTabComponent';
-import { CheckBoxLineComponent } from '../../../sharedComponents/checkBoxLineComponent';
 import { GlobalState } from '../../../globalState';
 import { InputNodeModel } from './inputNodeModel';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
@@ -15,6 +14,7 @@ import { LineContainerComponent } from '../../../sharedComponents/lineContainerC
 import { StringTools } from '../../../stringTools';
 import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
 import { TextInputLineComponent } from '../../../sharedComponents/textInputLineComponent';
+import { CheckBoxLineComponent } from '../../../sharedComponents/checkBoxLineComponent';
 
 interface IInputPropertyTabComponentProps {
     globalState: GlobalState;
@@ -115,6 +115,18 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                     break;                
         }
 
+        var modeOptions = [
+            { label: "User-defined", value: 0 }
+        ];
+
+        if (attributeOptions.length > 0) {
+            modeOptions.push({ label: "Mesh attribute", value: 1 });
+        }
+
+        if (wellKnownOptions.length > 0) {
+            modeOptions.push({ label: "Well-known value", value: 2 });
+        }
+
         return (
             <div>
                 <LineContainerComponent title="GENERAL">
@@ -122,19 +134,36 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                     <TextLineComponent label="Type" value={StringTools.GetBaseType(inputBlock.type)} />
                 </LineContainerComponent>
                 <LineContainerComponent title="PROPERTIES">
-                    {
-                        attributeOptions.length > 0 &&
-                        <CheckBoxLineComponent label="Is mesh attribute" onSelect={value => {
-                            if (!value) {
-                                inputBlock.isUniform = true;
-                                this.setDefaultValue();
-                            } else {
-                                inputBlock.setAsAttribute(attributeOptions[0].value);
+                    <OptionsLineComponent label="Mode" options={modeOptions} target={inputBlock} 
+                        noDirectUpdate={true}
+                        getSelection={(block) => {
+                            if (block.isAttribute) {
+                                return 1;
+                            }
+
+                            if (block.isWellKnownValue) {
+                                return 2;
+                            }
+
+                            return 0;
+                        }}
+                        onSelect={(value: any) => {
+                            switch (value) {
+                                case 0:
+                                    inputBlock.isUniform = true;
+                                    inputBlock.setAsWellKnownValue(null);
+                                    this.setDefaultValue();
+                                    break;
+                                case 1:
+                                    inputBlock.setAsAttribute(attributeOptions[0].value);
+                                    break;
+                                case 2:
+                                    inputBlock.setAsWellKnownValue(wellKnownOptions[0].value);
+                                    break;
                             }
-                            this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                             this.forceUpdate();
-                        }} isSelected={() => inputBlock.isAttribute} />
-                    }
+                            this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+                        }} />
                     {
                         inputBlock.isAttribute &&
                         <OptionsLineComponent label="Attribute" valuesAreStrings={true} options={attributeOptions} target={inputBlock} propertyName="name" onSelect={(value: any) => {
@@ -144,25 +173,16 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                         }} />
                     }
                     {
-                        inputBlock.isUniform && wellKnownOptions.length > 0 &&
-                        <CheckBoxLineComponent label="Is well known value" onSelect={value => {
-                            if (value) {
-                                inputBlock.setAsWellKnownValue(wellKnownOptions[0].value);
-                            } else {
-                                inputBlock.setAsWellKnownValue(null);
-                                this.setDefaultValue();
-                            }
-                            this.props.globalState.onRebuildRequiredObservable.notifyObservers();
-                            this.forceUpdate();
-                        }} isSelected={() => inputBlock.isWellKnownValue} />
-                    }
-                    {
                         inputBlock.isUniform && animationOptions.length > 0 &&
                         <OptionsLineComponent label="Animation type" options={animationOptions} target={inputBlock} propertyName="animationType" onSelect={(value: any) => {
                             this.forceUpdate();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
-                    }                    
+                    }   
+                    {
+                        inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
+                        <CheckBoxLineComponent label="Visible in the Inspector" target={inputBlock} propertyName="visibleInInspector"/>
+                    }                 
                     {
                         inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
                         this.renderValue(this.props.globalState)

+ 1 - 2
nodeEditor/src/components/diagram/texture/texturePropertyTabComponent.tsx

@@ -4,7 +4,6 @@ import { GlobalState } from '../../../globalState';
 import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
 import { FileButtonLineComponent } from '../../../sharedComponents/fileButtonLineComponent';
 import { Tools } from 'babylonjs/Misc/tools';
-import { Engine } from 'babylonjs/Engines/engine';
 import { TextureNodeModel } from './textureNodeModel';
 import { TextLineComponent } from '../../../sharedComponents/textLineComponent';
 import { LineContainerComponent } from '../../../sharedComponents/lineContainerComponent';
@@ -35,7 +34,7 @@ export class TexturePropertyTabComponent extends React.Component<ITexturePropert
 
         let texture = this.props.node.texture as BaseTexture;
         if (!texture) {
-            this.props.node.texture = new Texture(null, Engine.LastCreatedScene)
+            this.props.node.texture = new Texture(null, this.props.globalState.nodeMaterial.getScene(), false, false)
             texture = this.props.node.texture;
         }
 

+ 99 - 95
nodeEditor/src/components/nodeList/nodeList.scss

@@ -7,110 +7,114 @@
     width: 100%; 
     overflow: hidden;
 
-    .pane {
-        color: white;
-
-        overflow-x: hidden;
-        overflow-y: auto;
-        height: 100%;
-
-        -webkit-user-select: none; 
-        -moz-user-select: none;   
-        -ms-user-select: none;    
-        user-select: none;     
-
-        .underline {
-            border-bottom: 0.5px solid rgba(255, 255, 255, 0.5);
-        }
-
-        .draggableLine {
-            height: 30px;
-            display: grid;
-            align-items: center;
-            justify-items: stretch;
-            background: #222222;
-            cursor: grab;
-            text-align: center;
-            margin: 0;
-            box-sizing: border-box;
-
-            &:hover {
-                background: rgb(51, 122, 183);
-                color: white;
-            }
-        }
-    
-        .buttonLine {
-            height: 30px;
-            display: grid;
-            align-items: center;
-            justify-items: stretch;
-
-            button {
-                background: #222222;
-                margin: 5px 10px 5px 10px;
-                color:white;
-                padding: 4px 5px;
-                opacity: 0.9;
+    .panes {
+        overflow: hidden;
+        
+        .pane {
+            color: white;
+
+            overflow-x: hidden;
+            overflow-y: auto;
+            height: 100%;
+
+            -webkit-user-select: none; 
+            -moz-user-select: none;   
+            -ms-user-select: none;    
+            user-select: none;     
+
+            .underline {
+                border-bottom: 0.5px solid rgba(255, 255, 255, 0.5);
             }
 
-            button:hover {
-                opacity: 1.0;
+            .draggableLine {
+                height: 30px;
+                display: grid;
+                align-items: center;
+                justify-items: stretch;
+                background: #222222;
+                cursor: grab;
+                text-align: center;
+                margin: 0;
+                box-sizing: border-box;
+
+                &:hover {
+                    background: rgb(51, 122, 183);
+                    color: white;
+                }
             }
+        
+            .buttonLine {
+                height: 30px;
+                display: grid;
+                align-items: center;
+                justify-items: stretch;
+
+                button {
+                    background: #222222;
+                    margin: 5px 10px 5px 10px;
+                    color:white;
+                    padding: 4px 5px;
+                    opacity: 0.9;
+                }
 
-            button:active {
-                background: #282828;
-            }   
-            
-            button:focus {
-                outline: 0px;
-            }  
-        }
-
-        .paneContainer {
-            margin-top: 3px;
-            display:grid;
-            grid-template-rows: 100%;
-            grid-template-columns: 100%;
-
-            .paneContainer-content {
-                grid-row: 1;
-                grid-column: 1;
-
-                .header {
-                    display: grid;
-                    grid-template-columns: 1fr auto;
-                    background: #555555;    
-                    height: 30px;   
-                    padding-right: 5px;                        
-                    cursor: pointer;
-                    
-                    .title {                                
-                        border-left: 3px solid transparent;
-                        padding-left: 5px;
-                        grid-column: 1;
-                        display: flex;
-                        align-items: center;
-                    }
+                button:hover {
+                    opacity: 1.0;
+                }
 
-                    .collapse {
-                        grid-column: 2;
-                        display: flex;
-                        align-items: center;  
-                        justify-items: center;
-                        transform-origin: center;
+                button:active {
+                    background: #282828;
+                }   
+                
+                button:focus {
+                    outline: 0px;
+                }  
+            }
 
-                        &.closed {
-                            transform: rotate(180deg);
+            .paneContainer {
+                margin-top: 3px;
+                display:grid;
+                grid-template-rows: 100%;
+                grid-template-columns: 100%;
+
+                .paneContainer-content {
+                    grid-row: 1;
+                    grid-column: 1;
+
+                    .header {
+                        display: grid;
+                        grid-template-columns: 1fr auto;
+                        background: #555555;    
+                        height: 30px;   
+                        padding-right: 5px;                        
+                        cursor: pointer;
+                        
+                        .title {                                
+                            border-left: 3px solid transparent;
+                            padding-left: 5px;
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
                         }
-                    }                        
-                }
 
-                .paneList > div:not(:last-child) {
-                    border-bottom: 1px solid rgba(255, 255, 255, 0.3);
+                        .collapse {
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;  
+                            justify-items: center;
+                            transform-origin: center;
+
+                            &.closed {
+                                transform: rotate(180deg);
+                            }
+                        }                        
+                    }
+
+                    .paneList > div:not(:last-child) {
+                        border-bottom: 1px solid rgba(255, 255, 255, 0.3);
+                    }
                 }
             }
-        }
-    }    
+        }    
+    }
 }
 

+ 1 - 1
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -15,7 +15,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps>
         // Block types used to create the menu from
         const allBlocks = {
             Vertex: ["BonesBlock", "InstancesBlock", "MorphTargetsBlock"],
-            Fragment: ["AlphaTestBlock", "FogBlock", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "TextureBlock"],
+            Fragment: ["AlphaTestBlock", "FogBlock", "Fresnel", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "TextureBlock"],
             Outputs: ["VertexOutputBlock", "FragmentOutputBlock"],
             Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "RemapBlock", "NormalizeBlock", "ScaleBlock", "TransformBlock", "TrigonometryBlock"],
             Conversion: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],

+ 2 - 2
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -64,8 +64,8 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
 
             serializationObject.locations.push({
                 blockId: block.uniqueId,
-                x: node.x,
-                y: node.y
+                x: node ? node.x : 0,
+                y: node ? node.y : 0
             });
         }
 

+ 9 - 5
nodeEditor/src/sharedComponents/optionsLineComponent.tsx

@@ -11,20 +11,24 @@ class ListLineOption {
 interface IOptionsLineComponentProps {
     label: string,
     target: any,
-    propertyName: string,
+    propertyName?: string,
     options: ListLineOption[],
     noDirectUpdate?: boolean,
     onSelect?: (value: number | string) => void,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
     valuesAreStrings?: boolean
-    defaultIfNull?: number
+    defaultIfNull?: number,
+    getSelection?: (target: any) => number;
 }
 
 export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, { value: number | string }> {
     private _localChange = false;
 
     private _getValue(props: IOptionsLineComponentProps) {
-        return props.target ? props.target[props.propertyName] : props.options[props.defaultIfNull || 0];
+        if (props.getSelection) {
+            return props.getSelection(props.target);
+        }
+        return (props.target && props.propertyName) ? props.target[props.propertyName] : props.options[props.defaultIfNull || 0];
     }
 
     constructor(props: IOptionsLineComponentProps) {
@@ -54,7 +58,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
 
         this.props.onPropertyChangedObservable.notifyObservers({
             object: this.props.target,
-            property: this.props.propertyName,
+            property: this.props.propertyName!,
             value: newValue,
             initialValue: previousValue
         });
@@ -66,7 +70,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
 
         const store = this.state.value;
         if (!this.props.noDirectUpdate) {
-            this.props.target[this.props.propertyName] = value;
+            this.props.target[this.props.propertyName!] = value;
         }
         this.setState({ value: value });
 

+ 8 - 0
src/Audio/audioSceneComponent.ts

@@ -364,6 +364,10 @@ export class AudioSceneComponent implements ISceneSerializableComponent {
         const scene = this.scene;
         this._audioEnabled = false;
 
+        if (Engine.audioEngine && Engine.audioEngine.audioContext) {
+            Engine.audioEngine.audioContext.suspend();
+        }
+
         let i: number;
         for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {
             scene.mainSoundTrack.soundCollection[i].pause();
@@ -384,6 +388,10 @@ export class AudioSceneComponent implements ISceneSerializableComponent {
         const scene = this.scene;
         this._audioEnabled = true;
 
+        if (Engine.audioEngine && Engine.audioEngine.audioContext) {
+            Engine.audioEngine.audioContext.resume();
+        }
+
         let i: number;
         for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {
             if (scene.mainSoundTrack.soundCollection[i].isPaused) {

+ 3 - 3
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -237,7 +237,9 @@ export class LightBlock extends NodeMaterialBlock {
 
         // Code
         if (this._lightId === 0) {
-            state.compilationString += `vec3 viewDirectionW = normalize(${this.cameraPosition.associatedVariableName} - ${"v_" + worldPos.associatedVariableName});\r\n`;
+            if (state._registerTempVariable("viewDirectionW")) {
+                state.compilationString += `vec3 viewDirectionW = normalize(${this.cameraPosition.associatedVariableName} - ${"v_" + worldPos.associatedVariableName});\r\n`;
+            }
             state.compilationString += `lightingInfo info;\r\n`;
             state.compilationString += `float shadow = 1.;\r\n`;
             state.compilationString += `float glossiness = 0.;\r\n`;
@@ -263,9 +265,7 @@ export class LightBlock extends NodeMaterialBlock {
 
         state.compilationString += this._declareOutput(diffuseOutput, state) + ` = diffuseBase;\r\n`;
         if (specularOutput.hasEndpoints) {
-            state.compilationString += `#ifdef SPECULARTERM\r\n`;
             state.compilationString += this._declareOutput(specularOutput, state) + ` = specularBase;\r\n`;
-            state.compilationString += `#endif\r\n`;
         }
 
         return this;

+ 116 - 0
src/Materials/Node/Blocks/Fragment/fresnelBlock.ts

@@ -0,0 +1,116 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
+
+/**
+ * Block used to compute fresnel value
+ */
+export class FresnelBlock extends NodeMaterialBlock {
+
+    /**
+     * Create a new FresnelBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.VertexAndFragment);
+
+        this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("cameraPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("bias", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("power", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Vertex);
+
+        this.registerOutput("fresnel", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "FresnelBlock";
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get worldPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the world normal input component
+     */
+    public get worldNormal(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+    * Gets the camera (or eye) position component
+    */
+    public get cameraPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+    * Gets the bias input component
+    */
+    public get bias(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
+    }
+
+    /**
+    * Gets the camera (or eye) position component
+    */
+    public get power(): NodeMaterialConnectionPoint {
+        return this._inputs[4];
+    }
+
+    /**
+     * Gets the fresnel output component
+     */
+    public get fresnel(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    public autoConfigure() {
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let comments = `//${this.name}`;
+
+        let worldPos = this.worldPosition;
+        let worldNormal = this.worldNormal;
+        let worldPosVaryingName = "v_" + worldPos.associatedVariableName;
+        let worldNormalVaryingName = "v_" + worldNormal.associatedVariableName;
+
+        if (state.target !== NodeMaterialBlockTargets.Fragment) {
+            // Inject code in vertex
+            if (state._emitVaryingFromString(worldPosVaryingName, "vec3")) {
+                state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName}.xyz;\r\n`;
+            }
+
+            if (state._emitVaryingFromString(worldNormalVaryingName, "vec3")) {
+                state.compilationString += `${worldNormalVaryingName} = ${worldNormal.associatedVariableName}.xyz;\r\n`;
+            }
+
+            return;
+        }
+
+        state._emitFunctionFromInclude("fresnelFunction", comments);
+
+        if (state._registerTempVariable("viewDirectionW")) {
+            state.compilationString += `vec3 viewDirectionW = normalize(${this.cameraPosition.associatedVariableName} - ${worldPosVaryingName});\r\n`;
+        }
+        state.compilationString += this._declareOutput(this.fresnel, state) + ` = computeFresnelTerm(viewDirectionW, ${worldNormalVaryingName}, ${this.bias.associatedVariableName}, ${this.power.associatedVariableName});;\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.FresnelBlock"] = FresnelBlock;

+ 1 - 4
src/Materials/Node/Blocks/Fragment/index.ts

@@ -1,8 +1,5 @@
 
 export * from "./fragmentOutputBlock";
 export * from "./alphaTestBlock";
-export * from "../colorMergerBlock";
-export * from "../vectorMergerBlock";
-export * from "../colorSplitterBlock";
-export * from "../vectorSplitterBlock";
+export * from "./fresnelBlock";
 export * from "./imageProcessingBlock";

+ 4 - 0
src/Materials/Node/Blocks/colorSplitterBlock.ts

@@ -87,6 +87,10 @@ export class ColorSplitterBlock extends NodeMaterialBlock {
 
         let input = this.rgba.isConnected ? this.rgba : this.rgbIn;
 
+        if (!input.isConnected) {
+            return;
+        }
+
         let rgbOutput = this._outputs[0];
         let rOutput = this._outputs[1];
         let gOutput = this._outputs[2];

+ 5 - 1
src/Materials/Node/Blocks/index.ts

@@ -11,4 +11,8 @@ export * from "./dotBlock";
 export * from "./transformBlock";
 export * from "./remapBlock";
 export * from "./normalizeBlock";
-export * from "./trigonometryBlock";
+export * from "./trigonometryBlock";
+export * from "./colorMergerBlock";
+export * from "./vectorMergerBlock";
+export * from "./colorSplitterBlock";
+export * from "./vectorSplitterBlock";

+ 36 - 15
src/Materials/Node/nodeMaterial.ts

@@ -25,6 +25,8 @@ import { FragmentOutputBlock } from './Blocks/Fragment/fragmentOutputBlock';
 import { InputBlock } from './Blocks/Input/inputBlock';
 import { _TypeStore } from '../../Misc/typeStore';
 import { SerializationHelper } from '../../Misc/decorators';
+import { TextureBlock } from './Blocks/Dual/textureBlock';
+import { ReflectionTextureBlock } from './Blocks/Dual/reflectionTextureBlock';
 
 // declare NODEEDITOR namespace for compilation issue
 declare var NODEEDITOR: any;
@@ -817,6 +819,14 @@ export class NodeMaterial extends PushMaterial {
     }
 
     /**
+     * Gets the list of texture blocks
+     * @returns an array of texture blocks
+     */
+    public getTextureBlocks(): (TextureBlock | ReflectionTextureBlock)[] {
+        return this._sharedData.textureBlocks.filter((tb) => tb.texture);
+    }
+
+    /**
      * Specifies if the material uses a texture
      * @param texture defines the texture to check against the material
      * @returns a boolean specifying if the material uses the texture
@@ -997,6 +1007,27 @@ export class NodeMaterial extends PushMaterial {
         return serializationObject;
     }
 
+    private _restoreConnections(block: NodeMaterialBlock, source: any, map: {[key: number]: NodeMaterialBlock}) {
+        for (var outputPoint of block.outputs) {
+            for (var candidate of source.blocks) {
+                let target = map[candidate.id];
+
+                for (var input of candidate.inputs) {
+                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {
+                        let inputPoint = target.getInputByName(input.inputName);
+                        if (!inputPoint || inputPoint.isConnected) {
+                            continue;
+                        }
+
+                        outputPoint.connectTo(inputPoint);
+                        this._restoreConnections(target, source, map);
+                        continue;
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Clear the current graph and load a new one from a serialization object
      * @param source defines the JSON representation of the material
@@ -1021,25 +1052,15 @@ export class NodeMaterial extends PushMaterial {
 
         // Connections
 
-        // Play them in reverse to make sure types are defined
-        for (var blockIndex = source.blocks.length - 1; blockIndex >= 0; blockIndex--) {
+        // Starts with input blocks only
+        for (var blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {
             let parsedBlock = source.blocks[blockIndex];
             let block = map[parsedBlock.id];
 
-            for (var input of parsedBlock.inputs) {
-                if (!input.targetBlockId) {
-                    continue;
-                }
-                let inputPoint = block.getInputByName(input.inputName);
-                let targetBlock = map[input.targetBlockId];
-                if (targetBlock) {
-                    let outputPoint = targetBlock.getOutputByName(input.targetConnectionName);
-
-                    if (inputPoint && outputPoint) {
-                        outputPoint.connectTo(inputPoint);
-                    }
-                }
+            if (!block.isInput) {
+                continue;
             }
+            this._restoreConnections(block, source, map);
         }
 
         // Outputs

+ 10 - 0
src/Materials/Node/nodeMaterialBuildState.ts

@@ -272,6 +272,16 @@ export class NodeMaterialBuildState {
     }
 
     /** @hidden */
+    public _registerTempVariable(name: string) {
+        if (this.sharedData.temps.indexOf(name) !== -1) {
+            return false;
+        }
+
+        this.sharedData.temps.push(name);
+        return true;
+    }
+
+    /** @hidden */
     public _emitVaryingFromString(name: string, type: string, define: string = "", notDefine = false) {
         if (this.sharedData.varyings.indexOf(name) !== -1) {
             return false;

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

@@ -9,6 +9,11 @@ import { ReflectionTextureBlock } from './Blocks/Dual/reflectionTextureBlock';
  */
 export class NodeMaterialBuildStateSharedData {
     /**
+    * Gets the list of emitted varyings
+    */
+    public temps = new Array<string>();
+
+    /**
      * Gets the list of emitted varyings
      */
     public varyings = new Array<string>();

+ 56 - 36
src/Materials/effect.ts

@@ -406,6 +406,15 @@ export class Effect implements IDisposable {
      * @returns if the effect is compiled and prepared.
      */
     public isReady(): boolean {
+        try {
+            return this._isReadyInternal();
+        }
+        catch {
+            return false;
+        }
+    }
+
+    private _isReadyInternal(): boolean {
         if (this._isReady) {
             return true;
         }
@@ -523,9 +532,15 @@ export class Effect implements IDisposable {
     }
 
     private _checkIsReady() {
-        if (this.isReady()) {
+        try {
+            if (this._isReadyInternal()) {
+                return;
+            }
+        } catch (e) {
+            this._processCompilationErrors(e);
             return;
         }
+
         setTimeout(() => {
             this._checkIsReady();
         }, 16);
@@ -687,7 +702,6 @@ export class Effect implements IDisposable {
     public _prepareEffect() {
         let attributesNames = this._attributesNames;
         let defines = this.defines;
-        let fallbacks = this._fallbacks;
         this._valueCache = {};
 
         var previousPipelineContext = this._pipelineContext;
@@ -758,45 +772,51 @@ export class Effect implements IDisposable {
             }
 
         } catch (e) {
-            this._compilationError = e.message;
-
-            // Let's go through fallbacks then
-            Logger.Error("Unable to compile effect:");
-            Logger.Error("Uniforms: " + this._uniformsNames.map(function(uniform) {
-                return " " + uniform;
-            }));
-            Logger.Error("Attributes: " + attributesNames.map(function(attribute) {
-                return " " + attribute;
-            }));
-            Logger.Error("Defines:\r\n" + this.defines);
-            Logger.Error("Error: " + this._compilationError);
-            if (previousPipelineContext) {
-                this._pipelineContext = previousPipelineContext;
-                this._isReady = true;
+           this._processCompilationErrors(e, previousPipelineContext);
+        }
+    }
+
+    private _processCompilationErrors(e: any, previousPipelineContext: Nullable<IPipelineContext> = null) {
+        this._compilationError = e.message;
+        let attributesNames = this._attributesNames;
+        let fallbacks = this._fallbacks;
+
+        // Let's go through fallbacks then
+        Logger.Error("Unable to compile effect:");
+        Logger.Error("Uniforms: " + this._uniformsNames.map(function(uniform) {
+            return " " + uniform;
+        }));
+        Logger.Error("Attributes: " + attributesNames.map(function(attribute) {
+            return " " + attribute;
+        }));
+        Logger.Error("Defines:\r\n" + this.defines);
+        Logger.Error("Error: " + this._compilationError);
+        if (previousPipelineContext) {
+            this._pipelineContext = previousPipelineContext;
+            this._isReady = true;
+            if (this.onError) {
+                this.onError(this, this._compilationError);
+            }
+            this.onErrorObservable.notifyObservers(this);
+        }
+
+        if (fallbacks) {
+            this._pipelineContext = null;
+            if (fallbacks.isMoreFallbacks) {
+                Logger.Error("Trying next fallback.");
+                this.defines = fallbacks.reduce(this.defines, this);
+                this._prepareEffect();
+            } else { // Sorry we did everything we can
+
                 if (this.onError) {
                     this.onError(this, this._compilationError);
                 }
                 this.onErrorObservable.notifyObservers(this);
-            }
-
-            if (fallbacks) {
-                this._pipelineContext = null;
-                if (fallbacks.isMoreFallbacks) {
-                    Logger.Error("Trying next fallback.");
-                    this.defines = fallbacks.reduce(this.defines, this);
-                    this._prepareEffect();
-                } else { // Sorry we did everything we can
-
-                    if (this.onError) {
-                        this.onError(this, this._compilationError);
-                    }
-                    this.onErrorObservable.notifyObservers(this);
-                    this.onErrorObservable.clear();
+                this.onErrorObservable.clear();
 
-                    // Unbind mesh reference in fallbacks
-                    if (this._fallbacks) {
-                        this._fallbacks.unBindMesh();
-                    }
+                // Unbind mesh reference in fallbacks
+                if (this._fallbacks) {
+                    this._fallbacks.unBindMesh();
                 }
             }
         }

+ 3 - 3
src/Meshes/mesh.ts

@@ -1690,9 +1690,9 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             sideOrientation = this.overrideMaterialSideOrientation;
             if (sideOrientation == null) {
                 sideOrientation = this._effectiveMaterial.sideOrientation;
-                if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
-                    sideOrientation = (sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation);
-                }
+            }
+            if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
+                sideOrientation = (sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation);
             }
             instanceDataStorage.sideOrientation = sideOrientation!;
         } else {