David Catuhe před 6 roky
rodič
revize
6491e878a5

+ 12 - 12
nodeEditor/src/blockTools.ts

@@ -3,10 +3,10 @@ import { BonesBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/bonesBlock';
 import { InstancesBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/instancesBlock';
 import { MorphTargetsBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/morphTargetsBlock';
 import { ImageProcessingBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/imageProcessingBlock';
-import { RGBAMergerBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbaMergerBlock';
-import { RGBASplitterBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbaSplitterBlock';
-import { RGBMergerBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbMergerBlock';
-import { RGBSplitterBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/rgbSplitterBlock';
+import { ColorMergerBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/colorMergerBlock';
+import { VectorMergerBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/vectorMergerBlock';
+import { ColorSplitterBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/colorSplitterBlock';
+import { VectorSplitterBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/vectorSplitterBlock';
 import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
 import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
 import { FogBlock } from 'babylonjs/Materials/Node/Blocks/Dual/fogBlock';
@@ -33,14 +33,14 @@ export class BlockTools {
                 return new AlphaTestBlock("AlphaTest");
             case "ImageProcessingBlock":
                 return new ImageProcessingBlock("ImageProcessing");
-            case "RGBAMergerBlock":
-                return new RGBAMergerBlock("RGBAMerger");
-            case "RGBASplitterBlock":
-                return new RGBASplitterBlock("RGBASplitter");
-            case "RGBMergerBlock":
-                return new RGBMergerBlock("RGBMerger");
-            case "RGBSplitterBlock":
-                return new RGBSplitterBlock("RGBSplitter");
+            case "ColorMergerBlock":
+                return new ColorMergerBlock("ColorMerger");
+            case "VectorMergerBlock":
+                return new VectorMergerBlock("VectorMerger");                
+            case "ColorSplitterBlock":
+                return new ColorSplitterBlock("ColorSplitter");
+            case "VectorSplitterBlock":
+                return new VectorSplitterBlock("VectorSplitter");
             case "TextureBlock":
                 return new TextureBlock("Texture");
             case "LightBlock":

+ 3 - 3
nodeEditor/src/components/diagram/defaultNodeModel.ts

@@ -31,7 +31,7 @@ export class DefaultNodeModel extends NodeModel {
         }
         // Create output ports
         options.nodeMaterialBlock._outputs.forEach((connection: any) => {
-            var outputPort = new DefaultPortModel(connection.name, "output");
+            var outputPort = new DefaultPortModel(connection.name + "-output", "output");
             outputPort.syncWithNodeMaterialConnectionPoint(connection);
             this.addPort(outputPort)
         })
@@ -42,7 +42,7 @@ export class DefaultNodeModel extends NodeModel {
                 return;
             }
 
-            var inputPort = new DefaultPortModel(connection.name, "input");
+            var inputPort = new DefaultPortModel(connection.name + "-input", "input");
             inputPort.connection = connection;
             this.addPort(inputPort)
 
@@ -56,7 +56,7 @@ export class DefaultNodeModel extends NodeModel {
                     connectedNode = existingNodes[0];
                 }
 
-                let link = connectedNode.ports[connection.connectedPoint.name].link(inputPort);
+                let link = connectedNode.ports[connection.connectedPoint.name + "-output"].link(inputPort);
                 if (graphEditor._toAdd) {
                     graphEditor._toAdd.push(link);
                 } else {

+ 1 - 1
nodeEditor/src/components/diagram/port/defaultPortModel.ts

@@ -37,7 +37,7 @@ export class DefaultPortModel extends PortModel {
 
     syncWithNodeMaterialConnectionPoint(connection: NodeMaterialConnectionPoint) {
         this.connection = connection;
-        this.name = connection.name;
+        this.name = connection.name + "-" + this.position;
     }
 
     getNodeModel() {

+ 2 - 2
nodeEditor/src/components/diagram/portHelper.tsx

@@ -54,7 +54,7 @@ export class PortHelper {
                         {
                             !ignoreLabel &&
                             <div className="output-port-label">
-                                {port.name}
+                                {port.connection!.name}
                             </div>
                         }
                         <div className="output-port-plug">
@@ -111,7 +111,7 @@ export class PortHelper {
                                 </div>                         
                             </div>
                             <div className="input-port-label">
-                                {port.name}
+                                {port.connection!.name}
                             </div>   
                         </div>
                     );

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

@@ -15,9 +15,9 @@ export class NodeListComponent extends React.Component<INodeListComponentProps>
         // Block types used to create the menu from
         const allBlocks = {
             Vertex: ["BonesBlock", "InstancesBlock", "MorphTargetsBlock"],
-            Fragment: ["AlphaTestBlock", "ImageProcessingBlock", "RGBAMergerBlock", "RGBASplitterBlock", "RGBMergerBlock", "RGBSplitterBlock", "TextureBlock", "LightBlock", "FogBlock"],
+            Fragment: ["AlphaTestBlock", "ImageProcessingBlock", "TextureBlock", "LightBlock", "FogBlock"],
             Outputs: ["VertexOutputBlock", "FragmentOutputBlock"],
-            Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "TransformBlock"],
+            Math: ["AddBlock", "ClampBlock", "CrossBlock", "DotBlock", "MultiplyBlock", "TransformBlock", "ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "Matrix"],
         }
 

+ 22 - 14
src/Materials/Node/Blocks/Fragment/rgbMergerBlock.ts

@@ -6,11 +6,11 @@ import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPo
 import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
- * Block used to create a Color3 out of 3 inputs (one for each component)
+ * Block used to create a Color3/4 out of individual inputs (one for each component)
  */
-export class RGBMergerBlock extends NodeMaterialBlock {
+export class ColorMergerBlock extends NodeMaterialBlock {
     /**
-     * Create a new RGBMergerBlock
+     * Create a new ColorMergerBlock
      * @param name defines the block name
      */
     public constructor(name: string) {
@@ -19,8 +19,10 @@ export class RGBMergerBlock extends NodeMaterialBlock {
         this.registerInput("r", NodeMaterialBlockConnectionPointTypes.Float);
         this.registerInput("g", NodeMaterialBlockConnectionPointTypes.Float);
         this.registerInput("b", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerInput("a", NodeMaterialBlockConnectionPointTypes.Float, true);
 
-        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Color3);
+        this.registerOutput("rgba", NodeMaterialBlockConnectionPointTypes.Color4);
+        this.registerOutput("rgb", NodeMaterialBlockConnectionPointTypes.Color3);
     }
 
     /**
@@ -28,35 +30,35 @@ export class RGBMergerBlock extends NodeMaterialBlock {
      * @returns the class name
      */
     public getClassName() {
-        return "RGBMergerBlock";
+        return "ColorMergerBlock";
     }
 
     /**
-     * Gets the R component input
+     * Gets the r component input
      */
     public get r(): NodeMaterialConnectionPoint {
         return this._inputs[0];
     }
 
     /**
-     * Gets the G component input
+     * Gets the g component input
      */
     public get g(): NodeMaterialConnectionPoint {
         return this._inputs[1];
     }
 
     /**
-     * Gets the B component input
+     * Gets the b component input
      */
     public get b(): NodeMaterialConnectionPoint {
         return this._inputs[2];
     }
 
     /**
-     * Gets the output component
+     * Gets the a component input
      */
-    public get output(): NodeMaterialConnectionPoint {
-        return this._outputs[0];
+    public get a(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {
@@ -65,13 +67,19 @@ export class RGBMergerBlock extends NodeMaterialBlock {
         let rInput = this.r;
         let gInput = this.g;
         let bInput = this.b;
+        let aInput = this.a;
 
-        let output = this._outputs[0];
+        let color4Output = this._outputs[0];
+        let color3Output = this._outputs[1];
 
-        state.compilationString += this._declareOutput(output, state) + ` = vec3(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)});\r\n`;
+        if (color4Output.endpoints.length) {
+            state.compilationString += this._declareOutput(color4Output, state) + ` = vec4(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)}, ${aInput.isConnected ? this._writeVariable(aInput) : "0.0"});\r\n`;
+        } else if (color3Output.endpoints.length) {
+            state.compilationString += this._declareOutput(color3Output, state) + ` = vec3(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)});\r\n`;
+        }
 
         return this;
     }
 }
 
-_TypeStore.RegisteredTypes["BABYLON.RGBMergerBlock"] = RGBMergerBlock;
+_TypeStore.RegisteredTypes["BABYLON.ColorMergerBlock"] = ColorMergerBlock;

+ 19 - 9
src/Materials/Node/Blocks/Fragment/rgbaSplitterBlock.ts

@@ -6,18 +6,20 @@ import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPo
 import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
- * Block used to expand a Color4 or a Vector4 into 4 outputs (one for each component)
+ * Block used to expand a Color3/4 into 4 outputs (one for each component)
  */
-export class RGBASplitterBlock extends NodeMaterialBlock {
+export class ColorSplitterBlock extends NodeMaterialBlock {
 
     /**
-     * Create a new RGBASplitterBlock
+     * Create a new ColorSplitterBlock
      * @param name defines the block name
      */
     public constructor(name: string) {
         super(name, NodeMaterialBlockTargets.Fragment);
 
-        this.registerInput("input", NodeMaterialBlockConnectionPointTypes.Color4);
+        this.registerInput("rgba", NodeMaterialBlockConnectionPointTypes.Color4, true);
+        this.registerInput("rgb", NodeMaterialBlockConnectionPointTypes.Color3, true);
+
         this.registerOutput("rgb", NodeMaterialBlockConnectionPointTypes.Color3);
         this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float);
         this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float);
@@ -30,20 +32,28 @@ export class RGBASplitterBlock extends NodeMaterialBlock {
      * @returns the class name
      */
     public getClassName() {
-        return "RGBASplitterBlock";
+        return "ColorSplitterBlock";
     }
 
     /**
-     * Gets the input component
+     * Gets the rgba input component
      */
-    public get input(): NodeMaterialConnectionPoint {
+    public get rgba(): NodeMaterialConnectionPoint {
         return this._inputs[0];
     }
 
+    /**
+     * Gets the rgb input component
+     */
+    public get rgb(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
-        let input = this.input;
+        let input = this.rgba.isConnected ? this.rgba : this.rgb;
+
         let rgbOutput = this._outputs[0];
         let rOutput = this._outputs[1];
         let gOutput = this._outputs[2];
@@ -70,4 +80,4 @@ export class RGBASplitterBlock extends NodeMaterialBlock {
     }
 }
 
-_TypeStore.RegisteredTypes["BABYLON.RGBASplitterBlock"] = RGBASplitterBlock;
+_TypeStore.RegisteredTypes["BABYLON.ColorSplitterBlock"] = ColorSplitterBlock;

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

@@ -1,8 +1,8 @@
 
 export * from "./fragmentOutputBlock";
 export * from "./alphaTestBlock";
-export * from "./rgbaMergerBlock";
-export * from "./rgbMergerBlock";
-export * from "./rgbaSplitterBlock";
-export * from "./rgbSplitterBlock";
+export * from "./colorMergerBlock";
+export * from "./vectorMergerBlock";
+export * from "./colorSplitterBlock";
+export * from "./vectorSplitterBlock";
 export * from "./imageProcessingBlock";

+ 0 - 62
src/Materials/Node/Blocks/Fragment/rgbSplitterBlock.ts

@@ -1,62 +0,0 @@
-import { NodeMaterialBlock } from '../../nodeMaterialBlock';
-import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
-import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
-import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
-import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
-import { _TypeStore } from '../../../../Misc/typeStore';
-
-/**
- * Block used to expand a Color3 or a Vector3 into 3 outputs (one for each component)
- */
-export class RGBSplitterBlock extends NodeMaterialBlock {
-
-    /**
-     * Create a new RGBSplitterBlock
-     * @param name defines the block name
-     */
-    public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Fragment);
-
-        this.registerInput("input", NodeMaterialBlockConnectionPointTypes.Vector3OrColor3);
-        this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float);
-        this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float);
-        this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float);
-    }
-
-    /**
-     * Gets the current class name
-     * @returns the class name
-     */
-    public getClassName() {
-        return "RGBSplitterBlock";
-    }
-
-    /**
-     * Gets the input component
-     */
-    public get input(): NodeMaterialConnectionPoint {
-        return this._inputs[0];
-    }
-
-    protected _buildBlock(state: NodeMaterialBuildState) {
-        super._buildBlock(state);
-
-        let input = this.input;
-        let rOutput = this._outputs[0];
-        let gOutput = this._outputs[1];
-        let bOutput = this._outputs[2];
-
-        if (rOutput.connectedBlocks.length > 0) {
-            state.compilationString += this._declareOutput(rOutput, state) + ` = ${input.associatedVariableName}.r;\r\n`;
-        }
-        if (gOutput.connectedBlocks.length > 0) {
-            state.compilationString += this._declareOutput(gOutput, state) + ` = ${input.associatedVariableName}.g;\r\n`;
-        }
-        if (bOutput.connectedBlocks.length > 0) {
-            state.compilationString += this._declareOutput(bOutput, state) + ` = ${input.associatedVariableName}.b;\r\n`;
-        }
-        return this;
-    }
-}
-
-_TypeStore.RegisteredTypes["BABYLON.RGBSplitterBlock"] = RGBSplitterBlock;

+ 0 - 99
src/Materials/Node/Blocks/Fragment/rgbaMergerBlock.ts

@@ -1,99 +0,0 @@
-import { NodeMaterialBlock } from '../../nodeMaterialBlock';
-import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
-import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
-import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
-import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
-import { _TypeStore } from '../../../../Misc/typeStore';
-
-/**
- * Block used to create a Color4 out of 4 inputs (one for each component)
- */
-export class RGBAMergerBlock extends NodeMaterialBlock {
-    /**
-     * Create a new RGBAMergerBlock
-     * @param name defines the block name
-     */
-    public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Fragment);
-
-        this.registerInput("rgb", NodeMaterialBlockConnectionPointTypes.Vector3OrColor3OrVector4OrColor4, true);
-        this.registerInput("r", NodeMaterialBlockConnectionPointTypes.Float, true);
-        this.registerInput("g", NodeMaterialBlockConnectionPointTypes.Float, true);
-        this.registerInput("b", NodeMaterialBlockConnectionPointTypes.Float, true);
-        this.registerInput("a", NodeMaterialBlockConnectionPointTypes.Float, true);
-
-        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Color4);
-    }
-
-    /**
-     * Gets the current class name
-     * @returns the class name
-     */
-    public getClassName() {
-        return "RGBAMergerBlock";
-    }
-
-    /**
-     * Gets the R input component
-     */
-    public get r(): NodeMaterialConnectionPoint {
-        return this._inputs[1];
-    }
-
-    /**
-     * Gets the G input component
-     */
-    public get g(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
-     * Gets the B input component
-     */
-    public get b(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
-    }
-
-    /**
-     * Gets the RGB input component
-     */
-    public get rgb(): NodeMaterialConnectionPoint {
-        return this._inputs[0];
-    }
-
-    /**
-     * Gets the R input component
-     */
-    public get a(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
-    }
-
-    /**
-     * Gets the output component
-     */
-    public get output(): NodeMaterialConnectionPoint {
-        return this._outputs[0];
-    }
-
-    protected _buildBlock(state: NodeMaterialBuildState) {
-        super._buildBlock(state);
-
-        let rgbInput = this.rgb;
-        let aInput = this.a;
-        let output = this._outputs[0];
-
-        if (rgbInput.connectedPoint) {
-            state.compilationString += this._declareOutput(output, state) + ` = vec4(${rgbInput.associatedVariableName}.rgb, ${this._writeVariable(aInput)});\r\n`;
-        } else {
-            let rInput = this._inputs[0];
-            let gInput = this._inputs[1];
-            let bInput = this._inputs[2];
-
-            state.compilationString += this._declareOutput(output, state) + ` = vec4(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)}, ${this._writeVariable(aInput)});\r\n`;
-        }
-
-        return this;
-    }
-}
-
-_TypeStore.RegisteredTypes["BABYLON.RGBAMergerBlock"] = RGBAMergerBlock;

+ 89 - 0
src/Materials/Node/Blocks/Fragment/vectorMergerBlock.ts

@@ -0,0 +1,89 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
+
+/**
+ * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
+ */
+export class VectorMergerBlock extends NodeMaterialBlock {
+    /**
+     * Create a new VectorMergerBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        this.registerInput("x", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerInput("y", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerInput("z", NodeMaterialBlockConnectionPointTypes.Float, true);
+        this.registerInput("w", NodeMaterialBlockConnectionPointTypes.Float, true);
+
+        this.registerOutput("xyzw", NodeMaterialBlockConnectionPointTypes.Vector4);
+        this.registerOutput("xyz", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerOutput("xy", NodeMaterialBlockConnectionPointTypes.Vector2);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "VectorMergerBlock";
+    }
+
+    /**
+     * Gets the x component input
+     */
+    public get x(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the y component input
+     */
+    public get y(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the z component input
+     */
+    public get z(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+     * Gets the w component input
+     */
+    public get w(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let xInput = this.x;
+        let yInput = this.y;
+        let zInput = this.z;
+        let wInput = this.w;
+
+        let v4Output = this._outputs[0];
+        let v3Output = this._outputs[1];
+        let v2Output = this._outputs[2];
+
+        if (v4Output.endpoints.length) {
+            state.compilationString += this._declareOutput(v4Output, state) + ` = vec4(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)}, ${zInput.isConnected ? this._writeVariable(zInput) : "0.0"}, ${zInput.isConnected ? this._writeVariable(wInput) : "0.0"});\r\n`;
+        } else if (v3Output.endpoints.length) {
+            state.compilationString += this._declareOutput(v3Output, state) + ` = vec3(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)}, ${zInput.isConnected ? this._writeVariable(zInput) : "0.0"});\r\n`;
+        } else if (v2Output.endpoints.length) {
+            state.compilationString += this._declareOutput(v2Output, state) + ` = vec2(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)});\r\n`;
+        }
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.VectorMergerBlock"] = VectorMergerBlock;

+ 83 - 0
src/Materials/Node/Blocks/Fragment/vectorSplitterBlock.ts

@@ -0,0 +1,83 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
+
+/**
+ * Block used to expand a Vector3/4 into 4 outputs (one for each component)
+ */
+export class VectorSplitterBlock extends NodeMaterialBlock {
+
+    /**
+     * Create a new VectorSplitterBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        this.registerInput("xyzw", NodeMaterialBlockConnectionPointTypes.Vector4, true);
+        this.registerInput("xyz", NodeMaterialBlockConnectionPointTypes.Vector3, true);
+
+        this.registerOutput("xyz", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerOutput("x", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerOutput("y", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerOutput("z", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerOutput("w", NodeMaterialBlockConnectionPointTypes.Float);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "VectorSplitterBlock";
+    }
+
+    /**
+     * Gets the rgba input component
+     */
+    public get xyzw(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the rgb input component
+     */
+    public get xyz(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let input = this.xyzw.isConnected ? this.xyzw : this.xyz;
+
+        let xyzOutput = this._outputs[0];
+        let xOutput = this._outputs[1];
+        let yOutput = this._outputs[2];
+        let zOutput = this._outputs[3];
+        let wOutput = this._outputs[4];
+
+        if (xyzOutput.connectedBlocks.length > 0) {
+            state.compilationString += this._declareOutput(xyzOutput, state) + ` = ${input.associatedVariableName}.xyz;\r\n`;
+        }
+        if (xOutput.connectedBlocks.length > 0) {
+            state.compilationString += this._declareOutput(xOutput, state) + ` = ${input.associatedVariableName}.x;\r\n`;
+        }
+        if (yOutput.connectedBlocks.length > 0) {
+            state.compilationString += this._declareOutput(yOutput, state) + ` = ${input.associatedVariableName}.y;\r\n`;
+        }
+        if (zOutput.connectedBlocks.length > 0) {
+            state.compilationString += this._declareOutput(zOutput, state) + ` = ${input.associatedVariableName}.z;\r\n`;
+        }
+        if (wOutput.connectedBlocks.length > 0) {
+            state.compilationString += this._declareOutput(wOutput, state) + ` = ${input.associatedVariableName}.w;\r\n`;
+        }
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.VectorSplitterBlock"] = VectorSplitterBlock;