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

Add some nodes for shader graph

ShiroSmith пре 4 година
родитељ
комит
3c4dfbd492

+ 62 - 0
hrt/shgraph/ShaderCameraInput.hx

@@ -0,0 +1,62 @@
+package hrt.shgraph;
+
+using hxsl.Ast;
+
+@name("Camera")
+@description("Inputs from Camera")
+@group("Property")
+@color("#0e8826")
+class ShaderCameraInput extends ShaderInput {
+
+	static var cameraInputs = [	{ parent: null, id: 0, kind: Global, name: "camera.view", type: TMat4 },
+								{ parent: null, id: 0, kind: Global, name: "camera.proj", type: TVec(3, VFloat) },
+								{ parent: null, id: 0, kind: Global, name: "camera.position", type: TVec(3, VFloat) },
+								{ parent: null, id: 0, kind: Global, name: "camera.projFlip", type: TFloat },
+								{ parent: null, id: 0, kind: Global, name: "camera.projDiag", type: TVec(3, VFloat) },
+								{ parent: null, id: 0, kind: Global, name: "camera.viewProj", type: TMat4 },
+								{ parent: null, id: 0, kind: Global, name: "camera.inverseViewProj", type: TMat4 },
+								{ parent: null, id: 0, kind: Global, name: "camera.zNear", type: TFloat },
+								{ parent: null, id: 0, kind: Global, name: "camera.zFar", type: TFloat },
+								{ parent: null, id: 0, kind: Global, name: "camera.dir", type: TVec(3, VFloat) } ];
+
+	override public function loadProperties(props : Dynamic) {
+		var paramVariable : String = Reflect.field(props, "variable");
+		for (c in ShaderCameraInput.cameraInputs) {
+			if (c.name == paramVariable) {
+				this.variable = c;
+				return;
+			}
+		}
+	}
+
+	#if editor
+	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
+		var elements = [];
+		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
+		element.append(new hide.Element('<select id="variable"></select>'));
+
+		if (this.variable == null) 
+			this.variable = ShaderCameraInput.cameraInputs[0];
+		
+		var input = element.children("select");
+		var indexOption = 0;
+		for (c in ShaderCameraInput.cameraInputs) {
+			var name = c.name.split(".")[1];
+			input.append(new hide.Element('<option value="${indexOption}">${name}</option>'));
+			if (this.variable.name == c.name) {
+				input.val(indexOption);
+			}
+			indexOption++;
+		}
+		input.on("change", function(e) {
+			var value = input.val();
+			this.variable = ShaderCameraInput.cameraInputs[value];
+		});
+
+		elements.push(element);
+
+		return elements;
+	}
+	#end
+
+}

+ 56 - 0
hrt/shgraph/ShaderGlobalInput.hx

@@ -0,0 +1,56 @@
+package hrt.shgraph;
+
+using hxsl.Ast;
+
+@name("Global")
+@description("Global Inputs")
+@group("Property")
+@color("#0e8826")
+class ShaderGlobalInput extends ShaderInput {
+
+	static 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.modelView", 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;
+			}
+		}
+	}
+
+	#if editor
+	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
+		var elements = [];
+		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
+		element.append(new hide.Element('<select id="variable"></select>'));
+
+		if (this.variable == null) 
+			this.variable = ShaderGlobalInput.globalInputs[0];
+		
+		var input = element.children("select");
+		var indexOption = 0;
+		for (c in ShaderGlobalInput.globalInputs) {
+			var name = c.name.split(".")[1];
+			input.append(new hide.Element('<option value="${indexOption}">${name}</option>'));
+			if (this.variable.name == c.name) {
+				input.val(indexOption);
+			}
+			indexOption++;
+		}
+		input.on("change", function(e) {
+			var value = input.val();
+			this.variable = ShaderGlobalInput.globalInputs[value];
+		});
+
+		elements.push(element);
+
+		return elements;
+	}
+	#end
+
+}

+ 16 - 17
hrt/shgraph/ShaderInput.hx

@@ -5,7 +5,6 @@ using hxsl.Ast;
 @name("Inputs")
 @description("Shader inputs of Heaps, it's dynamic")
 @group("Property")
-@noheader()
 @color("#0e8826")
 class ShaderInput extends ShaderNode {
 
@@ -21,20 +20,20 @@ class ShaderInput extends ShaderNode {
 		return null;
 	}
 
-	static var availableInputs = [{
-						parent: null,
-						id: 0,
-						kind: Global,
-						name: "global.time",
-						type: TFloat
-					},
-					{
-						parent: null,
-						id: 0,
-						kind: Input,
-						name: "uv",
-						type: TVec(2, VFloat)
-					}];
+	static var availableInputs = [ 	{ parent: null, id: 0, kind: Input, name: "position", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "color", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "uv", type: TVec(2, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "normal", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "tangent", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "relativePosition", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "transformedPosition", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "projectedPosition", type: TVec(4, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "transformedNormal", type: TVec(3, VFloat) },
+									{ parent: null, id: 0, kind: Input, name: "screenUV", type: TVec(2, VFloat) } ];
+
+	function getAvailableInputs() {
+		return ShaderInput.availableInputs;
+	}
 
 	override public function loadProperties(props : Dynamic) {
 		var paramVariable : String = Reflect.field(props, "variable");
@@ -64,7 +63,7 @@ class ShaderInput extends ShaderNode {
 	#if editor
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
 		var elements = super.getPropertiesHTML(width);
-		var element = new hide.Element('<div style="width: 110px; height: 30px"></div>');
+		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
 		element.append(new hide.Element('<select id="variable"></select>'));
 
 		if (this.variable == null) {
@@ -73,7 +72,7 @@ class ShaderInput extends ShaderNode {
 		var input = element.children("select");
 		var indexOption = 0;
 		for (c in ShaderNode.availableVariables) {
-			input.append(new hide.Element('<option value="${indexOption}">${c.name}</option>'));
+			input.append(new hide.Element('<option value="${indexOption}">${c.name.split(".")[1]}</option>'));
 			if (this.variable.name == c.name) {
 				input.val(indexOption);
 			}

+ 2 - 1
hrt/shgraph/ShaderNode.hx

@@ -11,7 +11,8 @@ class ShaderNode {
 
 	public var id : Int;
 
-	static var availableVariables = [{
+	static var availableVariables = [
+					{
 						parent: null,
 						id: 0,
 						kind: Global,

+ 28 - 1
hrt/shgraph/ShaderOutput.hx

@@ -5,7 +5,6 @@ using hxsl.Ast;
 @name("Outputs")
 @description("Parameters outputs, it's dynamic")
 @group("Output")
-@noheader()
 @color("#A90707")
 class ShaderOutput extends ShaderNode {
 
@@ -40,6 +39,34 @@ class ShaderOutput extends ShaderNode {
 			kind: Var,
 			name: "calculatedUV",
 			type: TVec(2, VFloat)
+		},
+		{
+			parent: null,
+			id: 0,
+			kind: Var,
+			name: "transformedNormal",
+			type: TVec(3, VFloat)
+		},
+		{
+			parent: null,
+			id: 0,
+			kind: Var,
+			name: "metalnessValue",
+			type: TFloat
+		},
+		{
+			parent: null,
+			id: 0,
+			kind: Var,
+			name: "roughnessValue",
+			type: TFloat
+		},
+		{
+			parent: null,
+			id: 0,
+			kind: Var,
+			name: "emissiveValue",
+			type: TFloat
 		}
 	];
 

+ 24 - 0
hrt/shgraph/nodes/Acos.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Arc Cosinus")
+@description("The output is the arc cosinus of A")
+@width(80)
+@group("Math")
+class Acos extends ShaderFunction {
+
+	@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");
+	}
+
+}

+ 24 - 0
hrt/shgraph/nodes/Asin.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Arc Sinus")
+@description("The output is the arc sinus of A")
+@width(80)
+@group("Math")
+class Asin extends ShaderFunction {
+
+	@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");
+	}
+
+}

+ 24 - 0
hrt/shgraph/nodes/Atan.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Arc Tangent")
+@description("The output is the arc tangent of A")
+@width(80)
+@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");
+	}
+
+}

+ 24 - 0
hrt/shgraph/nodes/Ceil.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Ceil")
+@description("The nearest integer greater than or equal to X")
+@width(80)
+@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");
+	}
+
+}

+ 1 - 1
hrt/shgraph/nodes/Clamp.hx

@@ -8,7 +8,7 @@ using hxsl.Ast;
 @group("Math")
 class Clamp extends ShaderFunction {
 
-	@input("X") var x = SType.Number;
+	@input("x") var x = SType.Number;
 	@input("min", true) var min = SType.Number;
 	@input("max", true) var max = SType.Number;
 

+ 1 - 1
hrt/shgraph/nodes/Combine.hx

@@ -73,7 +73,7 @@ class Combine extends ShaderNode {
 		}
 		if (numberOutputs >= 3) {
 			args.push({ name: "b", type : TFloat });
-			valueArgs.push(g.getVar());
+			valueArgs.push(b.getVar());
 			opTGlobal = Vec3;
 		}
 		if (numberOutputs >= 4) {

+ 24 - 0
hrt/shgraph/nodes/Cos.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Cosinus")
+@description("The output is the cosinus of A")
+@width(80)
+@group("Math")
+class Cos extends ShaderFunction {
+
+	@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");
+	}
+
+}

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

@@ -0,0 +1,28 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Cross")
+@description("The output is the cross product of a and b")
+@width(80)
+@group("Math")
+class Cross extends ShaderFunction {
+
+	@input("a") var a = SType.Number;
+	@input("b") var b = SType.Number;
+
+	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");
+	}
+}

+ 21 - 0
hrt/shgraph/nodes/Dot.hx

@@ -0,0 +1,21 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Dot")
+@description("The output is the dot product of a and b")
+@width(80)
+@group("Math")
+class Dot extends ShaderFunction {
+
+	@input("a") var a = SType.Number;
+	@input("b") var b = SType.Number;
+
+	public function new() {
+		super(Dot);
+	}
+
+	override public function computeOutputs() {
+		addOutput("output", TFloat);
+	}
+}

+ 24 - 0
hrt/shgraph/nodes/Exp.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Exp")
+@description("The output is the result of exp(x)")
+@width(80)
+@group("Math")
+class Exp extends ShaderFunction {
+
+	@input("x") var x = SType.Number;
+	@input("p", true) var p = SType.Number;
+
+	public function new() {
+		super(Exp);
+	}
+
+	override public function computeOutputs() {
+		if (x != null && !x.isEmpty())
+			addOutput("output", x.getType());
+		else
+			removeOutput("output");
+	}
+}

+ 24 - 0
hrt/shgraph/nodes/Log.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Log")
+@description("The output is the result of log(x)")
+@width(80)
+@group("Math")
+class Log extends ShaderFunction {
+
+	@input("x") var x = SType.Number;
+	@input("p", true) var p = SType.Number;
+
+	public function new() {
+		super(Log);
+	}
+
+	override public function computeOutputs() {
+		if (x != null && !x.isEmpty())
+			addOutput("output", x.getType());
+		else
+			removeOutput("output");
+	}
+}

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

@@ -0,0 +1,28 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Max")
+@description("The output is the maximum between A and B")
+@width(80)
+@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");
+	}
+
+
+}

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

@@ -0,0 +1,27 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Min")
+@description("The output is the minimum between A and B")
+@width(80)
+@group("Math")
+class Min 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");
+	}
+
+}

+ 23 - 0
hrt/shgraph/nodes/Normalize.hx

@@ -0,0 +1,23 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Normalize")
+@description("The output is the result of normalize(x)")
+@width(80)
+@group("Math")
+class Normalize extends ShaderFunction {
+
+	@input("x") var x = SType.Number;
+
+	public function new() {
+		super(Normalize);
+	}
+
+	override public function computeOutputs() {
+		if (x != null && !x.isEmpty())
+			addOutput("output", x.getType());
+		else
+			removeOutput("output");
+	}
+}

+ 24 - 0
hrt/shgraph/nodes/Pow.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Pow")
+@description("The output is the result of x ^ b")
+@width(80)
+@group("Math")
+class Pow extends ShaderFunction {
+
+	@input("x") var x = SType.Number;
+	@input("p", true) var p = SType.Number;
+
+	public function new() {
+		super(Pow);
+	}
+
+	override public function computeOutputs() {
+		if (x != null && !x.isEmpty())
+			addOutput("output", x.getType());
+		else
+			removeOutput("output");
+	}
+}

+ 30 - 0
hrt/shgraph/nodes/SmoothStep.hx

@@ -0,0 +1,30 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("SmoothStep")
+@description("Linear interpolation between a and b using mix")
+@width(80)
+@group("Math")
+class SmoothStep extends ShaderFunction {
+
+	@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");
+	}
+
+}

+ 29 - 0
hrt/shgraph/nodes/Step.hx

@@ -0,0 +1,29 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Step")
+@description("Generate a step function by comparing a[i] to edge[i]")
+@width(80)
+@group("Math")
+class Step extends ShaderFunction {
+
+	@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");
+	}
+
+}

+ 10 - 0
hrt/shgraph/nodes/SubGraph.hx

@@ -49,6 +49,16 @@ class SubGraph extends ShaderNode {
 					case "ShaderInput":
 						var shaderInput = Std.downcast(node.instance, ShaderInput);
 
+						inputsInfo.set(prefixSubGraph+node.id, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, id : node.id });
+						inputInfoKeys.push(prefixSubGraph+node.id);
+					case "ShaderGlobalInput":
+						var shaderInput = Std.downcast(node.instance, ShaderGlobalInput);
+
+						inputsInfo.set(prefixSubGraph+node.id, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, id : node.id });
+						inputInfoKeys.push(prefixSubGraph+node.id);
+					case "ShaderCameraInput":
+						var shaderInput = Std.downcast(node.instance, ShaderCameraInput);
+
 						inputsInfo.set(prefixSubGraph+node.id, { name : "*" + shaderInput.variable.name , type: ShaderType.getSType(shaderInput.variable.type), hasProperty: false, isRequired : false, id : node.id });
 						inputInfoKeys.push(prefixSubGraph+node.id);
 					case "ShaderOutput":

+ 24 - 0
hrt/shgraph/nodes/Tan.hx

@@ -0,0 +1,24 @@
+package hrt.shgraph.nodes;
+
+using hxsl.Ast;
+
+@name("Tangent")
+@description("The output is the tangent of A")
+@width(80)
+@group("Math")
+class Tan extends ShaderFunction {
+
+	@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");
+	}
+
+}