diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index 6b188a607d78..5d147bd542bf 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -16,6 +16,13 @@
Clears the default input ports value.
+
+
+
+
+ Returns the input port which should be connected by default when this node is created as a result of dragging a connection from an existing node to the empty space on the graph.
+
+
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
index 480f7dfe0e8a..8a90d5dd0f6b 100644
--- a/doc/classes/VisualShaderNodeCustom.xml
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -37,6 +37,14 @@
Defining this method is [b]required[/b].
+
+
+
+
+ Override this method to define the input port which should be connected by default when this node is created as a result of dragging a connection from an existing node to the empty space on the graph.
+ Defining this method is [b]optional[/b]. If not overridden, the connection will be created to the first valid port.
+
+
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index bd30c3b6b718..f180f72cdc66 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -3083,6 +3083,9 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector &p_ops, Stri
if (!is_native) {
vsnode->set_script(add_options[p_idx].script);
}
+ VisualShaderNodeCustom *custom_node = Object::cast_to(vsn);
+ ERR_FAIL_COND(!custom_node);
+ custom_node->update_ports();
}
bool is_texture2d = (Object::cast_to(vsnode.ptr()) != nullptr);
@@ -3211,16 +3214,26 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector &p_ops, Stri
undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
} else {
- // Attempting to connect to the first correct port.
+ int _to_slot = -1;
+
+ // Attempting to connect to the default input port or to the first correct port (if it's not found).
for (int i = 0; i < vsnode->get_input_port_count(); i++) {
if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) {
- undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
- break;
+ if (i == vsnode->get_default_input_port(output_port_type)) {
+ _to_slot = i;
+ break;
+ } else if (_to_slot == -1) {
+ _to_slot = i;
+ }
}
}
+
+ if (_to_slot >= 0) {
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ }
}
if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 8d034d3458d9..7f1c322c8fc8 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -46,6 +46,10 @@ bool VisualShaderNode::is_simple_decl() const {
return simple_decl;
}
+int VisualShaderNode::get_default_input_port(PortType p_type) const {
+ return 0;
+}
+
void VisualShaderNode::set_output_port_for_preview(int p_index) {
port_preview = p_index;
}
@@ -378,6 +382,8 @@ bool VisualShaderNode::is_input_port_default(int p_port, Shader::Mode p_mode) co
}
void VisualShaderNode::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_default_input_port", "type"), &VisualShaderNode::get_default_input_port);
+
ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview);
ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview);
@@ -481,6 +487,12 @@ String VisualShaderNodeCustom::get_input_port_name(int p_port) const {
return input_ports[p_port].name;
}
+int VisualShaderNodeCustom::get_default_input_port(PortType p_type) const {
+ int ret = 0;
+ GDVIRTUAL_CALL(_get_default_input_port, p_type, ret);
+ return ret;
+}
+
int VisualShaderNodeCustom::get_output_port_count() const {
return output_ports.size();
}
@@ -649,6 +661,7 @@ void VisualShaderNodeCustom::_bind_methods() {
GDVIRTUAL_BIND(_get_input_port_count);
GDVIRTUAL_BIND(_get_input_port_type, "port");
GDVIRTUAL_BIND(_get_input_port_name, "port");
+ GDVIRTUAL_BIND(_get_default_input_port, "type");
GDVIRTUAL_BIND(_get_output_port_count);
GDVIRTUAL_BIND(_get_output_port_type, "port");
GDVIRTUAL_BIND(_get_output_port_name, "port");
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 61418b680e6c..d3657eae07d0 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -289,6 +289,7 @@ class VisualShaderNode : public Resource {
virtual int get_input_port_count() const = 0;
virtual PortType get_input_port_type(int p_port) const = 0;
virtual String get_input_port_name(int p_port) const = 0;
+ virtual int get_default_input_port(PortType p_type) const;
virtual void set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value = Variant());
Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied)
@@ -367,6 +368,7 @@ class VisualShaderNodeCustom : public VisualShaderNode {
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
@@ -384,6 +386,7 @@ class VisualShaderNodeCustom : public VisualShaderNode {
GDVIRTUAL0RC(int, _get_input_port_count)
GDVIRTUAL1RC(PortType, _get_input_port_type, int)
GDVIRTUAL1RC(String, _get_input_port_name, int)
+ GDVIRTUAL1RC(int, _get_default_input_port, PortType)
GDVIRTUAL0RC(int, _get_output_port_count)
GDVIRTUAL1RC(PortType, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 9eca4b912726..9d5689572028 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -4137,6 +4137,10 @@ String VisualShaderNodeStep::get_input_port_name(int p_port) const {
return String();
}
+int VisualShaderNodeStep::get_default_input_port(PortType p_type) const {
+ return 1;
+}
+
int VisualShaderNodeStep::get_output_port_count() const {
return 1;
}
@@ -4292,6 +4296,10 @@ String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const {
return String();
}
+int VisualShaderNodeSmoothStep::get_default_input_port(PortType p_type) const {
+ return 2;
+}
+
int VisualShaderNodeSmoothStep::get_output_port_count() const {
return 1;
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 2372bc03840e..4973db0a2205 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1661,6 +1661,7 @@ class VisualShaderNodeStep : public VisualShaderNode {
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
@@ -1707,6 +1708,7 @@ class VisualShaderNodeSmoothStep : public VisualShaderNode {
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;