Browse Source

Shadergraph 2 (#229)

Reworked from the ground up old shadergraph
Valden 2 years ago
parent
commit
fba04f280d
68 changed files with 2179 additions and 2446 deletions
  1. 25 35
      hide/view/Graph.hx
  2. 14 14
      hide/view/shadereditor/Box.hx
  3. 99 59
      hide/view/shadereditor/ShaderEditor.hx
  4. 2 2
      hrt/prefab/ShaderGraph.hx
  5. 1 1
      hrt/prefab/rfx/ScreenShaderGraph.hx
  6. 16 1
      hrt/shader/UVDebug.hx
  7. 164 0
      hrt/shgraph/Macros.hx
  8. 5 270
      hrt/shgraph/NodeVar.hx
  9. 40 41
      hrt/shgraph/Operation.hx
  10. 0 176
      hrt/shgraph/ParseFieldsMacro.hx
  11. 3 3
      hrt/shgraph/ShaderConst.hx
  12. 41 42
      hrt/shgraph/ShaderFunction.hx
  13. 15 17
      hrt/shgraph/ShaderGlobalInput.hx
  14. 550 334
      hrt/shgraph/ShaderGraph.hx
  15. 17 7
      hrt/shgraph/ShaderInput.hx
  16. 79 88
      hrt/shgraph/ShaderNode.hx
  17. 65 0
      hrt/shgraph/ShaderNodeHxsl.hx
  18. 27 15
      hrt/shgraph/ShaderOutput.hx
  19. 15 4
      hrt/shgraph/ShaderParam.hx
  20. 8 13
      hrt/shgraph/nodes/Abs.hx
  21. 8 13
      hrt/shgraph/nodes/Acos.hx
  22. 7 2
      hrt/shgraph/nodes/Add.hx
  23. 8 13
      hrt/shgraph/nodes/Asin.hx
  24. 8 14
      hrt/shgraph/nodes/Atan.hx
  25. 6 10
      hrt/shgraph/nodes/BoolConst.hx
  26. 8 14
      hrt/shgraph/nodes/Ceil.hx
  27. 10 14
      hrt/shgraph/nodes/Clamp.hx
  28. 104 55
      hrt/shgraph/nodes/Color.hx
  29. 9 98
      hrt/shgraph/nodes/Combine.hx
  30. 8 45
      hrt/shgraph/nodes/CombineAlpha.hx
  31. 94 95
      hrt/shgraph/nodes/Cond.hx
  32. 8 13
      hrt/shgraph/nodes/Cos.hx
  33. 9 17
      hrt/shgraph/nodes/Cross.hx
  34. 9 4
      hrt/shgraph/nodes/Divide.hx
  35. 9 10
      hrt/shgraph/nodes/Dot.hx
  36. 8 13
      hrt/shgraph/nodes/Exp.hx
  37. 22 15
      hrt/shgraph/nodes/FloatConst.hx
  38. 8 13
      hrt/shgraph/nodes/Floor.hx
  39. 8 13
      hrt/shgraph/nodes/Fract.hx
  40. 44 45
      hrt/shgraph/nodes/IfCondition.hx
  41. 8 13
      hrt/shgraph/nodes/Length.hx
  42. 8 13
      hrt/shgraph/nodes/Log.hx
  43. 9 17
      hrt/shgraph/nodes/Max.hx
  44. 0 28
      hrt/shgraph/nodes/Maximum.hx
  45. 9 16
      hrt/shgraph/nodes/Min.hx
  46. 0 27
      hrt/shgraph/nodes/Minimum.hx
  47. 10 19
      hrt/shgraph/nodes/Mix.hx
  48. 9 14
      hrt/shgraph/nodes/Mod.hx
  49. 8 4
      hrt/shgraph/nodes/Multiply.hx
  50. 8 12
      hrt/shgraph/nodes/Normalize.hx
  51. 9 13
      hrt/shgraph/nodes/Pow.hx
  52. 55 44
      hrt/shgraph/nodes/Preview.hx
  53. 93 82
      hrt/shgraph/nodes/Sampler.hx
  54. 8 13
      hrt/shgraph/nodes/Saturate.hx
  55. 8 13
      hrt/shgraph/nodes/Sin.hx
  56. 10 19
      hrt/shgraph/nodes/SmoothStep.hx
  57. 15 30
      hrt/shgraph/nodes/Split.hx
  58. 8 13
      hrt/shgraph/nodes/Sqrt.hx
  59. 9 18
      hrt/shgraph/nodes/Step.hx
  60. 10 38
      hrt/shgraph/nodes/StripAlpha.hx
  61. 149 226
      hrt/shgraph/nodes/SubGraph.hx
  62. 8 4
      hrt/shgraph/nodes/Subtract.hx
  63. 8 13
      hrt/shgraph/nodes/Tan.hx
  64. 2 2
      hrt/shgraph/nodes/Text.hx
  65. 105 93
      hrt/shgraph/nodes/UVScroll.hx
  66. 8 13
      hrt/shgraph/nodes/UnpackNormal.hx
  67. 8 11
      hrt/shgraph/nodes/UvToScreen.hx
  68. 16 0
      hrt/shgraph/nodes/test/CalculatedUVNode.hx

+ 25 - 35
hide/view/Graph.hx

@@ -56,6 +56,9 @@ class Graph extends FileView {
 	// used for deleting
 	// used for deleting
 	var currentEdge : Edge;
 	var currentEdge : Edge;
 
 
+	// aaaaaa
+	var domain : hrt.shgraph.ShaderGraph.Domain;
+
 	override function onDisplay() {
 	override function onDisplay() {
 		element.html('
 		element.html('
 			<div class="flex vertical" >
 			<div class="flex vertical" >
@@ -262,21 +265,17 @@ class Graph extends FileView {
 		});
 		});
 		listOfBoxes.push(box);
 		listOfBoxes.push(box);
 
 
-		for (inputKey in box.getInstance().getInputInfoKeys()) {
-			var inputInfo = box.getInstance().getInputInfo(inputKey);
-
-			if (inputInfo == null) {
-				trace(inputKey);
-			}
-
-			var defaultValue = null;
-			if (inputInfo.hasProperty) {
-				defaultValue = Reflect.field(box.getInstance(), 'prop_${inputKey}');
-				if (defaultValue == null) {
-					defaultValue = "0";
-				}
+		for (inputName => inputVar in box.getInstance().getInputs2(domain)) {
+			var defaultValue : String = null;
+			switch (inputVar.def) {
+				case Const(defValue):
+					defaultValue= Reflect.getProperty(box.getInstance().defaults, '${inputName}');
+					if (defaultValue == null) {
+						defaultValue = '$defValue';
+					}
+				default:
 			}
 			}
-			var grNode = box.addInput(editor, inputInfo.name, defaultValue, inputInfo.type);
+			var grNode = box.addInput(editor, inputName, defaultValue, inputVar.v.type);
 			if (defaultValue != null) {
 			if (defaultValue != null) {
 				var fieldEditInput = grNode.find("input");
 				var fieldEditInput = grNode.find("input");
 				fieldEditInput.on("change", function(ev) {
 				fieldEditInput.on("change", function(ev) {
@@ -284,13 +283,14 @@ class Graph extends FileView {
 					if (Math.isNaN(tmpValue) ) {
 					if (Math.isNaN(tmpValue) ) {
 						fieldEditInput.addClass("error");
 						fieldEditInput.addClass("error");
 					} else {
 					} else {
-						Reflect.setField(box.getInstance(), 'prop_${inputKey}', tmpValue);
+						// Store the value as a string anyway
+						Reflect.setField(box.getInstance().defaults, '${inputName}', '$tmpValue');
 						fieldEditInput.val(tmpValue);
 						fieldEditInput.val(tmpValue);
 						fieldEditInput.removeClass("error");
 						fieldEditInput.removeClass("error");
 					}
 					}
 				});
 				});
 			}
 			}
-			grNode.find(".node").attr("field", inputKey);
+			grNode.find(".node").attr("field", inputName);
 			grNode.on("mousedown", function(e : js.jquery.Event) {
 			grNode.on("mousedown", function(e : js.jquery.Event) {
 				e.stopPropagation();
 				e.stopPropagation();
 				var node = grNode.find(".node");
 				var node = grNode.find(".node");
@@ -305,10 +305,9 @@ class Graph extends FileView {
 				setAvailableOutputNodes(box, grNode.find(".node").attr("field"));
 				setAvailableOutputNodes(box, grNode.find(".node").attr("field"));
 			});
 			});
 		}
 		}
-		for (outputKey in box.getInstance().getOutputInfoKeys()) {
-			var outputInfo = box.getInstance().getOutputInfo(outputKey);
-			var grNode = box.addOutput(editor, outputInfo.name, box.getInstance().getOutputType(outputKey));
-			grNode.find(".node").attr("field", outputKey);
+		for (outputName => outputVar in box.getInstance().getOutputs2(domain)) {
+			var grNode = box.addOutput(editor, outputName, outputVar.type);
+			grNode.find(".node").attr("field", outputName);
 			grNode.on("mousedown", function(e) {
 			grNode.on("mousedown", function(e) {
 				e.stopPropagation();
 				e.stopPropagation();
 				var node = grNode.find(".node");
 				var node = grNode.find(".node");
@@ -381,18 +380,14 @@ class Graph extends FileView {
 		}
 		}
 	}
 	}
 
 
+	// TODO(ces) : nuke SType from orbit
 	function setAvailableInputNodes(boxOutput : Box, field : String) {
 	function setAvailableInputNodes(boxOutput : Box, field : String) {
-		var type = boxOutput.getInstance().getOutputType(field);
+		var type = boxOutput.getInstance().getOutputs2(domain)[field].type;
 		var sType : SType;
 		var sType : SType;
-		if (type == null) {
-			sType = boxOutput.getInstance().getOutputInfo(field).type;
-		} else {
-			sType = ShaderType.getSType(type);
-		}
 
 
 		for (box in listOfBoxes) {
 		for (box in listOfBoxes) {
 			for (input in box.inputs) {
 			for (input in box.inputs) {
-				if (box.getInstance().checkTypeAndCompatibilyInput(input.attr("field"), sType)) {
+				if (box.getInstance().checkTypeAndCompatibilyInput(input.attr("field"), type)) {
 					input.addClass("nodeMatch");
 					input.addClass("nodeMatch");
 				}
 				}
 			}
 			}
@@ -403,14 +398,9 @@ class Graph extends FileView {
 		for (box in listOfBoxes) {
 		for (box in listOfBoxes) {
 			for (output in box.outputs) {
 			for (output in box.outputs) {
 				var outputField = output.attr("field");
 				var outputField = output.attr("field");
-				var type = box.getInstance().getOutputType(outputField);
-				var sType : SType;
-				if (type == null) {
-					sType = box.getInstance().getOutputInfo(outputField).type;
-				} else {
-					sType = ShaderType.getSType(type);
-				}
-				if (boxInput.getInstance().checkTypeAndCompatibilyInput(field, sType)) {
+				var type = box.getInstance().getOutputs2(domain)[outputField].type;
+				var sType = ShaderType.getSType(type);
+				if (boxInput.getInstance().checkTypeAndCompatibilyInput(field, type)) {
 					output.addClass("nodeMatch");
 					output.addClass("nodeMatch");
 				}
 				}
 			}
 			}

+ 14 - 14
hide/view/shadereditor/Box.hx

@@ -89,28 +89,28 @@ class Box {
 		//editor.line(element, width/2, HEADER_HEIGHT, width/2, 0, {display: "none"}).addClass("nodes-separator");
 		//editor.line(element, width/2, HEADER_HEIGHT, width/2, 0, {display: "none"}).addClass("nodes-separator");
 	}
 	}
 
 
-	public function addInput(editor : SVG, name : String, valueDefault : String = null, type : hrt.shgraph.ShaderType.SType) {
+	public function addInput(editor : SVG, name : String, valueDefault : String = null, type : hxsl.Ast.Type) {
 		var node = editor.group(element).addClass("input-node-group");
 		var node = editor.group(element).addClass("input-node-group");
 		var nodeHeight = HEADER_HEIGHT + NODE_MARGIN * (inputs.length+1) + NODE_RADIUS * inputs.length;
 		var nodeHeight = HEADER_HEIGHT + NODE_MARGIN * (inputs.length+1) + NODE_RADIUS * inputs.length;
 		var style = {fill : ""}
 		var style = {fill : ""}
 		switch (type) {
 		switch (type) {
-			case Bool:
+			case TBool:
 				style.fill = boolColor;
 				style.fill = boolColor;
-			case Number:
-				style.fill = numberColor;
-			case Float:
+			case TFloat:
 				style.fill = floatColor;
 				style.fill = floatColor;
-			case Vec2:
-				style.fill = vec2Color;
-			case Vec3:
-				style.fill = vec3Color;
-			case Vec4:
-				style.fill = vec4Color;
-			case Sampler:
+			case TVec(size, _):
+				switch (size) {
+					case 2:
+						style.fill = vec2Color;
+					case 3:
+						style.fill = vec3Color;
+					case 4:
+						style.fill = vec4Color;
+				}
+			case TSampler2D:
 				style.fill = samplerColor;
 				style.fill = samplerColor;
 			default:
 			default:
 				style.fill = defaultColor;
 				style.fill = defaultColor;
-
 		}
 		}
 		var nodeCircle = editor.circle(node, 0, nodeHeight, NODE_RADIUS, style).addClass("node input-node");
 		var nodeCircle = editor.circle(node, 0, nodeHeight, NODE_RADIUS, style).addClass("node input-node");
 
 
@@ -166,7 +166,7 @@ class Box {
 		}
 		}
 		var nodeCircle = editor.circle(node, width, nodeHeight, NODE_RADIUS, style).addClass("node output-node");
 		var nodeCircle = editor.circle(node, width, nodeHeight, NODE_RADIUS, style).addClass("node output-node");
 
 
-		if (name.length > 0)
+		if (name.length > 0 && name != "output")
 			editor.text(node, width - NODE_TITLE_PADDING - (name.length * 6.75), nodeHeight + 4, name).addClass("title-node");
 			editor.text(node, width - NODE_TITLE_PADDING - (name.length * 6.75), nodeHeight + 4, name).addClass("title-node");
 
 
 		outputs.push(nodeCircle);
 		outputs.push(nodeCircle);

+ 99 - 59
hide/view/shadereditor/ShaderEditor.hx

@@ -30,6 +30,8 @@ typedef SavedClipboard = {
 class ShaderEditor extends hide.view.Graph {
 class ShaderEditor extends hide.view.Graph {
 
 
 	var parametersList : JQuery;
 	var parametersList : JQuery;
+	var domainSelection : JQuery;
+
 	var draggedParamId : Int;
 	var draggedParamId : Int;
 
 
 	var addMenu : JQuery;
 	var addMenu : JQuery;
@@ -45,6 +47,7 @@ class ShaderEditor extends hide.view.Graph {
 	var obj : h3d.scene.Object;
 	var obj : h3d.scene.Object;
 	var prefabObj : hrt.prefab.Prefab;
 	var prefabObj : hrt.prefab.Prefab;
 	var shaderGraph : ShaderGraph;
 	var shaderGraph : ShaderGraph;
+	var currentGraph : Graph;
 
 
 	var lastSnapshot : haxe.Json;
 	var lastSnapshot : haxe.Json;
 
 
@@ -60,6 +63,8 @@ class ShaderEditor extends hide.view.Graph {
 	override function onDisplay() {
 	override function onDisplay() {
 		super.onDisplay();
 		super.onDisplay();
 		shaderGraph = new ShaderGraph(state.path);
 		shaderGraph = new ShaderGraph(state.path);
+		domain = Fragment;
+
 		addMenu = null;
 		addMenu = null;
 
 
 		element.find("#rightPanel").html('
 		element.find("#rightPanel").html('
@@ -71,7 +76,9 @@ class ShaderEditor extends hide.view.Graph {
 							</div>
 							</div>
 							<div class="options-block hide-block">
 							<div class="options-block hide-block">
 								<input id="createParameter" type="button" value="Add parameter" />
 								<input id="createParameter" type="button" value="Add parameter" />
+								<select id="domainSelection"></select>
 								<input id="launchCompileShader" type="button" value="Compile shader" />
 								<input id="launchCompileShader" type="button" value="Compile shader" />
+
 								<input id="saveShader" type="button" value="Save" />
 								<input id="saveShader" type="button" value="Save" />
 								<div>
 								<div>
 									<input id="changeModel" type="button" value="Change Model" />
 									<input id="changeModel" type="button" value="Change Model" />
@@ -83,6 +90,7 @@ class ShaderEditor extends hide.view.Graph {
 									<input id="displayHxsl" type="button" value="Hxsl" />
 									<input id="displayHxsl" type="button" value="Hxsl" />
 									<input id="displayGlsl" type="button" value="Glsl" />
 									<input id="displayGlsl" type="button" value="Glsl" />
 									<input id="displayHlsl" type="button" value="Hlsl" />
 									<input id="displayHlsl" type="button" value="Hlsl" />
+									<input id="display2" type="button" value="2" />
 								</div>
 								</div>
 								<input id="togglelight" type="button" value="Toggle Default Lights" />
 								<input id="togglelight" type="button" value="Toggle Default Lights" />
 								<input id="refreshGraph" type="button" value="Refresh Shader Graph" />
 								<input id="refreshGraph" type="button" value="Refresh Shader Graph" />
@@ -90,7 +98,7 @@ class ShaderEditor extends hide.view.Graph {
 						</div>)');
 						</div>)');
 		parent.on("drop", function(e) {
 		parent.on("drop", function(e) {
 			var posCursor = new Point(lX(ide.mouseX - 25), lY(ide.mouseY - 10));
 			var posCursor = new Point(lX(ide.mouseX - 25), lY(ide.mouseY - 10));
-			var node = Std.downcast(shaderGraph.addNode(posCursor.x, posCursor.y, ShaderParam), ShaderParam);
+			var node = Std.downcast(currentGraph.addNode(posCursor.x, posCursor.y, ShaderParam), ShaderParam);
 			node.parameterId = draggedParamId;
 			node.parameterId = draggedParamId;
 			var paramShader = shaderGraph.getParameter(draggedParamId);
 			var paramShader = shaderGraph.getParameter(draggedParamId);
 			node.variable = paramShader.variable;
 			node.variable = paramShader.variable;
@@ -112,6 +120,19 @@ class ShaderEditor extends hide.view.Graph {
 			lightsAreOn == true;
 			lightsAreOn == true;
 		}
 		}
 
 
+		domainSelection = element.find("#domainSelection");
+		for (domain in haxe.EnumTools.getConstructors(hrt.shgraph.ShaderGraph.Domain)) {
+			domainSelection.append('<option value="$domain">$domain</option>');
+		};
+
+		domainSelection.val(haxe.EnumTools.EnumValueTools.getName(domain));
+
+		domainSelection.on("change", (e) -> {
+			var domainString : String = domainSelection.val();
+			var domain = haxe.EnumTools.createByName(hrt.shgraph.ShaderGraph.Domain, domainString);
+			setDomain(domain);
+		});
+
 		var def = new hrt.prefab.Library();
 		var def = new hrt.prefab.Library();
 		new hrt.prefab.RenderProps(def).name = "renderer";
 		new hrt.prefab.RenderProps(def).name = "renderer";
 		defaultLight = new hrt.prefab.Light(def);
 		defaultLight = new hrt.prefab.Light(def);
@@ -279,6 +300,16 @@ class ShaderEditor extends hide.view.Graph {
 		element.find("#displayGlsl").on("click", () -> displayCompiled("glsl"));
 		element.find("#displayGlsl").on("click", () -> displayCompiled("glsl"));
 		element.find("#displayHlsl").on("click", () -> displayCompiled("hlsl"));
 		element.find("#displayHlsl").on("click", () -> displayCompiled("hlsl"));
 
 
+		var preview : hrt.shgraph.nodes.Preview = null;
+		for (selected in listOfBoxesSelected) {
+			var asPrev = Std.downcast(selected.getInstance(), hrt.shgraph.nodes.Preview);
+			if (asPrev != null) {
+				preview = asPrev;
+				break;
+			}
+		}
+		element.find("#display2").on("click", () -> {@:privateAccess info(hxsl.Printer.shaderToString(shaderGraph.compile2(preview).shader.data, true));});
+
 		editorMatrix.on("click", "input, select", function(ev) {
 		editorMatrix.on("click", "input, select", function(ev) {
 			beforeChange();
 			beforeChange();
 		});
 		});
@@ -286,7 +317,7 @@ class ShaderEditor extends hide.view.Graph {
 		editorMatrix.on("change", "input, select", function(ev) {
 		editorMatrix.on("change", "input, select", function(ev) {
 			try {
 			try {
 				var idBox = ev.target.closest(".box").id;
 				var idBox = ev.target.closest(".box").id;
-				shaderGraph.nodeUpdated(idBox);
+				//shaderGraph.nodeUpdated(idBox);
 				afterChange();
 				afterChange();
 				launchCompileShader();
 				launchCompileShader();
 			} catch (e : Dynamic) {
 			} catch (e : Dynamic) {
@@ -356,7 +387,7 @@ class ShaderEditor extends hide.view.Graph {
 	}
 	}
 
 
 	override function save() {
 	override function save() {
-		var content = shaderGraph.save();
+		var content = shaderGraph.saveToText();
 		currentSign = ide.makeSignature(content);
 		currentSign = ide.makeSignature(content);
 		sys.io.File.saveContent(getPath(), content);
 		sys.io.File.saveContent(getPath(), content);
 		super.save();
 		super.save();
@@ -448,10 +479,17 @@ class ShaderEditor extends hide.view.Graph {
 		saveDisplayState("useDefaultLights", lightsAreOn);
 		saveDisplayState("useDefaultLights", lightsAreOn);
 	}
 	}
 
 
+	function setDomain(domain: hrt.shgraph.ShaderGraph.Domain) {
+		this.domain = domain;
+		refreshShaderGraph(true);
+	}
+
 	function refreshShaderGraph(readyEvent : Bool = true) {
 	function refreshShaderGraph(readyEvent : Bool = true) {
 		listOfBoxes = [];
 		listOfBoxes = [];
 		listOfEdges = [];
 		listOfEdges = [];
 
 
+		currentGraph = shaderGraph.getGraph(domain);
+
 		var saveToggleParams = new Map<Int, Bool>();
 		var saveToggleParams = new Map<Int, Bool>();
 		for (pElt in parametersList.find(".parameter").elements()) {
 		for (pElt in parametersList.find(".parameter").elements()) {
 			saveToggleParams.set(Std.parseInt(pElt.get()[0].id.split("_")[1]), pElt.find(".content").css("display") != "none");
 			saveToggleParams.set(Std.parseInt(pElt.get()[0].id.split("_")[1]), pElt.find(".content").css("display") != "none");
@@ -461,7 +499,7 @@ class ShaderEditor extends hide.view.Graph {
 
 
 		updateMatrix();
 		updateMatrix();
 
 
-		for (node in shaderGraph.getNodes()) {
+		for (node in currentGraph.getNodes()) {
 			var shaderPreview = Std.downcast(node.instance, hrt.shgraph.nodes.Preview);
 			var shaderPreview = Std.downcast(node.instance, hrt.shgraph.nodes.Preview);
 			if (shaderPreview != null) {
 			if (shaderPreview != null) {
 				shaderPreview.config = config;
 				shaderPreview.config = config;
@@ -474,7 +512,7 @@ class ShaderEditor extends hide.view.Graph {
 				var paramShader = shaderGraph.getParameter(paramNode.parameterId);
 				var paramShader = shaderGraph.getParameter(paramNode.parameterId);
 				paramNode.setName(paramShader.name);
 				paramNode.setName(paramShader.name);
 				setDisplayValue(paramNode, paramShader.type, paramShader.defaultValue);
 				setDisplayValue(paramNode, paramShader.type, paramShader.defaultValue);
-				shaderGraph.nodeUpdated(paramNode.id);
+				//shaderGraph.nodeUpdated(paramNode.id);
 				addBox(new Point(node.x, node.y), ShaderParam, paramNode);
 				addBox(new Point(node.x, node.y), ShaderParam, paramNode);
 			} else {
 			} else {
 				addBox(new Point(node.x, node.y), std.Type.getClass(node.instance), node.instance);
 				addBox(new Point(node.x, node.y), std.Type.getClass(node.instance), node.instance);
@@ -515,40 +553,33 @@ class ShaderEditor extends hide.view.Graph {
 	}
 	}
 
 
 	function generateEdgesFromBox(box : Box) {
 	function generateEdgesFromBox(box : Box) {
-		for (outputKey in box.getInstance().getOutputInfoKeys()) {
-			var output = box.getInstance().getOutput(outputKey);
-			if (output != null) {
-				for (b in listOfBoxes) {
-					for (key in b.getInstance().getInputsKey()) {
-						var input = b.getInstance().getInput(key);
-						if (input != null && input.node.id == box.getId() && input.keyOutput == outputKey) {
-							var nodeFrom = box.getElement().find('[field=${outputKey}]');
-							var nodeTo = b.getElement().find('[field=${key}]');
-							edgeStyle.stroke = nodeFrom.css("fill");
-							createEdgeInEditorGraph({from: box, nodeFrom: nodeFrom, to : b, nodeTo: nodeTo, elt : createCurve(nodeFrom, nodeTo) });
-						}
-					}
+
+		for (b in listOfBoxes) {
+			for (inputName => connection in b.getInstance().connections) {
+				if (connection.from.id == box.getId()) {
+					var nodeFrom = box.getElement().find('[field=${connection.fromName}]');
+					var nodeTo = b.getElement().find('[field=${inputName}]');
+					edgeStyle.stroke = nodeFrom.css("fill");
+					createEdgeInEditorGraph({from: box, nodeFrom: nodeFrom, to : b, nodeTo: nodeTo, elt : createCurve(nodeFrom, nodeTo) });
 				}
 				}
+
 			}
 			}
 		}
 		}
 	}
 	}
 
 
 	function generateEdgesToBox(box : Box) {
 	function generateEdgesToBox(box : Box) {
-		for (key in box.getInstance().getInputsKey()) {
-			var input = box.getInstance().getInput(key);
-			if (input != null) {
-				var fromBox : Box = null;
-				for (boxFrom in listOfBoxes) {
-					if (boxFrom.getId() == input.node.id) {
-						fromBox = boxFrom;
-						break;
-					}
+		for (inputName => connection in box.getInstance().connections) {
+			var fromBox : Box = null;
+			for (boxFrom in listOfBoxes) {
+				if (boxFrom.getId() == connection.from.id) {
+					fromBox = boxFrom;
+					break;
 				}
 				}
-				var nodeFrom = fromBox.getElement().find('[field=${input.getKey()}]');
-				var nodeTo = box.getElement().find('[field=${key}]');
-				edgeStyle.stroke = nodeFrom.css("fill");
-				createEdgeInEditorGraph({from: fromBox, nodeFrom: nodeFrom, to : box, nodeTo: nodeTo, elt : createCurve(nodeFrom, nodeTo) });
 			}
 			}
+			var nodeFrom = fromBox.getElement().find('[field=${connection.fromName}]');
+			var nodeTo = box.getElement().find('[field=${inputName}]');
+			edgeStyle.stroke = nodeFrom.css("fill");
+			createEdgeInEditorGraph({from: fromBox, nodeFrom: nodeFrom, to : box, nodeTo: nodeTo, elt : createCurve(nodeFrom, nodeTo) });
 		}
 		}
 	}
 	}
 
 
@@ -886,7 +917,7 @@ class ShaderEditor extends hide.view.Graph {
 				for (m in obj.getMaterials())
 				for (m in obj.getMaterials())
 					m.mainPass.removeShader(currentShader);
 					m.mainPass.removeShader(currentShader);
 
 
-			var shaderGraphDef = shaderGraph.compile();
+			var shaderGraphDef = shaderGraph.compile2();
 			newShader = new hxsl.DynamicShader(shaderGraphDef.shader);
 			newShader = new hxsl.DynamicShader(shaderGraphDef.shader);
 			for (init in shaderGraphDef.inits) {
 			for (init in shaderGraphDef.inits) {
 				setParamValue(newShader, init.variable, init.value);
 				setParamValue(newShader, init.variable, init.value);
@@ -896,7 +927,16 @@ class ShaderEditor extends hide.view.Graph {
 			}
 			}
 			sceneEditor.scene.render(sceneEditor.scene.engine);
 			sceneEditor.scene.render(sceneEditor.scene.engine);
 			currentShader = newShader;
 			currentShader = newShader;
-			currentShaderDef = shaderGraphDef;
+			currentShaderDef = shaderGraphDef;//{shader: shaderGraphDef, inits:[]};
+
+			for (node in currentGraph.getNodes()) {
+				var preview = Std.downcast(node.instance, hrt.shgraph.nodes.Preview);
+				if (preview != null) {
+					preview.config = config;
+					preview.shaderGraph = shaderGraph;
+					preview.update();
+				}
+			}
 			info('Shader compiled in  ${Date.now().getTime() - timeStart}ms');
 			info('Shader compiled in  ${Date.now().getTime() - timeStart}ms');
 
 
 		} catch (e : Dynamic) {
 		} catch (e : Dynamic) {
@@ -962,10 +1002,10 @@ class ShaderEditor extends hide.view.Graph {
 		var param = shaderGraph.getParameter(id);
 		var param = shaderGraph.getParameter(id);
 		setParamValueByName(currentShader, param.name, param.defaultValue);
 		setParamValueByName(currentShader, param.name, param.defaultValue);
 		for (b in listOfBoxes) {
 		for (b in listOfBoxes) {
-			var previewBox = Std.downcast(b.getInstance(), hrt.shgraph.nodes.Preview);
+			/*var previewBox = Std.downcast(b.getInstance(), hrt.shgraph.nodes.Preview);
 			if (previewBox != null) {
 			if (previewBox != null) {
 				previewBox.setParamValueByName(param.variable.name, param.defaultValue);
 				previewBox.setParamValueByName(param.variable.name, param.defaultValue);
-			}
+			}*/
 		}
 		}
 	}
 	}
 
 
@@ -992,17 +1032,17 @@ class ShaderEditor extends hide.view.Graph {
 			shaderPreview.shaderGraph = shaderGraph;
 			shaderPreview.shaderGraph = shaderGraph;
 			return;
 			return;
 		}
 		}
-		var subGraphNode = Std.downcast(node, hrt.shgraph.nodes.SubGraph);
-		if (subGraphNode != null) {
-			subGraphNode.loadGraphShader();
-			return;
-		}
+		// var subGraphNode = Std.downcast(node, hrt.shgraph.nodes.SubGraph);
+		// if (subGraphNode != null) {
+		// 	subGraphNode.loadGraphShader();
+		// 	return;
+		// }
 	}
 	}
 
 
 	function addNode(p : Point, nodeClass : Class<ShaderNode>) {
 	function addNode(p : Point, nodeClass : Class<ShaderNode>) {
 		beforeChange();
 		beforeChange();
 
 
-		var node = shaderGraph.addNode(p.x, p.y, nodeClass);
+		var node = currentGraph.addNode(p.x, p.y, nodeClass);
 		afterChange();
 		afterChange();
 
 
 		initSpecifics(node);
 		initSpecifics(node);
@@ -1015,7 +1055,7 @@ class ShaderEditor extends hide.view.Graph {
 	function addSubGraph(p : Point, path : String) {
 	function addSubGraph(p : Point, path : String) {
 		var node : SubGraph = cast addNode(p, SubGraph);
 		var node : SubGraph = cast addNode(p, SubGraph);
 		@:privateAccess node.pathShaderGraph = path;
 		@:privateAccess node.pathShaderGraph = path;
-		node.loadGraphShader();
+		// node.loadGraphShader();
 		return node;
 		return node;
 	}
 	}
 
 
@@ -1043,7 +1083,7 @@ class ShaderEditor extends hide.view.Graph {
 		}
 		}
 		try {
 		try {
 			beforeChange();
 			beforeChange();
-			if (shaderGraph.addEdge({ idOutput: startLinkBox.getId(), nameOutput: startLinkNode.attr("field"), idInput: endLinkBox.getId(), nameInput: endLinkNode.attr("field") })) {
+			if (currentGraph.addEdge({ outputNodeId: startLinkBox.getId(), nameOutput: startLinkNode.attr("field"), inputNodeId: endLinkBox.getId(), nameInput: endLinkNode.attr("field") })) {
 				afterChange();
 				afterChange();
 				createEdgeInEditorGraph(newEdge);
 				createEdgeInEditorGraph(newEdge);
 				currentLink.removeClass("draft");
 				currentLink.removeClass("draft");
@@ -1315,11 +1355,11 @@ class ShaderEditor extends hide.view.Graph {
 	}
 	}
 
 
 	function beforeChange() {
 	function beforeChange() {
-		lastSnapshot = haxe.Json.parse(shaderGraph.save());
+		lastSnapshot = haxe.Json.parse(shaderGraph.saveToText());
 	}
 	}
 
 
 	function afterChange() {
 	function afterChange() {
-		var newVal = haxe.Json.parse(shaderGraph.save());
+		var newVal = haxe.Json.parse(shaderGraph.saveToText());
 		var oldVal = lastSnapshot;
 		var oldVal = lastSnapshot;
 		undo.change(Custom(function(undo) {
 		undo.change(Custom(function(undo) {
 			if (undo)
 			if (undo)
@@ -1331,7 +1371,7 @@ class ShaderEditor extends hide.view.Graph {
 	}
 	}
 
 
 	function removeShaderGraphEdge(edge : Graph.Edge) {
 	function removeShaderGraphEdge(edge : Graph.Edge) {
-		shaderGraph.removeEdge(edge.to.getId(), edge.nodeTo.attr("field"));
+		currentGraph.removeEdge(edge.to.getId(), edge.nodeTo.attr("field"));
 	}
 	}
 
 
 	function removeEdgeSubGraphUpdate(edge : Graph.Edge) {
 	function removeEdgeSubGraphUpdate(edge : Graph.Edge) {
@@ -1344,7 +1384,7 @@ class ShaderEditor extends hide.view.Graph {
 				field = edge.nodeFrom.attr("field");
 				field = edge.nodeFrom.attr("field");
 			}
 			}
 			var newBox = refreshBox(edge.to);
 			var newBox = refreshBox(edge.to);
-			subGraph.loadGraphShader();
+			// subGraph.loadGraphShader();
 
 
 			clearAvailableNodes();
 			clearAvailableNodes();
 			if (isCreatingLink == FromInput) {
 			if (isCreatingLink == FromInput) {
@@ -1440,14 +1480,14 @@ class ShaderEditor extends hide.view.Graph {
 				instancedBoxes.push(null);
 				instancedBoxes.push(null);
 				continue;
 				continue;
 			}
 			}
-			var node = shaderGraph.addNode(offset.x + n.pos.x, offset.y + n.pos.y, n.nodeType);
+			var node = currentGraph.addNode(offset.x + n.pos.x, offset.y + n.pos.y, n.nodeType);
 			node.loadProperties(n.props);
 			node.loadProperties(n.props);
 			initSpecifics(node);
 			initSpecifics(node);
 			var shaderParam = Std.downcast(node, ShaderParam);
 			var shaderParam = Std.downcast(node, ShaderParam);
 			if( shaderParam != null ) {
 			if( shaderParam != null ) {
-				var paramShader = shaderGraph.getParameter(shaderParam.parameterId);
+				var paramShader = currentGraph.getParameter(shaderParam.parameterId);
 				if( paramShader == null ) {
 				if( paramShader == null ) {
-					shaderGraph.removeNode(node.id);
+					currentGraph.removeNode(node.id);
 					instancedBoxes.push(null);
 					instancedBoxes.push(null);
 					continue;
 					continue;
 				}
 				}
@@ -1463,12 +1503,12 @@ class ShaderEditor extends hide.view.Graph {
 			if( instancedBoxes[edge.fromIdx] == null || instancedBoxes[edge.toIdx] == null )
 			if( instancedBoxes[edge.fromIdx] == null || instancedBoxes[edge.toIdx] == null )
 				continue;
 				continue;
 			var toCreate = {
 			var toCreate = {
-				idOutput: instancedBoxes[edge.fromIdx].getId(),
+				outputNodeId: instancedBoxes[edge.fromIdx].getId(),
 				nameOutput: edge.fromName,
 				nameOutput: edge.fromName,
-				idInput: instancedBoxes[edge.toIdx].getId(),
+				inputNodeId: instancedBoxes[edge.toIdx].getId(),
 				nameInput: edge.toName,
 				nameInput: edge.toName,
 			}
 			}
-			if( !shaderGraph.addEdge(toCreate) ) {
+			if( !currentGraph.addEdge(toCreate) ) {
 				error("A pasted edge creates a cycle");
 				error("A pasted edge creates a cycle");
 			}
 			}
 		}
 		}
@@ -1537,7 +1577,7 @@ class ShaderEditor extends hide.view.Graph {
 				if (!isSubShader) removeEdgeSubGraphUpdate(edge);
 				if (!isSubShader) removeEdgeSubGraphUpdate(edge);
 			}
 			}
 		}
 		}
-		shaderGraph.removeNode(box.getId());
+		currentGraph.removeNode(box.getId());
 		if( trackChanges )
 		if( trackChanges )
 			afterChange();
 			afterChange();
 		box.dispose();
 		box.dispose();
@@ -1557,19 +1597,19 @@ class ShaderEditor extends hide.view.Graph {
 
 
 	override function updatePosition(box : Box) {
 	override function updatePosition(box : Box) {
 		var previewBox = Std.downcast(box.getInstance(), hrt.shgraph.nodes.Preview);
 		var previewBox = Std.downcast(box.getInstance(), hrt.shgraph.nodes.Preview);
-		if (previewBox != null){
+		/*if (previewBox != null){
 			previewBox.onMove(gX(box.getX()), gY(box.getY()), transformMatrix[0]);
 			previewBox.onMove(gX(box.getX()), gY(box.getY()), transformMatrix[0]);
-		}
-		shaderGraph.setPosition(box.getId(), box.getX(), box.getY());
+		}*/
+		currentGraph.setPosition(box.getId(), box.getX(), box.getY());
 	}
 	}
 
 
 	override function updateMatrix() {
 	override function updateMatrix() {
 		super.updateMatrix();
 		super.updateMatrix();
 		for (b in listOfBoxes) {
 		for (b in listOfBoxes) {
-			var previewBox = Std.downcast(b.getInstance(), hrt.shgraph.nodes.Preview);
+			/*var previewBox = Std.downcast(b.getInstance(), hrt.shgraph.nodes.Preview);
 			if (previewBox != null){
 			if (previewBox != null){
 				previewBox.onMove(gX(b.getX()), gY(b.getY()), transformMatrix[0]);
 				previewBox.onMove(gX(b.getX()), gY(b.getY()), transformMatrix[0]);
-			}
+			}*/
 		}
 		}
 	}
 	}
 
 

+ 2 - 2
hrt/prefab/ShaderGraph.hx

@@ -4,13 +4,13 @@ class ShaderGraph extends DynamicShader {
 
 
 	public function new(?parent) {
 	public function new(?parent) {
 		super(parent);
 		super(parent);
-		type = "shadergraph";
+		type = "shgraph";
 	}
 	}
 
 
 	override public function loadShaderDef(ctx: Context) {
 	override public function loadShaderDef(ctx: Context) {
 		if(shaderDef == null) {
 		if(shaderDef == null) {
 			var shaderGraph = new hrt.shgraph.ShaderGraph(source);
 			var shaderGraph = new hrt.shgraph.ShaderGraph(source);
-			shaderDef = shaderGraph.compile();
+			shaderDef = shaderGraph.compile2();
 		}
 		}
 		if(shaderDef == null)
 		if(shaderDef == null)
 			return;
 			return;

+ 1 - 1
hrt/prefab/rfx/ScreenShaderGraph.hx

@@ -73,7 +73,7 @@ class ScreenShaderGraph extends RendererFX {
 	}
 	}
 
 
 	public function loadShaderDef() {
 	public function loadShaderDef() {
-		shaderDef = shaderGraph.compile();
+		shaderDef = shaderGraph.compile2();
 		if(shaderDef == null)
 		if(shaderDef == null)
 			return;
 			return;
 
 

+ 16 - 1
hrt/shader/UVDebug.hx

@@ -17,7 +17,22 @@ class UVDebug extends hxsl.Shader {
         }*/
         }*/
 
 
         function fragment() {
         function fragment() {
-            pixelColor.rgb = vec3(calculatedUV.x % 1.0, calculatedUV.y, 0.0);
+			var uv = calculatedUV;
+			{
+				var a = uv.x;
+				a += 0.5;
+				uv.x = a;
+				uv.y = a;
+			}
+
+			{
+				var a = uv.y;
+				a += 0.5;
+				uv.x = a;
+				uv.y = a;
+			}
+
+            pixelColor.rgb = vec3(uv.x % 1.0, uv.y, 0.0);
             /*if (abs(calculatedUV.x % 1.0) < 0.05)
             /*if (abs(calculatedUV.x % 1.0) < 0.05)
                 pixelColor.rgb = vec3(1.0,0.0,1.0);
                 pixelColor.rgb = vec3(1.0,0.0,1.0);
             if (abs(calculatedUV.x % 1.0) > 0.95)
             if (abs(calculatedUV.x % 1.0) > 0.95)

+ 164 - 0
hrt/shgraph/Macros.hx

@@ -0,0 +1,164 @@
+package hrt.shgraph;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+import hxsl.Ast;
+using hxsl.Ast;
+using haxe.macro.Tools;
+
+class Macros {
+	#if macro
+	static function buildNode() {
+		var fields = Context.getBuildFields();
+		for (f in fields) {
+			if (f.name == "SRC") {
+				switch (f.kind) {
+					case FVar(_, expr) if (expr != null):
+						var pos = expr.pos;
+						if( !Lambda.has(f.access, AStatic) ) f.access.push(AStatic);
+						Context.getLocalClass().get().meta.add(":src", [expr], pos);
+						try {
+							var c = Context.getLocalClass();
+
+							// function map(e: haxe.macro.Expr) {
+							// 	switch(e) {
+							// 		case EMeta("sginput", args, e):
+							// 			trace("sginput");
+							// 	}
+							// }
+
+							// expr.map()
+
+							var inVars : Array<String> = [];
+							var outVars : Array<String> = [];
+							var defValues : Array<String> = [];
+
+							function iter(e: haxe.macro.Expr) : Void {
+								switch(e.expr) {
+									case EMeta(meta, subexpr):
+										switch (meta.name) {
+											case "sginput":
+												var defValue = null;
+												if (meta.params != null && meta.params.length > 0) {
+													switch (meta.params[0].expr) {
+														case EConst(v):
+															switch(v) {
+																case CIdent(name):
+																	defValue = name;
+																case CFloat(val), CInt(val):
+																	defValue = '$val';
+																default:
+																	throw "sginput default param must be an identifier or a integer";
+															}
+														default:
+															trace(meta.params[0].expr);
+															throw "sginput default param must be a constant value";
+													}
+												}
+
+												switch(subexpr.expr) {
+													case EVars(vars):
+														for (v in vars) {
+															inVars.push(v.name);
+															defValues.push(defValue);
+														}
+														e.expr = subexpr.expr;
+													default:
+														throw "sginput must be used with variables only";
+												}
+											case "sgoutput":
+												switch(subexpr.expr) {
+													case EVars(vars):
+														for (v in vars) {
+															outVars.push(v.name);
+														}
+														e.expr = subexpr.expr;
+													default:
+														throw "sgoutput must be used with variables only";
+												}
+											default:
+										}
+									default:
+								}
+							}
+
+							expr.iter(iter);
+							var shader = new hxsl.MacroParser().parseExpr(expr);
+							f.kind = FVar(null, macro @:pos(pos) $v{shader});
+							var check = new hxsl.Checker();
+							check.warning = function(msg,pos) {
+								haxe.macro.Context.warning(msg, pos);
+							};
+
+							var name = Std.string(c);
+
+							var name = Std.string(c);
+							var check = new hxsl.Checker();
+							check.warning = function(msg,pos) {
+								haxe.macro.Context.warning(msg, pos);
+							};
+							var shader = check.check(name, shader);
+							//trace(shader);
+							//Printer.check(shader);
+							var str = Context.defined("display") ? "" : hxsl.Serializer.run(shader);
+							f.kind = FVar(null, { expr : EConst(CString(str)), pos : pos } );
+							f.meta.push({
+								name : ":keep",
+								pos : pos,
+							});
+
+							function makeField(name: String, arr: Array<String>) : Field
+							{
+								return {
+									name: name,
+									access: [APublic, AStatic],
+									kind: FVar(macro : Array<String>, macro $v{arr}),
+									pos: f.pos,
+									meta: [{
+											name : ":keep",
+											pos : pos,}
+									],
+								};
+							}
+
+							var inVarField : Field = makeField("_inVars", inVars);
+							var outVarField : Field = makeField("_outVars", outVars);
+							var defValuesField : Field = makeField("_defValues", defValues);
+
+							fields.push(inVarField);
+							fields.push(outVarField);
+							fields.push(defValuesField);
+
+
+						} catch( e : hxsl.Ast.Error ) {
+							fields.remove(f);
+							Context.error(e.msg, e.pos);
+						}
+					default:
+				}
+			}
+		}
+		return fields;
+	}
+
+	static function autoRegisterNode() {
+		var fields = Context.getBuildFields();
+
+		var thisClass = Context.getLocalClass();
+		var cl = thisClass.get();
+		var clPath = cl.pack.copy();
+		clPath.push(cl.name);
+
+		#if editor
+		fields.push({
+			name: "_",
+			access: [Access.AStatic],
+			kind: FieldType.FVar(macro:Bool, macro ShaderNode.register($v{cl.name}, ${clPath.toFieldExpr()})),
+			pos: Context.currentPos(),
+		});
+		#end
+
+		return fields;
+	}
+	#end
+}

+ 5 - 270
hrt/shgraph/NodeVar.hx

@@ -17,289 +17,24 @@ class NodeVar {
 	}
 	}
 
 
 	public function getTVar() {
 	public function getTVar() {
-		return node.getOutput(keyOutput);
+		return null;//node.getOutput(keyOutput);
 	}
 	}
 
 
 	public function getType() : Type {
 	public function getType() : Type {
-		return node.getOutputType(keyOutput);
+		return TVoid;//node.getOutputType(keyOutput);
 	}
 	}
 
 
 	public function isEmpty() {
 	public function isEmpty() {
-		return node.getOutputTExpr(keyOutput) == null;
+		return true;//node.getOutputTExpr(keyOutput) == null;
 	}
 	}
 
 
 	public function getVar(?type: Type) : TExpr {
 	public function getVar(?type: Type) : TExpr {
 		var currentType = getType();
 		var currentType = getType();
 		if (type == null || currentType == type) {
 		if (type == null || currentType == type) {
-			return node.getOutputTExpr(keyOutput);
+			return null;//node.getOutputTExpr(keyOutput);
 		}
 		}
 
 
-		switch(currentType) {
-			case TBool:
-				var tExprBool = node.getOutputTExpr(keyOutput);
-				switch(type) {
-					case TVec(size, VBool):
-						if (size == 2) {
-							return {
-								e: TCall({
-									e: TGlobal(Vec2),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "u", type : TBool },
-											{ name: "v", type : TBool }]
-										}
-									])
-								}, [tExprBool,
-									tExprBool]),
-								p: null,
-								t: type
-							};
-						} else if (size == 3) {
-							return {
-								e: TCall({
-									e: TGlobal(Vec3),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "x", type : TBool },
-											{ name: "y", type : TBool },
-											{ name: "z", type : TBool }]
-										}
-									])
-								}, [tExprBool,
-									tExprBool,
-									tExprBool]),
-								p: null,
-								t: type
-							};
-						} else {
-							return {
-								e: TCall({
-									e: TGlobal(Vec4),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "r", type : TBool },
-											{ name: "g", type : TBool },
-											{ name: "b", type : TBool },
-											{ name: "a", type : TBool }]
-										}
-									])
-								}, [tExprBool,
-									tExprBool,
-									tExprBool,
-									tExprBool]),
-								p: null,
-								t: type
-							};
-						}
-					default:
-				};
-			case TFloat:
-				var tExprFloat = node.getOutputTExpr(keyOutput);
-				switch(type) {
-					case TVec(size, VFloat):
-						if (size == 2) {
-							return {
-								e: TCall({
-									e: TGlobal(Vec2),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "u", type : TFloat },
-											{ name: "v", type : TFloat }]
-										}
-									])
-								}, [tExprFloat,
-									tExprFloat]),
-								p: null,
-								t: type
-							};
-						} else if (size == 3) {
-							return {
-								e: TCall({
-									e: TGlobal(Vec3),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "x", type : TFloat },
-											{ name: "y", type : TFloat },
-											{ name: "z", type : TFloat }]
-										}
-									])
-								}, [tExprFloat,
-									tExprFloat,
-									tExprFloat]),
-								p: null,
-								t: type
-							};
-						} else {
-							return {
-								e: TCall({
-									e: TGlobal(Vec4),
-									p: null,
-									t: TFun([
-										{
-											ret: type,
-											args: [
-											{ name: "r", type : TFloat },
-											{ name: "g", type : TFloat },
-											{ name: "b", type : TFloat },
-											{ name: "a", type : TFloat }]
-										}
-									])
-								}, [tExprFloat,
-									tExprFloat,
-									tExprFloat,
-									{
-										e: TConst(CFloat(1.0)),
-										p: null,
-										t: TFloat
-									}]),
-								p: null,
-								t: type
-							};
-						}
-					default:
-				};
-			case TVec(sizeCurrentType, VFloat):
-				var tExprFloat = node.getOutputTExpr(keyOutput);
-				if (sizeCurrentType == 2) {
-					switch(type) {
-						case TVec(size, VFloat):
-							if (size == 3) {
-								return {
-									e: TCall({
-										e: TGlobal(Vec3),
-										p: null,
-										t: TFun([
-											{
-												ret: type,
-												args: [
-												{ name: "x", type : TFloat },
-												{ name: "y", type : TFloat },
-												{ name: "z", type : TFloat }]
-											}
-										])
-									}, [{
-											e: TSwiz(tExprFloat, [X]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TSwiz(tExprFloat, [Y]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TConst(CFloat(0.0)),
-											p: null,
-											t: TFloat
-										}]),
-									p: null,
-									t: type
-								};
-							} else if (size == 4) {
-								return {
-									e: TCall({
-										e: TGlobal(Vec4),
-										p: null,
-										t: TFun([
-											{
-												ret: type,
-												args: [
-												{ name: "r", type : TFloat },
-												{ name: "g", type : TFloat },
-												{ name: "b", type : TFloat },
-												{ name: "a", type : TFloat }]
-											}
-										])
-									}, [{
-											e: TSwiz(tExprFloat, [X]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TSwiz(tExprFloat, [Y]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TConst(CFloat(0.0)),
-											p: null,
-											t: TFloat
-										},
-										{
-											e: TConst(CFloat(0.0)),
-											p: null,
-											t: TFloat
-										}]),
-									p: null,
-									t: type
-								};
-							}
-						default:
-					};
-				} else if (sizeCurrentType == 3) {
-					switch(type) {
-						case TVec(size, VFloat):
-							if (size == 4) {
-								return {
-									e: TCall({
-										e: TGlobal(Vec4),
-										p: null,
-										t: TFun([
-											{
-												ret: type,
-												args: [
-												{ name: "r", type : TFloat },
-												{ name: "g", type : TFloat },
-												{ name: "b", type : TFloat },
-												{ name: "a", type : TFloat }]
-											}
-										])
-									}, [{
-											e: TSwiz(tExprFloat, [X]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TSwiz(tExprFloat, [Y]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TSwiz(tExprFloat, [Z]),
-											p: null,
-											t: TVec(1, VFloat)
-										},
-										{
-											e: TConst(CFloat(0.0)),
-											p: null,
-											t: TFloat
-										}]),
-									p: null,
-									t: type
-								};
-							}
-						default:
-					};
-				}
-
-			default:
-		}
-		return node.getOutputTExpr(keyOutput);
+		return null;
 	}
 	}
 
 
 	public function getExpr() : Array<TExpr> {
 	public function getExpr() : Array<TExpr> {

+ 40 - 41
hrt/shgraph/Operation.hx

@@ -2,46 +2,45 @@ package hrt.shgraph;
 
 
 using hxsl.Ast;
 using hxsl.Ast;
 
 
-class Operation extends ShaderNode {
-
-	@input("A", true) var a = SType.Number;
-	@input("B", true) var b = SType.Number;
-
-	@output("") var output = SType.Number;
-
-	var operation : Binop;
-
-	public function new(operation : Binop) {
-		this.operation = operation;
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty() && b != null && !b.isEmpty())
-			addOutput("output", a.getVar(b.getType()).t);
-		else if (a != null && !a.isEmpty() )
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
-
-	override public function build(key : String) : TExpr {
-
-		return { e: TBinop(OpAssign, {
-						e: TVar(output),
-						p: null,
-						t: output.type
-					}, {
-						e: TBinop(operation,
-							a.getVar(b.getType()),
-							b.getVar(a.getType())),
-						p: null,
-						t: output.type
-					}),
-					p: null,
-					t: output.type
-				};
-	}
+class Operation extends ShaderNodeHxsl {
+
+	// @input("A", true) var a = SType.Number;
+	// @input("B", true) var b = SType.Number;
+
+
+	// var operation : Binop;
+
+	// public function new(operation : Binop) {
+	// 	this.operation = operation;
+	// }
+
+	// override public function computeOutputs() {
+	// 	if (a != null && !a.isEmpty() && b != null && !b.isEmpty())
+	// 		addOutput("output", a.getVar(b.getType()).t);
+	// 	else if (a != null && !a.isEmpty() )
+	// 		addOutput("output", a.getType());
+	// 	else if (b != null && !b.isEmpty())
+	// 		addOutput("output", b.getType());
+	// 	else
+	// 		removeOutput("output");
+	// }
+
+	// override public function build(key : String) : TExpr {
+
+	// 	return { e: TBinop(OpAssign, {
+	// 					e: TVar(output),
+	// 					p: null,
+	// 					t: output.type
+	// 				}, {
+	// 					e: TBinop(operation,
+	// 						a.getVar(b.getType()),
+	// 						b.getVar(a.getType())),
+	// 					p: null,
+	// 					t: output.type
+	// 				}),
+	// 				p: null,
+	// 				t: output.type
+	// 			};
+	// }
 
 
 }
 }

+ 0 - 176
hrt/shgraph/ParseFieldsMacro.hx

@@ -1,176 +0,0 @@
-package hrt.shgraph;
-
-import haxe.macro.Context;
-import haxe.macro.Expr;
-using haxe.macro.Tools;
-
-class ParseFieldsMacro {
-
-#if macro
-
-	public static function build() : Array<Field> {
-		var fields = Context.getBuildFields();
-
-		var mapInputs = new Array<Expr>();
-		var inputsList = new Array<String>();
-		var hasInputs = false;
-		var mapOutputs = new Array<Expr>();
-		var outputsList = new Array<String>();
-		var hasOutputs = false;
-
-		for ( f in fields ) {
-			if( f.meta == null ) continue;
-			switch (f.kind) {
-				case FVar(t, e):
-					var saveMeta = f.meta;
-					for (m in saveMeta) {
-						if (m.name == "input") {
-							hasInputs = true;
-							var sel = f.name;
-							var get_sel = "get_" + sel;
-							var propSel = "prop_" + sel;
-							var hasProperty = false;
-							var isRequired = true;
-							var nameInput = "input";
-							if (m.params.length >= 1) {
-								switch(m.params[0].expr) {
-									case EConst(CString(s)):
-										if (s.length > 0)
-											nameInput = s;
-									default:
-								}
-							}
-							if (m.params.length >= 2) {
-								switch(m.params[1].expr) {
-									case EConst(CIdent(b)):
-										if (b == "true") {
-											hasProperty = true;
-											fields.push({
-												name: propSel,
-												access: [Access.APrivate],
-												kind: FieldType.FVar(macro:Float),
-												pos: Context.currentPos(),
-												meta: [{name: "prop", params: [{expr: EConst(CString("macro")), pos: Context.currentPos() }], pos: Context.currentPos()}]
-											});
-										}
-									default:
-								}
-							}
-							if (m.params.length >= 3) {
-								switch(m.params[2].expr) {
-									case EConst(CIdent(b)):
-										if (b == "false") {
-											isRequired = false;
-										}
-									default:
-								}
-							}
-							if (hasProperty) {
-								var sfields = macro class {
-									inline function $get_sel() : NodeVar {
-										var input = getInput($v{sel});
-										if (input == null)
-											return new NodeVar(new hrt.shgraph.nodes.FloatConst($i{propSel}), "output");
-										else
-											return getInput($v{sel});
-									}
-								};
-								for( field in sfields.fields )
-									fields.push(field);
-							} else {
-								var sfields = macro class {
-									inline function $get_sel() : NodeVar return getInput($v{sel});
-								};
-								for( field in sfields.fields )
-									fields.push(field);
-							}
-							if (e == null)
-								Context.error('Input ${sel} has not affectation', f.pos);
-
-							var enumValue = ["ShaderType", "SType", e.toString().split(".").pop()];
-							mapInputs.push(macro $v{sel} => { name : $v{nameInput}, type : ${enumValue.toFieldExpr()}, hasProperty: $v{hasProperty}, isRequired : $v{isRequired} });
-							f.kind = FProp("get", "null", TPath({ pack: ["hrt", "shgraph"], name: "NodeVar" }));
-							f.meta = saveMeta;
-							inputsList.push(f.name);
-
-							break;
-						} else if (m.name == "output") {
-							hasOutputs = true;
-							var sel = f.name;
-							var get_sel = "get_" + sel;
-							var sfields = macro class {
-								inline function $get_sel() : TVar return getOutput($v{sel});
-							};
-							for( field in sfields.fields )
-								fields.push(field);
-							if (e == null)
-								Context.error('Output ${sel} has not affectation', f.pos);
-							var nameOutput = "";
-							if (m.params.length > 0) {
-								switch(m.params[0].expr) {
-									case EConst(CString(s)):
-										if (s.length > 0)
-											nameOutput = s;
-									default:
-								}
-							}
-							var enumValue = ["ShaderType", "SType", e.toString().split(".").pop()];
-							mapOutputs.push(macro $v{sel} => { name : $v{nameOutput}, type : ${enumValue.toFieldExpr()} });
-							f.kind = FProp("get", "null", TPath({ pack: [], name: "TVar" }));
-							f.meta = saveMeta;
-							outputsList.push(f.name);
-
-							break;
-						}
-					}
-				default:
-			}
-		}
-		if (hasInputs) {
-			fields.push({
-				name: "inputsInfo",
-				access: [Access.APrivate],
-				kind: FieldType.FVar(macro:Map<String, ShaderNode.InputInfo>, macro $a{mapInputs}),
-				pos: Context.currentPos(),
-			});
-			var sfields = macro class {
-				override public function getInputInfo(key : String) : ShaderNode.InputInfo return inputsInfo.get(key);
-				override public function getInputInfoKeys() : Array<String> return $v{inputsList};
-			};
-			for( field in sfields.fields )
-				fields.push(field);
-		}
-		if (hasOutputs) {
-			fields.push({
-				name: "outputsInfo",
-				access: [Access.APrivate],
-				kind: FieldType.FVar(macro:Map<String, ShaderNode.OutputInfo>, macro $a{mapOutputs}),
-				pos: Context.currentPos(),
-			});
-			var sfields = macro class {
-				override public function getOutputInfo(key : String) : ShaderNode.OutputInfo return outputsInfo.get(key);
-				override public function getOutputInfoKeys() : Array<String> return $v{outputsList};
-			};
-			for( field in sfields.fields )
-				fields.push(field);
-		}
-
-		var thisClass = Context.getLocalClass();
-		var cl = thisClass.get();
-		var clPath = cl.pack.copy();
-		clPath.push(cl.name);
-
-		#if editor
-		fields.push({
-			name: "_",
-			access: [Access.AStatic],
-			kind: FieldType.FVar(macro:Bool, macro ShaderNode.register($v{cl.name}, ${clPath.toFieldExpr()})),
-			pos: Context.currentPos(),
-		});
-		#end
-
-		return fields;
-	}
-
-#end
-}

+ 3 - 3
hrt/shgraph/ShaderConst.hx

@@ -6,9 +6,9 @@ class ShaderConst extends ShaderNode {
 
 
 	@prop() public var name : String = "";
 	@prop() public var name : String = "";
 
 
-	override public function getOutputType(key : String) : Type {
-		return getOutputTExpr(key).t;
-	}
+	// override public function getOutputType(key : String) : Type {
+	// 	return getOutputTExpr(key).t;
+	// }
 
 
 	override public function build(key : String) : TExpr {
 	override public function build(key : String) : TExpr {
 		return null;
 		return null;

+ 41 - 42
hrt/shgraph/ShaderFunction.hx

@@ -4,7 +4,6 @@ using hxsl.Ast;
 
 
 class ShaderFunction extends ShaderNode {
 class ShaderFunction extends ShaderNode {
 
 
-	@output("") var output = SType.Variant;
 
 
 	var func : TGlobal;
 	var func : TGlobal;
 
 
@@ -12,46 +11,46 @@ class ShaderFunction extends ShaderNode {
 		this.func = func;
 		this.func = func;
 	}
 	}
 
 
-	override public function build(key : String) : TExpr {
-		var args = [];
-		var varArgs = [];
-
-		for (k in getInputInfoKeys()) {
-			if (getInputInfo(k).hasProperty && getInput(k) == null) {
-				var value : Dynamic = Reflect.field(this, "prop_"+k);
-				if (value == null)
-					value = 0;
-				args.push({ name: k, type: TFloat });
-				varArgs.push(new NodeVar(new hrt.shgraph.nodes.FloatConst(value), "output").getVar());
-			} else {
-				args.push({ name: k, type: getInput(k).getType() });
-				var wantedType = ShaderType.getType(getInputInfo(k).type);
-				varArgs.push(getInput(k).getVar((wantedType != null) ? wantedType : null));
-			}
-		}
-
-		return {
-					p : null,
-					t : output.type,
-					e : TBinop(OpAssign, {
-						e: TVar(output),
-						p: null,
-						t: output.type
-					}, {
-						e: TCall({
-							e: TGlobal(func),
-							p: null,
-							t: TFun([
-								{
-									ret: output.type,
-									args: args
-								}
-							])
-						}, varArgs),
-						p: null,
-						t: output.type
-					})
-				};
-	}
+	// override public function build(key : String) : TExpr {
+	// 	var args = [];
+	// 	var varArgs = [];
+
+	// 	for (k in getInputInfoKeys()) {
+	// 		if (getInputInfo(k).hasProperty && getInput(k) == null) {
+	// 			var value : Dynamic = Reflect.field(this, "prop_"+k);
+	// 			if (value == null)
+	// 				value = 0;
+	// 			args.push({ name: k, type: TFloat });
+	// 			varArgs.push(new NodeVar(new hrt.shgraph.nodes.FloatConst(value), "output").getVar());
+	// 		} else {
+	// 			args.push({ name: k, type: getInput(k).getType() });
+	// 			var wantedType = ShaderType.getType(getInputInfo(k).type);
+	// 			varArgs.push(getInput(k).getVar((wantedType != null) ? wantedType : null));
+	// 		}
+	// 	}
+
+	// 	return {
+	// 				p : null,
+	// 				t : output.type,
+	// 				e : TBinop(OpAssign, {
+	// 					e: TVar(output),
+	// 					p: null,
+	// 					t: output.type
+	// 				}, {
+	// 					e: TCall({
+	// 						e: TGlobal(func),
+	// 						p: null,
+	// 						t: TFun([
+	// 							{
+	// 								ret: output.type,
+	// 								args: args
+	// 							}
+	// 						])
+	// 					}, varArgs),
+	// 					p: null,
+	// 					t: output.type
+	// 				})
+	// 			};
+	// }
 
 
 }
 }

+ 15 - 17
hrt/shgraph/ShaderGlobalInput.hx

@@ -6,21 +6,24 @@ using hxsl.Ast;
 @description("Global Inputs")
 @description("Global Inputs")
 @group("Property")
 @group("Property")
 @color("#0e8826")
 @color("#0e8826")
-class ShaderGlobalInput extends ShaderInput {
+class ShaderGlobalInput extends ShaderNode {
+
+	@prop("Variable") public var variableIdx : Int = 0;
+
 
 
 	static public var globalInputs = [	{ parent: null, id: 0, kind: Global, name: "global.time", type: TFloat },
 	static public var globalInputs = [	{ parent: null, id: 0, kind: Global, name: "global.time", type: TFloat },
 										{ parent: null, id: 0, kind: Global, name: "global.pixelSize", type: TVec(2, VFloat) },
 										{ parent: null, id: 0, kind: Global, name: "global.pixelSize", type: TVec(2, VFloat) },
 										{ parent: null, id: 0, kind: Global, name: "global.modelView", type: TMat4 },
 										{ parent: null, id: 0, kind: Global, name: "global.modelView", type: TMat4 },
 										{ parent: null, id: 0, kind: Global, name: "global.modelViewInverse", type: TMat4 } ];
 										{ parent: null, id: 0, kind: Global, name: "global.modelViewInverse", type: TMat4 } ];
 
 
-	override public function loadProperties(props : Dynamic) {
-		var paramVariable : String = Reflect.field(props, "variable");
-		for (c in ShaderGlobalInput.globalInputs) {
-			if (c.name == paramVariable) {
-				this.variable = c;
-				return;
-			}
-		}
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var inVar : TVar = globalInputs[variableIdx];
+		var output : TVar = {name: "output", id:1, type: inVar.type, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
+
+		return {expr: finalExpr, inVars: [], outVars:[{v: output, internal: false}], externVars: [inVar], inits: []};
 	}
 	}
 
 
 	#if editor
 	#if editor
@@ -29,22 +32,17 @@ class ShaderGlobalInput extends ShaderInput {
 		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
 		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
 		element.append(new hide.Element('<select id="variable"></select>'));
 		element.append(new hide.Element('<select id="variable"></select>'));
 
 
-		if (this.variable == null)
-			this.variable = ShaderGlobalInput.globalInputs[0];
-
 		var input = element.children("select");
 		var input = element.children("select");
-		var indexOption = 0;
-		for (c in ShaderGlobalInput.globalInputs) {
+		for (indexOption => c in ShaderGlobalInput.globalInputs) {
 			var name = c.name.split(".")[1];
 			var name = c.name.split(".")[1];
 			input.append(new hide.Element('<option value="${indexOption}">${name}</option>'));
 			input.append(new hide.Element('<option value="${indexOption}">${name}</option>'));
-			if (this.variable.name == c.name) {
+			if (this.variableIdx == indexOption) {
 				input.val(indexOption);
 				input.val(indexOption);
 			}
 			}
-			indexOption++;
 		}
 		}
 		input.on("change", function(e) {
 		input.on("change", function(e) {
 			var value = input.val();
 			var value = input.val();
-			this.variable = ShaderGlobalInput.globalInputs[value];
+			this.variableIdx = value;
 		});
 		});
 
 
 		elements.push(element);
 		elements.push(element);

File diff suppressed because it is too large
+ 550 - 334
hrt/shgraph/ShaderGraph.hx


+ 17 - 7
hrt/shgraph/ShaderInput.hx

@@ -8,16 +8,26 @@ using hxsl.Ast;
 @color("#0e8826")
 @color("#0e8826")
 class ShaderInput extends ShaderNode {
 class ShaderInput extends ShaderNode {
 
 
-	@output() var output = SType.Variant;
 
 
-	@prop("Variable") public var variable : TVar;
+	@prop("Variable") public var variable : TVar = availableInputs[0];
+
+	// override public function getOutput(key : String) : TVar {
+	// 	return variable;
+	// }
+
+	// override public function build(key : String) : TExpr {
+	// 	return null;
+	// }
+
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var inVar : TVar = variable;
+		var output : TVar = {name: "output", id:1, type: this.variable.type, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
 
 
-	override public function getOutput(key : String) : TVar {
-		return variable;
-	}
 
 
-	override public function build(key : String) : TExpr {
-		return null;
+		return {expr: finalExpr, inVars: [], outVars:[{v:output, internal: false}], externVars: [inVar], inits: []};
 	}
 	}
 
 
 	public static var availableInputs : Array<TVar> = [
 	public static var availableInputs : Array<TVar> = [

+ 79 - 88
hrt/shgraph/ShaderNode.hx

@@ -5,12 +5,14 @@ using hxsl.Ast;
 typedef InputInfo = { name : String, type : ShaderType.SType, hasProperty : Bool, isRequired : Bool, ?ids : Array<Int>, ?index : Int };
 typedef InputInfo = { name : String, type : ShaderType.SType, hasProperty : Bool, isRequired : Bool, ?ids : Array<Int>, ?index : Int };
 typedef OutputInfo = { name : String, type : ShaderType.SType, ?id : Int };
 typedef OutputInfo = { name : String, type : ShaderType.SType, ?id : Int };
 
 
-@:autoBuild(hrt.shgraph.ParseFieldsMacro.build())
+@:autoBuild(hrt.shgraph.Macros.autoRegisterNode())
 @:keepSub
 @:keepSub
 class ShaderNode {
 class ShaderNode {
 
 
 	public var id : Int;
 	public var id : Int;
 
 
+	public var defaults : Dynamic = {};
+
 	static var availableVariables = [
 	static var availableVariables = [
 					{
 					{
 						parent: null,
 						parent: null,
@@ -20,142 +22,126 @@ class ShaderNode {
 						type: TVec(4, VFloat)
 						type: TVec(4, VFloat)
 					}];
 					}];
 
 
-	var inputs : Map<String, NodeVar> = [];
-	var outputs : Map<String, TVar> = [];
-	public var outputCompiled : Map<String, Bool> = []; // todo: put with outputs variable
 
 
-	public function setId(id : Int) {
-		this.id = id;
+	public function getShaderDef(domain: ShaderGraph.Domain) : ShaderGraph.ShaderNodeDef {
+		throw "getShaderDef is not defined for class " + Type.getClassName(Type.getClass(this));
+		return {expr: null, inVars: [], outVars: [], inits: [], externVars: []};
 	}
 	}
 
 
-	public function setInput(key : String, s : NodeVar) {
-		if (s == null)
-				inputs.remove(key);
-		else
-			inputs.set(key, s);
-	}
+	var inputs : Map<String, NodeVar> = [];
+	// var outputs : Map<String, TVar> = [];
 
 
-	public function getInput(key : String) : NodeVar {
-		return inputs.get(key);
-	}
+	public var connections : Map<String, ShaderGraph.Connection> = [];
+
+	public var outputCompiled : Map<String, Bool> = []; // todo: put with outputs variable
 
 
-	public function getInputsKey() {
-		return [for (k in inputs.keys()) k ];
+	// TODO(ces) : caching
+	public function getOutputs2(domain: ShaderGraph.Domain) : Map<String, TVar> {
+		var def = getShaderDef(domain);
+		var map : Map<String, TVar> = [];
+		for (tvar in def.outVars) {
+			if (!tvar.internal)
+				map.set(tvar.v.name, tvar.v);
+		}
+		return map;
 	}
 	}
 
 
-	public function getInputs() {
-		return [for (k in inputs.keys()) inputs.get(k) ];
+	// TODO(ces) : caching
+	public function getInputs2(domain: ShaderGraph.Domain) : Map<String, {v: TVar, ?def: hrt.shgraph.ShaderGraph.ShaderDefInput}> {
+		var def = getShaderDef(domain);
+		var map : Map<String, {v: TVar, ?def: hrt.shgraph.ShaderGraph.ShaderDefInput}> = [];
+		for (i => tvar in def.inVars) {
+			if (!tvar.internal) {
+				map.set(tvar.v.name, {v: tvar.v, def: tvar.defVal});
+			}
+		}
+		return map;
 	}
 	}
 
 
-	public function hasInputs() {
-		return inputs.keys().hasNext();
+
+	public function setId(id : Int) {
+		this.id = id;
 	}
 	}
 
 
+
 	function addOutput(key : String, t : Type) {
 	function addOutput(key : String, t : Type) {
-		outputs.set(key, { parent: null,
+		/*outputs.set(key, { parent: null,
 			id: 0,
 			id: 0,
 			kind: Local,
 			kind: Local,
 			name: "output_" + id + "_" + key,
 			name: "output_" + id + "_" + key,
 			type: t
 			type: t
-		});
+		});*/
 	}
 	}
 
 
 	function removeOutput(key : String) {
 	function removeOutput(key : String) {
-		outputs.remove(key);
+		/*outputs.remove(key);*/
 	}
 	}
 
 
 	function addOutputTvar(tVar : TVar) {
 	function addOutputTvar(tVar : TVar) {
-		outputs.set(tVar.name, tVar);
+		/*outputs.set(tVar.name, tVar);*/
 	}
 	}
 
 
 	public function computeOutputs() : Void {}
 	public function computeOutputs() : Void {}
 
 
-	public function getOutput(key : String) : TVar {
-		return outputs.get(key);
-	}
-
-	public function getOutputType(key : String) : Type {
-		var output = getOutput(key);
-		if (output == null)
-			return null;
-		return output.type;
-	}
-
-	public function getOutputTExpr(key : String) : TExpr {
-		var o = getOutput(key);
-		if (o == null)
-			return null;
-		return {
-			e: TVar(o),
-			p: null,
-			t: o.type
-		};
-	}
+	// public function getOutput(key : String) : TVar {
+	// 	return outputs.get(key);
+	// }
+
+	// public function getOutputType(key : String) : Type {
+	// 	var output = getOutput(key);
+	// 	if (output == null)
+	// 		return null;
+	// 	return output.type;
+	// }
+
+	// public function getOutputTExpr(key : String) : TExpr {
+	// 	var o = getOutput(key);
+	// 	if (o == null)
+	// 		return null;
+	// 	return {
+	// 		e: TVar(o),
+	// 		p: null,
+	// 		t: o.type
+	// 	};
+	// }
 
 
 	public function build(key : String) : TExpr {
 	public function build(key : String) : TExpr {
 		throw "Build function not implemented";
 		throw "Build function not implemented";
 	}
 	}
 
 
-	public function checkTypeAndCompatibilyInput(key : String, type : ShaderType.SType) : Bool {
-		var infoKey = getInputInfo(key).type;
+	public function checkTypeAndCompatibilyInput(key : String, type : hxsl.Ast.Type) : Bool {
+		/*var infoKey = getInputs2()[key].type;
 		if (infoKey != null && !(ShaderType.checkConversion(type, infoKey))) {
 		if (infoKey != null && !(ShaderType.checkConversion(type, infoKey))) {
 			return false;
 			return false;
 		}
 		}
-		return checkValidityInput(key, type);
+		return checkValidityInput(key, type);*/
+		return true;
 	}
 	}
 
 
-	public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
+	public function checkValidityInput(key : String, type : hxsl.Ast.Type) : Bool {
 		return true;
 		return true;
 	}
 	}
 
 
-	public function getInputInfoKeys() : Array<String> {
-		return [];
-	}
 
 
-	public function getInputInfo(key : String) : InputInfo {
-		return null;
-	}
 
 
-	public function getOutputInfoKeys() : Array<String> {
-		return [];
-	}
+	// public function getOutputInfoKeys() : Array<String> {
+	// 	return [];
+	// }
 
 
-	public function getOutputInfo(key : String) : OutputInfo {
-		return null;
-	}
+	// public function getOutputInfo(key : String) : OutputInfo {
+	// 	return null;
+	// }
 
 
 	public function loadProperties(props : Dynamic) {
 	public function loadProperties(props : Dynamic) {
 		var fields = Reflect.fields(props);
 		var fields = Reflect.fields(props);
 		for (f in fields) {
 		for (f in fields) {
-			Reflect.setField(this, f, Reflect.field(props, f));
-		}
-	}
-
-	public function savePropertiesNode() : Dynamic {
-		var parameters = saveProperties();
-
-		var thisClass = std.Type.getClass(this);
-		var fields = std.Type.getInstanceFields(thisClass);
-		var metas = haxe.rtti.Meta.getFields(thisClass);
-		var metaSuperClass = haxe.rtti.Meta.getFields(std.Type.getSuperClass(thisClass));
-
-		for (f in fields) {
-			var m = Reflect.field(metas, f);
-			if (m == null) {
-				m = Reflect.field(metaSuperClass, f);
-				if (m == null)
-					continue;
+			if (f == "defaults") {
+				defaults = Reflect.field(props, f);
 			}
 			}
-
-			if (Reflect.hasField(m, "prop")) {
-				var metaData : Array<String> = Reflect.field(m, "prop");
-				if (metaData != null && metaData.length >= 1 && metaData[0] == "macro") {
-					Reflect.setField(parameters, f, Reflect.getProperty(this, f));
-				}
+			else {
+				Reflect.setField(this, f, Reflect.field(props, f));
 			}
 			}
 		}
 		}
-
-		return parameters;
 	}
 	}
 
 
 	public function saveProperties() : Dynamic {
 	public function saveProperties() : Dynamic {
@@ -180,6 +166,11 @@ class ShaderNode {
 				}
 				}
 			}
 			}
 		}
 		}
+
+		if (Reflect.fields(defaults).length > 0) {
+			Reflect.setField(parameters, "defaults", defaults);
+		}
+
 		return parameters;
 		return parameters;
 	}
 	}
 
 

+ 65 - 0
hrt/shgraph/ShaderNodeHxsl.hx

@@ -0,0 +1,65 @@
+package hrt.shgraph;
+
+@:autoBuild(hrt.shgraph.Macros.buildNode())
+class ShaderNodeHxsl extends ShaderNode {
+
+	static var nodeCache : Map<String, ShaderGraph.ShaderNodeDef> = [];
+
+	override public function getShaderDef(domain: ShaderGraph.Domain) : ShaderGraph.ShaderNodeDef {
+		var cl = Type.getClass(this);
+		var className = Type.getClassName(cl);
+		var def = nodeCache.get(className);
+		if (def == null) {
+
+			var unser = new hxsl.Serializer();
+			var toUnser = (cl:Dynamic).SRC;
+			if (toUnser == null) throw "Node " + className + " has no SRC";
+			var data = @:privateAccess unser.unserialize(toUnser);
+			var expr = data.funs[0].expr;
+			var inVars = [];
+			var outVars = [];
+			var externVars = [];
+
+			for (tvar in data.vars) {
+					var input = false;
+					var output = false;
+					var classInVars : Array<String> = cast (cl:Dynamic)._inVars;
+					var classDefVal : Array<String> = cast (cl:Dynamic)._defValues;
+
+					var indexOf = classInVars.indexOf(tvar.name);
+					if (indexOf > -1) {
+						var defStr = classDefVal[indexOf];
+						var def : hrt.shgraph.ShaderGraph.ShaderDefInput = null;
+						if (defStr != null) {
+							var float = Std.parseFloat(defStr);
+							if (!Math.isNaN(float)) {
+								def = Const(float);
+							} else {
+								def = Var(defStr);
+							}
+							trace(def);
+						}
+						inVars.push({v:tvar, internal: false, defVal: def});
+						// TODO : handle default values
+						input = true;
+					}
+					var classOutVars : Array<String> = cast (cl:Dynamic)._outVars;
+					if (classOutVars.contains(tvar.name)) {
+						outVars.push({v: tvar, internal: false});
+						output = true;
+					}
+					if (input && output) {
+						throw "Variable is both sginput and sgoutput";
+					}
+					if (!input && !output) {
+						externVars.push(tvar);
+					}
+			}
+
+			def = {expr: expr, inVars: inVars, outVars: outVars, externVars: externVars, inits: []};
+			nodeCache.set(className, def);
+		}
+
+		return def;
+	}
+}

+ 27 - 15
hrt/shgraph/ShaderOutput.hx

@@ -8,29 +8,41 @@ using hxsl.Ast;
 @color("#A90707")
 @color("#A90707")
 class ShaderOutput extends ShaderNode {
 class ShaderOutput extends ShaderNode {
 
 
-	@input("input") var input = SType.Variant;
-
 	@prop("Variable") public var variable : TVar;
 	@prop("Variable") public var variable : TVar;
 
 
 	var components = [X, Y, Z, W];
 	var components = [X, Y, Z, W];
 
 
-	override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
-		return ShaderType.checkConversion(type, ShaderType.getSType(variable.type));
-	}
 
 
-	override public function build(key : String) : TExpr {
-		return {
-				p : null,
-				t : TVoid,
-				e : TBinop(OpAssign, {
-					e: TVar(variable),
-					p: null,
-					t: variable.type
-				}, input.getVar(variable.type))
-			};
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var inVar : TVar = {name: "input", id:0, type: this.variable.type, kind: Param, qualifiers: []};
+		var output : TVar = {name: variable.name, id:1, type: this.variable.type, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
 
 
+		//var param = getParameter(inputNode.parameterId);
+		//inits.push({variable: inVar, value: param.defaultValue});
+
+		return {expr: finalExpr, inVars: [{v: inVar, internal: false}], outVars:[{v: output, internal: true}], externVars: [], inits: []};
 	}
 	}
 
 
+	/*override public function checkValidityInput(key : String, type : hxsl.Ast.Type) : Bool {
+		return ShaderType.checkConversion(type, variable.type);
+	}*/
+
+	// override public function build(key : String) : TExpr {
+	// 	return {
+	// 			p : null,
+	// 			t : TVoid,
+	// 			e : TBinop(OpAssign, {
+	// 				e: TVar(variable),
+	// 				p: null,
+	// 				t: variable.type
+	// 			}, input.getVar(variable.type))
+	// 		};
+
+	// }
+
 	static var availableOutputs = [
 	static var availableOutputs = [
 		{
 		{
 			parent: null,
 			parent: null,

+ 15 - 4
hrt/shgraph/ShaderParam.hx

@@ -7,12 +7,26 @@ using hxsl.Ast;
 @color("#d6d6d6")
 @color("#d6d6d6")
 class ShaderParam extends ShaderNode {
 class ShaderParam extends ShaderNode {
 
 
-	@output() var output = SType.Variant;
 
 
 	@prop() public var parameterId : Int;
 	@prop() public var parameterId : Int;
 	@prop() public var perInstance : Bool;
 	@prop() public var perInstance : Bool;
 
 
 
 
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var qual = [];
+		if (this.variable.type == TSampler2D) {
+			qual.push(Sampler(this.variable.name));
+		}
+		var inVar : TVar = {name: this.variable.name, id:0, type: this.variable.type, kind: Param, qualifiers: qual};
+		var output : TVar = {name: "output", id:1, type: this.variable.type, kind: Local, qualifiers: []};
+		//var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
+
+
+		return {expr: null, inVars: [{v:inVar, internal: true}], outVars:[{v:output, internal: false}], externVars: [], inits: []};
+	}
+
 	public var variable : TVar;
 	public var variable : TVar;
 
 
 	override public function computeOutputs() {
 	override public function computeOutputs() {
@@ -22,9 +36,6 @@ class ShaderParam extends ShaderNode {
 			removeOutput("output");
 			removeOutput("output");
 	}
 	}
 
 
-	override public function getOutput(key : String) : TVar {
-		return variable;
-	}
 
 
 	override public function loadProperties(props : Dynamic) {
 	override public function loadProperties(props : Dynamic) {
 		parameterId = Reflect.field(props, "parameterId");
 		parameterId = Reflect.field(props, "parameterId");

+ 8 - 13
hrt/shgraph/nodes/Abs.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of |A|")
 @description("The output is the result of |A|")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Abs extends ShaderFunction {
+class Abs extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Number;
-
-	public function new() {
-		super(Abs);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = abs(a);
+		}
+	};
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Acos.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the arc cosinus of A")
 @description("The output is the arc cosinus of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Acos extends ShaderFunction {
+class Acos extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Acos);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = acos(a);
+		}
+	};
 
 
 }
 }

+ 7 - 2
hrt/shgraph/nodes/Add.hx

@@ -8,8 +8,13 @@ using hxsl.Ast;
 @group("Operation")
 @group("Operation")
 class Add extends Operation {
 class Add extends Operation {
 
 
-	public function new() {
-		super(OpAdd);
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = a + b;
+		}
 	}
 	}
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Asin.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the arc sinus of A")
 @description("The output is the arc sinus of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Asin extends ShaderFunction {
+class Asin extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Asin);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = asin(a);
+		}
+	};
 
 
 }
 }

+ 8 - 14
hrt/shgraph/nodes/Atan.hx

@@ -6,19 +6,13 @@ using hxsl.Ast;
 @description("The output is the arc tangent of A")
 @description("The output is the arc tangent of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Atan extends ShaderFunction {
-
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Atan);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+class Atan extends ShaderNodeHxsl {
 
 
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = atan(a);
+		}
+	};
 }
 }

+ 6 - 10
hrt/shgraph/nodes/BoolConst.hx

@@ -9,20 +9,16 @@ using hxsl.Ast;
 @noheader()
 @noheader()
 class BoolConst extends ShaderConst {
 class BoolConst extends ShaderConst {
 
 
-	@output() var fakeOutput = SType.Bool;
 
 
 	@prop() var value : Bool = true;
 	@prop() var value : Bool = true;
 
 
-	override public function getOutputTExpr(key : String) : TExpr {
-		return {
-					e: TConst(CBool(value)),
-					p: null,
-					t: TBool
-				};
-	}
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var output : TVar = {name: "output", id:1, type: TBool, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TConst(CBool(value)), p: pos, t: output.type}), p: pos, t: output.type};
 
 
-	override public function build(key : String) : TExpr {
-		return null;
+		return {expr: finalExpr, inVars: [], outVars:[{v: output, internal: false}], externVars: [], inits: []};
 	}
 	}
 
 
 	#if editor
 	#if editor

+ 8 - 14
hrt/shgraph/nodes/Ceil.hx

@@ -6,19 +6,13 @@ using hxsl.Ast;
 @description("The nearest integer greater than or equal to X")
 @description("The nearest integer greater than or equal to X")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Ceil extends ShaderFunction {
-
-	@input("x") var x = SType.Number;
-
-	public function new() {
-		super(Ceil);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+class Ceil extends ShaderNodeHxsl {
 
 
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = ceil(a);
+		}
+	};
 }
 }

+ 10 - 14
hrt/shgraph/nodes/Clamp.hx

@@ -6,20 +6,16 @@ using hxsl.Ast;
 @description("Limits value between min and max")
 @description("Limits value between min and max")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Clamp extends ShaderFunction {
+class Clamp extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-	@input("Min", true) var min = SType.Number;
-	@input("Max", true) var max = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput var min : Vec4;
+		@sginput var max : Vec4;
 
 
-	public function new() {
-		super(Clamp);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = clamp(a, min, max);
+		}
+	};
 }
 }

+ 104 - 55
hrt/shgraph/nodes/Color.hx

@@ -9,77 +9,126 @@ using hxsl.Ast;
 @noheader()
 @noheader()
 class Color extends ShaderConst {
 class Color extends ShaderConst {
 
 
-	@output() var output = SType.Vec4;
-
 	@prop() var r : Float = 0;
 	@prop() var r : Float = 0;
 	@prop() var g : Float = 0;
 	@prop() var g : Float = 0;
 	@prop() var b : Float = 0;
 	@prop() var b : Float = 0;
 	@prop() var a : Float = 1;
 	@prop() var a : Float = 1;
 
 
-	override public function computeOutputs() {
-		addOutput("output", TVec(4, VFloat));
-	}
+	// override public function computeOutputs() {
+	// 	addOutput("output", TVec(4, VFloat));
+	// }
 
 
-	override public function getOutputTExpr(key : String) : TExpr {
-		return {
-			e: TVar(output),
-			p: null,
-			t: TVec(4, VFloat)
-		};
-	}
+	// override public function getOutputTExpr(key : String) : TExpr {
+	// 	return {
+	// 		e: TVar(output),
+	// 		p: null,
+	// 		t: TVec(4, VFloat)
+	// 	};
+	// }
 
 
-	override public function build(key : String) : TExpr {
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
 
 
-		return { e: TBinop(OpAssign, {
-						e: TVar(output),
+		var output : TVar = {name: "output", id:1, type: TVec(4, VFloat), kind: Local, qualifiers: []};
+		var finalExpr : TExpr =
+		{ e: TBinop(OpAssign, {
+				e: TVar(output),
+				p: null,
+				t: output.type
+			}, {
+				e: TCall({
+					e: TGlobal(Vec4),
+					p: null,
+					t: TFun([
+						{
+							ret: output.type,
+							args: [
+							{ name: "r", type : TFloat },
+							{ name: "g", type : TFloat },
+							{ name: "b", type : TFloat },
+							{ name: "a", type : TFloat }]
+						}
+					])
+				}, [{
+						e: TConst(CFloat(r)),
 						p: null,
 						p: null,
-						t: output.type
-					}, {
-						e: TCall({
-							e: TGlobal(Vec4),
-							p: null,
-							t: TFun([
-								{
-									ret: output.type,
-									args: [
-									{ name: "r", type : TFloat },
-									{ name: "g", type : TFloat },
-									{ name: "b", type : TFloat },
-									{ name: "a", type : TFloat }]
-								}
-							])
-						}, [{
-								e: TConst(CFloat(r)),
-								p: null,
-								t: TFloat
-							},
-							{
-								e: TConst(CFloat(g)),
-								p: null,
-								t: TFloat
-							},
-							{
-								e: TConst(CFloat(b)),
-								p: null,
-								t: TFloat
-							},{
-								e: TConst(CFloat(a)),
-								p: null,
-								t: TFloat
-							}]),
+						t: TFloat
+					},
+					{
+						e: TConst(CFloat(g)),
 						p: null,
 						p: null,
-						t: output.type
-					}),
-					p: null,
-					t: output.type
-				};
+						t: TFloat
+					},
+					{
+						e: TConst(CFloat(b)),
+						p: null,
+						t: TFloat
+					},{
+						e: TConst(CFloat(a)),
+						p: null,
+						t: TFloat
+					}]),
+				p: null,
+				t: output.type
+			}),
+			p: null,
+			t: output.type
+		};
+		return {expr: finalExpr, inVars: [], outVars:[{v: output, internal: false}], externVars: [], inits: []};
 	}
 	}
 
 
+	// override public function build(key : String) : TExpr {
+
+	// 	return { e: TBinop(OpAssign, {
+	// 					e: TVar(output),
+	// 					p: null,
+	// 					t: output.type
+	// 				}, {
+	// 					e: TCall({
+	// 						e: TGlobal(Vec4),
+	// 						p: null,
+	// 						t: TFun([
+	// 							{
+	// 								ret: output.type,
+	// 								args: [
+	// 								{ name: "r", type : TFloat },
+	// 								{ name: "g", type : TFloat },
+	// 								{ name: "b", type : TFloat },
+	// 								{ name: "a", type : TFloat }]
+	// 							}
+	// 						])
+	// 					}, [{
+	// 							e: TConst(CFloat(r)),
+	// 							p: null,
+	// 							t: TFloat
+	// 						},
+	// 						{
+	// 							e: TConst(CFloat(g)),
+	// 							p: null,
+	// 							t: TFloat
+	// 						},
+	// 						{
+	// 							e: TConst(CFloat(b)),
+	// 							p: null,
+	// 							t: TFloat
+	// 						},{
+	// 							e: TConst(CFloat(a)),
+	// 							p: null,
+	// 							t: TFloat
+	// 						}]),
+	// 					p: null,
+	// 					t: output.type
+	// 				}),
+	// 				p: null,
+	// 				t: output.type
+	// 			};
+	// }
+
 	#if editor
 	#if editor
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 		var elements = super.getPropertiesHTML(width);
 		var elements = super.getPropertiesHTML(width);
 		var element = new hide.Element('<div style="width: 47px; height: 35px"></div>');
 		var element = new hide.Element('<div style="width: 47px; height: 35px"></div>');
-		var picker = new hide.comp.ColorPicker(true, element);
+		var picker = new hide.comp.ColorPicker.ColorBox(element, true, true);
 
 
 
 
 		var start = h3d.Vector.fromArray([r, g, b, a]);
 		var start = h3d.Vector.fromArray([r, g, b, a]);

+ 9 - 98
hrt/shgraph/nodes/Combine.hx

@@ -8,106 +8,17 @@ using hxsl.Ast;
 @name("Combine")
 @name("Combine")
 @description("Create a vector of size 4 from 4 floats")
 @description("Create a vector of size 4 from 4 floats")
 @group("Channel")
 @group("Channel")
-class Combine extends ShaderNode {
+class Combine extends ShaderNodeHxsl {
 
 
-	@input("R", false, false) var r = SType.Float;
-	@input("G", false, false) var g = SType.Float;
-	@input("B", false, false) var b = SType.Float;
-	@input("A", false, false) var a = SType.Float;
+	static var SRC = {
+		@sginput(0.0) var r : Float;
+		@sginput(0.0) var g : Float;
+		@sginput(0.0) var b : Float;
+		@sginput(0.0) var a : Float;
+		@sgoutput var output : Vec4;
 
 
-	@output() var output = SType.Number;
-
-	var components = [X, Y, Z, W];
-	var componentsString = ["r", "g", "b", "a"];
-	var numberOutputs = 0;
-
-	function generateOutputComp(idx : Int) : TExpr {
-		var comp = components[idx];
-
-		var input = getInput(componentsString[idx]);
-		return {
-					p : null,
-					t : output.type,
-					e : TBinop(OpAssign, {
-						e: TSwiz({
-							e: TVar(output),
-							p: null,
-							t : output.type
-						}, [comp]),
-						p: null,
-						t: TVec(1, VFloat)
-					}, input.getVar())
-				};
-	}
-
-	override public function computeOutputs() {
-		numberOutputs = 0;
-		if (a != null && !a.isEmpty()) {
-			numberOutputs = 4;
-		} else if (b != null && !b.isEmpty()) {
-			numberOutputs = 3;
-		} else if (g != null && !g.isEmpty()) {
-			numberOutputs = 2;
-		} else if (r != null && !r.isEmpty()) {
-			numberOutputs = 1;
-		}
-		if (numberOutputs == 1) {
-			addOutput("output", TFloat);
-		} else {
-			addOutput("output", TVec(numberOutputs, VFloat));
+		function fragment() {
+			output = vec4(r,g,b,a);
 		}
 		}
 	}
 	}
-
-	override public function build(key : String) : TExpr {
-
-		var args = [];
-		var valueArgs = [];
-		var opTGlobal : TGlobal = Vec4;
-		if (numberOutputs >= 1) {
-			args.push({ name: "r", type : TFloat });
-			valueArgs.push(r.getVar());
-			opTGlobal = ToFloat;
-		}
-		if (numberOutputs >= 2) {
-			args.push({ name: "g", type : TFloat });
-			valueArgs.push(g.getVar());
-			opTGlobal = Vec2;
-		}
-		if (numberOutputs >= 3) {
-			args.push({ name: "b", type : TFloat });
-			valueArgs.push(b.getVar());
-			opTGlobal = Vec3;
-		}
-		if (numberOutputs >= 4) {
-			args.push({ name: "a", type : TFloat });
-			valueArgs.push(a.getVar());
-			opTGlobal = Vec4;
-		}
-
-		return {
-			p : null,
-			t : output.type,
-			e : TBinop(OpAssign, {
-				e: TVar(output),
-				p: null,
-				t : output.type
-			},
-			{
-				e: TCall({
-					e: TGlobal(opTGlobal),
-					p: null,
-					t: TFun([
-						{
-							ret: output.type,
-							args: args
-						}
-					])
-				}, valueArgs
-				),
-				p: null,
-				t: output.type
-			})
-		};
-	}
-
 }
 }

+ 8 - 45
hrt/shgraph/nodes/CombineAlpha.hx

@@ -8,53 +8,16 @@ using hxsl.Ast;
 @name("Combine Alpha")
 @name("Combine Alpha")
 @description("Create a vector of size 4 from a RGB and an Alpha float")
 @description("Create a vector of size 4 from a RGB and an Alpha float")
 @group("Channel")
 @group("Channel")
-class CombineAlpha extends ShaderNode {
+class CombineAlpha extends ShaderNodeHxsl {
 
 
-	@input("RGB") var rgb = SType.Vec3;
-	@input("A", true) var a = SType.Float;
+	static var SRC = {
+		@sginput var rgb : Vec3;
+		@sginput var a : Float;
+		@sgoutput var output : Vec4;
 
 
-	@output("RGBA") var output = SType.Vec4;
-
-	override public function computeOutputs() {
-
-		addOutput("output", TVec(4, VFloat));
-	}
-
-	override public function build(key : String) : TExpr {
-
-		var args = [];
-		var valueArgs = [];
-		var opTGlobal : TGlobal = Vec4;
-		args.push({ name: "rgb", type : TVec(3, VFloat) });
-		valueArgs.push(rgb.getVar());
-		args.push({ name: "a", type : TFloat });
-		valueArgs.push(a.getVar());
-		opTGlobal = Vec4;
-
-		return {
-			p : null,
-			t : output.type,
-			e : TBinop(OpAssign, {
-				e: TVar(output),
-				p: null,
-				t : output.type
-			},
-			{
-				e: TCall({
-					e: TGlobal(opTGlobal),
-					p: null,
-					t: TFun([
-						{
-							ret: output.type,
-							args: args
-						}
-					])
-				}, valueArgs
-				),
-				p: null,
-				t: output.type
-			})
-		};
+		function fragment() {
+			output = vec4(rgb,a);
+		}
 	}
 	}
 
 
 }
 }

+ 94 - 95
hrt/shgraph/nodes/Cond.hx

@@ -7,100 +7,99 @@ using hxsl.Ast;
 @group("Condition")
 @group("Condition")
 class Cond extends ShaderNode {
 class Cond extends ShaderNode {
 
 
-	@input("Left") var leftVar = SType.Number;
-	@input("Right") var rightVar = SType.Number;
-
-	@output("Boolean") var output = SType.Bool;
-
-	@prop() var condition : Binop;
-
-	override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
-
-		if (key == "leftVar" && rightVar != null && !rightVar.isEmpty())
-			return ShaderType.checkCompatibilities(type, ShaderType.getSType(rightVar.getType()));
-
-		if (key == "rightVar" && leftVar != null && !leftVar.isEmpty())
-			return ShaderType.checkCompatibilities(type, ShaderType.getSType(leftVar.getType()));
-
-		return true;
-	}
-
-	override public function computeOutputs() {
-		if (leftVar != null && !leftVar.isEmpty() && rightVar != null && !rightVar.isEmpty()) {
-			var type = leftVar.getVar(rightVar.getType()).t;
-			switch(type) {
-				case TVec(s, t):
-					removeOutput("output");
-					throw ShaderException.t("Vector of bools is not supported", this.id); //addOutput("output", TVec(s, VBool));
-				case TFloat:
-					addOutput("output", TBool);
-				default:
-					removeOutput("output");
-			}
-		} else
-			removeOutput("output");
-	}
-
-	override public function build(key : String) : TExpr {
-		return {
-				p : null,
-				t : output.type,
-				e : TBinop(OpAssign, {
-						e: TVar(output),
-						p: null,
-						t: output.type
-					}, {e: TBinop(this.condition,
-							leftVar.getVar(rightVar.getType()),
-							rightVar.getVar(leftVar.getType())),
-						p: null, t: output.type })
-			};
-	}
-
-	var availableConditions = [OpEq, OpNotEq, OpGt, OpGte, OpLt, OpLte, OpAnd, OpOr];
-	var conditionStrings 	= ["==", "!=",    ">",  ">=",  "<",  "<=",  "AND", "OR"];
-
-	override public function loadProperties(props : Dynamic) {
-		this.condition = std.Type.createEnum(Binop, Reflect.field(props, "Condition"));
-	}
-
-	override public function saveProperties() : Dynamic {
-		if (this.condition == null)
-			this.condition = availableConditions[0];
-		var properties = {
-			condition: this.condition.getName()
-		};
-
-		return properties;
-	}
-
-	#if editor
-	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
-		var elements = super.getPropertiesHTML(width);
-		var element = new hide.Element('<div style="width: ${width * 0.8}px; height: 40px"></div>');
-		element.append('<span>Condition</span>');
-		element.append(new hide.Element('<select id="condition"></select>'));
-
-		if (this.condition == null) {
-			this.condition = availableConditions[0];
-		}
-		var input = element.children("select");
-		var indexOption = 0;
-		for (c in conditionStrings) {
-			input.append(new hide.Element('<option value="${indexOption}">${c}</option>'));
-			if (this.condition == availableConditions[indexOption]) {
-				input.val(indexOption);
-			}
-			indexOption++;
-		}
-		input.on("change", function(e) {
-			var value = input.val();
-			this.condition = availableConditions[value];
-		});
-
-		elements.push(element);
-
-		return elements;
-	}
-	#end
+	// @input("Left") var leftVar = SType.Number;
+	// @input("Right") var rightVar = SType.Number;
+
+
+	// @prop() var condition : Binop;
+
+	// override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
+
+	// 	if (key == "leftVar" && rightVar != null && !rightVar.isEmpty())
+	// 		return ShaderType.checkCompatibilities(type, ShaderType.getSType(rightVar.getType()));
+
+	// 	if (key == "rightVar" && leftVar != null && !leftVar.isEmpty())
+	// 		return ShaderType.checkCompatibilities(type, ShaderType.getSType(leftVar.getType()));
+
+	// 	return true;
+	// }
+
+	// override public function computeOutputs() {
+	// 	if (leftVar != null && !leftVar.isEmpty() && rightVar != null && !rightVar.isEmpty()) {
+	// 		var type = leftVar.getVar(rightVar.getType()).t;
+	// 		switch(type) {
+	// 			case TVec(s, t):
+	// 				removeOutput("output");
+	// 				throw ShaderException.t("Vector of bools is not supported", this.id); //addOutput("output", TVec(s, VBool));
+	// 			case TFloat:
+	// 				addOutput("output", TBool);
+	// 			default:
+	// 				removeOutput("output");
+	// 		}
+	// 	} else
+	// 		removeOutput("output");
+	// }
+
+	// override public function build(key : String) : TExpr {
+	// 	return {
+	// 			p : null,
+	// 			t : output.type,
+	// 			e : TBinop(OpAssign, {
+	// 					e: TVar(output),
+	// 					p: null,
+	// 					t: output.type
+	// 				}, {e: TBinop(this.condition,
+	// 						leftVar.getVar(rightVar.getType()),
+	// 						rightVar.getVar(leftVar.getType())),
+	// 					p: null, t: output.type })
+	// 		};
+	// }
+
+	// var availableConditions = [OpEq, OpNotEq, OpGt, OpGte, OpLt, OpLte, OpAnd, OpOr];
+	// var conditionStrings 	= ["==", "!=",    ">",  ">=",  "<",  "<=",  "AND", "OR"];
+
+	// override public function loadProperties(props : Dynamic) {
+	// 	this.condition = std.Type.createEnum(Binop, Reflect.field(props, "Condition"));
+	// }
+
+	// override public function saveProperties() : Dynamic {
+	// 	if (this.condition == null)
+	// 		this.condition = availableConditions[0];
+	// 	var properties = {
+	// 		condition: this.condition.getName()
+	// 	};
+
+	// 	return properties;
+	// }
+
+	// #if editor
+	// override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
+	// 	var elements = super.getPropertiesHTML(width);
+	// 	var element = new hide.Element('<div style="width: ${width * 0.8}px; height: 40px"></div>');
+	// 	element.append('<span>Condition</span>');
+	// 	element.append(new hide.Element('<select id="condition"></select>'));
+
+	// 	if (this.condition == null) {
+	// 		this.condition = availableConditions[0];
+	// 	}
+	// 	var input = element.children("select");
+	// 	var indexOption = 0;
+	// 	for (c in conditionStrings) {
+	// 		input.append(new hide.Element('<option value="${indexOption}">${c}</option>'));
+	// 		if (this.condition == availableConditions[indexOption]) {
+	// 			input.val(indexOption);
+	// 		}
+	// 		indexOption++;
+	// 	}
+	// 	input.on("change", function(e) {
+	// 		var value = input.val();
+	// 		this.condition = availableConditions[value];
+	// 	});
+
+	// 	elements.push(element);
+
+	// 	return elements;
+	// }
+	// #end
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Cos.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the cosinus of A")
 @description("The output is the cosinus of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Cos extends ShaderFunction {
+class Cos extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Cos);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = cos(a);
+		}
+	};
 
 
 }
 }

+ 9 - 17
hrt/shgraph/nodes/Cross.hx

@@ -6,23 +6,15 @@ using hxsl.Ast;
 @description("The output is the cross product of a and b")
 @description("The output is the cross product of a and b")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Cross extends ShaderFunction {
+class Cross extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
+	static var SRC = {
+		@sginput var a : Vec3;
+		@sginput var b : Vec3;
+		@sgoutput var output : Vec3;
+		function fragment() {
+			output = cross(a,b);
+		}
+	};
 
 
-	public function new() {
-		super(Cross);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty() && b != null && !b.isEmpty())
-			addOutput("output", a.getVar(b.getType()).t);
-		else if (a != null && !a.isEmpty() )
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
 }
 }

+ 9 - 4
hrt/shgraph/nodes/Divide.hx

@@ -6,10 +6,15 @@ using hxsl.Ast;
 @description("The output is the result of A / B")
 @description("The output is the result of A / B")
 @width(80)
 @width(80)
 @group("Operation")
 @group("Operation")
-class Divide extends Operation {
+class Divide extends ShaderNodeHxsl {
 
 
-	public function new() {
-		super(OpDiv);
-	}
+	static var SRC = {
+		@sginput(1.0) var a : Vec4;
+		@sginput(1.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = a / b;
+		}
+	};
 
 
 }
 }

+ 9 - 10
hrt/shgraph/nodes/Dot.hx

@@ -6,16 +6,15 @@ using hxsl.Ast;
 @description("The output is the dot product of a and b")
 @description("The output is the dot product of a and b")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Dot extends ShaderFunction {
+class Dot extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Float;
+		function fragment() {
+			output = dot(a,b);
+		}
+	};
 
 
-	public function new() {
-		super(Dot);
-	}
-
-	override public function computeOutputs() {
-		addOutput("output", TFloat);
-	}
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Exp.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of exp(x)")
 @description("The output is the result of exp(x)")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Exp extends ShaderFunction {
+class Exp extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-	@input("P", true) var p = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = exp(a);
+		}
+	};
 
 
-	public function new() {
-		super(Exp);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
 }
 }

+ 22 - 15
hrt/shgraph/nodes/FloatConst.hx

@@ -9,26 +9,33 @@ using hxsl.Ast;
 @noheader()
 @noheader()
 class FloatConst extends ShaderConst {
 class FloatConst extends ShaderConst {
 
 
-	@output() var output = SType.Float;
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
 
 
-	@prop() var value : Float = 0.;
+		var output : TVar = {name: "output", id:1, type: TFloat, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TConst(CFloat(value)), p: pos, t: output.type}), p: pos, t: output.type};
 
 
-	public function new(?value : Float) {
-		if (value != null)
-			this.value = value;
+		return {expr: finalExpr, inVars: [], outVars:[{v: output, internal: false}], externVars: [], inits: []};
 	}
 	}
 
 
-	override public function getOutputTExpr(key : String) : TExpr {
-		return {
-					e: TConst(CFloat(value)),
-					p: null,
-					t: TFloat
-				};
-	}
+	@prop() var value : Float = 0.;
 
 
-	override public function build(key : String) : TExpr {
-		return null;
-	}
+	// public function new(?value : Float) {
+	// 	if (value != null)
+	// 		this.value = value;
+	// }
+
+	// override public function getOutputTExpr(key : String) : TExpr {
+	// 	return {
+	// 				e: TConst(CFloat(value)),
+	// 				p: null,
+	// 				t: TFloat
+	// 			};
+	// }
+
+	// override public function build(key : String) : TExpr {
+	// 	return null;
+	// }
 
 
 	#if editor
 	#if editor
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {

+ 8 - 13
hrt/shgraph/nodes/Floor.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The nearest integer less than or equal to X")
 @description("The nearest integer less than or equal to X")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Floor extends ShaderFunction {
+class Floor extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-
-	public function new() {
-		super(Floor);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = floor(a);
+		}
+	};
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Fract.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The fractional part of X")
 @description("The fractional part of X")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Fract extends ShaderFunction {
+class Fract extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-
-	public function new() {
-		super(Fract);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = fract(a);
+		}
+	};
 
 
 }
 }

+ 44 - 45
hrt/shgraph/nodes/IfCondition.hx

@@ -7,50 +7,49 @@ using hxsl.Ast;
 @group("Condition")
 @group("Condition")
 class IfCondition extends ShaderNode {
 class IfCondition extends ShaderNode {
 
 
-	@input("Condition") var condition = SType.Bool;
-	@input("True") var trueVar = SType.Variant;
-	@input("False") var falseVar = SType.Variant;
-
-	@output() var output = SType.Variant;
-
-	override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
-
-		if (key == "trueVar" && falseVar != null && !falseVar.isEmpty())
-			return ShaderType.checkCompatibilities(type, ShaderType.getSType(falseVar.getType()));
-
-		if (key == "falseVar" && trueVar != null && !trueVar.isEmpty())
-			return ShaderType.checkCompatibilities(type, ShaderType.getSType(trueVar.getType()));
-
-		return true;
-	}
-
-	override public function computeOutputs() {
-		if (trueVar != null && !trueVar.isEmpty() && falseVar != null && !falseVar.isEmpty())
-			addOutput("output", trueVar.getVar(falseVar.getType()).t);
-		else if (trueVar != null && !trueVar.isEmpty())
-			addOutput("output", trueVar.getType());
-		else if (falseVar != null && !falseVar.isEmpty())
-			addOutput("output", falseVar.getType());
-		else
-			removeOutput("output");
-	}
-
-	override public function build(key : String) : TExpr {
-		return {
-			p : null,
-			t: output.type,
-			e : TBinop(OpAssign, {
-					e: TVar(output),
-					p: null,
-					t: output.type
-				}, {
-				e: TIf( condition.getVar(),
-						trueVar.getVar(falseVar.getType()),
-						falseVar.getVar(trueVar.getType())),
-				p: null,
-				t: output.type
-			})
-		};
-	}
+	// @input("Condition") var condition = SType.Bool;
+	// @input("True") var trueVar = SType.Variant;
+	// @input("False") var falseVar = SType.Variant;
+
+
+	// override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
+
+	// 	if (key == "trueVar" && falseVar != null && !falseVar.isEmpty())
+	// 		return ShaderType.checkCompatibilities(type, ShaderType.getSType(falseVar.getType()));
+
+	// 	if (key == "falseVar" && trueVar != null && !trueVar.isEmpty())
+	// 		return ShaderType.checkCompatibilities(type, ShaderType.getSType(trueVar.getType()));
+
+	// 	return true;
+	// }
+
+	// override public function computeOutputs() {
+	// 	if (trueVar != null && !trueVar.isEmpty() && falseVar != null && !falseVar.isEmpty())
+	// 		addOutput("output", trueVar.getVar(falseVar.getType()).t);
+	// 	else if (trueVar != null && !trueVar.isEmpty())
+	// 		addOutput("output", trueVar.getType());
+	// 	else if (falseVar != null && !falseVar.isEmpty())
+	// 		addOutput("output", falseVar.getType());
+	// 	else
+	// 		removeOutput("output");
+	// }
+
+	// // override public function build(key : String) : TExpr {
+	// // 	return {
+	// // 		p : null,
+	// // 		t: output.type,
+	// // 		e : TBinop(OpAssign, {
+	// // 				e: TVar(output),
+	// // 				p: null,
+	// // 				t: output.type
+	// // 			}, {
+	// // 			e: TIf( condition.getVar(),
+	// // 					trueVar.getVar(falseVar.getType()),
+	// // 					falseVar.getVar(trueVar.getType())),
+	// // 			p: null,
+	// // 			t: output.type
+	// // 		})
+	// // 	};
+	// // }
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Length.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("")
 @description("")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Length extends ShaderFunction {
+class Length extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Vec2;
-
-	public function new() {
-		super(Length);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", TFloat);
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Float;
+		function fragment() {
+			output = length(a);
+		}
+	};
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Log.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of log(x)")
 @description("The output is the result of log(x)")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Log extends ShaderFunction {
+class Log extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-	@input("P", true) var p = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = log(a);
+		}
+	};
 
 
-	public function new() {
-		super(Log);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
 }
 }

+ 9 - 17
hrt/shgraph/nodes/Max.hx

@@ -6,23 +6,15 @@ using hxsl.Ast;
 @description("The output is the maximum between A and B")
 @description("The output is the maximum between A and B")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Max extends ShaderFunction {
-
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
-
-	public function new() {
-		super(Max);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
+class Max extends ShaderNodeHxsl {
 
 
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = max(a,b);
+		}
+	};
 
 
 }
 }

+ 0 - 28
hrt/shgraph/nodes/Maximum.hx

@@ -1,28 +0,0 @@
-package hrt.shgraph.nodes;
-
-using hxsl.Ast;
-
-@name("Maximum")
-@description("The output is the maximum between A and B")
-@width(80)
-@group("Math")
-class Maximum extends ShaderFunction {
-
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
-
-	public function new() {
-		super(Max);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
-
-
-}

+ 9 - 16
hrt/shgraph/nodes/Min.hx

@@ -6,22 +6,15 @@ using hxsl.Ast;
 @description("The output is the minimum between A and B")
 @description("The output is the minimum between A and B")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Min extends ShaderFunction {
+class Min extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
-
-	public function new() {
-		super(Min);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = min(a,b);
+		}
+	};
 
 
 }
 }

+ 0 - 27
hrt/shgraph/nodes/Minimum.hx

@@ -1,27 +0,0 @@
-package hrt.shgraph.nodes;
-
-using hxsl.Ast;
-
-@name("Minimum")
-@description("The output is the minimum between A and B")
-@width(80)
-@group("Math")
-class Minimum extends ShaderFunction {
-
-	@input("A") var a = SType.Number;
-	@input("B") var b = SType.Number;
-
-	public function new() {
-		super(Min);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else if (b != null && !b.isEmpty())
-			addOutput("output", b.getType());
-		else
-			removeOutput("output");
-	}
-
-}

+ 10 - 19
hrt/shgraph/nodes/Mix.hx

@@ -6,25 +6,16 @@ using hxsl.Ast;
 @description("Linear interpolation between A and B using Mix")
 @description("Linear interpolation between A and B using Mix")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Mix extends ShaderFunction {
+class Mix extends ShaderNodeHxsl {
 
 
-	@input("A") var x = SType.Number;
-	@input("B") var y = SType.Number;
-	@input("Mix") var a = SType.Number;
-
-	public function new() {
-		super(Mix);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty() && y != null && !y.isEmpty())
-			addOutput("output", x.getVar(y.getType()).t);
-		else if (x != null && !x.isEmpty() )
-			addOutput("output", x.getType());
-		else if (y != null && !y.isEmpty())
-			addOutput("output", y.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sginput var fact : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = mix(a,b, fact);
+		}
+	};
 
 
 }
 }

+ 9 - 14
hrt/shgraph/nodes/Mod.hx

@@ -6,20 +6,15 @@ using hxsl.Ast;
 @description("The output is the result of X modulo MOD")
 @description("The output is the result of X modulo MOD")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Mod extends ShaderFunction {
+class Mod extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Variant;
-	@input("Mod", true) var mod = SType.Float;
-
-	public function new() {
-		super(Mod);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = mod(a,b);
+		}
+	};
 
 
 }
 }

+ 8 - 4
hrt/shgraph/nodes/Multiply.hx

@@ -6,10 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of A * B")
 @description("The output is the result of A * B")
 @width(80)
 @width(80)
 @group("Operation")
 @group("Operation")
-class Multiply extends Operation {
+class Multiply extends ShaderNodeHxsl {
 
 
-	public function new() {
-		super(OpMult);
+	static var SRC = {
+		@sginput(1.0) var a : Vec4;
+		@sginput(1.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = a * b;
+		}
 	}
 	}
-
 }
 }

+ 8 - 12
hrt/shgraph/nodes/Normalize.hx

@@ -6,18 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of normalize(x)")
 @description("The output is the result of normalize(x)")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Normalize extends ShaderFunction {
+class Normalize extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = normalize(a);
+		}
+	};
 
 
-	public function new() {
-		super(Normalize);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
 }
 }

+ 9 - 13
hrt/shgraph/nodes/Pow.hx

@@ -6,19 +6,15 @@ using hxsl.Ast;
 @description("The output is the result of x ^ b")
 @description("The output is the result of x ^ b")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Pow extends ShaderFunction {
+class Pow extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-	@input("P", true) var p = SType.Number;
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = pow(a,b);
+		}
+	};
 
 
-	public function new() {
-		super(Pow);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
 }
 }

+ 55 - 44
hrt/shgraph/nodes/Preview.hx

@@ -11,62 +11,74 @@ using hxsl.Ast;
 @noheader()
 @noheader()
 class Preview extends ShaderNode {
 class Preview extends ShaderNode {
 
 
-	@input("Input") var input = SType.Vec4;
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
 
 
-	public var variable : TVar;
+		var inVar : TVar = {name: "input", id:0, type: TVec(4, VFloat), kind: Param, qualifiers: []};
+		var output : TVar = {name: "pixelColor", id:1, type: TVec(4, VFloat), kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
 
 
-	override public function build(key : String) : TExpr {
-
-		return {
-				p : null,
-				t : TVoid,
-				e : TBinop(OpAssign, {
-					e: TVar(variable),
-					p: null,
-					t: variable.type
-				}, input.getVar(variable.type))
-			};
+		//var param = getParameter(inputNode.parameterId);
+		//inits.push({variable: inVar, value: param.defaultValue});
 
 
+		return {expr: finalExpr, inVars: [{v: inVar, internal: false}], outVars:[], externVars: [output], inits: []};
 	}
 	}
 
 
+	// @input("Input") var input = SType.Vec4;
+
+	// public var variable : TVar;
+
+	// override public function build(key : String) : TExpr {
+
+	// 	return {
+	// 			p : null,
+	// 			t : TVoid,
+	// 			e : TBinop(OpAssign, {
+	// 				e: TVar(variable),
+	// 				p: null,
+	// 				t: variable.type
+	// 			}, input.getVar(variable.type))
+	// 		};
+
+	// }
+
 	#if editor
 	#if editor
-	public var shaderGraph : ShaderGraph;
 	var nodePreview : js.jquery.JQuery;
 	var nodePreview : js.jquery.JQuery;
+	var element : js.jquery.JQuery;
+	public var shaderGraph: ShaderGraph;
 	var cube : Mesh;
 	var cube : Mesh;
 	var scene : hide.comp.Scene;
 	var scene : hide.comp.Scene;
 	var currentShaderPreview : hxsl.DynamicShader;
 	var currentShaderPreview : hxsl.DynamicShader;
 	var currentShaderDef : hrt.prefab.ContextShared.ShaderDef;
 	var currentShaderDef : hrt.prefab.ContextShared.ShaderDef;
+	var inited = false;
 	public var config : hide.Config;
 	public var config : hide.Config;
 
 
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 		var elements = super.getPropertiesHTML(width);
 		var elements = super.getPropertiesHTML(width);
-		for (c in ShaderNode.availableVariables) {
-			if (c.name == "pixelColor") {
-				this.variable = c;
-			}
-		}
 
 
-		if (this.variable == null) {
-			throw ShaderException.t("The preview is not available", this.id);
+		if (element == null) {
+			element = new hide.Element('<div style="width: 100px; height: 100px"><div class="preview-parent" top="-10px" ><div class="node-preview" style="height: 100px" ></div></div></div>');
+			nodePreview = element.find(".node-preview");
+
+			scene = new hide.comp.Scene(config, null, nodePreview);
+
+			scene.onReady = function() {
+				var prim = new h3d.prim.Cube();
+				prim.addUVs();
+				prim.addNormals();
+				cube = new Mesh(prim, scene.s3d);
+				scene.s3d.camera.pos = new h3d.Vector(0.5, 3.4, 0.5);
+				scene.s3d.camera.target = new h3d.Vector(0.5, 0.5, 0.5);
+				var light = new h3d.scene.pbr.DirLight(scene.s3d.camera.target.sub(scene.s3d.camera.pos), scene.s3d);
+				light.setPosition(scene.s3d.camera.pos.x, scene.s3d.camera.pos.y, scene.s3d.camera.pos.z);
+				scene.s3d.camera.zoom = 1;
+				scene.init();
+				onMove();
+				inited = true;
+
+				update();
+			};
 		}
 		}
-		var element = new hide.Element('<div style="width: 100px; height: 100px"><div class="preview-parent" top="-10px" ><div class="node-preview" style="height: 100px" ></div></div></div>');
-		nodePreview = element.find(".node-preview");
-		scene = new hide.comp.Scene(config, null, nodePreview);
-		
-		scene.onReady = function() {
-			var prim = new h3d.prim.Cube();
-			prim.addUVs();
-			prim.addNormals();
-			cube = new Mesh(prim, scene.s3d);
-			scene.s3d.camera.pos = new h3d.Vector(0.5, 3.4, 0.5);
-			scene.s3d.camera.target = new h3d.Vector(0.5, 0.5, 0.5);
-			var light = new h3d.scene.pbr.DirLight(scene.s3d.camera.target.sub(scene.s3d.camera.pos), scene.s3d);
-			light.setPosition(scene.s3d.camera.pos.x, scene.s3d.camera.pos.y, scene.s3d.camera.pos.z);
-			scene.s3d.camera.zoom = 1;
-			scene.init();
-			onMove();
-			computeOutputs();
-		};
 
 
 		elements.push(element);
 		elements.push(element);
 		return elements;
 		return elements;
@@ -95,10 +107,11 @@ class Preview extends ShaderNode {
 
 
 	function onResize() {
 	function onResize() {
 		if( cube == null ) return;
 		if( cube == null ) return;
-
 	}
 	}
 
 
-	override public function computeOutputs() {
+	public function update() {
+		if (!inited)
+			return;
 		if (currentShaderPreview != null) {
 		if (currentShaderPreview != null) {
 			for (m in cube.getMaterials()) {
 			for (m in cube.getMaterials()) {
 				m.mainPass.removeShader(currentShaderPreview);
 				m.mainPass.removeShader(currentShaderPreview);
@@ -106,15 +119,13 @@ class Preview extends ShaderNode {
 			currentShaderPreview = null;
 			currentShaderPreview = null;
 		}
 		}
 
 
-		if (scene == null || input == null || input.isEmpty()) return;
-
 		if (@:privateAccess scene.window == null)
 		if (@:privateAccess scene.window == null)
 			return;
 			return;
 		scene.setCurrent();
 		scene.setCurrent();
 
 
 		var shader : hxsl.DynamicShader = null;
 		var shader : hxsl.DynamicShader = null;
 		try {
 		try {
-			var shaderGraphDef = shaderGraph.compile(this);
+			var shaderGraphDef = shaderGraph.compile2(this);
 			shader = new hxsl.DynamicShader(shaderGraphDef.shader);
 			shader = new hxsl.DynamicShader(shaderGraphDef.shader);
 			for (init in shaderGraphDef.inits) {
 			for (init in shaderGraphDef.inits) {
 				setParamValue(init.variable, init.value, shader);
 				setParamValue(init.variable, init.value, shader);

+ 93 - 82
hrt/shgraph/nodes/Sampler.hx

@@ -5,94 +5,105 @@ using hxsl.Ast;
 @name("Sampler")
 @name("Sampler")
 @description("Get color from texture and UV")
 @description("Get color from texture and UV")
 @group("Property")
 @group("Property")
-class Sampler extends ShaderNode {
+class Sampler extends ShaderNodeHxsl {
 
 
-	@input("Texture") var texture = SType.Sampler;
-	@input("UV") var uv = SType.Vec2;
+	static var SRC = {
+		@sginput var texture : Sampler2D;
+		@sginput(uv) var uv : Vec2;
+		@sgoutput var RGBA : Vec4;
+		@sgoutput var RGB : Vec3;
+		@sgoutput var A : Float;
 
 
-	@output("RGBA") var rgba = SType.Vec4;
-	@output("R") var r = SType.Float;
-	@output("G") var g = SType.Float;
-	@output("B") var b = SType.Float;
-	@output("A") var a = SType.Float;
 
 
-	var components = [X, Y, Z, W];
-	var componentsString = ["r", "g", "b", "a"];
-
-	override public function computeOutputs() {
-		addOutput("rgba", TVec(4, VFloat));
-		addOutput("r", TFloat);
-		addOutput("g", TFloat);
-		addOutput("b", TFloat);
-		addOutput("a", TFloat);
+		function fragment() {
+			RGBA = texture.get(uv);
+			RGB = RGBA.rgb;
+			A = RGBA.a;
+		}
 	}
 	}
 
 
-	override public function build(key : String) : TExpr {
-		if (key == "rgba") {
-			var args = [];
-			var varArgs = [];
+	// @input("Texture") var texture = SType.Sampler;
+	// @input("UV") var uv = SType.Vec2;
 
 
-			for (k in getInputInfoKeys()) {
-				args.push({ name: k, type: getInput(k).getType() });
-				var wantedType = ShaderType.getType(getInputInfo(k).type);
-				varArgs.push(getInput(k).getVar((wantedType != null) ? wantedType : null));
-			}
 
 
-			return {
-						p : null,
-						t : rgba.type,
-						e : TBinop(OpAssign, {
-							e: TVar(rgba),
-							p: null,
-							t: rgba.type
-						}, {
-							e: TCall({
-								e: TGlobal(Texture),
-								p: null,
-								t: TFun([
-									{
-										ret: rgba.type,
-										args: args
-									}
-								])
-							}, varArgs),
-							p: null,
-							t: rgba.type
-						})
-					};
-		} else {
-			var arrayExpr = [];
-			if (!outputCompiled.get("rgba")) {
-				arrayExpr.push({ e : TVarDecl(rgba), t : rgba.type, p : null });
-				arrayExpr.push(build("rgba"));
-				outputCompiled.set("rgba", true);
-			}
-			var compIdx = componentsString.indexOf(key);
-			arrayExpr.push({ e: TBinop(OpAssign, {
-						e: TVar(getOutput(key)),
-						p: null,
-						t: getOutput(key).type
-					}, {e: TSwiz({
-							e: TVar(rgba),
-							p: null,
-							t: rgba.type
-						},
-						[components[compIdx]]),
-						p: null,
-						t: getOutput(key).type }),
-					p: null,
-					t: getOutput(key).type
-				});
-			if (arrayExpr.length > 1) {
-				return {
-					p : null,
-					t : TVoid,
-					e : TBlock(arrayExpr)
-				};
-			} else {
-				return arrayExpr[0];
-			}
-		}
-	}
+
+	// var components = [X, Y, Z, W];
+	// var componentsString = ["r", "g", "b", "a"];
+
+	// override public function computeOutputs() {
+	// 	addOutput("rgba", TVec(4, VFloat));
+	// 	addOutput("r", TFloat);
+	// 	addOutput("g", TFloat);
+	// 	addOutput("b", TFloat);
+	// 	addOutput("a", TFloat);
+	// }
+
+	// override public function build(key : String) : TExpr {
+	// 	if (key == "rgba") {
+	// 		var args = [];
+	// 		var varArgs = [];
+
+	// 		for (k in getInputInfoKeys()) {
+	// 			args.push({ name: k, type: getInput(k).getType() });
+	// 			var wantedType = ShaderType.getType(getInputInfo(k).type);
+	// 			varArgs.push(getInput(k).getVar((wantedType != null) ? wantedType : null));
+	// 		}
+
+	// 		return {
+	// 					p : null,
+	// 					t : rgba.type,
+	// 					e : TBinop(OpAssign, {
+	// 						e: TVar(rgba),
+	// 						p: null,
+	// 						t: rgba.type
+	// 					}, {
+	// 						e: TCall({
+	// 							e: TGlobal(Texture),
+	// 							p: null,
+	// 							t: TFun([
+	// 								{
+	// 									ret: rgba.type,
+	// 									args: args
+	// 								}
+	// 							])
+	// 						}, varArgs),
+	// 						p: null,
+	// 						t: rgba.type
+	// 					})
+	// 				};
+	// 	} else {
+	// 		var arrayExpr = [];
+	// 		if (!outputCompiled.get("rgba")) {
+	// 			arrayExpr.push({ e : TVarDecl(rgba), t : rgba.type, p : null });
+	// 			arrayExpr.push(build("rgba"));
+	// 			outputCompiled.set("rgba", true);
+	// 		}
+	// 		var compIdx = componentsString.indexOf(key);
+	// 		arrayExpr.push({ e: TBinop(OpAssign, {
+	// 					e: TVar(getOutput(key)),
+	// 					p: null,
+	// 					t: getOutput(key).type
+	// 				}, {e: TSwiz({
+	// 						e: TVar(rgba),
+	// 						p: null,
+	// 						t: rgba.type
+	// 					},
+	// 					[components[compIdx]]),
+	// 					p: null,
+	// 					t: getOutput(key).type }),
+	// 				p: null,
+	// 				t: getOutput(key).type
+	// 			});
+	// 		if (arrayExpr.length > 1) {
+	// 			return {
+	// 				p : null,
+	// 				t : TVoid,
+	// 				e : TBlock(arrayExpr)
+	// 			};
+	// 		} else {
+	// 			return arrayExpr[0];
+	// 		}
+	// 	}
+	// }
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Saturate.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("Saturate input A")
 @description("Saturate input A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Saturate extends ShaderFunction {
+class Saturate extends ShaderNodeHxsl {
 
 
-	@input("X") var x = SType.Number;
-
-	public function new() {
-		super(Saturate);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty())
-			addOutput("output", x.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = saturate(a);
+		}
+	};
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Sin.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the sinus of A")
 @description("The output is the sinus of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Sin extends ShaderFunction {
+class Sin extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Sin);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = sin(a);
+		}
+	};
 
 
 }
 }

+ 10 - 19
hrt/shgraph/nodes/SmoothStep.hx

@@ -6,25 +6,16 @@ using hxsl.Ast;
 @description("Linear interpolation between A and B using Mix")
 @description("Linear interpolation between A and B using Mix")
 @width(100)
 @width(100)
 @group("Math")
 @group("Math")
-class SmoothStep extends ShaderFunction {
+class SmoothStep extends ShaderNodeHxsl {
 
 
-	@input("A") var x = SType.Number;
-	@input("B") var y = SType.Number;
-	@input("Mix") var a = SType.Number;
-
-	public function new() {
-		super(Smoothstep);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty() && y != null && !y.isEmpty())
-			addOutput("output", x.getVar(y.getType()).t);
-		else if (x != null && !x.isEmpty() )
-			addOutput("output", x.getType());
-		else if (y != null && !y.isEmpty())
-			addOutput("output", y.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sginput var fact : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = smoothstep(a,b, fact);
+		}
+	};
 
 
 }
 }

+ 15 - 30
hrt/shgraph/nodes/Split.hx

@@ -5,35 +5,20 @@ using hxsl.Ast;
 @name("Split")
 @name("Split")
 @description("Split all components of a vector into floats")
 @description("Split all components of a vector into floats")
 @group("Channel")
 @group("Channel")
-class Split extends ShaderNode {
-
-	@input("RGBA") var input = SType.Vec4;
-
-	@output("R") var r = SType.Float;
-	@output("G") var g = SType.Float;
-	@output("B") var b = SType.Float;
-	@output("A") var a = SType.Float;
-
-	var components = [X, Y, Z, W];
-	var componentsString = ["r", "g", "b", "a"];
-
-	override public function computeOutputs() {
-		addOutput("r", TFloat);
-		addOutput("g", TFloat);
-		addOutput("b", TFloat);
-		addOutput("a", TFloat);
-	}
-
-	override public function build(key : String) : TExpr {
-		var compIdx = componentsString.indexOf(key);
-		return { e: TBinop(OpAssign, {
-					e: TVar(getOutput(key)),
-					p: null,
-					t: getOutput(key).type
-				}, {e: TSwiz(input.getVar(TVec(4, VFloat)), [components[compIdx]]), p: null, t: getOutput(key).type }),
-				p: null,
-				t: getOutput(key).type
-			};
-	}
+class Split extends ShaderNodeHxsl {
+
+	static var SRC = {
+		@sginput var rgba : Vec4;
+		@sgoutput var r : Float;
+		@sgoutput var g : Float;
+		@sgoutput var b : Float;
+		@sgoutput var a : Float;
+		function fragment() {
+			r = rgba.r;
+			g = rgba.g;
+			b = rgba.b;
+			a = rgba.a;
+		}
+	};
 
 
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Sqrt.hx

@@ -7,19 +7,14 @@ using hxsl.Ast;
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
 @:keep
 @:keep
-class Sqrt extends ShaderFunction {
+class Sqrt extends ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Number;
-
-	public function new() {
-		super(Sqrt);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = sqrt(a);
+		}
+	};
 
 
 }
 }

+ 9 - 18
hrt/shgraph/nodes/Step.hx

@@ -6,24 +6,15 @@ using hxsl.Ast;
 @description("Generate a step function by comparing a[i] to edge[i]")
 @description("Generate a step function by comparing a[i] to edge[i]")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Step extends ShaderFunction {
+class Step extends ShaderNodeHxsl {
 
 
-	@input("Edge") var edge = SType.Number;
-	@input("A") var x = SType.Number;
-
-	public function new() {
-		super(Step);
-	}
-
-	override public function computeOutputs() {
-		if (x != null && !x.isEmpty() && edge != null && !edge.isEmpty())
-			addOutput("output", edge.getVar(x.getType()).t);
-		else if (x != null && !x.isEmpty() )
-			addOutput("output", x.getType());
-		else if (edge != null && !edge.isEmpty())
-			addOutput("output", edge.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput var edge : Vec4;
+		@sginput var fact : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = step(edge, fact);
+		}
+	};
 
 
 }
 }

+ 10 - 38
hrt/shgraph/nodes/StripAlpha.hx

@@ -5,45 +5,17 @@ using hxsl.Ast;
 @name("Strip Alpha")
 @name("Strip Alpha")
 @description("Separate the rgb and a components of an rgba vector")
 @description("Separate the rgb and a components of an rgba vector")
 @group("Channel")
 @group("Channel")
-class StripAlpha extends ShaderNode {
+class StripAlpha extends ShaderNodeHxsl {
 
 
-	@input("RGBA") var input = SType.Vec4;
+	static var SRC = {
+		@sginput var rgba : Vec4;
+		@sgoutput var rgb : Vec3;
+		@sgoutput var a : Float;
 
 
-	@output("RGB") var rgb = SType.Vec3;
-	@output("A") var a = SType.Float;
-
-	override public function computeOutputs() {
-		addOutput("rgb", TVec(3, VFloat));
-		addOutput("a", TFloat);
-	}
-
-	override public function build(key : String) : TExpr {
-        if( key == "a" ) {
-            return { e: TBinop(OpAssign, {
-                    e: TVar(getOutput(key)),
-                    p: null,
-                    t: getOutput(key).type
-                }, {
-                    e: TSwiz(input.getVar(TVec(4, VFloat)), [W]),
-                    p: null,
-                    t: getOutput(key).type
-                }),
-                p: null,
-                t: getOutput(key).type
-            };
-	    }
-        return { e: TBinop(OpAssign, {
-                e: TVar(getOutput(key)),
-                p: null,
-                t: getOutput(key).type
-            }, {
-                e: TSwiz(input.getVar(TVec(4, VFloat)), [X, Y, Z]),
-                p: null,
-                t: getOutput(key).type
-            }),
-            p: null,
-            t: getOutput(key).type
-        };
-    }
+		function fragment() {
+			rgb = rgba.rgb;
+			a = rgba.a;
+		}
+	};
 
 
 }
 }

+ 149 - 226
hrt/shgraph/nodes/SubGraph.hx

@@ -10,6 +10,24 @@ class SubGraph extends ShaderNode {
 
 
 	@prop() public var pathShaderGraph : String;
 	@prop() public var pathShaderGraph : String;
 
 
+	override public function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var shader = new ShaderGraph(pathShaderGraph);
+		var gen = shader.getGraph(domain).generate2();
+
+		// for (tvar in gen.externVars) {
+		// 	if (tvar.qualifiers != null) {
+		// 		if (tvar.qualifiers.contains(SgInput)) {
+		// 			gen.inVars.push(tvar);
+		// 		}
+		// 		if (tvar.qualifiers.contains(SgOutput)) {
+		// 			gen.outVars.push(tvar);
+		// 		}
+		// 	}
+		// }
+
+		return gen;
+	}
+
 	var inputsInfo : Map<String, ShaderNode.InputInfo>;
 	var inputsInfo : Map<String, ShaderNode.InputInfo>;
 	var inputInfoKeys : Array<String> = [];
 	var inputInfoKeys : Array<String> = [];
 	var outputsInfo : Map<String, ShaderNode.OutputInfo>;
 	var outputsInfo : Map<String, ShaderNode.OutputInfo>;
@@ -21,232 +39,137 @@ class SubGraph extends ShaderNode {
 
 
 	public var varsSubGraph : Array<TVar> = [];
 	public var varsSubGraph : Array<TVar> = [];
 
 
-	public function loadGraphShader() {
-		if (this.pathShaderGraph != null) {
-			subShaderGraph = new ShaderGraph(pathShaderGraph);
-			inputsInfo = new Map<String, ShaderNode.InputInfo>();
-			inputInfoKeys = [];
-			var paramInfoKeys = [];
-			outputsInfo = new Map<String, ShaderNode.OutputInfo>();
-			outputInfoKeys = [];
-			parameters = [];
-			propertiesSubGraph = new Map<Int, Dynamic>();
-			var prefixSubGraph = "shgraph_" + id + "_";
-
-			for (node in subShaderGraph.getNodes()) {
-				switch (node.type.split(".").pop()) {
-					case "ShaderParam": // params become inputs
-						var shaderParam = Std.downcast(node.instance, ShaderParam);
-						var paramName = subShaderGraph.getParameter(shaderParam.parameterId).name;
-						var paramId = "param_" + shaderParam.parameterId;
-						var paramInfo = inputsInfo.get(prefixSubGraph+paramId);
-						var ids = [];
-						if (paramInfo != null && paramInfo.ids != null)
-							ids = paramInfo.ids;
-						ids.push(node.id);
-						if (!inputsInfo.exists(prefixSubGraph + paramId)) {
-							paramInfoKeys.push(prefixSubGraph+paramId);
-						}
-						inputsInfo.set(prefixSubGraph+paramId, { name : paramName , type: ShaderType.getSType(shaderParam.variable.type), hasProperty: false, isRequired : false, ids : ids, index :  subShaderGraph.getParameter(shaderParam.parameterId).index});
-					case "ShaderInput":
-						var shaderInput = Std.downcast(node.instance, ShaderInput);
-						var inputId = "input_" + shaderInput.variable.name;
-						var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
-						var ids = [];
-						if (inputInfo != null && inputInfo.ids != null)
-							ids = inputInfo.ids;
-						ids.push(node.id);
-						if (!inputsInfo.exists(prefixSubGraph+inputId)) {
-							inputInfoKeys.push(prefixSubGraph+inputId);
-						}
-						inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
-					case "ShaderGlobalInput":
-						var shaderInput = Std.downcast(node.instance, ShaderGlobalInput);
-						var inputId = "globalInput_" + shaderInput.variable.name;
-						var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
-						var ids = [];
-						if (inputInfo != null && inputInfo.ids != null)
-							ids = inputInfo.ids;
-						ids.push(node.id);
-						if (!inputsInfo.exists(prefixSubGraph+inputId)) {
-							inputInfoKeys.push(prefixSubGraph+inputId);
-						}
-						inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
-					case "ShaderCameraInput":
-						var shaderInput = Std.downcast(node.instance, ShaderCameraInput);
-						var inputId = "cameraInput_" + shaderInput.variable.name;
-						var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
-						var ids = [];
-						if (inputInfo != null && inputInfo.ids != null)
-							ids = inputInfo.ids;
-						ids.push(node.id);
-						if (!inputsInfo.exists(prefixSubGraph+inputId)) {
-							inputInfoKeys.push(prefixSubGraph+inputId);
-						}
-						inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
-					case "ShaderOutput":
-						var shaderOutput = Std.downcast(node.instance, ShaderOutput);
-						var prefix = shaderOutput.variable.kind == Local ? "" : "*";
-
-						outputsInfo.set(prefixSubGraph+node.id, { name : prefix + shaderOutput.variable.name , type: ShaderType.getSType(shaderOutput.variable.type), id : node.id });
-						outputInfoKeys.push(prefixSubGraph+node.id);
-
-						addOutput(prefixSubGraph+node.id, shaderOutput.variable.type);
-					default:
-						var shaderConst = Std.downcast(node.instance, ShaderConst);
-						if (shaderConst != null) { // input static become properties
-							if (shaderConst.name.length == 0) continue;
-							if (Std.isOfType(shaderConst, BoolConst)) {
-								parameters.push({ name : shaderConst.name, type : TBool, defaultValue : null, id : shaderConst.id, index : parameters.length });
-							} else if (Std.isOfType(shaderConst, FloatConst)) {
-								parameters.push({ name : shaderConst.name, type : TFloat, defaultValue : null, id : shaderConst.id, index : parameters.length });
-							} else if (Std.isOfType(shaderConst, Color)) {
-								parameters.push({ name : shaderConst.name, type : TVec(4, VFloat), defaultValue : null, id : shaderConst.id, index : parameters.length });
-							}
-						}
-				}
-			}
-			paramInfoKeys.sort((x,y) -> Reflect.compare(inputsInfo[x].index, inputsInfo[y].index));
-			inputInfoKeys = paramInfoKeys.concat(inputInfoKeys);
-		}
-	}
-
-	override public function build(key : String) : TExpr {
-
-		for (inputKey in inputInfoKeys) {
-			var inputInfo = inputsInfo.get(inputKey);
-			var inputTVar = getInput(inputKey);
-
-			if (inputTVar != null) {
-				for (id in inputInfo.ids) {
-					var nodeToReplace = subShaderGraph.getNodes().get(id);
-					for (i in 0...nodeToReplace.outputs.length) {
-						var inputNode = nodeToReplace.outputs[i];
-
-						for (inputKey in inputNode.instance.getInputsKey()) {
-							var input = inputNode.instance.getInput(inputKey);
-							if (input.node == nodeToReplace.instance) {
-								inputNode.instance.setInput(inputKey, inputTVar);
-							}
-						}
-					}
-				}
-			}
-		}
-
-		for (p in parameters) {
-			if (p.defaultValue != null) {
-				var node = subShaderGraph.getNode(p.id);
-				switch (p.type) {
-					case TBool:
-						var boolConst = Std.downcast(node.instance, BoolConst);
-						@:privateAccess boolConst.value = p.defaultValue;
-					case TVec(4, VFloat):
-						var colorConst = Std.downcast(node.instance, Color);
-						@:privateAccess {
-							colorConst.r = p.defaultValue.x;
-							colorConst.g = p.defaultValue.y;
-							colorConst.b = p.defaultValue.z;
-							colorConst.a = p.defaultValue.w;
-						}
-					case TFloat:
-						var floatConst = Std.downcast(node.instance, FloatConst);
-						@:privateAccess floatConst.value = p.defaultValue;
-					default:
-				}
-			}
-		}
-
-		var shaderDef;
-		try {
-			shaderDef = subShaderGraph.generateShader(null, id);
-		} catch (e : ShaderException) {
-			throw ShaderException.t(e.msg, id);
-		}
-		if (shaderDef.funs.length > 1) {
-			throw ShaderException.t("The sub shader is vertex and fragment.", id);
-		}
-		varsSubGraph = shaderDef.vars;
-		var arrayExpr : Array<TExpr> = [];
-		switch (shaderDef.funs[0].expr.e) {
-			case TBlock(block):
-				arrayExpr = block;
-			default:
-
-		}
-
-		for (outputKey in outputInfoKeys) {
-			var outputInfo = outputsInfo.get(outputKey);
-			var outputTVar = getOutput(outputKey);
-			if (outputTVar != null) {
-				arrayExpr.push({
-					p : null,
-					t : outputTVar.type,
-					e : TBinop(OpAssign, {
-							e: TVar(outputTVar),
-							p: null,
-							t: outputTVar.type
-						}, subShaderGraph.getNodes().get(outputInfo.id).instance.getInput("input").getVar(outputTVar.type))
-				});
-			}
-		}
-
-		return {
-				p : null,
-				t : TVoid,
-				e : TBlock(arrayExpr)
-			};
-	}
-
-	override public function getInputInfo(key : String) : ShaderNode.InputInfo {
-		return inputsInfo.get(key);
-	}
-
-	override public function getInputInfoKeys() : Array<String> {
-		return inputInfoKeys;
-	}
-
-	override public function getOutputInfo(key : String) : ShaderNode.OutputInfo {
-		return outputsInfo.get(key);
-	}
-
-	override public function getOutputInfoKeys() : Array<String> {
-		return outputInfoKeys;
-	}
-
-	override public function loadProperties(props : Dynamic) {
-		this.pathShaderGraph = Reflect.field(props, "pathShaderGraph");
-		loadGraphShader();
-
-		var parametersValues : Array<hrt.shgraph.ShaderGraph.Parameter> = Reflect.field(props, "parametersValues");
-		if (parametersValues == null) return;
-		var index = 0;
-		for (p in this.parameters) {
-			if (parametersValues.length <= index) break;
-			if (p.id != parametersValues[index].id) {
-				continue;
-			}
-			p.defaultValue = parametersValues[index].defaultValue;
-			index++;
-		}
-	}
-
-	override public function saveProperties() : Dynamic {
-
-		var parametersValues = [];
-		for (p in this.parameters) {
-			if (p.defaultValue != null) {
-				parametersValues.push({id: p.id, defaultValue : p.defaultValue});
-			}
-		}
-
-		var properties = {
-			pathShaderGraph: this.pathShaderGraph,
-			parametersValues : parametersValues
-		};
-
-		return properties;
-	}
+	// public function loadGraphShader() {
+	// 	if (this.pathShaderGraph != null) {
+	// 		subShaderGraph = new ShaderGraph(pathShaderGraph);
+	// 		inputsInfo = new Map<String, ShaderNode.InputInfo>();
+	// 		inputInfoKeys = [];
+	// 		var paramInfoKeys = [];
+	// 		outputsInfo = new Map<String, ShaderNode.OutputInfo>();
+	// 		outputInfoKeys = [];
+	// 		parameters = [];
+	// 		propertiesSubGraph = new Map<Int, Dynamic>();
+	// 		var prefixSubGraph = "shgraph_" + id + "_";
+
+	// 		for (node in subShaderGraph.getNodes()) {
+	// 			switch (node.type.split(".").pop()) {
+	// 				case "ShaderParam": // params become inputs
+	// 					var shaderParam = Std.downcast(node.instance, ShaderParam);
+	// 					var paramName = subShaderGraph.getParameter(shaderParam.parameterId).name;
+	// 					var paramId = "param_" + shaderParam.parameterId;
+	// 					var paramInfo = inputsInfo.get(prefixSubGraph+paramId);
+	// 					var ids = [];
+	// 					if (paramInfo != null && paramInfo.ids != null)
+	// 						ids = paramInfo.ids;
+	// 					ids.push(node.id);
+	// 					if (!inputsInfo.exists(prefixSubGraph + paramId)) {
+	// 						paramInfoKeys.push(prefixSubGraph+paramId);
+	// 					}
+	// 					inputsInfo.set(prefixSubGraph+paramId, { name : paramName , type: ShaderType.getSType(shaderParam.variable.type), hasProperty: false, isRequired : false, ids : ids, index :  subShaderGraph.getParameter(shaderParam.parameterId).index});
+	// 				case "ShaderInput":
+	// 					var shaderInput = Std.downcast(node.instance, ShaderInput);
+	// 					var inputId = "input_" + shaderInput.variable.name;
+	// 					var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
+	// 					var ids = [];
+	// 					if (inputInfo != null && inputInfo.ids != null)
+	// 						ids = inputInfo.ids;
+	// 					ids.push(node.id);
+	// 					if (!inputsInfo.exists(prefixSubGraph+inputId)) {
+	// 						inputInfoKeys.push(prefixSubGraph+inputId);
+	// 					}
+	// 					inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
+	// 				case "ShaderGlobalInput":
+	// 					var shaderInput = Std.downcast(node.instance, ShaderGlobalInput);
+	// 					var inputId = "globalInput_" + shaderInput.variable.name;
+	// 					var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
+	// 					var ids = [];
+	// 					if (inputInfo != null && inputInfo.ids != null)
+	// 						ids = inputInfo.ids;
+	// 					ids.push(node.id);
+	// 					if (!inputsInfo.exists(prefixSubGraph+inputId)) {
+	// 						inputInfoKeys.push(prefixSubGraph+inputId);
+	// 					}
+	// 					inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
+	// 				case "ShaderCameraInput":
+	// 					var shaderInput = Std.downcast(node.instance, ShaderCameraInput);
+	// 					var inputId = "cameraInput_" + shaderInput.variable.name;
+	// 					var inputInfo = inputsInfo.get(prefixSubGraph+inputId);
+	// 					var ids = [];
+	// 					if (inputInfo != null && inputInfo.ids != null)
+	// 						ids = inputInfo.ids;
+	// 					ids.push(node.id);
+	// 					if (!inputsInfo.exists(prefixSubGraph+inputId)) {
+	// 						inputInfoKeys.push(prefixSubGraph+inputId);
+	// 					}
+	// 					inputsInfo.set(prefixSubGraph+inputId, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, ids : ids });
+	// 				case "ShaderOutput":
+	// 					var shaderOutput = Std.downcast(node.instance, ShaderOutput);
+	// 					var prefix = shaderOutput.variable.kind == Local ? "" : "*";
+
+	// 					outputsInfo.set(prefixSubGraph+node.id, { name : prefix + shaderOutput.variable.name , type: ShaderType.getSType(shaderOutput.variable.type), id : node.id });
+	// 					outputInfoKeys.push(prefixSubGraph+node.id);
+
+	// 					addOutput(prefixSubGraph+node.id, shaderOutput.variable.type);
+	// 				default:
+	// 					var shaderConst = Std.downcast(node.instance, ShaderConst);
+	// 					if (shaderConst != null) { // input static become properties
+	// 						if (shaderConst.name.length == 0) continue;
+	// 						if (Std.isOfType(shaderConst, BoolConst)) {
+	// 							parameters.push({ name : shaderConst.name, type : TBool, defaultValue : null, id : shaderConst.id, index : parameters.length });
+	// 						} else if (Std.isOfType(shaderConst, FloatConst)) {
+	// 							parameters.push({ name : shaderConst.name, type : TFloat, defaultValue : null, id : shaderConst.id, index : parameters.length });
+	// 						} else if (Std.isOfType(shaderConst, Color)) {
+	// 							parameters.push({ name : shaderConst.name, type : TVec(4, VFloat), defaultValue : null, id : shaderConst.id, index : parameters.length });
+	// 						}
+	// 					}
+	// 			}
+	// 		}
+	// 		paramInfoKeys.sort((x,y) -> Reflect.compare(inputsInfo[x].index, inputsInfo[y].index));
+	// 		inputInfoKeys = paramInfoKeys.concat(inputInfoKeys);
+	// 	}
+	// }
+
+	// override public function getOutputInfo(key : String) : ShaderNode.OutputInfo {
+	// 	return outputsInfo.get(key);
+	// }
+
+	// override public function getOutputInfoKeys() : Array<String> {
+	// 	return outputInfoKeys;
+	// }
+
+	// override public function loadProperties(props : Dynamic) {
+	// 	this.pathShaderGraph = Reflect.field(props, "pathShaderGraph");
+	// 	loadGraphShader();
+
+	// 	var parametersValues : Array<hrt.shgraph.ShaderGraph.Parameter> = Reflect.field(props, "parametersValues");
+	// 	if (parametersValues == null) return;
+	// 	var index = 0;
+	// 	for (p in this.parameters) {
+	// 		if (parametersValues.length <= index) break;
+	// 		if (p.id != parametersValues[index].id) {
+	// 			continue;
+	// 		}
+	// 		p.defaultValue = parametersValues[index].defaultValue;
+	// 		index++;
+	// 	}
+	// }
+
+	// override public function saveProperties() : Dynamic {
+
+	// 	var parametersValues = [];
+	// 	for (p in this.parameters) {
+	// 		if (p.defaultValue != null) {
+	// 			parametersValues.push({id: p.id, defaultValue : p.defaultValue});
+	// 		}
+	// 	}
+
+	// 	var properties = {
+	// 		pathShaderGraph: this.pathShaderGraph,
+	// 		parametersValues : parametersValues
+	// 	};
+
+	// 	return properties;
+	// }
 
 
 	#if editor
 	#if editor
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {

+ 8 - 4
hrt/shgraph/nodes/Subtract.hx

@@ -6,10 +6,14 @@ using hxsl.Ast;
 @description("The output is the result of A - B")
 @description("The output is the result of A - B")
 @width(80)
 @width(80)
 @group("Operation")
 @group("Operation")
-class Subtract extends Operation {
+class Subtract extends ShaderNodeHxsl {
 
 
-	public function new() {
-		super(OpSub);
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sginput(0.0) var b : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = a - b;
+		}
 	}
 	}
-
 }
 }

+ 8 - 13
hrt/shgraph/nodes/Tan.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("The output is the tangent of A")
 @description("The output is the tangent of A")
 @width(80)
 @width(80)
 @group("Math")
 @group("Math")
-class Tan extends ShaderFunction {
+class Tan extends  ShaderNodeHxsl {
 
 
-	@input("A") var a = SType.Float;
-
-	public function new() {
-		super(Tan);
-	}
-
-	override public function computeOutputs() {
-		if (a != null && !a.isEmpty())
-			addOutput("output", a.getType());
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = tan(a);
+		}
+	};
 
 
 }
 }

+ 2 - 2
hrt/shgraph/nodes/Text.hx

@@ -12,8 +12,8 @@ class Text extends ShaderNode {
 
 
 	@prop() var text : String = "";
 	@prop() var text : String = "";
 
 
-	override public function build(key : String) : TExpr {
-		return null;
+	override function getShaderDef(domain: ShaderGraph.Domain):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		return {expr: null, inVars: [], outVars: [], inits: [], externVars: []};
 	}
 	}
 
 
 	#if editor
 	#if editor

+ 105 - 93
hrt/shgraph/nodes/UVScroll.hx

@@ -5,105 +5,117 @@ using hxsl.Ast;
 @name("UV Scroll")
 @name("UV Scroll")
 @description("Scroll UV according to U & V speed")
 @description("Scroll UV according to U & V speed")
 @group("Specials")
 @group("Specials")
-class UVScroll extends ShaderNode {
+class UVScroll extends  ShaderNodeHxsl {
 
 
-	@input("UV") var uv = SType.Vec2;
-	@input("USpeed", true) var uSpeed = SType.Number;
-	@input("VSpeed", true) var vSpeed = SType.Number;
+	static var SRC = {
+		@sginput(uv) var uv : Vec2;
+		@sginput(0.0) var uSpeed : Float;
+		@sginput(0.0) var vSpeed : Float;
+		@sginput(0.0) var time : Float;
 
 
-	@output("") var output = SType.Vec2;
+		@sgoutput var output : Vec2;
 
 
-	var operation : Binop;
+		function fragment() {
+			output = mod(uv + vec2(uSpeed * time, vSpeed * time), 1.0);
+		}
+	};
 
 
-	public function new(operation : Binop) {
-		this.operation = operation;
-	}
+}
 
 
-	override public function computeOutputs() {
-		if (uv != null && !uv.isEmpty())
-			addOutput("output", uv.getType());
-		else
-			removeOutput("output");
-	}
+	// @input("UV") var uv = SType.Vec2;
+	// @input("USpeed", true) var uSpeed = SType.Number;
+	// @input("VSpeed", true) var vSpeed = SType.Number;
 
 
-	override public function build(key : String) : TExpr {
 
 
-		var globalTime : TVar = @:privateAccess ShaderGlobalInput.globalInputs.filter(i -> i.name.indexOf("time") != -1)[0];
-		var timeExpr : TExpr = { e: TVar(globalTime), p: null, t: globalTime.type };
+	// var operation : Binop;
 
 
-		return { e: TBinop(OpAssign, {
-						e: TVar(output),
-						p: null,
-						t: output.type
-					}, {
-						// uv % 1 (wrap)
-						e: TCall({
-							e: TGlobal(Mod),
-							p: null,
-							t: TFun([
-								{
-									ret: output.type,
-									args: [
-										{ name: "uv", type : output.type }, 
-										{ name: "mod", type : TFloat }
-									]
-								}
-							])
-						}, [
-							{
-								// uv + speed * time
-								e: TBinop(OpAdd,
-									uv.getVar(),
-									{
-										e: TCall({
-											e: TGlobal(Vec2),
-											p: null,
-											t: TFun([
-												{
-													ret: output.type,
-													args: [
-														{ name: "u", type : TFloat }, 
-														{ name: "v", type : TFloat }
-													]
-												}
-											])
-										}, [
-											// uSpeed * time
-											{
-												e: TBinop(OpMult,
-													uSpeed.getVar(),
-													timeExpr),
-												p: null,
-												t: uSpeed.getType()
-											},
-											// vSpeed * time
-											{
-												e: TBinop(OpMult,
-													vSpeed.getVar(),
-													timeExpr),
-												p: null,
-												t: vSpeed.getType()
-											}
-										]
-										),
-										p: null,
-										t: output.type
-									}),
-								p: null,
-								t: uSpeed.getType()
-							},
-							{
-								e: TConst(CFloat(1)),
-								p: null,
-								t: TFloat
-							}
-						]),
-						p: null,
-						t: output.type
-					}),
-					p: null,
-					t: output.type
-				};
-	}
+	// public function new(operation : Binop) {
+	// 	this.operation = operation;
+	// }
 
 
-}
+	// override public function computeOutputs() {
+	// 	if (uv != null && !uv.isEmpty())
+	// 		addOutput("output", uv.getType());
+	// 	else
+	// 		removeOutput("output");
+	// }
+
+	// override public function build(key : String) : TExpr {
+
+	// 	var globalTime : TVar = @:privateAccess ShaderGlobalInput.globalInputs.filter(i -> i.name.indexOf("time") != -1)[0];
+	// 	var timeExpr : TExpr = { e: TVar(globalTime), p: null, t: globalTime.type };
+
+	// 	return { e: TBinop(OpAssign, {
+	// 					e: TVar(output),
+	// 					p: null,
+	// 					t: output.type
+	// 				}, {
+	// 					// uv % 1 (wrap)
+	// 					e: TCall({
+	// 						e: TGlobal(Mod),
+	// 						p: null,
+	// 						t: TFun([
+	// 							{
+	// 								ret: output.type,
+	// 								args: [
+	// 									{ name: "uv", type : output.type },
+	// 									{ name: "mod", type : TFloat }
+	// 								]
+	// 							}
+	// 						])
+	// 					}, [
+	// 						{
+	// 							// uv + speed * time
+	// 							e: TBinop(OpAdd,
+	// 								uv.getVar(),
+	// 								{
+	// 									e: TCall({
+	// 										e: TGlobal(Vec2),
+	// 										p: null,
+	// 										t: TFun([
+	// 											{
+	// 												ret: output.type,
+	// 												args: [
+	// 													{ name: "u", type : TFloat },
+	// 													{ name: "v", type : TFloat }
+	// 												]
+	// 											}
+	// 										])
+	// 									}, [
+	// 										// uSpeed * time
+	// 										{
+	// 											e: TBinop(OpMult,
+	// 												uSpeed.getVar(),
+	// 												timeExpr),
+	// 											p: null,
+	// 											t: uSpeed.getType()
+	// 										},
+	// 										// vSpeed * time
+	// 										{
+	// 											e: TBinop(OpMult,
+	// 												vSpeed.getVar(),
+	// 												timeExpr),
+	// 											p: null,
+	// 											t: vSpeed.getType()
+	// 										}
+	// 									]
+	// 									),
+	// 									p: null,
+	// 									t: output.type
+	// 								}),
+	// 							p: null,
+	// 							t: uSpeed.getType()
+	// 						},
+	// 						{
+	// 							e: TConst(CFloat(1)),
+	// 							p: null,
+	// 							t: TFloat
+	// 						}
+	// 					]),
+	// 					p: null,
+	// 					t: output.type
+	// 				}),
+	// 				p: null,
+	// 				t: output.type
+	// 			};
+	// }

+ 8 - 13
hrt/shgraph/nodes/UnpackNormal.hx

@@ -6,19 +6,14 @@ using hxsl.Ast;
 @description("")
 @description("")
 @width(120)
 @width(120)
 @group("Channel")
 @group("Channel")
-class UnpackNormal extends ShaderFunction {
+class UnpackNormal extends  ShaderNodeHxsl {
 
 
-	@input("normal") var normal = SType.Vec4;
-
-	public function new() {
-		super(UnpackNormal);
-	}
-
-	override public function computeOutputs() {
-		if (normal != null && !normal.isEmpty())
-			addOutput("output", TVec(3, VFloat));
-		else
-			removeOutput("output");
-	}
+	static var SRC = {
+		@sginput(0.0) var a : Vec4;
+		@sgoutput var output : Vec3;
+		function fragment() {
+			output = unpackNormal(a);
+		}
+	};
 
 
 }
 }

+ 8 - 11
hrt/shgraph/nodes/UvToScreen.hx

@@ -6,19 +6,16 @@ using hxsl.Ast;
 @description("")
 @description("")
 @width(100)
 @width(100)
 @group("Math")
 @group("Math")
-class UvToScreen extends ShaderFunction {
+class UvToScreen extends ShaderNodeHxsl {
 
 
-	@input("UV") var uv = SType.Vec2;
+	static var SRC = {
+		@sginput var uv : Vec2;
 
 
-	public function new() {
-		super(UvToScreen);
-	}
+		@sgoutput var output : Vec2;
 
 
-	override public function computeOutputs() {
-		if (uv != null && !uv.isEmpty())
-			addOutput("output", uv.getType());
-		else
-			removeOutput("output");
-	}
+		function fragment() {
+			output = uvToScreen(uv);
+		}
+	};
 
 
 }
 }

+ 16 - 0
hrt/shgraph/nodes/test/CalculatedUVNode.hx

@@ -0,0 +1,16 @@
+package hrt.shgraph.nodes.test;
+
+@name("Calculated UV")
+@description("Testing only")
+@width(80)
+@group("Misc")
+class CalculatedUVNode extends ShaderNodeHxsl {
+
+	static var SRC = {
+		@input var uv : Vec2;
+		@sgoutput var output : Vec4;
+		function fragment() {
+			output = vec4(uv, 0.0,0.0);
+		}
+	}
+}

Some files were not shown because too many files changed in this diff