Browse Source

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

David Catuhe 6 năm trước cách đây
mục cha
commit
d09b2f98a2
40 tập tin đã thay đổi với 2281 bổ sung167 xóa
  1. 148 4
      Playground/babylon.d.txt
  2. 149 4
      dist/preview release/babylon.d.ts
  3. 6 2
      dist/preview release/babylon.js
  4. 501 23
      dist/preview release/babylon.max.js
  5. 5 1
      dist/preview release/babylon.max.js.map
  6. 311 8
      dist/preview release/babylon.module.d.ts
  7. 149 4
      dist/preview release/documentation.d.ts
  8. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  9. 1 0
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  10. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  11. 2 1
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  12. 6 6
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  13. 23 6
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  14. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  15. 5 2
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  16. 1 1
      dist/preview release/packagesSizeBaseLine.json
  17. 311 8
      dist/preview release/viewer/babylon.module.d.ts
  18. 48 32
      dist/preview release/viewer/babylon.viewer.js
  19. 4 0
      dist/preview release/viewer/babylon.viewer.max.js
  20. 1 0
      inspector/src/components/globalState.ts
  21. 3 0
      nodeEditor/src/blockTools.ts
  22. 1 1
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  23. 8 1
      nodeEditor/src/components/preview/previewManager.ts
  24. 3 1
      nodeEditor/src/components/propertyTab/properties/floatPropertyTabComponent.tsx
  25. 3 1
      nodeEditor/src/components/propertyTab/properties/vector2PropertyTabComponent.tsx
  26. 3 1
      nodeEditor/src/components/propertyTab/properties/vector3PropertyTabComponent.tsx
  27. 1 1
      nodeEditor/src/sharedComponents/floatLineComponent.tsx
  28. 7 0
      src/Gizmos/lightGizmo.ts
  29. 2 1
      src/Materials/Node/Blocks/Dual/index.ts
  30. 6 5
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  31. 391 0
      src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts
  32. 37 2
      src/Materials/Node/Blocks/Dual/textureBlock.ts
  33. 3 3
      src/Materials/Node/nodeMaterial.ts
  34. 27 5
      src/Materials/Node/nodeMaterialBlock.ts
  35. 1 1
      src/Materials/Node/nodeMaterialBlockConnectionPoint.ts
  36. 9 2
      src/Materials/Node/nodeMaterialBuildState.ts
  37. 2 1
      src/Materials/Node/nodeMaterialBuildStateSharedData.ts
  38. 1 0
      src/Materials/effect.ts
  39. 91 28
      src/Shaders/ShadersInclude/reflectionFunction.fx
  40. 8 8
      src/Shaders/default.vertex.fx

+ 148 - 4
Playground/babylon.d.txt

@@ -43823,6 +43823,10 @@ declare module BABYLON {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -51183,9 +51187,29 @@ declare module BABYLON {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -51199,6 +51223,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 {
+    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
@@ -51217,7 +51352,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -51366,7 +51501,7 @@ declare module BABYLON {
                 replace: string;
             }[];
         }, storeKey?: string): void;
-        /** @hidden */
private _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        /** @hidden */
private _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
private _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
 }
@@ -51482,6 +51617,12 @@ declare module BABYLON {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -51576,6 +51717,8 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+<<<<<<< HEAD
+=======
      * Enum used to define well known values e.g. values automatically provided by the system
      */
     export enum NodeMaterialWellKnownValues {
@@ -51599,6 +51742,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
      * Block used to expose an input value
      */
     export class InputBlock extends NodeMaterialBlock {

+ 149 - 4
dist/preview release/babylon.d.ts

@@ -44573,6 +44573,10 @@ declare module BABYLON {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -51964,9 +51968,29 @@ declare module BABYLON {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -51981,6 +52005,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 {
+    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
@@ -51999,7 +52135,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -52163,7 +52299,7 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -52282,6 +52418,12 @@ declare module BABYLON {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -52377,6 +52519,8 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+<<<<<<< HEAD
+=======
      * Enum used to define well known values e.g. values automatically provided by the system
      */
     export enum NodeMaterialWellKnownValues {
@@ -52400,6 +52544,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
      * Block used to expose an input value
      */
     export class InputBlock extends NodeMaterialBlock {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 2
dist/preview release/babylon.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 501 - 23
dist/preview release/babylon.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5 - 1
dist/preview release/babylon.max.js.map


+ 311 - 8
dist/preview release/babylon.module.d.ts

@@ -46377,6 +46377,7 @@ declare module "babylonjs/Gizmos/lightGizmo" {
     import { Nullable } from "babylonjs/types";
     import { Gizmo } from "babylonjs/Gizmos/gizmo";
     import { UtilityLayerRenderer } from "babylonjs/Rendering/utilityLayerRenderer";
+    import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
     import { Light } from "babylonjs/Lights/light";
     /**
      * Gizmo that enables viewing a light
@@ -46397,6 +46398,10 @@ declare module "babylonjs/Gizmos/lightGizmo" {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -54381,9 +54386,29 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -54396,11 +54421,134 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
         _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
     }
 }
+declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
+    /**
+     * 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 "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
+    import { NodeMaterial, NodeMaterialDefines } from "babylonjs/Materials/Node/nodeMaterial";
+    import { Effect } from "babylonjs/Materials/effect";
+    import { Mesh } from "babylonjs/Meshes/mesh";
+    import { Nullable } from "babylonjs/types";
+    import { Scene } from "babylonjs/scene";
+    /**
+     * 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 "babylonjs/Materials/Node/nodeMaterialBuildStateSharedData" {
     import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { InputBlock } from "babylonjs/Materials/Node/Blocks/Input/inputBlock";
     import { TextureBlock } from "babylonjs/Materials/Node/Blocks/Dual/textureBlock";
+    import { ReflectionTextureBlock } from "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock";
     /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
@@ -54420,7 +54568,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBuildStateSharedData" {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -54587,7 +54735,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBuildState" {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -54716,6 +54864,12 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlock" {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -54809,6 +54963,8 @@ declare module "babylonjs/Materials/Node/NodeMaterialBlockConnectionPointMode" {
         Undefined = 3
     }
 }
+<<<<<<< HEAD
+=======
 declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
     /**
      * Enum used to define well known values e.g. values automatically provided by the system
@@ -54832,6 +54988,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
         FogColor = 8
     }
 }
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
 declare module "babylonjs/Materials/Node/Blocks/Input/inputBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { NodeMaterialBlockConnectionPointTypes } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes";
@@ -55620,6 +55777,7 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/index" {
     export * from "babylonjs/Materials/Node/Blocks/Dual/fogBlock";
     export * from "babylonjs/Materials/Node/Blocks/Dual/lightBlock";
     export * from "babylonjs/Materials/Node/Blocks/Dual/textureBlock";
+    export * from "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock";
 }
 declare module "babylonjs/Materials/Node/Blocks/Input/index" {
     export * from "babylonjs/Materials/Node/Blocks/Input/inputBlock";
@@ -108820,6 +108978,10 @@ declare module BABYLON {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -116211,9 +116373,29 @@ declare module BABYLON {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -116228,6 +116410,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 {
+    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
@@ -116246,7 +116540,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -116410,7 +116704,7 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -116529,6 +116823,12 @@ declare module BABYLON {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -116624,6 +116924,8 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+<<<<<<< HEAD
+=======
      * Enum used to define well known values e.g. values automatically provided by the system
      */
     export enum NodeMaterialWellKnownValues {
@@ -116647,6 +116949,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
      * Block used to expose an input value
      */
     export class InputBlock extends NodeMaterialBlock {

+ 149 - 4
dist/preview release/documentation.d.ts

@@ -44573,6 +44573,10 @@ declare module BABYLON {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -51964,9 +51968,29 @@ declare module BABYLON {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -51981,6 +52005,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 {
+    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
@@ -51999,7 +52135,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -52163,7 +52299,7 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -52282,6 +52418,12 @@ declare module BABYLON {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -52377,6 +52519,8 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+<<<<<<< HEAD
+=======
      * Enum used to define well known values e.g. values automatically provided by the system
      */
     export enum NodeMaterialWellKnownValues {
@@ -52400,6 +52544,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
      * Block used to expose an input value
      */
     export class InputBlock extends NodeMaterialBlock {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


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

@@ -41308,6 +41308,7 @@ var GlobalState = /** @class */ (function () {
                 light.reservedDataStore.lightGizmo = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["LightGizmo"]();
                 this.lightGizmos.push(light.reservedDataStore.lightGizmo);
                 light.reservedDataStore.lightGizmo.light = light;
+                light.reservedDataStore.lightGizmo.material.reservedDataStore = { hidden: true };
             }
         }
         else if (light.reservedDataStore && light.reservedDataStore.lightGizmo) {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 23 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -62138,6 +62138,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 var BlockTools = /** @class */ (function () {
     function BlockTools() {
     }
@@ -62163,6 +62164,8 @@ var BlockTools = /** @class */ (function () {
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["VectorSplitterBlock"]("VectorSplitter");
             case "TextureBlock":
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["TextureBlock"]("Texture");
+            case "ReflectionTextureBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["ReflectionTextureBlock"]("Texture");
             case "LightBlock":
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["LightBlock"]("Lights");
             case "FogBlock":
@@ -64128,7 +64131,7 @@ var NodeListComponent = /** @class */ (function (_super) {
         // Block types used to create the menu from
         var allBlocks = {
             Vertex: ["BonesBlock", "InstancesBlock", "MorphTargetsBlock"],
-            Fragment: ["AlphaTestBlock", "ImageProcessingBlock", "TextureBlock", "LightBlock", "FogBlock"],
+            Fragment: ["AlphaTestBlock", "ImageProcessingBlock", "TextureBlock", "ReflectionTextureBlock", "LightBlock", "FogBlock"],
             Outputs: ["VertexOutputBlock", "FragmentOutputBlock"],
             Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "RemapBlock", "NormalizeBlock", "TransformBlock", "ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "Matrix"],
@@ -64185,13 +64188,17 @@ var PreviewManager = /** @class */ (function () {
         this._onPreviewMeshTypeChangedObserver = globalState.onPreviewMeshTypeChanged.add(function () {
             _this._refreshPreviewMesh();
         });
+        this._onUpdateRequiredObserver = globalState.onUpdateRequiredObservable.add(function () {
+            var serializationObject = _this._nodeMaterial.serialize();
+            _this._updatePreview(serializationObject);
+        });
         this._engine = new babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["Engine"](targetCanvas, true);
         this._scene = new babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["Scene"](this._engine);
         this._camera = new babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCamera"]("Camera", 0, 0.8, 4, babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), this._scene);
         this._light = new babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["HemisphericLight"]("light", new babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1, 0), this._scene);
         this._camera.lowerRadiusLimit = 3;
         this._camera.upperRadiusLimit = 10;
-        this._camera.wheelPrecision = 10;
+        this._camera.wheelPrecision = 20;
         this._camera.attachControl(targetCanvas, false);
         this._refreshPreviewMesh();
         this._engine.runRenderLoop(function () {
@@ -64232,6 +64239,7 @@ var PreviewManager = /** @class */ (function () {
     PreviewManager.prototype.dispose = function () {
         this._nodeMaterial.onBuildObservable.remove(this._onBuildObserver);
         this._globalState.onPreviewMeshTypeChanged.remove(this._onPreviewMeshTypeChangedObserver);
+        this._globalState.onUpdateRequiredObservable.remove(this._onUpdateRequiredObserver);
         if (this._material) {
             this._material.dispose();
         }
@@ -64382,7 +64390,10 @@ var FloatPropertyTabComponent = /** @class */ (function (_super) {
         return _super !== null && _super.apply(this, arguments) || this;
     }
     FloatPropertyTabComponent.prototype.render = function () {
-        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_floatLineComponent__WEBPACK_IMPORTED_MODULE_2__["FloatLineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value" }));
+        var _this = this;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_floatLineComponent__WEBPACK_IMPORTED_MODULE_2__["FloatLineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value", onChange: function () {
+                _this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            } }));
     };
     return FloatPropertyTabComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -64414,7 +64425,10 @@ var Vector2PropertyTabComponent = /** @class */ (function (_super) {
         return _super !== null && _super.apply(this, arguments) || this;
     }
     Vector2PropertyTabComponent.prototype.render = function () {
-        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_vector2LineComponent__WEBPACK_IMPORTED_MODULE_2__["Vector2LineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value" }));
+        var _this = this;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_vector2LineComponent__WEBPACK_IMPORTED_MODULE_2__["Vector2LineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value", onChange: function () {
+                _this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            } }));
     };
     return Vector2PropertyTabComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -64446,7 +64460,10 @@ var Vector3PropertyTabComponent = /** @class */ (function (_super) {
         return _super !== null && _super.apply(this, arguments) || this;
     }
     Vector3PropertyTabComponent.prototype.render = function () {
-        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_vector3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Vector3LineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value" }));
+        var _this = this;
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_vector3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Vector3LineComponent"], { label: "Value", target: this.props.inputBlock, propertyName: "value", onChange: function () {
+                _this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            } }));
     };
     return Vector3PropertyTabComponent;
 }(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
@@ -65811,8 +65828,8 @@ var FloatLineComponent = /** @class */ (function (_super) {
         if (isNaN(valueAsNumber)) {
             return;
         }
-        this.raiseOnPropertyChanged(valueAsNumber, this._store);
         this.props.target[this.props.propertyName] = valueAsNumber;
+        this.raiseOnPropertyChanged(valueAsNumber, this._store);
         this._store = valueAsNumber;
     };
     FloatLineComponent.prototype.render = function () {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


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

@@ -1 +1 @@
-{"engineOnly":166856,"sceneOnly":506554,"minGridMaterial":635455,"minStandardMaterial":762736}
+{"engineOnly":166895,"sceneOnly":506593,"minGridMaterial":635494,"minStandardMaterial":764695}

+ 311 - 8
dist/preview release/viewer/babylon.module.d.ts

@@ -46377,6 +46377,7 @@ declare module "babylonjs/Gizmos/lightGizmo" {
     import { Nullable } from "babylonjs/types";
     import { Gizmo } from "babylonjs/Gizmos/gizmo";
     import { UtilityLayerRenderer } from "babylonjs/Rendering/utilityLayerRenderer";
+    import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
     import { Light } from "babylonjs/Lights/light";
     /**
      * Gizmo that enables viewing a light
@@ -46397,6 +46398,10 @@ declare module "babylonjs/Gizmos/lightGizmo" {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -54381,9 +54386,29 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -54396,11 +54421,134 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
         _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
     }
 }
+declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
+    /**
+     * 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 "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
+    import { NodeMaterial, NodeMaterialDefines } from "babylonjs/Materials/Node/nodeMaterial";
+    import { Effect } from "babylonjs/Materials/effect";
+    import { Mesh } from "babylonjs/Meshes/mesh";
+    import { Nullable } from "babylonjs/types";
+    import { Scene } from "babylonjs/scene";
+    /**
+     * 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 "babylonjs/Materials/Node/nodeMaterialBuildStateSharedData" {
     import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { InputBlock } from "babylonjs/Materials/Node/Blocks/Input/inputBlock";
     import { TextureBlock } from "babylonjs/Materials/Node/Blocks/Dual/textureBlock";
+    import { ReflectionTextureBlock } from "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock";
     /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
@@ -54420,7 +54568,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBuildStateSharedData" {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -54587,7 +54735,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBuildState" {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -54716,6 +54864,12 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlock" {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -54809,6 +54963,8 @@ declare module "babylonjs/Materials/Node/NodeMaterialBlockConnectionPointMode" {
         Undefined = 3
     }
 }
+<<<<<<< HEAD
+=======
 declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
     /**
      * Enum used to define well known values e.g. values automatically provided by the system
@@ -54832,6 +54988,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialWellKnownValues" {
         FogColor = 8
     }
 }
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
 declare module "babylonjs/Materials/Node/Blocks/Input/inputBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { NodeMaterialBlockConnectionPointTypes } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes";
@@ -55620,6 +55777,7 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/index" {
     export * from "babylonjs/Materials/Node/Blocks/Dual/fogBlock";
     export * from "babylonjs/Materials/Node/Blocks/Dual/lightBlock";
     export * from "babylonjs/Materials/Node/Blocks/Dual/textureBlock";
+    export * from "babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock";
 }
 declare module "babylonjs/Materials/Node/Blocks/Input/index" {
     export * from "babylonjs/Materials/Node/Blocks/Input/inputBlock";
@@ -108820,6 +108978,10 @@ declare module BABYLON {
          */
         light: Nullable<Light>;
         /**
+         * Gets the material used to render the light gizmo
+         */
+        readonly material: StandardMaterial;
+        /**
          * @hidden
          * Updates the gizmo to match the attached mesh's position/rotation
          */
@@ -116211,9 +116373,29 @@ declare module BABYLON {
          */
         readonly uv: NodeMaterialConnectionPoint;
         /**
-         * Gets the output component
+         * Gets the rgba output component
          */
-        readonly output: NodeMaterialConnectionPoint;
+        readonly rgba: 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;
+        /**
+         * Gets the a output component
+         */
+        readonly a: NodeMaterialConnectionPoint;
         autoConfigure(): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
@@ -116228,6 +116410,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 {
+    /**
      * Class used to store shared data between 2 NodeMaterialBuildState
      */
     export class NodeMaterialBuildStateSharedData {
@@ -116246,7 +116540,7 @@ declare module BABYLON {
         /**
          * Input blocks
          */
-        textureBlocks: TextureBlock[];
+        textureBlocks: (TextureBlock | ReflectionTextureBlock)[];
         /**
          * Bindable blocks (Blocks that need to set data to the effect)
          */
@@ -116410,7 +116704,7 @@ declare module BABYLON {
             }[];
         }, storeKey?: string): void;
         /** @hidden */
-        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
+        _emitVaryingFromString(name: string, type: string, define?: string, notDefine?: boolean): boolean;
         /** @hidden */
         _emitUniformFromString(name: string, type: string, define?: string, notDefine?: boolean): void;
     }
@@ -116529,6 +116823,12 @@ declare module BABYLON {
          */
         getFirstAvailableOutput(forBlock?: Nullable<NodeMaterialBlock>): Nullable<NodeMaterialConnectionPoint>;
         /**
+         * Gets the sibling of the given output
+         * @param current defines the current output
+         * @returns the next output in the list or null
+         */
+        getSiblingOutput(current: NodeMaterialConnectionPoint): Nullable<NodeMaterialConnectionPoint>;
+        /**
          * Connect current block with another block
          * @param other defines the block to connect with
          * @param options define the various options to help pick the right connections
@@ -116624,6 +116924,8 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+<<<<<<< HEAD
+=======
      * Enum used to define well known values e.g. values automatically provided by the system
      */
     export enum NodeMaterialWellKnownValues {
@@ -116647,6 +116949,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+>>>>>>> e47aa63d1958a485f9b8ebff19354e6c3644dd46
      * Block used to expose an input value
      */
     export class InputBlock extends NodeMaterialBlock {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 48 - 32
dist/preview release/viewer/babylon.viewer.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4 - 0
dist/preview release/viewer/babylon.viewer.max.js


+ 1 - 0
inspector/src/components/globalState.ts

@@ -109,6 +109,7 @@ export class GlobalState {
                 light.reservedDataStore.lightGizmo = new LightGizmo();
                 this.lightGizmos.push(light.reservedDataStore.lightGizmo)
                 light.reservedDataStore.lightGizmo.light = light;
+                light.reservedDataStore.lightGizmo.material.reservedDataStore = {hidden: true};
             }
         } else if (light.reservedDataStore && light.reservedDataStore.lightGizmo) {
             this.lightGizmos.splice(this.lightGizmos.indexOf(light.reservedDataStore.lightGizmo), 1);

+ 3 - 0
nodeEditor/src/blockTools.ts

@@ -9,6 +9,7 @@ import { ColorSplitterBlock } from 'babylonjs/Materials/Node/Blocks/colorSplitte
 import { VectorSplitterBlock } from 'babylonjs/Materials/Node/Blocks/vectorSplitterBlock';
 import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
 import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
+import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
 import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
 import { FogBlock } from 'babylonjs/Materials/Node/Blocks/Dual/fogBlock';
 import { VertexOutputBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/vertexOutputBlock';
@@ -45,6 +46,8 @@ export class BlockTools {
                 return new VectorSplitterBlock("VectorSplitter");
             case "TextureBlock":
                 return new TextureBlock("Texture");
+            case "ReflectionTextureBlock":
+                return new ReflectionTextureBlock("Texture");                
             case "LightBlock":
                 return new LightBlock("Lights");
             case "FogBlock":

+ 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", "ImageProcessingBlock", "TextureBlock", "LightBlock", "FogBlock"],
+            Fragment: ["AlphaTestBlock", "ImageProcessingBlock", "TextureBlock", "ReflectionTextureBlock","LightBlock", "FogBlock"],
             Outputs: ["VertexOutputBlock", "FragmentOutputBlock"],
             Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "RemapBlock", "NormalizeBlock", "TransformBlock", "ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "Matrix"],

+ 8 - 1
nodeEditor/src/components/preview/previewManager.ts

@@ -14,6 +14,7 @@ export class PreviewManager {
     private _nodeMaterial: NodeMaterial;
     private _onBuildObserver: Nullable<Observer<NodeMaterial>>;    
     private _onPreviewMeshTypeChangedObserver: Nullable<Observer<void>>;
+    private _onUpdateRequiredObserver: Nullable<Observer<void>>;
     private _engine: Engine;
     private _scene: Scene;
     private _light: HemisphericLight;
@@ -35,6 +36,11 @@ export class PreviewManager {
             this._refreshPreviewMesh();
         });
 
+        this._onUpdateRequiredObserver = globalState.onUpdateRequiredObservable.add(() => {
+            let serializationObject = this._nodeMaterial.serialize();
+            this._updatePreview(serializationObject);
+        });
+
         this._engine = new Engine(targetCanvas, true);
         this._scene = new Scene(this._engine);
         this._camera = new ArcRotateCamera("Camera", 0, 0.8, 4, Vector3.Zero(), this._scene);
@@ -43,7 +49,7 @@ export class PreviewManager {
 
         this._camera.lowerRadiusLimit = 3;
         this._camera.upperRadiusLimit = 10;
-        this._camera.wheelPrecision = 10;
+        this._camera.wheelPrecision = 20;
         this._camera.attachControl(targetCanvas, false);
 
         this._refreshPreviewMesh();
@@ -92,6 +98,7 @@ export class PreviewManager {
     public dispose() {
         this._nodeMaterial.onBuildObservable.remove(this._onBuildObserver);
         this._globalState.onPreviewMeshTypeChanged.remove(this._onPreviewMeshTypeChangedObserver);
+        this._globalState.onUpdateRequiredObservable.remove(this._onUpdateRequiredObserver);
 
         if (this._material) {
             this._material.dispose();

+ 3 - 1
nodeEditor/src/components/propertyTab/properties/floatPropertyTabComponent.tsx

@@ -13,7 +13,9 @@ export class FloatPropertyTabComponent extends React.Component<IFloatPropertyTab
 
     render() {
         return (
-            <FloatLineComponent label="Value" target={this.props.inputBlock} propertyName="value"></FloatLineComponent>
+            <FloatLineComponent label="Value" target={this.props.inputBlock} propertyName="value" onChange={() => {
+                this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            }}></FloatLineComponent>
         );
     }
 }

+ 3 - 1
nodeEditor/src/components/propertyTab/properties/vector2PropertyTabComponent.tsx

@@ -13,7 +13,9 @@ export class Vector2PropertyTabComponent extends React.Component<IVector2Propert
 
     render() {
         return (
-            <Vector2LineComponent label="Value" target={this.props.inputBlock} propertyName="value"></Vector2LineComponent>
+            <Vector2LineComponent label="Value" target={this.props.inputBlock} propertyName="value" onChange={() => {
+                this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            }}></Vector2LineComponent>
         );
     }
 }

+ 3 - 1
nodeEditor/src/components/propertyTab/properties/vector3PropertyTabComponent.tsx

@@ -13,7 +13,9 @@ export class Vector3PropertyTabComponent extends React.Component<IVector3Propert
 
     render() {
         return (
-            <Vector3LineComponent label="Value" target={this.props.inputBlock} propertyName="value"></Vector3LineComponent>
+            <Vector3LineComponent label="Value" target={this.props.inputBlock} propertyName="value" onChange={() => {
+                this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            }}></Vector3LineComponent>
         );
     }
 }

+ 1 - 1
nodeEditor/src/sharedComponents/floatLineComponent.tsx

@@ -80,8 +80,8 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
             return;
         }
 
-        this.raiseOnPropertyChanged(valueAsNumber, this._store);
         this.props.target[this.props.propertyName] = valueAsNumber;
+        this.raiseOnPropertyChanged(valueAsNumber, this._store);
 
         this._store = valueAsNumber;
     }

+ 7 - 0
src/Gizmos/lightGizmo.ts

@@ -89,6 +89,13 @@ export class LightGizmo extends Gizmo {
     }
 
     /**
+     * Gets the material used to render the light gizmo
+     */
+    public get material() {
+        return this._material;
+    }
+
+    /**
      * @hidden
      * Updates the gizmo to match the attached mesh's position/rotation
      */

+ 2 - 1
src/Materials/Node/Blocks/Dual/index.ts

@@ -1,4 +1,5 @@
 
 export * from "./fogBlock";
 export * from "./lightBlock";
-export * from "./textureBlock";
+export * from "./textureBlock";
+export * from "./reflectionTextureBlock";

+ 6 - 5
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -167,10 +167,14 @@ export class LightBlock extends NodeMaterialBlock {
 
         // Inject code in vertex
         let worldPosVaryingName = "v_" + worldPos.associatedVariableName;
-        state._emitVaryingFromString(worldPosVaryingName, "vec3");
+        if (state._emitVaryingFromString(worldPosVaryingName, "vec3")) {
+            state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName}.xyz;\r\n`;
+        }
 
         let worldNormalVaryingName = "v_" + worldNormal.associatedVariableName;
-        state._emitVaryingFromString(worldNormalVaryingName, "vec3");
+        if (state._emitVaryingFromString(worldNormalVaryingName, "vec3")) {
+            state.compilationString += `${worldNormalVaryingName} = ${worldNormal.associatedVariableName}.xyz;\r\n`;
+        }
 
         if (this.light) {
             state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
@@ -185,9 +189,6 @@ export class LightBlock extends NodeMaterialBlock {
                 repeatKey: "maxSimultaneousLights"
             });
         }
-
-        state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName}.xyz;\r\n`;
-        state.compilationString += `${worldNormalVaryingName} = ${worldNormal.associatedVariableName}.xyz;\r\n`;
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {

+ 391 - 0
src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts

@@ -0,0 +1,391 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { BaseTexture } from '../../../Textures/baseTexture';
+import { AbstractMesh } from '../../../../Meshes/abstractMesh';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { Effect } from '../../../effect';
+import { Mesh } from '../../../../Meshes/mesh';
+import { Nullable } from '../../../../types';
+import { _TypeStore } from '../../../../Misc/typeStore';
+import { Texture } from '../../../Textures/texture';
+import { Scene } from '../../../../scene';
+import { InputBlock } from '../Input/inputBlock';
+import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { Constants } from '../../../../Engines/constants';
+
+/**
+ * Block used to read a reflection texture from a sampler
+ */
+export class ReflectionTextureBlock extends NodeMaterialBlock {
+    private _define3DName: string;
+    private _defineCubicName: string;
+    private _defineExplicitName: string;
+    private _defineProjectionName: string;
+    private _defineLocalCubicName: string;
+    private _defineSphericalName: string;
+    private _definePlanarName: string;
+    private _defineEquirectangularName: string;
+    private _defineMirroredEquirectangularFixedName: string;
+    private _defineEquirectangularFixedName: string;
+    private _defineSkyboxName: string;
+    private _cubeSamplerName: string;
+    private _2DSamplerName: string;
+    private _positionUVWName: string;
+    private _directionWName: string;
+    private _reflectionCoordsName: string;
+    private _reflection2DCoordsName: string;
+    private _reflectionColorName: string;
+    private _reflectionMatrixName: string;
+
+    /**
+     * Gets or sets the texture associated with the node
+     */
+    public texture: Nullable<BaseTexture>;
+
+    /**
+     * Create a new TextureBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.VertexAndFragment);
+
+        this.registerInput("position", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);
+
+        this.registerInput("cameraPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Fragment);
+
+        this.registerOutput("rgb", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "ReflectionTextureBlock";
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get position(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get worldPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the world normal input component
+     */
+    public get worldNormal(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+     * Gets the world input component
+     */
+    public get world(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
+    }
+
+    /**
+    * Gets the camera (or eye) position component
+    */
+    public get cameraPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[4];
+    }
+
+    /**
+     * Gets the view input component
+     */
+    public get view(): NodeMaterialConnectionPoint {
+        return this._inputs[5];
+    }
+
+    /**
+     * Gets the rgb output component
+     */
+    public get rgb(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Gets the r output component
+     */
+    public get r(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    /**
+     * Gets the g output component
+     */
+    public get g(): NodeMaterialConnectionPoint {
+        return this._outputs[2];
+    }
+
+    /**
+     * Gets the b output component
+     */
+    public get b(): NodeMaterialConnectionPoint {
+        return this._outputs[3];
+    }
+
+    public autoConfigure() {
+        if (!this.position.isConnected) {
+            let positionInput = new InputBlock("position");
+            positionInput.setAsAttribute();
+            positionInput.output.connectTo(this.position);
+        }
+
+        if (!this.world.isConnected) {
+            let worldInput = new InputBlock("world");
+            worldInput.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+            worldInput.output.connectTo(this.world);
+        }
+
+        if (!this.cameraPosition.isConnected) {
+            let cameraPositionInput = new InputBlock("cameraPosition");
+            cameraPositionInput.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+            cameraPositionInput.output.connectTo(this.cameraPosition);
+        }
+
+        if (!this.view.isConnected) {
+            let viewInput = new InputBlock("view");
+            viewInput.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+            viewInput.output.connectTo(this.view);
+        }
+    }
+
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
+        if (!defines._areTexturesDirty) {
+            return;
+        }
+
+        if (!this.texture || !this.texture.getTextureMatrix) {
+            return;
+        }
+
+        defines.setValue(this._define3DName, this.texture.isCube);
+        defines.setValue(this._defineLocalCubicName, (<any>this.texture).boundingBoxSize ? true : false);
+        defines.setValue(this._defineExplicitName, this.texture.coordinatesMode === Constants.TEXTURE_EXPLICIT_MODE);
+        defines.setValue(this._defineSkyboxName, this.texture.coordinatesMode === Constants.TEXTURE_SKYBOX_MODE);
+        defines.setValue(this._defineCubicName, this.texture.coordinatesMode === Constants.TEXTURE_CUBIC_MODE);
+        defines.setValue(this._defineSphericalName, this.texture.coordinatesMode === Constants.TEXTURE_SPHERICAL_MODE);
+        defines.setValue(this._definePlanarName, this.texture.coordinatesMode === Constants.TEXTURE_PLANAR_MODE);
+        defines.setValue(this._defineProjectionName, this.texture.coordinatesMode === Constants.TEXTURE_PROJECTION_MODE);
+        defines.setValue(this._defineEquirectangularName, this.texture.coordinatesMode === Constants.TEXTURE_EQUIRECTANGULAR_MODE);
+        defines.setValue(this._defineEquirectangularFixedName, this.texture.coordinatesMode === Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE);
+        defines.setValue(this._defineMirroredEquirectangularFixedName, this.texture.coordinatesMode === Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE);
+    }
+
+    public isReady() {
+        if (this.texture && !this.texture.isReadyOrNotBlocking()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
+        if (!mesh || !this.texture) {
+            return;
+        }
+
+        effect.setMatrix(this._reflectionMatrixName, this.texture.getReflectionTextureMatrix());
+
+        if (this.texture.isCube) {
+            effect.setTexture(this._cubeSamplerName, this.texture);
+        } else {
+            effect.setTexture(this._2DSamplerName, this.texture);
+        }
+    }
+
+    private _injectVertexCode(state: NodeMaterialBuildState) {
+        let worldPosVaryingName = "v_" + this.worldPosition.associatedVariableName;
+        if (state._emitVaryingFromString(worldPosVaryingName, "vec3")) {
+            state.compilationString += `${worldPosVaryingName} = ${this.worldPosition.associatedVariableName}.xyz;\r\n`;
+        }
+
+        let worldNormalVaryingName = "v_" + this.worldNormal.associatedVariableName;
+        if (state._emitVaryingFromString(worldNormalVaryingName, "vec3")) {
+            state.compilationString += `${worldNormalVaryingName} = ${this.worldNormal.associatedVariableName}.xyz;\r\n`;
+        }
+
+        this._positionUVWName = state._getFreeVariableName("positionUVW");
+        this._directionWName = state._getFreeVariableName("directionW");
+
+        if (state._emitVaryingFromString(this._positionUVWName, "vec3", this._defineSkyboxName)) {
+            state.compilationString += `#ifdef ${this._defineSkyboxName}\r\n`;
+            state.compilationString += `${this._positionUVWName} = ${this.position.associatedVariableName};\r\n`;
+            state.compilationString += `#endif\r\n`;
+        }
+
+        if (state._emitVaryingFromString(this._directionWName, "vec3", `defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})`)) {
+            state.compilationString += `#if defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})\r\n`;
+            state.compilationString += `${this._directionWName} = normalize(vec3(${this.world.associatedVariableName} * vec4(${this.position.associatedVariableName}, 0.0)));\r\n`;
+            state.compilationString += `#endif\r\n`;
+        }
+    }
+
+    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string) {
+        state.compilationString += `${this._declareOutput(output, state)} = ${this._reflectionColorName}.${swizzle};\r\n`;
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        if (state.target !== NodeMaterialBlockTargets.Fragment) {
+            this._define3DName = state._getFreeDefineName("REFLECTIONMAP_3D");
+            this._defineCubicName = state._getFreeDefineName("REFLECTIONMAP_CUBIC");
+            this._defineSphericalName = state._getFreeDefineName("REFLECTIONMAP_SPHERICAL");
+            this._definePlanarName = state._getFreeDefineName("REFLECTIONMAP_PLANAR");
+            this._defineProjectionName = state._getFreeDefineName("REFLECTIONMAP_PROJECTION");
+            this._defineExplicitName = state._getFreeDefineName("REFLECTIONMAP_EXPLICIT");
+            this._defineEquirectangularName = state._getFreeDefineName("REFLECTIONMAP_EQUIRECTANGULAR");
+            this._defineLocalCubicName = state._getFreeDefineName("USE_LOCAL_REFLECTIONMAP_CUBIC");
+            this._defineMirroredEquirectangularFixedName = state._getFreeDefineName("REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED");
+            this._defineEquirectangularFixedName = state._getFreeDefineName("REFLECTIONMAP_EQUIRECTANGULAR_FIXED");
+            this._defineSkyboxName = state._getFreeDefineName("REFLECTIONMAP_SKYBOX");
+
+            // Vertex
+            this._injectVertexCode(state);
+            return;
+        }
+
+        state.sharedData.blockingBlocks.push(this);
+        state.sharedData.textureBlocks.push(this);
+
+        // Samplers
+        this._cubeSamplerName = state._getFreeVariableName(this.name + "CubeSampler");
+        state.samplers.push(this._cubeSamplerName);
+
+        this._2DSamplerName = state._getFreeVariableName(this.name + "2DSampler");
+        state.samplers.push(this._2DSamplerName);
+
+        state._samplerDeclaration += `#ifdef ${this._define3DName}\r\n`;
+        state._samplerDeclaration += `uniform samplerCube ${this._cubeSamplerName};\r\n`;
+        state._samplerDeclaration += `#else\r\n`;
+        state._samplerDeclaration += `uniform sampler2D ${this._2DSamplerName};\r\n`;
+        state._samplerDeclaration += `#endif\r\n`;
+
+        // Fragment
+        state.sharedData.blocksWithDefines.push(this);
+        state.sharedData.bindableBlocks.push(this);
+
+        let comments = `//${this.name}`;
+        state._emitFunction("ReciprocalPI", "#define RECIPROCAL_PI2 0.15915494", "");
+        state._emitFunctionFromInclude("reflectionFunction", comments);
+
+        this._reflectionColorName = state._getFreeVariableName("reflectionColor");
+        this._reflectionCoordsName = state._getFreeVariableName("reflectionUVW");
+        this._reflection2DCoordsName = state._getFreeVariableName("reflectionUV");
+        this._reflectionMatrixName = state._getFreeVariableName("reflectionMatrix");
+
+        state._emitUniformFromString(this._reflectionMatrixName, "mat4");
+
+        // Code
+        let worldPos = `vec4(v_${this.worldPosition.associatedVariableName}, 1.0)`;
+        let worldNormal = "v_" + this.worldNormal.associatedVariableName + ".xyz";
+        let reflectionMatrix = this._reflectionMatrixName;
+        let direction = `normalize(${this._directionWName})`;
+        let positionUVW = `${this._positionUVWName}`;
+        let vEyePosition = `${this.cameraPosition.associatedVariableName}`;
+        let view = `${this.view.associatedVariableName}`;
+
+        state.compilationString += `vec3 ${this._reflectionColorName};\r\n`;
+        state.compilationString += `#ifdef ${this._define3DName}\r\n`;
+        state.compilationString += `#ifdef ${this._defineMirroredEquirectangularFixedName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeMirroredFixedEquirectangularCoords(${worldPos}, ${worldNormal}, ${direction});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineEquirectangularFixedName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeFixedEquirectangularCoords(${worldPos}, ${worldNormal}, ${direction});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineEquirectangularName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeEquirectangularCoords(${worldPos}, ${worldNormal}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n`;
+        state.compilationString += ` #endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineSphericalName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeSphericalCoords(${worldPos}, ${worldNormal}, ${view}, ${reflectionMatrix});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._definePlanarName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computePlanarCoords(${worldPos}, ${worldNormal}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineCubicName}\r\n`;
+        state.compilationString += `    #ifdef ${this._defineLocalCubicName}\r\n`;
+        state.compilationString += `        vec3 ${this._reflectionCoordsName} = computeCubicLocalCoords(${worldPos}, ${worldNormal}, ${vEyePosition}.xyz, ${reflectionMatrix}, vReflectionSize, vReflectionPosition);\r\n`;
+        state.compilationString += `    #else\r\n`;
+        state.compilationString += `       vec3 ${this._reflectionCoordsName} = computeCubicCoords(${worldPos}, ${worldNormal}, ${vEyePosition}.xyz, ${reflectionMatrix});\r\n`;
+        state.compilationString += `    #endif\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineProjectionName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeProjectionCoords(${worldPos}, ${view}, ${reflectionMatrix});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineSkyboxName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = computeSkyBoxCoords(${positionUVW}, ${reflectionMatrix});\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineExplicitName}\r\n`;
+        state.compilationString += `    vec3 ${this._reflectionCoordsName} = vec3(0, 0, 0);\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `${this._reflectionColorName} = textureCube(${this._cubeSamplerName}, ${this._reflectionCoordsName}).rgb;\r\n`;
+        state.compilationString += `#else\r\n`;
+        state.compilationString += `vec2 ${this._reflection2DCoordsName} = ${this._reflectionCoordsName}.xy;\r\n`;
+
+        state.compilationString += `#ifdef ${this._defineProjectionName}\r\n`;
+        state.compilationString += `${this._reflection2DCoordsName} /= ${this._reflectionCoordsName}.z;\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `${this._reflection2DCoordsName}.y = 1.0 - ${this._reflection2DCoordsName}.y;\r\n`;
+        state.compilationString += `${this._reflectionColorName} = texture2D(${this._2DSamplerName}, ${this._reflection2DCoordsName}).rgb;\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        for (var output of this._outputs) {
+            if (output.connectedBlocks.length) {
+                this._writeOutput(state, output, output.name);
+            }
+        }
+
+        return this;
+    }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        if (this.texture) {
+            serializationObject.texture = this.texture.serialize();
+        }
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        if (serializationObject.texture) {
+            this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);
+        }
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.ReflectionTextureBlock"] = ReflectionTextureBlock;

+ 37 - 2
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -69,12 +69,47 @@ export class TextureBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the output component
+     * Gets the rgba output component
      */
-    public get output(): NodeMaterialConnectionPoint {
+    public get rgba(): NodeMaterialConnectionPoint {
         return this._outputs[0];
     }
 
+    /**
+     * Gets the rgb output component
+     */
+    public get rgb(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    /**
+     * Gets the r output component
+     */
+    public get r(): NodeMaterialConnectionPoint {
+        return this._outputs[2];
+    }
+
+    /**
+     * Gets the g output component
+     */
+    public get g(): NodeMaterialConnectionPoint {
+        return this._outputs[3];
+    }
+
+    /**
+     * Gets the b output component
+     */
+    public get b(): NodeMaterialConnectionPoint {
+        return this._outputs[4];
+    }
+
+    /**
+     * Gets the a output component
+     */
+    public get a(): NodeMaterialConnectionPoint {
+        return this._outputs[5];
+    }
+
     public autoConfigure() {
         if (!this.uv.isConnected) {
             let uvInput = new InputBlock("uv");

+ 3 - 3
src/Materials/Node/nodeMaterial.ts

@@ -882,12 +882,12 @@ export class NodeMaterial extends PushMaterial {
         var pixelColor = new InputBlock("color");
         pixelColor.value = new Color4(0.8, 0.8, 0.8, 1);
 
-        var pixelOutput = new FragmentOutputBlock("pixelOutput");
-        pixelColor.connectTo(pixelOutput);
+        var fragmentOutput = new FragmentOutputBlock("fragmentOutput");
+        pixelColor.connectTo(fragmentOutput);
 
         // Add to nodes
         this.addOutputNode(vertexOutput);
-        this.addOutputNode(pixelOutput);
+        this.addOutputNode(fragmentOutput);
     }
 
     private _gatherBlocks(rootNode: NodeMaterialBlock, list: NodeMaterialBlock[]) {

+ 27 - 5
src/Materials/Node/nodeMaterialBlock.ts

@@ -256,6 +256,21 @@ export class NodeMaterialBlock {
     }
 
     /**
+     * Gets the sibling of the given output
+     * @param current defines the current output
+     * @returns the next output in the list or null
+     */
+    public getSiblingOutput(current: NodeMaterialConnectionPoint) {
+        let index = this._outputs.indexOf(current);
+
+        if (index === -1 || index >= this._outputs.length) {
+            return null;
+        }
+
+        return this._outputs[index + 1];
+    }
+
+    /**
      * Connect current block with another block
      * @param other defines the block to connect with
      * @param options define the various options to help pick the right connections
@@ -271,12 +286,19 @@ export class NodeMaterialBlock {
         }
 
         let output = options && options.output ? this.getOutputByName(options.output) : this.getFirstAvailableOutput(other);
-        let input = options && options.input ? other.getInputByName(options.input) : other.getFirstAvailableInput(output);
 
-        if (output && input) {
-            output.connectTo(input);
-        } else {
-            throw "Unable to find a compatible match";
+        let notFound = true;
+        while (notFound) {
+            let input = options && options.input ? other.getInputByName(options.input) : other.getFirstAvailableInput(output);
+
+            if (output && input && output.canConnectTo(input)) {
+                output.connectTo(input);
+                notFound = false;
+            } else if (!output) {
+                throw "Unable to find a compatible match";
+            } else {
+                output = this.getSiblingOutput(output);
+            }
         }
 
         return this;

+ 1 - 1
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -175,7 +175,7 @@ export class NodeMaterialConnectionPoint {
      */
     public canConnectTo(connectionPoint: NodeMaterialConnectionPoint) {
         if (this.type !== connectionPoint.type && connectionPoint.type !== NodeMaterialBlockConnectionPointTypes.AutoDetect) {
-            return (connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1);
+            return (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1);
         }
 
         return true;

+ 9 - 2
src/Materials/Node/nodeMaterialBuildState.ts

@@ -2,6 +2,7 @@ import { NodeMaterialBlockConnectionPointTypes } from './nodeMaterialBlockConnec
 import { NodeMaterialBlockTargets } from './nodeMaterialBlockTargets';
 import { NodeMaterialBuildStateSharedData } from './nodeMaterialBuildStateSharedData';
 import { Effect } from '../effect';
+import { StringTools } from '../../Misc/stringTools';
 
 /**
  * Class used to store node based material build state
@@ -273,18 +274,24 @@ export class NodeMaterialBuildState {
     /** @hidden */
     public _emitVaryingFromString(name: string, type: string, define: string = "", notDefine = false) {
         if (this.sharedData.varyings.indexOf(name) !== -1) {
-            return;
+            return false;
         }
 
         this.sharedData.varyings.push(name);
 
         if (define) {
-            this.sharedData.varyingDeclaration += `${notDefine ? "#ifndef" : "#ifdef"} ${define}\r\n`;
+            if (StringTools.StartsWith(define, "defined(")) {
+                this.sharedData.varyingDeclaration += `#if ${define}\r\n`;
+            } else {
+                this.sharedData.varyingDeclaration += `${notDefine ? "#ifndef" : "#ifdef"} ${define}\r\n`;
+            }
         }
         this.sharedData.varyingDeclaration += `varying ${type} ${name};\r\n`;
         if (define) {
             this.sharedData.varyingDeclaration += `#endif\r\n`;
         }
+
+        return true;
     }
 
     /** @hidden */

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

@@ -2,6 +2,7 @@ import { NodeMaterialConnectionPoint } from './nodeMaterialBlockConnectionPoint'
 import { NodeMaterialBlock } from './nodeMaterialBlock';
 import { InputBlock } from './Blocks/Input/inputBlock';
 import { TextureBlock } from './Blocks/Dual/textureBlock';
+import { ReflectionTextureBlock } from './Blocks/Dual/reflectionTextureBlock';
 
 /**
  * Class used to store shared data between 2 NodeMaterialBuildState
@@ -25,7 +26,7 @@ export class NodeMaterialBuildStateSharedData {
     /**
      * Input blocks
      */
-    public textureBlocks = new Array<TextureBlock>();
+    public textureBlocks = new Array<TextureBlock | ReflectionTextureBlock>();
 
     /**
      * Bindable blocks (Blocks that need to set data to the effect)

+ 1 - 0
src/Materials/effect.ts

@@ -768,6 +768,7 @@ export class Effect implements IDisposable {
             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;

+ 91 - 28
src/Shaders/ShadersInclude/reflectionFunction.fx

@@ -1,5 +1,4 @@
-#ifdef USE_LOCAL_REFLECTIONMAP_CUBIC
-vec3 parallaxCorrectNormal( vec3 vertexPos, vec3 origVec, vec3 cubeSize, vec3 cubePos ) {
+vec3 parallaxCorrectNormal( vec3 vertexPos, vec3 origVec, vec3 cubeSize, vec3 cubePos ) {
 	// Find the ray intersection with box plane
 	vec3 invOrigVec = vec3(1.0,1.0,1.0) / origVec;
 	vec3 halfSize = cubeSize * 0.5;
@@ -14,28 +13,32 @@ vec3 parallaxCorrectNormal( vec3 vertexPos, vec3 origVec, vec3 cubeSize, vec3 cu
 	// Get corrected vector
 	return intersectPositionWS - cubePos;
 }
-#endif
 
-vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
+vec3 computeFixedEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 direction)
 {
-#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)
-	vec3 direction = normalize(vDirectionW);
 	float lon = atan(direction.z, direction.x);
 	float lat = acos(direction.y);
 	vec2 sphereCoords = vec2(lon, lat) * RECIPROCAL_PI2 * 2.0;
 	float s = sphereCoords.x * 0.5 + 0.5;
 	float t = sphereCoords.y;
 
- 	#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED
-		return vec3(1.0 - s, t, 0);
-	#else
-		return vec3(s, t, 0);
-	#endif
-#endif
+	return vec3(s, t, 0);	
+}
 
-#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+vec3 computeMirroredFixedEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 direction)
+{
+	float lon = atan(direction.z, direction.x);
+	float lat = acos(direction.y);
+	vec2 sphereCoords = vec2(lon, lat) * RECIPROCAL_PI2 * 2.0;
+	float s = sphereCoords.x * 0.5 + 0.5;
+	float t = sphereCoords.y;
 
-	vec3 cameraToVertex = normalize(worldPos.xyz - vEyePosition.xyz);
+	return vec3(1.0 - s, t, 0);	
+}
+
+vec3 computeEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix)
+{
+	vec3 cameraToVertex = normalize(worldPos.xyz - eyePosition);
 	vec3 r = normalize(reflect(cameraToVertex, worldNormal));
 	r = vec3(reflectionMatrix * vec4(r, 0));
 	float lon = atan(r.z, r.x);
@@ -45,9 +48,10 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 	float t = sphereCoords.y;
 
 	return vec3(s, t, 0);
-#endif
+}
 
-#ifdef REFLECTIONMAP_SPHERICAL
+vec3 computeSphericalCoords(vec4 worldPos, vec3 worldNormal, mat4 view, mat4 reflectionMatrix)
+{
 	vec3 viewDir = normalize(vec3(view * worldPos));
 	vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
 
@@ -58,44 +62,103 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 	float m = 2.0 * length(r);
 
 	return vec3(r.x / m + 0.5, 1.0 - r.y / m - 0.5, 0);
-#endif
+}
 
-#ifdef REFLECTIONMAP_PLANAR
-	vec3 viewDir = worldPos.xyz - vEyePosition.xyz;
+vec3 computePlanarCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix)
+{
+	vec3 viewDir = worldPos.xyz - eyePosition;
 	vec3 coords = normalize(reflect(viewDir, worldNormal));
 
 	return vec3(reflectionMatrix * vec4(coords, 1));
-#endif
+}
 
-#ifdef REFLECTIONMAP_CUBIC
-    vec3 viewDir = normalize(worldPos.xyz - vEyePosition.xyz);
+vec3 computeCubicCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix)
+{
+    vec3 viewDir = normalize(worldPos.xyz - eyePosition);
 
     // worldNormal has already been normalized.
     vec3 coords = reflect(viewDir, worldNormal);
 
-    #ifdef USE_LOCAL_REFLECTIONMAP_CUBIC
-        coords = parallaxCorrectNormal(worldPos.xyz, coords, vReflectionSize, vReflectionPosition);
+    coords = vec3(reflectionMatrix * vec4(coords, 0));
+
+    #ifdef INVERTCUBICMAP // This is not (yet) supported by Node Material
+        coords.y *= -1.0;
     #endif
 
+    return coords;
+}
+
+vec3 computeCubicLocalCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix, vec3 reflectionSize, vec3 reflectionPosition)
+{
+    vec3 viewDir = normalize(worldPos.xyz - eyePosition);
+
+    // worldNormal has already been normalized.
+    vec3 coords = reflect(viewDir, worldNormal);
+
+	coords = parallaxCorrectNormal(worldPos.xyz, coords, reflectionSize, reflectionPosition);
+
     coords = vec3(reflectionMatrix * vec4(coords, 0));
 
-    #ifdef INVERTCUBICMAP
+    #ifdef INVERTCUBICMAP // This is not (yet) supported by Node Material
         coords.y *= -1.0;
     #endif
 
     return coords;
+}
+
+vec3 computeProjectionCoords(vec4 worldPos, mat4 view, mat4 reflectionMatrix)
+{
+	return vec3(reflectionMatrix * (view * worldPos));
+}
+
+vec3 computeSkyBoxCoords(vec3 positionW, mat4 reflectionMatrix)
+{
+	return vec3(reflectionMatrix * vec4(positionW, 0));
+}
+
+#ifdef REFLECTION
+vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
+{
+#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED
+	vec3 direction = normalize(vDirectionW);
+	return computeMirroredFixedEquirectangularCoords(worldPos, worldNormal, direction);
 #endif
 
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED
+	vec3 direction = normalize(vDirectionW);
+	return computeFixedEquirectangularCoords(worldPos, worldNormal, direction);
+#endif
+
+#ifdef REFLECTIONMAP_EQUIRECTANGULAR
+	return computeEquirectangularCoords(worldPos, worldNormal, vEyePosition.xyz, reflectionMatrix);
+#endif
+
+#ifdef REFLECTIONMAP_SPHERICAL
+	return computeSphericalCoords(worldPos, worldNormal, view, reflectionMatrix);
+#endif
+
+#ifdef REFLECTIONMAP_PLANAR
+	return computePlanarCoords(worldPos, worldNormal, vEyePosition.xyz, reflectionMatrix);
+#endif
+
+#ifdef REFLECTIONMAP_CUBIC
+	#ifdef USE_LOCAL_REFLECTIONMAP_CUBIC
+    	return computeCubicLocalCoords(worldPos, worldNormal, vEyePosition.xyz, reflectionMatrix, vReflectionSize, vReflectionPosition);
+	#else
+    	return computeCubicCoords(worldPos, worldNormal, vEyePosition.xyz, reflectionMatrix);
+	#endif
+#endif
 
 #ifdef REFLECTIONMAP_PROJECTION
-	return vec3(reflectionMatrix * (view * worldPos));
+	return computeProjectionCoords(worldPos, view, reflectionMatrix);
 #endif
 
 #ifdef REFLECTIONMAP_SKYBOX
-	return vec3(reflectionMatrix * vec4(vPositionUVW, 0));
+	return computeSkyBoxCoords(vPositionUVW, reflectionMatrix);
 #endif
 
 #ifdef REFLECTIONMAP_EXPLICIT
 	return vec3(0, 0, 0);
 #endif
-}
+}
+#endif

+ 8 - 8
src/Shaders/default.vertex.fx

@@ -113,9 +113,9 @@ void main(void) {
 
 #ifdef REFLECTIONMAP_SKYBOX
 	#ifdef REFLECTIONMAP_SKYBOX_TRANSFORMED
-		vPositionUVW = (reflectionMatrix * vec4(position, 1.0)).xyz;
+		vPositionUVW = (reflectionMatrix * vec4(positionUpdated, 1.0)).xyz;
 	#else
-		vPositionUVW = position;
+		vPositionUVW = positionUpdated;
 	#endif
 #endif 
 
@@ -126,18 +126,18 @@ void main(void) {
 #include<instancesVertex>
 #include<bonesVertex>
 
+	vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
+
 #ifdef MULTIVIEW
 	if (gl_ViewID_OVR == 0u) {
-		gl_Position = viewProjection * finalWorld * vec4(positionUpdated, 1.0);
+		gl_Position = viewProjection * worldPos;
 	} else {
-		gl_Position = viewProjectionR * finalWorld * vec4(positionUpdated, 1.0);
+		gl_Position = viewProjectionR * worldPos;
 	}
 #else
-	gl_Position = viewProjection * finalWorld * vec4(positionUpdated, 1.0);
-#endif
-	
+	gl_Position = viewProjection * worldPos;
+#endif	
 
-	vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
 	vPositionW = vec3(worldPos);
 
 #ifdef NORMAL