浏览代码

ShaderGraph: Preview node with param update + fix on edge replace

Tom SPIRA 6 年之前
父节点
当前提交
cc241b2da4
共有 4 个文件被更改,包括 104 次插入42 次删除
  1. 16 14
      hide/view/Graph.hx
  2. 28 1
      hide/view/shadereditor/ShaderEditor.hx
  3. 1 0
      hrt/shgraph/ShaderGraph.hx
  4. 59 27
      hrt/shgraph/nodes/Preview.hx

+ 16 - 14
hide/view/Graph.hx

@@ -175,7 +175,7 @@ class Graph extends FileView {
 			if (distOutput > distInput) {
 				replaceEdge(FromOutput, currentEdge.nodeTo, clientX, clientY);
 			} else {
-				replaceEdge(FromInput, currentEdge.nodeFrom, clientX, clientY);
+				replaceEdge(FromInput, currentEdge, clientX, clientY);
 			}
 			currentEdge = null;
 			return;
@@ -368,28 +368,30 @@ class Graph extends FileView {
 		listOfEdges.remove(edge);
 	}
 
-	function replaceEdge(state : EdgeState, node : JQuery, x : Int, y : Int) {
+	function replaceEdge(state : EdgeState, ?edge : Edge, ?node : JQuery, x : Int, y : Int) {
 		switch (state) {
 			case FromOutput:
-				for (edge in listOfEdges) {
-					if (edge.nodeTo.is(node)) {
+				for (e in listOfEdges) {
+					if (e.nodeTo.is(node)) {
 						isCreatingLink = FromOutput;
-						startLinkGrNode = edge.nodeFrom.parent();
-						startLinkBox = edge.from;
-						setAvailableInputNodes(edge.from, edge.nodeFrom.attr("field"));
-						removeEdge(edge);
+						startLinkGrNode = e.nodeFrom.parent();
+						startLinkBox = e.from;
+						setAvailableInputNodes(e.from, e.nodeFrom.attr("field"));
+						removeEdge(e);
 						createLink(x, y);
+						return;
 					}
 				}
 			case FromInput:
-				for (edge in listOfEdges) {
-					if (edge.nodeFrom.is(node)) {
+				for (e in listOfEdges) {
+					if (e.nodeTo.is(edge.nodeTo) && e.nodeFrom.is(edge.nodeFrom)) {
 						isCreatingLink = FromInput;
-						startLinkGrNode = edge.nodeTo.parent();
-						startLinkBox = edge.to;
-						setAvailableOutputNodes(edge.to, edge.nodeTo.attr("field"));
-						removeEdge(edge);
+						startLinkGrNode = e.nodeTo.parent();
+						startLinkBox = e.to;
+						setAvailableOutputNodes(e.to, e.nodeTo.attr("field"));
+						removeEdge(e);
 						createLink(x, y);
+						return;
 					}
 				}
 			default:

+ 28 - 1
hide/view/shadereditor/ShaderEditor.hx

@@ -44,6 +44,7 @@ class ShaderEditor extends hide.view.Graph {
 	var COMPILE_SHADER_DEBOUNCE : Int = 100;
 	var VIEW_VISIBLE_CHECK_TIMER : Int = 500;
 	var currentShader : DynamicShader;
+	var currentShaderDef : hrt.prefab.ContextShared.ShaderDef;
 
 	override function onDisplay() {
 		super.onDisplay();
@@ -610,6 +611,7 @@ class ShaderEditor extends hide.view.Graph {
 			}
 			@:privateAccess sceneEditor.scene.render(sceneEditor.scene.engine);
 			currentShader = newShader;
+			currentShaderDef = shaderGraphDef;
 			info('Shader compiled in  ${Date.now().getTime() - timeStart}ms');
 
 		} catch (e : Dynamic) {
@@ -651,8 +653,25 @@ class ShaderEditor extends hide.view.Graph {
 	}
 
 	function updateParam(id : Int) {
+		sceneEditor.scene.setCurrent();
 		var param = shaderGraph.getParameter(id);
-		setParamValue(currentShader, param.variable, param.defaultValue);
+		setParamValueByName(currentShader, param.name, param.defaultValue);
+		for (b in listOfBoxes) {
+			var previewBox = Std.instance(b.getInstance(), hrt.shgraph.nodes.Preview);
+			if (previewBox != null) {
+				previewBox.setParamValueByName(param.variable.name, param.defaultValue);
+			}
+		}
+	}
+
+	function setParamValueByName(shader : DynamicShader, varName : String, value : Dynamic) {
+		if (currentShaderDef == null) return;
+		for (init in currentShaderDef.inits) {
+			if (init.variable.name == varName) {
+				setParamValue(shader, init.variable, value);
+				return;
+			}
+		}
 	}
 
 	function setParamValue(shader : DynamicShader, variable : hxsl.Ast.TVar, value : Dynamic) {
@@ -678,6 +697,14 @@ class ShaderEditor extends hide.view.Graph {
 		var node = shaderGraph.addNode(p.x, p.y, nodeClass);
 		afterChange();
 
+		var shaderPreview = Std.instance(node, hrt.shgraph.nodes.Preview);
+		if (shaderPreview != null) {
+			shaderPreview.config = config;
+			shaderPreview.shaderGraph = shaderGraph;
+			addBox(p, nodeClass, shaderPreview);
+			return node;
+		}
+
 		addBox(p, nodeClass, node);
 
 		return node;

+ 1 - 0
hrt/shgraph/ShaderGraph.hx

@@ -195,6 +195,7 @@ class ShaderGraph {
 		}
 		var shaderParam = Std.instance(node, ShaderParam);
 		if (shaderParam != null && !alreadyAddVariable(shaderParam.variable)) {
+			shaderParam.variable = generateParameter(shaderParam.variable.name, shaderParam.variable.type);
 			allVariables.push(shaderParam.variable);
 			allParameters.push(shaderParam.variable);
 			allParamDefaultValue.push(getParameter(shaderParam.parameterId).defaultValue);

+ 59 - 27
hrt/shgraph/nodes/Preview.hx

@@ -27,13 +27,14 @@ class Preview extends ShaderNode {
 			};
 
 	}
-	static var availableOutputs = [];
 
 	#if editor
 	public var shaderGraph : ShaderGraph;
+	var nodePreview : js.jquery.JQuery;
 	var cube : Mesh;
 	var scene : hide.comp.Scene;
-	var saveShader : hxsl.DynamicShader;
+	var currentShaderPreview : hxsl.DynamicShader;
+	var currentShaderDef : hrt.prefab.ContextShared.ShaderDef;
 	public var config : hide.Config;
 
 	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
@@ -48,19 +49,22 @@ class Preview extends ShaderNode {
 			throw ShaderException.t("The preview is not available", this.id);
 		}
 		var element = new hide.Element('<div style="width: 100px; height: 90px"><div class="preview-parent" ><div class="node-preview" style="height: 100px" ></div></div></div>');
-		scene = new hide.comp.Scene(config, null, element.find(".node-preview"));
-		element.find(".node-preview").hide();
+		nodePreview = element.find(".node-preview");
+		scene = new hide.comp.Scene(config, null, nodePreview);
+		nodePreview.hide();
 		scene.onReady = function() {
 			var prim = new h3d.prim.Cube();
 			prim.addUVs();
 			prim.addNormals();
 			cube = new Mesh(prim, scene.s3d);
-			element.find(".node-preview").removeClass("hide-scene-container");
-			//var c = new h3d.scene.CameraController(scene.s3d);
-			//trace(cube.getBounds());
-			//c.setPosition(5, 0, 0);
-			//c.setDirection(cube.getAbsPos().getPosition().sub(c.getAbsPos().getPosition()));
-			scene.resetCamera(cube);
+			nodePreview.removeClass("hide-scene-container");
+			var c = new h3d.scene.CameraController(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;
+			c.loadFromCamera();
 			scene.init();
 			onMove();
 			computeOutputs();
@@ -73,22 +77,22 @@ class Preview extends ShaderNode {
 	public function onMove(?x : Float, ?y : Float, zoom : Float = 1.) {
 		var top : Float;
 		var left : Float;
-		var preview = new hide.Element(".node-preview");
-		var parent = preview.parent();
+		var parent = nodePreview.parent();
 		if (x != null && y != null) {
 			left = x;
 			top = y;
 		} else {
-			var offsetWindow = preview.closest(".heaps-scene").offset();
-			var offset = preview.closest("foreignObject").offset();
+			var offsetWindow = nodePreview.closest(".heaps-scene").offset();
+			var offset = nodePreview.closest("foreignObject").offset();
+			if (offsetWindow == null || offset == null) return;
 			top = offset.top - offsetWindow.top - 32;
 			left = offset.left - offsetWindow.left;
 		}
-		preview.closest(".properties-group").children().first().css("fill", "#000");
+		nodePreview.closest(".properties-group").children().first().css("fill", "#000");
 		parent.css("top", top/zoom + 17);
 		parent.css("left", left/zoom);
 		parent.css("zoom", zoom);
-		preview.show();
+		nodePreview.show();
 	}
 
 	function onResize() {
@@ -97,20 +101,50 @@ class Preview extends ShaderNode {
 	}
 
 	override public function computeOutputs() {
-		if (saveShader != null) {
+		if (currentShaderPreview != null) {
 			for (m in cube.getMaterials()) {
-				m.mainPass.removeShader(saveShader);
+				m.mainPass.removeShader(currentShaderPreview);
 			}
 		}
 
 		if (scene == null || input == null || input.isEmpty()) return;
 
 		scene.setCurrent();
-		var shaderGraphDef = shaderGraph.compile(this);
-		var shader = new hxsl.DynamicShader(shaderGraphDef.shader);
-		for (init in shaderGraphDef.inits) {
-			var variable = init.variable;
-			var value : Dynamic = init.value;
+
+		var shader : hxsl.DynamicShader = null;
+		try {
+			var shaderGraphDef = shaderGraph.compile(this);
+			shader = new hxsl.DynamicShader(shaderGraphDef.shader);
+			for (init in shaderGraphDef.inits) {
+				setParamValue(init.variable, init.value, shader);
+			}
+			for (m in cube.getMaterials()) {
+				m.mainPass.addShader(shader);
+			}
+			currentShaderPreview = shader;
+			currentShaderDef = shaderGraphDef;
+		} catch(e : Dynamic) {
+			if (shader != null) {
+				for (m in cube.getMaterials()) {
+					m.mainPass.removeShader(shader);
+				}
+			}
+		}
+	}
+
+	public function setParamValueByName(varName : String, value : Dynamic) {
+		if (currentShaderDef == null) return;
+		for (init in currentShaderDef.inits) {
+			if (init.variable.name == varName) {
+				setParamValue(init.variable, value, currentShaderPreview);
+				return;
+			}
+		}
+	}
+
+	public function setParamValue(variable : TVar, value : Dynamic, shader : hxsl.DynamicShader) {
+		scene.setCurrent();
+		try {
 			switch (variable.type) {
 				case TSampler2D:
 					shader.setParamValue(variable, scene.loadTexture("", value));
@@ -121,11 +155,9 @@ class Preview extends ShaderNode {
 						shader.setParamValue(variable, value);
 					}
 			}
+		} catch (e : Dynamic) {
+			// variable not used
 		}
-		for (m in cube.getMaterials()) {
-			m.mainPass.addShader(shader);
-		}
-		saveShader = shader;
 	}
 
 	#end