David Catuhe 6 سال پیش
والد
کامیت
dbf1d828f7
34فایلهای تغییر یافته به همراه881 افزوده شده و 2457 حذف شده
  1. 1 61
      Playground/babylon.d.txt
  2. 1 61
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 30 219
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 2 130
      dist/preview release/babylon.module.d.ts
  7. 1 61
      dist/preview release/documentation.d.ts
  8. 2 2
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  9. 13 7
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  10. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  11. 2 130
      dist/preview release/viewer/babylon.module.d.ts
  12. 8 16
      dist/preview release/viewer/babylon.viewer.js
  13. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  14. 95 1189
      localDev/src/webgl-debug.js
  15. 2 0
      nodeEditor/src/components/diagram/input/inputNodeModel.tsx
  16. 24 1
      nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx
  17. 1 3
      nodeEditor/src/components/diagram/input/inputNodeWidget.tsx
  18. 27 1
      nodeEditor/src/graphEditor.tsx
  19. 14 7
      src/Materials/Node/Blocks/Dual/fogBlock.ts
  20. 19 18
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  21. 4 2
      src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts
  22. 51 97
      src/Materials/Node/Blocks/Fragment/textureBlock.ts
  23. 1 0
      src/Materials/Node/Blocks/Input/index.ts
  24. 402 0
      src/Materials/Node/Blocks/Input/inputBlock.ts
  25. 21 10
      src/Materials/Node/Blocks/Vertex/bonesBlock.ts
  26. 16 5
      src/Materials/Node/Blocks/Vertex/instancesBlock.ts
  27. 13 8
      src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts
  28. 1 0
      src/Materials/Node/Blocks/index.ts
  29. 29 27
      src/Materials/Node/nodeMaterial.ts
  30. 28 21
      src/Materials/Node/nodeMaterialBlock.ts
  31. 39 250
      src/Materials/Node/nodeMaterialBlockConnectionPoint.ts
  32. 3 7
      src/Materials/Node/nodeMaterialBlockConnectionPointTypes.ts
  33. 18 118
      src/Materials/Node/nodeMaterialBuildState.ts
  34. 9 2
      src/Materials/Node/nodeMaterialBuildStateSharedData.ts

+ 1 - 61
Playground/babylon.d.txt

@@ -51298,7 +51298,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -51388,36 +51388,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Block used to transform a vector2 with a matrix
      */
     export class Vector2TransformBlock extends NodeMaterialBlock {
@@ -51490,36 +51460,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {

+ 1 - 61
dist/preview release/babylon.d.ts

@@ -52099,7 +52099,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -52189,36 +52189,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Block used to transform a vector2 with a matrix
      */
     export class Vector2TransformBlock extends NodeMaterialBlock {
@@ -52291,36 +52261,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/babylon.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 30 - 219
dist/preview release/babylon.max.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/babylon.max.js.map


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

@@ -54481,7 +54481,7 @@ declare module "babylonjs/Materials/Node/Blocks/multiplyBlock" {
     import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
     import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -54575,39 +54575,6 @@ declare module "babylonjs/Materials/Node/Blocks/clampBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
-declare module "babylonjs/Materials/Node/Blocks/scaleBlock" {
-    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
-    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
-    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
-    /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
 declare module "babylonjs/Materials/Node/Blocks/vector2TransformBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
@@ -54686,39 +54653,6 @@ declare module "babylonjs/Materials/Node/Blocks/vector3TransformBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
-declare module "babylonjs/Materials/Node/Blocks/matrixMultiplicationBlock" {
-    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
-    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
-    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
-    /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
 declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/Vertex/index";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/index";
@@ -54726,11 +54660,9 @@ declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/multiplyBlock";
     export * from "babylonjs/Materials/Node/Blocks/addBlock";
     export * from "babylonjs/Materials/Node/Blocks/clampBlock";
-    export * from "babylonjs/Materials/Node/Blocks/scaleBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector2TransformBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector3TransformBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector4TransformBlock";
-    export * from "babylonjs/Materials/Node/Blocks/matrixMultiplicationBlock";
 }
 declare module "babylonjs/Materials/Node/Optimizers/index" {
     export * from "babylonjs/Materials/Node/Optimizers/nodeMaterialOptimizer";
@@ -115148,7 +115080,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -115238,36 +115170,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Block used to transform a vector2 with a matrix
      */
     export class Vector2TransformBlock extends NodeMaterialBlock {
@@ -115340,36 +115242,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {

+ 1 - 61
dist/preview release/documentation.d.ts

@@ -52099,7 +52099,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -52189,36 +52189,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Block used to transform a vector2 with a matrix
      */
     export class Vector2TransformBlock extends NodeMaterialBlock {
@@ -52291,36 +52261,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 13 - 7
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 2 - 130
dist/preview release/viewer/babylon.module.d.ts

@@ -54481,7 +54481,7 @@ declare module "babylonjs/Materials/Node/Blocks/multiplyBlock" {
     import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
     import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -54575,39 +54575,6 @@ declare module "babylonjs/Materials/Node/Blocks/clampBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
-declare module "babylonjs/Materials/Node/Blocks/scaleBlock" {
-    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
-    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
-    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
-    /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
 declare module "babylonjs/Materials/Node/Blocks/vector2TransformBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
     import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
@@ -54686,39 +54653,6 @@ declare module "babylonjs/Materials/Node/Blocks/vector3TransformBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
-declare module "babylonjs/Materials/Node/Blocks/matrixMultiplicationBlock" {
-    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
-    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
-    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
-    /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
 declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/Vertex/index";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/index";
@@ -54726,11 +54660,9 @@ declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/multiplyBlock";
     export * from "babylonjs/Materials/Node/Blocks/addBlock";
     export * from "babylonjs/Materials/Node/Blocks/clampBlock";
-    export * from "babylonjs/Materials/Node/Blocks/scaleBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector2TransformBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector3TransformBlock";
     export * from "babylonjs/Materials/Node/Blocks/vector4TransformBlock";
-    export * from "babylonjs/Materials/Node/Blocks/matrixMultiplicationBlock";
 }
 declare module "babylonjs/Materials/Node/Optimizers/index" {
     export * from "babylonjs/Materials/Node/Optimizers/nodeMaterialOptimizer";
@@ -115148,7 +115080,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply 2 vector4
+     * Block used to multiply 2 values
      */
     export class MultiplyBlock extends NodeMaterialBlock {
         /**
@@ -115238,36 +115170,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to scale a value
-     */
-    export class ScaleBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new ScaleBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        /**
-         * Gets the value operand input component
-         */
-        readonly value: NodeMaterialConnectionPoint;
-        /**
-         * Gets the scale operand input component
-         */
-        readonly scale: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Block used to transform a vector2 with a matrix
      */
     export class Vector2TransformBlock extends NodeMaterialBlock {
@@ -115340,36 +115242,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Block used to multiply two matrices
-     */
-    export class MatrixMultiplicationBlock extends NodeMaterialBlock {
-        /**
-         * Creates a new MatrixMultiplicationBlock
-         * @param name defines the block name
-         */
-        constructor(name: string);
-        /**
-         * Gets the left operand
-         */
-        readonly left: NodeMaterialConnectionPoint;
-        /**
-         * Gets the right operand
-         */
-        readonly right: NodeMaterialConnectionPoint;
-        /**
-         * Gets the output component
-         */
-        readonly output: NodeMaterialConnectionPoint;
-        /**
-         * Gets the current class name
-         * @returns the class name
-         */
-        getClassName(): string;
-        protected _buildBlock(state: NodeMaterialBuildState): this;
-    }
-}
-declare module BABYLON {
-    /**
      * Helper class to push actions to a pool of workers.
      */
     export class WorkerPool implements IDisposable {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 8 - 16
dist/preview release/viewer/babylon.viewer.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 95 - 1189
localDev/src/webgl-debug.js


+ 2 - 0
nodeEditor/src/components/diagram/input/inputNodeModel.tsx

@@ -3,12 +3,14 @@ import { DefaultNodeModel } from '../defaultNodeModel';
 import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
 import { GlobalState } from '../../../globalState';
 import { InputPropertyTabComponentProps } from './inputNodePropertyComponent';
+import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
 
 /**
  * Generic node model which stores information about a node editor block
  */
 export class InputNodeModel extends DefaultNodeModel {
     public connection?: NodeMaterialConnectionPoint;
+    public outputType: NodeMaterialBlockConnectionPointTypes;
 
 	/**
 	 * Constructs the node model

+ 24 - 1
nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx

@@ -49,6 +49,29 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                     <Vector3PropertyTabComponent globalState={globalState} connection={connection} />
                 );
         }
+
+        switch (this.props.inputNode.outputType) {
+            case NodeMaterialBlockConnectionPointTypes.Float:
+                return (
+                    <FloatPropertyTabComponent globalState={globalState} connection={connection} />
+                );
+            case NodeMaterialBlockConnectionPointTypes.Vector2:
+                return (
+                    <Vector2PropertyTabComponent globalState={globalState} connection={connection} />
+                );
+            case NodeMaterialBlockConnectionPointTypes.Color3:
+            case NodeMaterialBlockConnectionPointTypes.Color3OrColor4:
+            case NodeMaterialBlockConnectionPointTypes.Color4:
+                return (
+                    <Color3PropertyTabComponent globalState={globalState} connection={connection} />
+                );
+            case NodeMaterialBlockConnectionPointTypes.Vector3:
+            case NodeMaterialBlockConnectionPointTypes.Vector3OrColor3:
+                return (
+                    <Vector3PropertyTabComponent globalState={globalState} connection={connection} />
+                );
+        }
+
         return null;
     }
 
@@ -98,7 +121,7 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
         return (
             <div>
                 <LineContainerComponent title="GENERAL">
-                    <TextLineComponent label="Type" value={StringTools.GetBaseType(connection.type)} />
+                    <TextLineComponent label="Type" value={StringTools.GetBaseType(this.props.inputNode.outputType)} />
                 </LineContainerComponent>
                 <LineContainerComponent title="PROPERTIES">
                     <CheckBoxLineComponent label="Is mesh attribute" onSelect={value => {

+ 1 - 3
nodeEditor/src/components/diagram/input/inputNodeWidget.tsx

@@ -89,11 +89,9 @@ export class InputNodeWidget extends React.Component<InputNodeWidgetProps> {
 
         let connection = this.props.node!.connection;
         let value = "";
-        let name = "";
+        let name = StringTools.GetBaseType(this.props.node!.outputType);
 
         if (connection) {
-            name = StringTools.GetBaseType(connection.type)
-
             if (connection.isAttribute) {
                 value = "mesh." + connection.name;
             } else if (connection.isWellKnownValue) {

+ 27 - 1
nodeEditor/src/graphEditor.tsx

@@ -29,6 +29,7 @@ import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
 import { LightNodeModel } from './components/diagram/light/lightNodeModel';
 import { LightNodeFactory } from './components/diagram/light/lightNodeFactory';
 import { DataStorage } from './dataStorage';
+import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
 
 require("storm-react-diagrams/dist/style.min.css");
 require("./main.scss");
@@ -108,7 +109,32 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
         } else {
             newNode = new InputNodeModel();
-            (newNode as InputNodeModel).connection = options.connection;
+            let inputNodeModel = newNode as InputNodeModel;
+            inputNodeModel.connection = options.connection;
+
+            switch (options.type) {
+                case "Float":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Float;
+                    break;
+                case "Vector2":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Vector2;
+                    break;
+                case "Vector3":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Vector3;
+                    break;
+                case "Vector4":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Vector4;
+                    break;
+                case "Matrix":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Matrix;
+                    break;
+                case "Color3":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Color3;
+                    break;
+                case "Color4":
+                    inputNodeModel.outputType = NodeMaterialBlockConnectionPointTypes.Color4;
+                    break;
+            }
         }
         this._nodes.push(newNode)
         newNode.setPosition(1600 - (300 * options.column), 210 * this._rowPos[options.column])

+ 14 - 7
src/Materials/Node/Blocks/Dual/fogBlock.ts

@@ -9,6 +9,7 @@ import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPo
 import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { MaterialHelper } from '../../../materialHelper';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { InputBlock } from '../Input/inputBlock';
 
 /**
  * Block used to add support for scene fog
@@ -86,16 +87,22 @@ export class FogBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure() {
-        if (this.view.isUndefined) {
-            this.view.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+        if (!this.view.isConnected) {
+            let viewInput = new InputBlock("view");
+            viewInput.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+            viewInput.output.connectTo(this.view);
         }
-        if (this.fogColor.isUndefined) {
-            this.fogColor.setAsWellKnownValue(NodeMaterialWellKnownValues.Automatic);
+        if (!this.fogColor.isConnected) {
+            let fogColorInput = new InputBlock("fogColor");
+            fogColorInput.setAsWellKnownValue(NodeMaterialWellKnownValues.Automatic);
+            fogColorInput.output.connectTo(this.fogColor);
         }
-        if (this.fogParameters.isUndefined) {
-            this.fogParameters.setAsWellKnownValue(NodeMaterialWellKnownValues.Automatic);
+        if (!this.fogParameters.isConnected) {
+            let fogParametersInput = new InputBlock("fogParameters");
+            fogParametersInput.setAsWellKnownValue(NodeMaterialWellKnownValues.Automatic);
+            fogParametersInput.output.connectTo(this.fogParameters);
         }
-        this._outputs[0].isVarying = true;
+        this._outputs[0]._needToEmitVarying = true;
     }
 
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {

+ 19 - 18
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -9,6 +9,9 @@ import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
 import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { InputBlock } from '../Input/inputBlock';
+import { Light } from '../../../../Lights/light';
+import { Nullable } from '../../../../types';
 
 /**
  * Block used to add light in the fragment shader
@@ -17,6 +20,11 @@ export class LightBlock extends NodeMaterialBlock {
     private _lightId: number;
 
     /**
+     * Gets or sets the light associated with this block
+     */
+    public light: Nullable<Light>;
+
+    /**
      * Create a new LightBlock
      * @param name defines the block name
      */
@@ -26,7 +34,6 @@ export class LightBlock extends NodeMaterialBlock {
         this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
         this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
 
-        this.registerInput("light", NodeMaterialBlockConnectionPointTypes.Light, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("cameraPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("diffuseOutput", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("specularOutput", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
@@ -55,18 +62,10 @@ export class LightBlock extends NodeMaterialBlock {
     }
 
     /**
-    * Gets the light input component.
-    * If not defined, all lights will be considered
-    */
-    public get light(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
     * Gets the camera (or eye) position component
     */
     public get cameraPosition(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
+        return this._inputs[2];
     }
 
     /**
@@ -84,15 +83,17 @@ export class LightBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure() {
-        if (this.cameraPosition.isUndefined) {
-            this.cameraPosition.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+        if (!this.cameraPosition.isConnected) {
+            let cameraPositionInput = new InputBlock("cameraPosition");
+            cameraPositionInput.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+            cameraPositionInput.output.connectTo(this.cameraPosition);
         }
     }
 
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         const scene = mesh.getScene();
 
-        if (!this.light.value) {
+        if (!this.light) {
             MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, nodeMaterial.maxSimultaneousLights);
         } else {
             let state = {
@@ -103,7 +104,7 @@ export class LightBlock extends NodeMaterialBlock {
                 specularEnabled: false
             };
 
-            MaterialHelper.PrepareDefinesForLight(scene, mesh, this.light.value, this._lightId, defines, true, state);
+            MaterialHelper.PrepareDefinesForLight(scene, mesh, this.light, this._lightId, defines, true, state);
 
             if (state.needRebuild) {
                 defines.rebuild();
@@ -127,10 +128,10 @@ export class LightBlock extends NodeMaterialBlock {
 
         const scene = mesh.getScene();
 
-        if (!this.light.value) {
+        if (!this.light) {
             MaterialHelper.BindLights(scene, mesh, effect, true, nodeMaterial.maxSimultaneousLights, false);
         } else {
-            MaterialHelper.BindLight(this.light.value, this._lightId, scene, mesh, effect, true, false);
+            MaterialHelper.BindLight(this.light, this._lightId, scene, mesh, effect, true, false);
         }
     }
 
@@ -172,7 +173,7 @@ export class LightBlock extends NodeMaterialBlock {
             ]
         });
 
-        if (!this.light.value) { // Emit for all lights
+        if (!this.light) { // Emit for all lights
             state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                 repeatKey: "maxSimultaneousLights"
             });
@@ -203,7 +204,7 @@ export class LightBlock extends NodeMaterialBlock {
             state.compilationString += `vec3 normalW = v_${this.worldNormal.associatedVariableName};\r\n`;
         }
 
-        if (this.light.value) {
+        if (this.light) {
             state.compilationString += state._emitCodeFromInclude("lightFragment", comments, {
                 replaceStrings: [
                     { search: /{X}/g, replace: this._lightId.toString() }

+ 4 - 2
src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts

@@ -19,7 +19,7 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
     public constructor(name: string) {
         super(name, NodeMaterialBlockTargets.Fragment, true);
 
-        this.registerInput("color", NodeMaterialBlockConnectionPointTypes.Color3OrColor4);
+        this.registerInput("color", NodeMaterialBlockConnectionPointTypes.Vector2OrColor3OrColor4);
     }
 
     /**
@@ -43,7 +43,9 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
         let input = this.color;
         state.sharedData.hints.needAlphaBlending = this.alphaBlendingEnabled;
 
-        if (input.connectedPoint && input.connectedPoint!.type === NodeMaterialBlockConnectionPointTypes.Color3) {
+        if (input.connectedPoint && input.connectedPoint!.type === NodeMaterialBlockConnectionPointTypes.Vector2) {
+            state.compilationString += `gl_FragColor = vec4(${input.associatedVariableName}.r, ${input.associatedVariableName}.g, 0., 1.0);\r\n`;
+        } else if (input.connectedPoint && input.connectedPoint!.type === NodeMaterialBlockConnectionPointTypes.Color3) {
             state.compilationString += `gl_FragColor = vec4(${input.associatedVariableName}, 1.0);\r\n`;
         } else {
             state.compilationString += `gl_FragColor = ${input.associatedVariableName};\r\n`;

+ 51 - 97
src/Materials/Node/Blocks/Fragment/textureBlock.ts

@@ -6,22 +6,24 @@ import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPo
 import { BaseTexture } from '../../../Textures/baseTexture';
 import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { InputBlock } from '../Input/inputBlock';
+import { Effect } from '../../../../Materials/effect';
+import { Mesh } from '../../../../Meshes/mesh';
 
 /**
  * Block used to read a texture from a sampler
  */
 export class TextureBlock extends NodeMaterialBlock {
     private _defineName: string;
+    private _samplerName: string;
+    private _transformedUVName: string;
+    private _textureTransformName: string;
+    private _textureInfoName: string;
 
     /**
-     * Gets or sets a boolean indicating that the block can automatically fetch the texture matrix
+     * Gets or sets the texture associated with the node
      */
-    public autoConnectTextureMatrix = true;
-
-    /**
-     * Gets or sets a boolean indicating that the block can automatically select the uv channel based on texture
-     */
-    public autoSelectUV = true;
+    public texture: BaseTexture;
 
     /**
      * Create a new TextureBlock
@@ -31,17 +33,11 @@ export class TextureBlock extends NodeMaterialBlock {
         super(name, NodeMaterialBlockTargets.Fragment);
 
         this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2);
-        this.registerInput("textureInfo", NodeMaterialBlockConnectionPointTypes.Vector2, true);
-
-        this.registerInput("transformedUV", NodeMaterialBlockConnectionPointTypes.Vector2, false, NodeMaterialBlockTargets.Vertex);
-        this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Texture, false, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("textureTransform", NodeMaterialBlockConnectionPointTypes.Matrix, true, NodeMaterialBlockTargets.Vertex);
 
         this.registerOutput("color", NodeMaterialBlockConnectionPointTypes.Color4);
 
         // Setup
         this._inputs[0]._needToEmitVarying = false;
-        this._inputs[0]._forceUniformInVertexShaderOnly = true;
     }
 
     /**
@@ -60,34 +56,6 @@ export class TextureBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the texture information input component
-     */
-    public get textureInfo(): NodeMaterialConnectionPoint {
-        return this._inputs[1];
-    }
-
-    /**
-     * Gets the transformed uv input component
-     */
-    public get transformedUV(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
-     * Gets the texture input component
-     */
-    public get texture(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
-    }
-
-    /**
-     * Gets the texture transform input component
-     */
-    public get textureTransform(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
-    }
-
-    /**
      * Gets the output component
      */
     public get output(): NodeMaterialConnectionPoint {
@@ -95,42 +63,22 @@ export class TextureBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure() {
-        if (this.uv.isUndefined) {
-            this.uv.setAsAttribute();
-            this.uv.connectTo(this.transformedUV);
-        }
-
-        if (this.transformedUV.isUndefined) {
-            this.uv.connectTo(this.transformedUV);
-        }
-    }
-
-    public initialize(state: NodeMaterialBuildState) {
-        if (this.texture.value && this.texture.value.getTextureMatrix) {
-            const texture = this.texture.value as BaseTexture;
-
-            if (this.autoConnectTextureMatrix) {
-                this.textureTransform.valueCallback = () => texture.getTextureMatrix();
-            }
-            if (this.autoSelectUV) {
-                this.uv.setAsAttribute("uv" + (texture.coordinatesIndex ? (texture.coordinatesIndex + 1) : ""));
-            }
+        if (!this.uv.isConnected) {
+            let uvInput = new InputBlock("uv");
+            uvInput.setAsAttribute();
+            uvInput.output.connectTo(this.uv);
         }
     }
 
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
-        if (!this.texture.value || !this.texture.value.getTextureMatrix) {
+        if (!this.texture || !this.texture.getTextureMatrix) {
             return;
         }
 
         let uvInput = this.uv;
-        let textureTransform = this.textureTransform;
-        let isTextureTransformConnected = textureTransform.connectedPoint != null || textureTransform.isUniform;
-
-        const texture = this.texture.value as BaseTexture;
         let mainUVName = ("vMain" + uvInput.associatedVariableName).toUpperCase();
 
-        if (isTextureTransformConnected && !texture.getTextureMatrix().isIdentityAs3x2()) {
+        if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {
             defines.setValue(this._defineName, true);
             defines.setValue(mainUVName, false);
         } else {
@@ -140,43 +88,50 @@ export class TextureBlock extends NodeMaterialBlock {
     }
 
     public isReady() {
-        let texture = this.texture.value as BaseTexture;
-        if (texture && !texture.isReadyOrNotBlocking()) {
+        if (this.texture && !this.texture.isReadyOrNotBlocking()) {
             return false;
         }
 
         return true;
     }
 
+    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
+        if (!mesh) {
+            return;
+        }
+
+        effect.setFloat(this._textureInfoName, this.texture.level);
+        effect.setMatrix(this._textureTransformName, this.texture.getTextureMatrix());
+        effect.setTexture(this._samplerName, this.texture);
+    }
+
     private _injectVertexCode(state: NodeMaterialBuildState) {
         let uvInput = this.uv;
-        let transformedUV = this.transformedUV;
-        let textureTransform = this.textureTransform;
-        let isTextureTransformConnected = textureTransform.connectedPoint != null || textureTransform.isUniform;
 
         // Inject code in vertex
         this._defineName = state._getFreeDefineName("UVTRANSFORM");
         let mainUVName = "vMain" + uvInput.associatedVariableName;
 
-        transformedUV.associatedVariableName = state._getFreeVariableName(transformedUV.name);
-        state._emitVaryings(transformedUV, this._defineName, true);
-        state._emitVaryings(transformedUV, mainUVName.toUpperCase(), true, false, mainUVName);
-
-        textureTransform.associatedVariableName = state._getFreeVariableName(textureTransform.name);
-        state._emitUniformOrAttributes(textureTransform, this._defineName);
-
-        if (isTextureTransformConnected) {
-            if (state.sharedData.emitComments) {
-                state.compilationString += `\r\n//${this.name}\r\n`;
-            }
-            state.compilationString += `#ifdef ${this._defineName}\r\n`;
-            state.compilationString += `${transformedUV.associatedVariableName} = vec2(${textureTransform.associatedVariableName} * vec4(${uvInput.associatedVariableName}, 1.0, 0.0));\r\n`;
-            state.compilationString += `#else\r\n`;
-            state.compilationString += `${mainUVName} = ${uvInput.associatedVariableName};\r\n`;
-            state.compilationString += `#endif\r\n`;
-        } else {
-            state.compilationString += `${mainUVName} = ${uvInput.associatedVariableName};\r\n`;
+        this._transformedUVName = state._getFreeVariableName("transformedUV");
+        this._textureTransformName = state._getFreeVariableName("textureTransform");
+        this._textureInfoName = state._getFreeVariableName("textureInfoName");
+
+        state._emitVaryingFromString(this._transformedUVName, "vec2", this._defineName);
+
+        state.uniforms.push(this._textureTransformName);
+        state.uniforms.push(this._textureInfoName);
+
+        state.compilationString += `mat4 ${this._textureTransformName};\r\n`;
+        state.compilationString += `float ${this._textureInfoName};\r\n`;
+
+        if (state.sharedData.emitComments) {
+            state.compilationString += `\r\n//${this.name}\r\n`;
         }
+        state.compilationString += `#ifdef ${this._defineName}\r\n`;
+        state.compilationString += `${this._transformedUVName} = vec2(${this._textureTransformName} * vec4(${uvInput.associatedVariableName}, 1.0, 0.0));\r\n`;
+        state.compilationString += `#else\r\n`;
+        state.compilationString += `${mainUVName} = ${uvInput.associatedVariableName};\r\n`;
+        state.compilationString += `#endif\r\n`;
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {
@@ -184,6 +139,9 @@ export class TextureBlock extends NodeMaterialBlock {
 
         state.sharedData.blockingBlocks.push(this);
 
+        this._samplerName = state._getFreeVariableName(this.name + "Sampler");
+        state.samplers.push(this._samplerName);
+
         // Vertex
         this._injectVertexCode(state._vertexState);
 
@@ -191,17 +149,13 @@ export class TextureBlock extends NodeMaterialBlock {
         state.sharedData.blocksWithDefines.push(this);
 
         let uvInput = this.uv;
-        let transformedUV = this.transformedUV;
-        let textureInfo = this.textureInfo;
-        let samplerInput = this.texture;
         let output = this._outputs[0];
-        let isTextureInfoConnected = textureInfo.connectedPoint != null || textureInfo.isUniform;
-        const complement = isTextureInfoConnected ? ` * ${textureInfo.associatedVariableName}.y` : "";
+        const complement = ` * ${this._textureInfoName}`;
 
         state.compilationString += `#ifdef ${this._defineName}\r\n`;
-        state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${samplerInput.associatedVariableName}, ${transformedUV.associatedVariableName})${complement};\r\n`;
+        state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${this._samplerName}, ${this._transformedUVName})${complement};\r\n`;
         state.compilationString += `#else\r\n`;
-        state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${samplerInput.associatedVariableName}, ${"vMain" + uvInput.associatedVariableName})${complement};\r\n`;
+        state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${this._samplerName}, ${"vMain" + uvInput.associatedVariableName})${complement};\r\n`;
         state.compilationString += `#endif\r\n`;
 
         return this;

+ 1 - 0
src/Materials/Node/Blocks/Input/index.ts

@@ -0,0 +1 @@
+export * from "./inputBlock";

+ 402 - 0
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -0,0 +1,402 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBlockConnectionPointMode } from '../../NodeMaterialBlockConnectionPointMode';
+import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { Nullable } from '../../../../types';
+import { Effect } from '../../../../Materials/effect';
+import { Matrix } from '../../../../Maths/math';
+import { Scene } from '../../../../scene';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+
+/**
+ * Block used to expose an input value
+ */
+export class InputBlock extends NodeMaterialBlock {
+    private _mode = NodeMaterialBlockConnectionPointMode.Undefined;
+    private _associatedVariableName: string;
+    private _storedValue: any;
+    private _valueCallback: () => any;
+    private _type: NodeMaterialBlockConnectionPointTypes;
+
+    /** @hidden */
+    public _wellKnownValue: Nullable<NodeMaterialWellKnownValues> = null;
+
+    /**
+     * Gets or sets the connection point type (default is float)
+     */
+    public get type(): NodeMaterialBlockConnectionPointTypes {
+        if (this._type === NodeMaterialBlockConnectionPointTypes.AutoDetect) {
+            if (this.isUniform && this.value != null) {
+                if (!isNaN(this.value)) {
+                    return NodeMaterialBlockConnectionPointTypes.Float;
+                }
+
+                switch (this.value.getClassName()) {
+                    case "Vector2":
+                        return NodeMaterialBlockConnectionPointTypes.Vector2;
+                    case "Vector3":
+                        return NodeMaterialBlockConnectionPointTypes.Vector3;
+                    case "Vector4":
+                        return NodeMaterialBlockConnectionPointTypes.Vector4;
+                    case "Color3":
+                        return NodeMaterialBlockConnectionPointTypes.Color3;
+                    case "Color4":
+                        return NodeMaterialBlockConnectionPointTypes.Color4;
+                }
+            }
+
+            if (this.isAttribute) {
+                switch (this.name) {
+                    case "position":
+                    case "normal":
+                    case "tangent":
+                        return NodeMaterialBlockConnectionPointTypes.Vector3;
+                    case "uv":
+                    case "uv2":
+                        return NodeMaterialBlockConnectionPointTypes.Vector2;
+                }
+            }
+
+            if (this.isWellKnownValue) {
+                switch (this._wellKnownValue) {
+                    case NodeMaterialWellKnownValues.World:
+                    case NodeMaterialWellKnownValues.WorldView:
+                    case NodeMaterialWellKnownValues.WorldViewProjection:
+                    case NodeMaterialWellKnownValues.View:
+                    case NodeMaterialWellKnownValues.ViewProjection:
+                    case NodeMaterialWellKnownValues.Projection:
+                        return NodeMaterialBlockConnectionPointTypes.Matrix;
+                    case NodeMaterialWellKnownValues.CameraPosition:
+                        return NodeMaterialBlockConnectionPointTypes.Vector3;
+                }
+            }
+        }
+
+        return this._type;
+    }
+
+    /**
+     * Creates a new InputBlock
+     * @param name defines the block name
+     * @param type defines the type of the input (can be set to NodeMaterialBlockConnectionPointTypes.AutoDetect)
+     */
+    public constructor(name: string, type: NodeMaterialBlockConnectionPointTypes = NodeMaterialBlockConnectionPointTypes.AutoDetect) {
+        super(name, undefined, false, true);
+
+        this._type = type;
+
+        this.registerOutput("output", type);
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Set the source of this connection point to a vertex attribute
+     * @param attributeName defines the attribute name (position, uv, normal, etc...). If not specified it will take the connection point name
+     * @returns the current connection point
+     */
+    public setAsAttribute(attributeName?: string): InputBlock {
+        if (attributeName) {
+            this.name = attributeName;
+        }
+        this._mode = NodeMaterialBlockConnectionPointMode.Attribute;
+        return this;
+    }
+
+    /**
+     * Set the source of this connection point to a well known value
+     * @param value define the well known value to use (world, view, etc...) or null to switch to manual value
+     * @returns the current connection point
+     */
+    public setAsWellKnownValue(value: Nullable<NodeMaterialWellKnownValues>): InputBlock {
+        this.wellKnownValue = value;
+        return this;
+    }
+
+    /**
+     * Gets or sets the value of that point.
+     * Please note that this value will be ignored if valueCallback is defined
+     */
+    public get value(): any {
+        return this._storedValue;
+    }
+
+    public set value(value: any) {
+        this._storedValue = value;
+        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
+    }
+
+    /**
+     * Gets or sets a callback used to get the value of that point.
+     * Please note that setting this value will force the connection point to ignore the value property
+     */
+    public get valueCallback(): () => any {
+        return this._valueCallback;
+    }
+
+    public set valueCallback(value: () => any) {
+        this._valueCallback = value;
+        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
+    }
+
+    /**
+     * Gets or sets the associated variable name in the shader
+     */
+    public get associatedVariableName(): string {
+        return this._associatedVariableName;
+    }
+
+    public set associatedVariableName(value: string) {
+        this._associatedVariableName = value;
+    }
+
+    /**
+     * Gets a boolean indicating that this connection point not defined yet
+     */
+    public get isUndefined(): boolean {
+        return this._mode === NodeMaterialBlockConnectionPointMode.Undefined;
+    }
+
+    /**
+     * Gets or sets a boolean indicating that this connection point is coming from an uniform.
+     * In this case the connection point name must be the name of the uniform to use.
+     * Can only be set on inputs
+     */
+    public get isUniform(): boolean {
+        return this._mode === NodeMaterialBlockConnectionPointMode.Uniform;
+    }
+
+    public set isUniform(value: boolean) {
+        this._mode = value ? NodeMaterialBlockConnectionPointMode.Uniform : NodeMaterialBlockConnectionPointMode.Undefined;
+        this.associatedVariableName = "";
+    }
+
+    /**
+     * Gets or sets a boolean indicating that this connection point is coming from an attribute.
+     * In this case the connection point name must be the name of the attribute to use
+     * Can only be set on inputs
+     */
+    public get isAttribute(): boolean {
+        return this._mode === NodeMaterialBlockConnectionPointMode.Attribute;
+    }
+
+    public set isAttribute(value: boolean) {
+        this._mode = value ? NodeMaterialBlockConnectionPointMode.Attribute : NodeMaterialBlockConnectionPointMode.Undefined;
+        this.associatedVariableName = "";
+    }
+
+    /**
+     * Gets or sets a boolean indicating that this connection point is generating a varying variable.
+     * Can only be set on exit points
+     */
+    public get isVarying(): boolean {
+        return this._mode === NodeMaterialBlockConnectionPointMode.Varying;
+    }
+
+    public set isVarying(value: boolean) {
+        this._mode = value ? NodeMaterialBlockConnectionPointMode.Varying : NodeMaterialBlockConnectionPointMode.Undefined;
+        this.associatedVariableName = "";
+    }
+
+    /**
+     * Gets a boolean indicating that the current connection point is a well known value
+     */
+    public get isWellKnownValue(): boolean {
+        return this._wellKnownValue != null;
+    }
+
+    /**
+     * Gets or sets the current well known value or null if not defined as well know value
+     */
+    public get wellKnownValue(): Nullable<NodeMaterialWellKnownValues> {
+        return this._wellKnownValue;
+    }
+
+    public set wellKnownValue(value: Nullable<NodeMaterialWellKnownValues>) {
+        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
+        this.associatedVariableName = "";
+        this._wellKnownValue = value;
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "InputBlock";
+    }
+
+    private _emitDefine(define: string): string {
+        if (define[0] === "!") {
+            return `#ifndef ${define.substring(1)}\r\n`;
+        }
+
+        return `#ifdef ${define}\r\n`;
+    }
+
+    /** @hidden */
+    public _emit(state: NodeMaterialBuildState, define?: string) {
+        // Uniforms
+        if (this.isUniform) {
+            if (!this.associatedVariableName) {
+                this.associatedVariableName = state._getFreeVariableName("u_" + this.name);
+            }
+
+            if (state.uniforms.indexOf(this.associatedVariableName) !== -1) {
+                return;
+            }
+
+            state.uniforms.push(this.associatedVariableName);
+            if (define) {
+                state._uniformDeclaration += this._emitDefine(define);
+            }
+            state._uniformDeclaration += `uniform ${state._getGLType(this.type)} ${this.associatedVariableName};\r\n`;
+            if (define) {
+                state._uniformDeclaration += `#endif\r\n`;
+            }
+
+            // well known
+            let hints = state.sharedData.hints;
+            if (this._wellKnownValue !== null) {
+                switch (this._wellKnownValue) {
+                    case NodeMaterialWellKnownValues.WorldView:
+                        hints.needWorldViewMatrix = true;
+                        break;
+                    case NodeMaterialWellKnownValues.WorldViewProjection:
+                        hints.needWorldViewProjectionMatrix = true;
+                        break;
+                }
+            }
+
+            return;
+        }
+
+        // Attribute
+        if (this.isAttribute) {
+            this.associatedVariableName = this.name;
+
+            if (this.target === NodeMaterialBlockTargets.Fragment) { // Attribute for fragment need to be carried over by varyings
+                this._emit(state._vertexState, define);
+
+                // if (this._needToEmitVarying) {
+                //     state._vertexState._emitVaryings(point, undefined, true, true, "v_" + this.associatedVariableName);
+                //     this.associatedVariableName = "v_" + this.associatedVariableName;
+                // }
+                return;
+            }
+
+            if (state.attributes.indexOf(this.associatedVariableName) !== -1) {
+                return;
+            }
+
+            state.attributes.push(this.associatedVariableName);
+            if (define) {
+                state._attributeDeclaration += this._emitDefine(define);
+            }
+            state._attributeDeclaration += `attribute ${state._getGLType(this.type)} ${this.associatedVariableName};\r\n`;
+            if (define) {
+                state._attributeDeclaration += `#endif\r\n`;
+            }
+        }
+    }
+
+    /** @hidden */
+    public _transmitWorld(effect: Effect, world: Matrix, worldView: Matrix, worldViewProjection: Matrix) {
+        if (!this._wellKnownValue) {
+            return;
+        }
+
+        let variableName = this.associatedVariableName;
+        switch (this._wellKnownValue) {
+            case NodeMaterialWellKnownValues.World:
+                effect.setMatrix(variableName, world);
+                break;
+            case NodeMaterialWellKnownValues.WorldView:
+                effect.setMatrix(variableName, worldView);
+                break;
+            case NodeMaterialWellKnownValues.WorldViewProjection:
+                effect.setMatrix(variableName, worldViewProjection);
+                break;
+        }
+    }
+
+    /** @hidden */
+    public _transmit(effect: Effect, scene: Scene) {
+        if (this.isAttribute) {
+            return;
+        }
+
+        let variableName = this.associatedVariableName;
+        if (this._wellKnownValue) {
+            switch (this._wellKnownValue) {
+                case NodeMaterialWellKnownValues.World:
+                case NodeMaterialWellKnownValues.WorldView:
+                case NodeMaterialWellKnownValues.WorldViewProjection:
+                    return;
+                case NodeMaterialWellKnownValues.View:
+                    effect.setMatrix(variableName, scene.getViewMatrix());
+                    break;
+                case NodeMaterialWellKnownValues.Projection:
+                    effect.setMatrix(variableName, scene.getProjectionMatrix());
+                    break;
+                case NodeMaterialWellKnownValues.ViewProjection:
+                    effect.setMatrix(variableName, scene.getTransformMatrix());
+                    break;
+                case NodeMaterialWellKnownValues.CameraPosition:
+                    effect.setVector3(variableName, scene.activeCamera!.globalPosition);
+                    break;
+            }
+            return;
+        }
+
+        let value = this._valueCallback ? this._valueCallback() : this._storedValue;
+
+        if (value === null) {
+            return;
+        }
+
+        switch (this.type) {
+            case NodeMaterialBlockConnectionPointTypes.Float:
+                effect.setFloat(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Int:
+                effect.setInt(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Color3:
+                effect.setColor3(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Color4:
+                effect.setDirectColor4(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Vector2:
+                effect.setVector2(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Vector3:
+                effect.setVector3(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Color3OrColor4:
+                effect.setFloat4(variableName, value.r, value.g, value.b, value.a || 1.0);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Vector4OrColor4:
+            case NodeMaterialBlockConnectionPointTypes.Vector4:
+                effect.setVector4(variableName, value);
+                break;
+            case NodeMaterialBlockConnectionPointTypes.Matrix:
+                effect.setMatrix(variableName, value);
+                break;
+        }
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        state.sharedData.inputBlocks.push(this);
+    }
+}

+ 21 - 10
src/Materials/Node/Blocks/Vertex/bonesBlock.ts

@@ -9,6 +9,7 @@ import { Effect, EffectFallbacks } from '../../../effect';
 import { MaterialHelper } from '../../../materialHelper';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { InputBlock } from '../Input/inputBlock';
 
 /**
  * Block used to add support for vertex skinning (bones)
@@ -92,20 +93,30 @@ export class BonesBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure() {
-        if (this.matricesIndices.isUndefined) {
-            this.matricesIndices.setAsAttribute();
+        if (!this.matricesIndices.isConnected) {
+            let matricesIndicesInput = new InputBlock("matricesIndices");
+            matricesIndicesInput.setAsAttribute("matricesIndices");
+            matricesIndicesInput.output.connectTo(this.matricesIndices);
         }
-        if (this.matricesWeights.isUndefined) {
-            this.matricesWeights.setAsAttribute();
+        if (!this.matricesWeights.isConnected) {
+            let matricesWeightsInput = new InputBlock("matricesWeights");
+            matricesWeightsInput.setAsAttribute("matricesWeights");
+            matricesWeightsInput.output.connectTo(this.matricesWeights);
         }
-        if (this.matricesIndicesExtra.isUndefined) {
-            this.matricesIndicesExtra.setAsAttribute();
+        if (!this.matricesIndicesExtra.isConnected) {
+            let matricesIndicesExtraInput = new InputBlock("matricesIndicesExtra");
+            matricesIndicesExtraInput.setAsAttribute("matricesIndicesExtra");
+            matricesIndicesExtraInput.output.connectTo(this.matricesIndicesExtra);
         }
-        if (this.matricesWeightsExtra.isUndefined) {
-            this.matricesWeightsExtra.setAsAttribute();
+        if (!this.matricesWeightsExtra.isConnected) {
+            let matricesWeightsExtraInput = new InputBlock("matricesWeightsExtra");
+            matricesWeightsExtraInput.setAsAttribute("matricesWeightsExtra");
+            matricesWeightsExtraInput.output.connectTo(this.matricesWeightsExtra);
         }
-        if (this.world.isUndefined) {
-            this.world.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+        if (!this.world.isConnected) {
+            let worldInput = new InputBlock("world");
+            worldInput.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+            worldInput.output.connectTo(this.world);
         }
     }
 

+ 16 - 5
src/Materials/Node/Blocks/Vertex/instancesBlock.ts

@@ -6,6 +6,7 @@ import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { InputBlock } from '../Input/inputBlock';
 
 /**
  * Block used to add support for instances
@@ -80,19 +81,29 @@ export class InstancesBlock extends NodeMaterialBlock {
 
     public autoConfigure() {
         if (!this.world0.connectedPoint) {
-            this.world0.setAsAttribute();
+            let world0Input = new InputBlock("world0");
+            world0Input.setAsAttribute("world0");
+            world0Input.output.connectTo(this.world0);
         }
         if (!this.world1.connectedPoint) {
-            this.world1.setAsAttribute();
+            let world1Input = new InputBlock("world1");
+            world1Input.setAsAttribute("world1");
+            world1Input.output.connectTo(this.world1);
         }
         if (!this.world2.connectedPoint) {
-            this.world2.setAsAttribute();
+            let world2Input = new InputBlock("world2");
+            world2Input.setAsAttribute("world2");
+            world2Input.output.connectTo(this.world2);
         }
         if (!this.world3.connectedPoint) {
-            this.world3.setAsAttribute();
+            let world3Input = new InputBlock("world3");
+            world3Input.setAsAttribute("world3");
+            world3Input.output.connectTo(this.world3);
         }
         if (!this.world.connectedPoint) {
-            this.world.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+            let worldInput = new InputBlock("world");
+            worldInput.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+            worldInput.output.connectTo(this.world);
         }
 
         this.world.define = "!INSTANCES";

+ 13 - 8
src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts

@@ -9,6 +9,7 @@ import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
 import { MaterialHelper } from '../../../materialHelper';
 import { VertexBuffer } from '../../../../Meshes/buffer';
+import { InputBlock } from '../Input/inputBlock';
 
 /**
  * Block used to add morph targets support to vertex shader
@@ -103,16 +104,20 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure() {
-        if (this.position.isUndefined) {
-            this.position.setAsAttribute();
+        if (!this.position.isConnected) {
+            let positionInput = new InputBlock("position");
+            positionInput.setAsAttribute("position");
+            positionInput.output.connectTo(this.position);
         }
-        if (this.normal.isUndefined) {
-            this.normal.setAsAttribute();
-            this.normal.define = "NORMAL";
+        if (!this.normal.isConnected) {
+            let normalInput = new InputBlock("normal");
+            normalInput.setAsAttribute("normal");
+            normalInput.output.connectTo(this.normal);
         }
-        if (this.tangent.isUndefined) {
-            this.tangent.setAsAttribute();
-            this.tangent.define = "TANGENT";
+        if (!this.tangent.isConnected) {
+            let tangentInput = new InputBlock("tangent");
+            tangentInput.setAsAttribute("tangent");
+            tangentInput.output.connectTo(this.tangent);
         }
     }
 

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

@@ -1,6 +1,7 @@
 export * from "./Vertex/index";
 export * from "./Fragment/index";
 export * from "./Dual/index";
+export * from "./Input/index";
 export * from "./multiplyBlock";
 export * from "./addBlock";
 export * from "./clampBlock";

+ 29 - 27
src/Materials/Node/nodeMaterial.ts

@@ -8,8 +8,6 @@ import { Engine } from '../../Engines/engine';
 import { NodeMaterialBuildState } from './nodeMaterialBuildState';
 import { EffectCreationOptions, EffectFallbacks } from '../effect';
 import { BaseTexture } from '../../Materials/Textures/baseTexture';
-import { NodeMaterialConnectionPoint } from './nodeMaterialBlockConnectionPoint';
-import { NodeMaterialBlockConnectionPointTypes } from './nodeMaterialBlockConnectionPointTypes';
 import { Observable, Observer } from '../../Misc/observable';
 import { NodeMaterialBlockTargets } from './nodeMaterialBlockTargets';
 import { NodeMaterialBuildStateSharedData } from './nodeMaterialBuildStateSharedData';
@@ -23,6 +21,7 @@ import { Tools } from '../../Misc/tools';
 import { Vector4TransformBlock } from './Blocks/vector4TransformBlock';
 import { VertexOutputBlock } from './Blocks/Vertex/vertexOutputBlock';
 import { FragmentOutputBlock } from './Blocks/Fragment/fragmentOutputBlock';
+import { InputBlock } from './Blocks/Input/inputBlock';
 
 // declare NODEEDITOR namespace for compilation issue
 declare var NODEEDITOR: any;
@@ -102,7 +101,7 @@ export class NodeMaterial extends PushMaterial {
     private _buildWasSuccessful = false;
     private _cachedWorldViewMatrix = new Matrix();
     private _cachedWorldViewProjectionMatrix = new Matrix();
-    private _textureConnectionPoints = new Array<NodeMaterialConnectionPoint>();
+    private _textures: BaseTexture[];
     private _optimizers = new Array<NodeMaterialOptimizer>();
 
     /** Define the URl to load node editor script */
@@ -470,10 +469,7 @@ export class NodeMaterial extends PushMaterial {
         this._vertexCompilationState.finalize(this._vertexCompilationState);
         this._fragmentCompilationState.finalize(this._fragmentCompilationState);
 
-        // Textures
-        this._textureConnectionPoints =
-            this._sharedData.uniformConnectionPoints.filter((u) => u.type === NodeMaterialBlockConnectionPointTypes.Texture || u.type === NodeMaterialBlockConnectionPointTypes.Texture3D);
-
+        this._textures = this._sharedData.textureBlocks.filter((tb) => tb.texture).map((tb) => tb.texture);
         this._buildId++;
 
         // Errors
@@ -677,8 +673,8 @@ export class NodeMaterial extends PushMaterial {
         }
 
         // Connection points
-        for (var connectionPoint of this._sharedData.uniformConnectionPoints) {
-            connectionPoint.transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);
+        for (var inputBlock of this._sharedData.inputBlocks) {
+            inputBlock._transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);
         }
     }
 
@@ -710,8 +706,8 @@ export class NodeMaterial extends PushMaterial {
                 }
 
                 // Connection points
-                for (var connectionPoint of sharedData.uniformConnectionPoints) {
-                    connectionPoint.transmit(effect, scene);
+                for (var inputBlock of sharedData.inputBlocks) {
+                    inputBlock._transmit(effect, scene);
                 }
             }
         }
@@ -726,11 +722,7 @@ export class NodeMaterial extends PushMaterial {
     public getActiveTextures(): BaseTexture[] {
         var activeTextures = super.getActiveTextures();
 
-        for (var connectionPoint of this._textureConnectionPoints) {
-            if (connectionPoint.value) {
-                activeTextures.push(connectionPoint.value);
-            }
-        }
+        activeTextures.push(...this._textures);
 
         return activeTextures;
     }
@@ -745,8 +737,8 @@ export class NodeMaterial extends PushMaterial {
             return true;
         }
 
-        for (var connectionPoint of this._textureConnectionPoints) {
-            if (connectionPoint.value === texture) {
+        for (var t of this._textures) {
+            if (t === texture) {
                 return true;
             }
         }
@@ -763,14 +755,12 @@ export class NodeMaterial extends PushMaterial {
     public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean, notBoundToMesh?: boolean): void {
 
         if (forceDisposeTextures) {
-            for (var connectionPoint of this._textureConnectionPoints) {
-                if (connectionPoint.value) {
-                    (connectionPoint.value as BaseTexture).dispose();
-                }
+            for (var texture of this._textures) {
+                texture.dispose();
             }
         }
 
-        this._textureConnectionPoints = [];
+        this._textures = [];
         this.onBuildObservable.clear();
 
         super.dispose(forceDisposeEffect, forceDisposeTextures, notBoundToMesh);
@@ -822,20 +812,32 @@ export class NodeMaterial extends PushMaterial {
     public setToDefault() {
         this.clear();
 
+        var positionInput = new InputBlock("position");
+        positionInput.setAsAttribute("position");
+
+        var worldInput = new InputBlock("world");
+        worldInput.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.World);
+
         var worldPos = new Vector4TransformBlock("worldPos");
-        worldPos.vector.setAsAttribute("position");
-        worldPos.transform.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.World);
+        positionInput.connectTo(worldPos);
+        worldInput.connectTo(worldPos);
+
+        var viewProjectionInput = new InputBlock("viewProjection");
+        viewProjectionInput.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.ViewProjection);
 
         var worldPosdMultipliedByViewProjection = new Vector4TransformBlock("worldPos * viewProjectionTransform");
         worldPos.connectTo(worldPosdMultipliedByViewProjection);
-        worldPosdMultipliedByViewProjection.transform.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.ViewProjection);
+        viewProjectionInput.connectTo(worldPosdMultipliedByViewProjection);
 
         var vertexOutput = new VertexOutputBlock("vertexOutput");
         worldPosdMultipliedByViewProjection.connectTo(vertexOutput);
 
         // Pixel
+        var pixelColor = new InputBlock("color");
+        pixelColor.value = new Color4(0.8, 0.8, 0.8, 1);
+
         var pixelOutput = new FragmentOutputBlock("pixelOutput");
-        pixelOutput.color.value = new Color4(0.8, 0.8, 0.8, 1);
+        pixelColor.connectTo(pixelOutput);
 
         // Add to nodes
         this.addOutputNode(vertexOutput);

+ 28 - 21
src/Materials/Node/nodeMaterialBlock.ts

@@ -15,6 +15,7 @@ export class NodeMaterialBlock {
     private _buildId: number;
     private _target: NodeMaterialBlockTargets;
     private _isFinalMerger = false;
+    private _isInput = false;
 
     /** @hidden */
     public _inputs = new Array<NodeMaterialConnectionPoint>();
@@ -34,6 +35,13 @@ export class NodeMaterialBlock {
     }
 
     /**
+     * Gets a boolean indicating that this block is an input (e.g. it sends data to the shader)
+     */
+    public get isInput(): boolean {
+        return this._isInput;
+    }
+
+    /**
      * Gets or sets the build Id
      */
     public get buildId(): number {
@@ -105,15 +113,15 @@ export class NodeMaterialBlock {
      * @param name defines the block name
      * @param target defines the target of that block (Vertex by default)
      * @param isFinalMerger defines a boolean indicating that this block is an end block (e.g. it is generating a system value). Default is false
+     * @param isInput defines a boolean indicating that this block is an input (e.g. it sends data to the shader). Default is false
      */
-    public constructor(name: string, target = NodeMaterialBlockTargets.Vertex, isFinalMerger = false) {
+    public constructor(name: string, target = NodeMaterialBlockTargets.Vertex, isFinalMerger = false, isInput = false) {
         this.name = name;
 
         this._target = target;
 
-        if (isFinalMerger) {
-            this._isFinalMerger = true;
-        }
+        this._isFinalMerger = isFinalMerger;
+        this._isInput = isInput;
     }
 
     /**
@@ -135,9 +143,9 @@ export class NodeMaterialBlock {
     }
 
     protected _declareOutput(output: NodeMaterialConnectionPoint, state: NodeMaterialBuildState): string {
-        if (output.isVarying) {
-            return `${output.associatedVariableName}`;
-        }
+        // if (output.isVarying) {
+        //     return `${output.associatedVariableName}`;
+        // }
 
         return `${state._getGLType(output.type)} ${output.associatedVariableName}`;
     }
@@ -211,7 +219,7 @@ export class NodeMaterialBlock {
      */
     public getFirstAvailableInput(forOutput: Nullable<NodeMaterialConnectionPoint> = null) {
         for (var input of this._inputs) {
-            if (!input.isUniform && !input.isAttribute && !input.connectedPoint) {
+            if (!input.connectedPoint) {
                 if (!forOutput || (forOutput.type & input.type) !== 0 || input.type === NodeMaterialBlockConnectionPointTypes.AutoDetect) {
                     return input;
                 }
@@ -268,6 +276,10 @@ export class NodeMaterialBlock {
         // Empty. Must be defined by child nodes
     }
 
+    protected _emit(state: NodeMaterialBuildState, define?: string) {
+        // Empty. Must be defined by child nodes
+    }
+
     /**
      * Add uniforms, samplers and uniform buffers at compilation time
      * @param state defines the state to update
@@ -341,7 +353,7 @@ export class NodeMaterialBlock {
         // Check if "parent" blocks are compiled
         for (var input of this._inputs) {
             if (!input.connectedPoint) {
-                if (!input.isOptional && !input.isAttribute && !input.isUniform) { // Emit a warning
+                if (!input.isOptional) { // Emit a warning
                     state.sharedData.checks.notConnectedNonOptionalInputs.push(input);
                 }
                 continue;
@@ -370,6 +382,10 @@ export class NodeMaterialBlock {
             console.log(`${state.target === NodeMaterialBlockTargets.Vertex ? "Vertex shader" : "Fragment shader"}: Building ${this.name} [${this.getClassName()}]`);
         }
 
+
+        /** Emit input blocks */
+        this._emit(state);
+
         /** Prepare outputs */
         for (var output of this._outputs) {
             if ((output.target & this.target!) === 0) {
@@ -378,19 +394,10 @@ export class NodeMaterialBlock {
             if ((output.target & state.target!) === 0) {
                 continue;
             }
-            output.associatedVariableName = state._getFreeVariableName(output.name);
-            state._emitVaryings(output);
-        }
 
-        // Build
-        for (var input of this._inputs) {
-            if ((input.target & this.target!) === 0) {
-                continue;
-            }
-            if ((input.target & state.target!) === 0) {
-                continue;
+            if (!output.associatedVariableName) {
+                output.associatedVariableName = state._getFreeVariableName(output.name);
             }
-            state._emitUniformOrAttributes(input);
         }
 
         // Checks final outputs
@@ -405,7 +412,7 @@ export class NodeMaterialBlock {
             }
         }
 
-        if (state.sharedData.emitComments) {
+        if (!this.isInput && state.sharedData.emitComments) {
             state.compilationString += `\r\n//${this.name}\r\n`;
         }
 

+ 39 - 250
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -1,11 +1,7 @@
 import { NodeMaterialBlockConnectionPointTypes } from './nodeMaterialBlockConnectionPointTypes';
 import { NodeMaterialBlockTargets } from './nodeMaterialBlockTargets';
 import { Nullable } from '../../types';
-import { Effect } from '../effect';
-import { NodeMaterialWellKnownValues } from './nodeMaterialWellKnownValues';
-import { Scene } from '../../scene';
-import { Matrix } from '../../Maths/math';
-import { NodeMaterialBlockConnectionPointMode } from './NodeMaterialBlockConnectionPointMode';
+import { InputBlock } from './Blocks/Input/inputBlock';
 
 declare type NodeMaterialBlock = import("./nodeMaterialBlock").NodeMaterialBlock;
 
@@ -16,15 +12,10 @@ export class NodeMaterialConnectionPoint {
     /** @hidden */
     public _ownerBlock: NodeMaterialBlock;
     /** @hidden */
-    public _connectedPoint: Nullable<NodeMaterialConnectionPoint>;
-    private _associatedVariableName: string;
-    private _endpoints = new Array<NodeMaterialConnectionPoint>();
-    private _storedValue: any;
-    private _valueCallback: () => any;
-    private _mode = NodeMaterialBlockConnectionPointMode.Undefined;
+    public _connectedPoint: Nullable<NodeMaterialConnectionPoint> = null;
 
-    /** @hidden */
-    public _wellKnownValue: Nullable<NodeMaterialWellKnownValues> = null;
+    private _endpoints = new Array<NodeMaterialConnectionPoint>();
+    private _associatedVariableName: string;
 
     /** @hidden */
     public _typeConnectionSource: Nullable<NodeMaterialConnectionPoint> = null;
@@ -32,36 +23,38 @@ export class NodeMaterialConnectionPoint {
     /** @hidden */
     public _needToEmitVarying = true;
 
-    /** @hidden */
-    public _forceUniformInVertexShaderOnly = false;
-
     private _type = NodeMaterialBlockConnectionPointTypes.Float;
+
+    /**
+     * Gets or sets the associated variable name in the shader
+     */
+    public get associatedVariableName(): string {
+        if (this._ownerBlock.isInput) {
+            return (this._ownerBlock as InputBlock).associatedVariableName;
+        }
+
+        if (this._connectedPoint) {
+            return this._connectedPoint.associatedVariableName;
+        }
+
+        return this._associatedVariableName;
+    }
+
+    public set associatedVariableName(value: string) {
+        this._associatedVariableName = value;
+    }
+
     /**
      * Gets or sets the connection point type (default is float)
      */
     public get type(): NodeMaterialBlockConnectionPointTypes {
         if (this._type === NodeMaterialBlockConnectionPointTypes.AutoDetect) {
-            if (this._connectedPoint) {
-                return this._connectedPoint.type;
+            if (this._ownerBlock.isInput) {
+                return (this._ownerBlock as InputBlock).type;
             }
 
-            if (this.isUniform && this.value != null) {
-                if (!isNaN(this.value)) {
-                    return NodeMaterialBlockConnectionPointTypes.Float;
-                }
-
-                switch (this.value.getClassName()) {
-                    case "Vector2":
-                        return NodeMaterialBlockConnectionPointTypes.Vector2;
-                    case "Vector3":
-                        return NodeMaterialBlockConnectionPointTypes.Vector3;
-                    case "Vector4":
-                        return NodeMaterialBlockConnectionPointTypes.Vector4;
-                    case "Color3":
-                        return NodeMaterialBlockConnectionPointTypes.Color3;
-                    case "Color4":
-                        return NodeMaterialBlockConnectionPointTypes.Color4;
-                }
+            if (this._connectedPoint) {
+                return this._connectedPoint.type;
             }
         }
 
@@ -100,92 +93,28 @@ export class NodeMaterialConnectionPoint {
     public target: NodeMaterialBlockTargets = NodeMaterialBlockTargets.VertexAndFragment;
 
     /**
-     * Gets or sets the value of that point.
-     * Please note that this value will be ignored if valueCallback is defined
+     * Gets a boolean indicating that the current point is connected
      */
-    public get value(): any {
-        return this._storedValue;
-    }
-
-    public set value(value: any) {
-        this._storedValue = value;
-        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
+    public get isConnected(): boolean {
+        return this.connectedPoint !== null;
     }
 
     /**
-     * Gets or sets a callback used to get the value of that point.
-     * Please note that setting this value will force the connection point to ignore the value property
+     * Gets a boolean indicating that the current point is connected to an input block
      */
-    public get valueCallback(): () => any {
-        return this._valueCallback;
-    }
-
-    public set valueCallback(value: () => any) {
-        this._valueCallback = value;
-        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
+    public get isConnectedToInput(): boolean {
+        return this.connectedPoint !== null && this.connectedPoint.ownerBlock.isInput;
     }
 
     /**
-     * Gets or sets the associated variable name in the shader
+     * Gets a the connected input block (if any)
      */
-    public get associatedVariableName(): string {
-        if (!this._associatedVariableName && this._connectedPoint) {
-            return this._connectedPoint.associatedVariableName;
+    public get connectInputBlock(): Nullable<InputBlock> {
+        if (!this.isConnectedToInput) {
+            return null;
         }
 
-        return this._associatedVariableName;
-    }
-
-    public set associatedVariableName(value: string) {
-        this._associatedVariableName = value;
-    }
-
-    /**
-     * Gets a boolean indicating that this connection point not defined yet
-     */
-    public get isUndefined(): boolean {
-        return this._mode === NodeMaterialBlockConnectionPointMode.Undefined;
-    }
-
-    /**
-     * Gets or sets a boolean indicating that this connection point is coming from an uniform.
-     * In this case the connection point name must be the name of the uniform to use.
-     * Can only be set on inputs
-     */
-    public get isUniform(): boolean {
-        return this._mode === NodeMaterialBlockConnectionPointMode.Uniform;
-    }
-
-    public set isUniform(value: boolean) {
-        this._mode = value ? NodeMaterialBlockConnectionPointMode.Uniform : NodeMaterialBlockConnectionPointMode.Undefined;
-        this.associatedVariableName = "";
-    }
-
-    /**
-     * Gets or sets a boolean indicating that this connection point is coming from an attribute.
-     * In this case the connection point name must be the name of the attribute to use
-     * Can only be set on inputs
-     */
-    public get isAttribute(): boolean {
-        return this._mode === NodeMaterialBlockConnectionPointMode.Attribute;
-    }
-
-    public set isAttribute(value: boolean) {
-        this._mode = value ? NodeMaterialBlockConnectionPointMode.Attribute : NodeMaterialBlockConnectionPointMode.Undefined;
-        this.associatedVariableName = "";
-    }
-
-    /**
-     * Gets or sets a boolean indicating that this connection point is generating a varying variable.
-     * Can only be set on exit points
-     */
-    public get isVarying(): boolean {
-        return this._mode === NodeMaterialBlockConnectionPointMode.Varying;
-    }
-
-    public set isVarying(value: boolean) {
-        this._mode = value ? NodeMaterialBlockConnectionPointMode.Varying : NodeMaterialBlockConnectionPointMode.Undefined;
-        this.associatedVariableName = "";
+        return this.connectedPoint!.ownerBlock as InputBlock;
     }
 
     /** Get the other side of the connection (if any) */
@@ -234,49 +163,6 @@ export class NodeMaterialConnectionPoint {
         return "NodeMaterialConnectionPoint";
     }
 
-    /**
-     * Set the source of this connection point to a vertex attribute
-     * @param attributeName defines the attribute name (position, uv, normal, etc...). If not specified it will take the connection point name
-     * @returns the current connection point
-     */
-    public setAsAttribute(attributeName?: string): NodeMaterialConnectionPoint {
-        if (attributeName) {
-            this.name = attributeName;
-        }
-        this._mode = NodeMaterialBlockConnectionPointMode.Attribute;
-        return this;
-    }
-
-    /**
-     * Set the source of this connection point to a well known value
-     * @param value define the well known value to use (world, view, etc...) or null to switch to manual value
-     * @returns the current connection point
-     */
-    public setAsWellKnownValue(value: Nullable<NodeMaterialWellKnownValues>): NodeMaterialConnectionPoint {
-        this.wellKnownValue = value;
-        return this;
-    }
-
-    /**
-     * Gets a boolean indicating that the current connection point is a well known value
-     */
-    public get isWellKnownValue(): boolean {
-        return this._wellKnownValue != null;
-    }
-
-    /**
-     * Gets or sets the current well known value or null if not defined as well know value
-     */
-    public get wellKnownValue(): Nullable<NodeMaterialWellKnownValues> {
-        return this._wellKnownValue;
-    }
-
-    public set wellKnownValue(value: Nullable<NodeMaterialWellKnownValues>) {
-        this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
-        this.associatedVariableName = "";
-        this._wellKnownValue = value;
-    }
-
     private _getTypeLength(type: NodeMaterialBlockConnectionPointTypes) {
         switch (type) {
             case NodeMaterialBlockConnectionPointTypes.Float:
@@ -349,101 +235,4 @@ export class NodeMaterialConnectionPoint {
         endpoint._connectedPoint = null;
         return this;
     }
-
-    /**
-     * When connection point is an uniform, this function will send its value to the effect
-     * @param effect defines the effect to transmit value to
-     * @param world defines the world matrix
-     * @param worldView defines the worldxview matrix
-     * @param worldViewProjection defines the worldxviewxprojection matrix
-     */
-    public transmitWorld(effect: Effect, world: Matrix, worldView: Matrix, worldViewProjection: Matrix) {
-        if (!this._wellKnownValue) {
-            return;
-        }
-
-        let variableName = this.associatedVariableName;
-        switch (this._wellKnownValue) {
-            case NodeMaterialWellKnownValues.World:
-                effect.setMatrix(variableName, world);
-                break;
-            case NodeMaterialWellKnownValues.WorldView:
-                effect.setMatrix(variableName, worldView);
-                break;
-            case NodeMaterialWellKnownValues.WorldViewProjection:
-                effect.setMatrix(variableName, worldViewProjection);
-                break;
-        }
-    }
-
-    /**
-     * When connection point is an uniform, this function will send its value to the effect
-     * @param effect defines the effect to transmit value to
-     * @param scene defines the hosting scene
-     */
-    public transmit(effect: Effect, scene: Scene) {
-        let variableName = this.associatedVariableName;
-        if (this._wellKnownValue) {
-            switch (this._wellKnownValue) {
-                case NodeMaterialWellKnownValues.World:
-                case NodeMaterialWellKnownValues.WorldView:
-                case NodeMaterialWellKnownValues.WorldViewProjection:
-                    return;
-                case NodeMaterialWellKnownValues.View:
-                    effect.setMatrix(variableName, scene.getViewMatrix());
-                    break;
-                case NodeMaterialWellKnownValues.Projection:
-                    effect.setMatrix(variableName, scene.getProjectionMatrix());
-                    break;
-                case NodeMaterialWellKnownValues.ViewProjection:
-                    effect.setMatrix(variableName, scene.getTransformMatrix());
-                    break;
-                case NodeMaterialWellKnownValues.CameraPosition:
-                    effect.setVector3(variableName, scene.activeCamera!.globalPosition);
-                    break;
-            }
-            return;
-        }
-
-        let value = this._valueCallback ? this._valueCallback() : this._storedValue;
-
-        if (value === null) {
-            return;
-        }
-
-        switch (this.type) {
-            case NodeMaterialBlockConnectionPointTypes.Float:
-                effect.setFloat(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Int:
-                effect.setInt(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Color3:
-                effect.setColor3(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Color4:
-                effect.setDirectColor4(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Vector2:
-                effect.setVector2(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Vector3:
-                effect.setVector3(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Color3OrColor4:
-                effect.setFloat4(variableName, value.r, value.g, value.b, value.a || 1.0);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Vector4OrColor4:
-            case NodeMaterialBlockConnectionPointTypes.Vector4:
-                effect.setVector4(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Matrix:
-                effect.setMatrix(variableName, value);
-                break;
-            case NodeMaterialBlockConnectionPointTypes.Texture:
-            case NodeMaterialBlockConnectionPointTypes.Texture3D:
-                effect.setTexture(variableName, value);
-                break;
-        }
-    }
 }

+ 3 - 7
src/Materials/Node/nodeMaterialBlockConnectionPointTypes.ts

@@ -18,10 +18,6 @@ export enum NodeMaterialBlockConnectionPointTypes {
     Color4 = 64,
     /** Matrix */
     Matrix = 128,
-    /** Texture */
-    Texture = 256,
-    /** Texture3D */
-    Texture3D = 512,
     /** Vector3 or Color3 */
     Vector3OrColor3 = Vector3 | Color3,
     /** Vector3 or Vector4 */
@@ -30,12 +26,12 @@ export enum NodeMaterialBlockConnectionPointTypes {
     Vector4OrColor4 = Vector4 | Color4,
     /** Color3 or Color4 */
     Color3OrColor4 = Color3 | Color4,
+    /** Vector2 or Color3 or Color4 */
+    Vector2OrColor3OrColor4 = Vector2 | Color3 | Color4,
     /** Vector3 or Color3 */
     Vector3OrColor3OrVector4OrColor4 = Vector3 | Color3 | Vector4 | Color4,
     /** Detect type based on connection */
     AutoDetect = 1024,
     /** Output type that will be defined by input type */
-    BasedOnInput = 2048,
-    /** Light */
-    Light = 4096
+    BasedOnInput = 2048
 }

+ 18 - 118
src/Materials/Node/nodeMaterialBuildState.ts

@@ -1,6 +1,5 @@
 import { NodeMaterialConnectionPoint } from './nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockConnectionPointTypes } from './nodeMaterialBlockConnectionPointTypes';
-import { NodeMaterialWellKnownValues } from './nodeMaterialWellKnownValues';
 import { NodeMaterialBlockTargets } from './nodeMaterialBlockTargets';
 import { NodeMaterialBuildStateSharedData } from './nodeMaterialBuildStateSharedData';
 import { Effect } from '../effect';
@@ -49,10 +48,14 @@ export class NodeMaterialBuildState {
     /** @hidden */
     public _vertexState: NodeMaterialBuildState;
 
-    private _attributeDeclaration = "";
-    private _uniformDeclaration = "";
-    private _samplerDeclaration = "";
-    private _varyingTransfer = "";
+    /** @hidden */
+    public _attributeDeclaration = "";
+    /** @hidden */
+    public _uniformDeclaration = "";
+    /** @hidden */
+    public _samplerDeclaration = "";
+    /** @hidden */
+    public _varyingTransfer = "";
 
     private _repeatableContentAnchorIndex = 0;
     /** @hidden */
@@ -159,15 +162,9 @@ export class NodeMaterialBuildState {
             case NodeMaterialBlockConnectionPointTypes.Color4:
             case NodeMaterialBlockConnectionPointTypes.Vector4:
             case NodeMaterialBlockConnectionPointTypes.Vector4OrColor4:
-            case NodeMaterialBlockConnectionPointTypes.Vector3OrVector4:
-            case NodeMaterialBlockConnectionPointTypes.Color3OrColor4:
                 return "vec4";
             case NodeMaterialBlockConnectionPointTypes.Matrix:
                 return "mat4";
-            case NodeMaterialBlockConnectionPointTypes.Texture:
-                return "sampler2D";
-            case NodeMaterialBlockConnectionPointTypes.Texture3D:
-                return "sampler3D";
         }
 
         return "";
@@ -280,7 +277,7 @@ export class NodeMaterialBuildState {
     /** @hidden */
     public _emitVaryings(point: NodeMaterialConnectionPoint, define: string = "", force = false, fromFragment = false, replacementName: string = "", type: Nullable<NodeMaterialBlockConnectionPointTypes> = null) {
         let name = replacementName || point.associatedVariableName;
-        if (point.isVarying || force) {
+        if (point._needToEmitVarying || force) {
             if (this.sharedData.varyings.indexOf(name) !== -1) {
                 return;
             }
@@ -290,7 +287,7 @@ export class NodeMaterialBuildState {
             if (define) {
                 this.sharedData.varyingDeclaration += `#ifdef ${define}\r\n`;
             }
-            this.sharedData.varyingDeclaration += `varying ${this._getGLType(type || point.type)} ${name};\r\n`;
+            this.sharedData.varyingDeclaration += `varying ${this._getGLType(point.type)} ${name};\r\n`;
             if (define) {
                 this.sharedData.varyingDeclaration += `#endif\r\n`;
             }
@@ -307,117 +304,20 @@ export class NodeMaterialBuildState {
         }
     }
 
-    private _emitDefine(define: string): string {
-        if (define[0] === "!") {
-            return `#ifndef ${define.substring(1)}\r\n`;
-        }
-
-        return `#ifdef ${define}\r\n`;
-    }
-
     /** @hidden */
-    public _emitUniformOrAttributes(point: NodeMaterialConnectionPoint, define?: string) {
-        define = define || point.define;
-
-        // Lights
-        if (point.type === NodeMaterialBlockConnectionPointTypes.Light) {
-            // Do nothing
+    public _emitVaryingFromString(name: string, type: string, define: string = "") {
+        if (this.sharedData.varyings.indexOf(name) !== -1) {
             return;
         }
 
-        // Samplers
-        if (point.type === NodeMaterialBlockConnectionPointTypes.Texture) {
-            point.name = this._getFreeVariableName(point.name);
-            point.associatedVariableName = point.name;
-
-            if (this.samplers.indexOf(point.name) !== -1) {
-                return;
-            }
-
-            this.samplers.push(point.name);
-            if (define) {
-                this._uniformDeclaration += this._emitDefine(define);
-            }
-            this._samplerDeclaration += `uniform ${this._getGLType(point.type)} ${point.name};\r\n`;
-            if (define) {
-                this._uniformDeclaration += `#endif\r\n`;
-            }
-            this.sharedData.uniformConnectionPoints.push(point);
-            return;
-        }
-
-        if (!point.isUniform && !point.isAttribute) {
-            return;
-        }
-
-        // Uniforms
-        if (point.isUniform) {
-            if (!point.associatedVariableName) {
-                point.associatedVariableName = this._getFreeVariableName("u_" + point.name);
-            }
-
-            if (point._forceUniformInVertexShaderOnly && this._vertexState) { // Uniform for fragment need to be carried over by varyings
-                this._vertexState._emitUniformOrAttributes(point);
-                return;
-            }
-
-            if (this.uniforms.indexOf(point.associatedVariableName) !== -1) {
-                return;
-            }
-
-            this.uniforms.push(point.associatedVariableName);
-            if (define) {
-                this._uniformDeclaration += this._emitDefine(define);
-            }
-            this._uniformDeclaration += `uniform ${this._getGLType(point.type)} ${point.associatedVariableName};\r\n`;
-            if (define) {
-                this._uniformDeclaration += `#endif\r\n`;
-            }
-
-            // well known
-            let hints = this.sharedData.hints;
-            if (point._wellKnownValue !== null) {
-                switch (point._wellKnownValue) {
-                    case NodeMaterialWellKnownValues.WorldView:
-                        hints.needWorldViewMatrix = true;
-                        break;
-                    case NodeMaterialWellKnownValues.WorldViewProjection:
-                        hints.needWorldViewProjectionMatrix = true;
-                        break;
-                }
-            }
+        this.sharedData.varyings.push(name);
 
-            this.sharedData.uniformConnectionPoints.push(point);
-
-            return;
+        if (define) {
+            this.sharedData.varyingDeclaration += `#ifdef ${define}\r\n`;
         }
-
-        // Attribute
-        if (point.isAttribute) {
-            point.associatedVariableName = point.name;
-
-            if (this.target === NodeMaterialBlockTargets.Fragment) { // Attribute for fragment need to be carried over by varyings
-                this._vertexState._emitUniformOrAttributes(point);
-
-                if (point._needToEmitVarying) {
-                    this._vertexState._emitVaryings(point, undefined, true, true, "v_" + point.associatedVariableName);
-                    point.associatedVariableName = "v_" + point.associatedVariableName;
-                }
-                return;
-            }
-
-            if (this.attributes.indexOf(point.associatedVariableName) !== -1) {
-                return;
-            }
-
-            this.attributes.push(point.associatedVariableName);
-            if (define) {
-                this._attributeDeclaration += this._emitDefine(define);
-            }
-            this._attributeDeclaration += `attribute ${this._getGLType(point.type)} ${point.associatedVariableName};\r\n`;
-            if (define) {
-                this._attributeDeclaration += `#endif\r\n`;
-            }
+        this.sharedData.varyingDeclaration += `varying ${type} ${name};\r\n`;
+        if (define) {
+            this.sharedData.varyingDeclaration += `#endif\r\n`;
         }
     }
 }

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

@@ -1,5 +1,7 @@
 import { NodeMaterialConnectionPoint } from './nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlock } from './nodeMaterialBlock';
+import { InputBlock } from './Blocks/Input/inputBlock';
+import { TextureBlock } from './Blocks/Fragment/textureBlock';
 
 /**
  * Class used to store shared data between 2 NodeMaterialBuildState
@@ -16,9 +18,14 @@ export class NodeMaterialBuildStateSharedData {
     public varyingDeclaration = "";
 
     /**
-     * Uniform connection points
+     * Input blocks
      */
-    public uniformConnectionPoints = new Array<NodeMaterialConnectionPoint>();
+    public inputBlocks = new Array<InputBlock>();
+
+    /**
+     * Input blocks
+     */
+    public textureBlocks = new Array<TextureBlock>();
 
     /**
      * Bindable blocks (Blocks that need to set data to the effect)