Sfoglia il codice sorgente

Merge pull request #40744 from Chaosus/vs_optimize_fresnel

Optimize code generation for fresnel node in visual shaders
Rémi Verschelde 5 anni fa
parent
commit
8965ec124d

+ 23 - 0
scene/resources/visual_shader.cpp

@@ -74,6 +74,21 @@ void VisualShaderNode::set_output_port_connected(int p_port, bool p_connected) {
 	connected_output_ports[p_port] = p_connected;
 }
 
+bool VisualShaderNode::is_input_port_connected(int p_port) const {
+	if (connected_input_ports.has(p_port)) {
+		return connected_input_ports[p_port];
+	}
+	return false;
+}
+
+void VisualShaderNode::set_input_port_connected(int p_port, bool p_connected) {
+	connected_input_ports[p_port] = p_connected;
+}
+
+bool VisualShaderNode::is_generate_input_var(int p_port) const {
+	return true;
+}
+
 bool VisualShaderNode::is_code_generated() const {
 	return true;
 }
@@ -444,6 +459,7 @@ void VisualShader::remove_node(Type p_type, int p_id) {
 			g->connections.erase(E);
 			if (E->get().from_node == p_id) {
 				g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
+				g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false);
 			}
 		}
 		E = N;
@@ -542,6 +558,7 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
 	g->connections.push_back(c);
 	g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
 	g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+	g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
 
 	_queue_update();
 }
@@ -574,6 +591,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
 	g->connections.push_back(c);
 	g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
 	g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true);
+	g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true);
 
 	_queue_update();
 	return OK;
@@ -588,6 +606,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
 			g->connections.erase(E);
 			g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
 			g->nodes[p_from_node].node->set_output_port_connected(p_from_port, false);
+			g->nodes[p_to_node].node->set_input_port_connected(p_to_port, false);
 			_queue_update();
 			return;
 		}
@@ -1210,6 +1229,10 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
 				inputs[i] = "int(" + src_var + ")";
 			}
 		} else {
+			if (!vsnode->is_generate_input_var(i)) {
+				continue;
+			}
+
 			Variant defval = vsnode->get_input_port_default_value(i);
 			if (defval.get_type() == Variant::FLOAT) {
 				float val = defval;

+ 4 - 0
scene/resources/visual_shader.h

@@ -182,6 +182,7 @@ class VisualShaderNode : public Resource {
 	int port_preview;
 
 	Map<int, Variant> default_input_values;
+	Map<int, bool> connected_input_ports;
 	Map<int, bool> connected_output_ports;
 
 protected:
@@ -225,6 +226,9 @@ public:
 
 	bool is_output_port_connected(int p_port) const;
 	void set_output_port_connected(int p_port, bool p_connected);
+	bool is_input_port_connected(int p_port) const;
+	void set_input_port_connected(int p_port, bool p_connected);
+	virtual bool is_generate_input_var(int p_port) const;
 
 	virtual bool is_code_generated() const;
 

+ 16 - 1
scene/resources/visual_shader_nodes.cpp

@@ -4457,6 +4457,13 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
 	return "result";
 }
 
+bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const {
+	if (p_port == 2) {
+		return false;
+	}
+	return true;
+}
+
 String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
 	String normal;
 	String view;
@@ -4471,7 +4478,15 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader:
 		view = p_input_vars[1];
 	}
 
-	return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+	if (is_input_port_connected(2)) {
+		return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
+	} else {
+		if (get_input_port_default_value(2)) {
+			return "\t" + p_output_vars[0] + " = pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+		} else {
+			return "\t" + p_output_vars[0] + " = pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
+		}
+	}
 }
 
 String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const {

+ 1 - 0
scene/resources/visual_shader_nodes.h

@@ -1877,6 +1877,7 @@ public:
 	virtual String get_output_port_name(int p_port) const override;
 
 	virtual String get_input_port_default_hint(int p_port) const override;
+	virtual bool is_generate_input_var(int p_port) const override;
 	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
 
 	VisualShaderNodeFresnel();