Browse Source

Fix visual shader graph not correctly updating when multiple tabs opened

Yuri Rubinsky 3 years ago
parent
commit
f05fce405e

+ 10 - 0
editor/plugins/shader_editor_plugin.cpp

@@ -923,6 +923,15 @@ ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_sha
 	return nullptr;
 }
 
+VisualShaderEditor *ShaderEditorPlugin::get_visual_shader_editor(const Ref<Shader> &p_for_shader) {
+	for (uint32_t i = 0; i < edited_shaders.size(); i++) {
+		if (edited_shaders[i].shader == p_for_shader) {
+			return edited_shaders[i].visual_shader_editor;
+		}
+	}
+	return nullptr;
+}
+
 void ShaderEditorPlugin::save_external_data() {
 	for (uint32_t i = 0; i < edited_shaders.size(); i++) {
 		if (edited_shaders[i].shader_editor) {
@@ -950,6 +959,7 @@ void ShaderEditorPlugin::_close_shader(int p_index) {
 	memdelete(c);
 	edited_shaders.remove_at(index);
 	_update_shader_list();
+	EditorNode::get_singleton()->get_undo_redo()->clear_history(); // To prevent undo on deleted graphs.
 }
 
 void ShaderEditorPlugin::_resource_saved(Object *obj) {

+ 1 - 0
editor/plugins/shader_editor_plugin.h

@@ -209,6 +209,7 @@ public:
 	virtual void selected_notify() override;
 
 	ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader);
+	VisualShaderEditor *get_visual_shader_editor(const Ref<Shader> &p_for_shader);
 
 	virtual void save_external_data() override;
 	virtual void apply_changes() override;

+ 57 - 64
editor/plugins/visual_shader_editor_plugin.cpp

@@ -40,6 +40,7 @@
 #include "editor/editor_node.h"
 #include "editor/editor_properties.h"
 #include "editor/editor_scale.h"
+#include "editor/plugins/shader_editor_plugin.h"
 #include "scene/animation/animation_player.h"
 #include "scene/gui/menu_button.h"
 #include "scene/gui/panel.h"
@@ -72,6 +73,10 @@ const int MAX_FLOAT_CONST_DEFS = sizeof(float_constant_defs) / sizeof(FloatConst
 
 ///////////////////
 
+void VisualShaderNodePlugin::set_editor(VisualShaderEditor *p_editor) {
+	vseditor = p_editor;
+}
+
 Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
 	Object *ret;
 	if (GDVIRTUAL_CALL(_create_editor, p_parent_resource, p_node, ret)) {
@@ -115,6 +120,10 @@ void VisualShaderGraphPlugin::_bind_methods() {
 	ClassDB::bind_method("update_curve_xyz", &VisualShaderGraphPlugin::update_curve_xyz);
 }
 
+void VisualShaderGraphPlugin::set_editor(VisualShaderEditor *p_editor) {
+	editor = p_editor;
+}
+
 void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) {
 	visual_shader = Ref<VisualShader>(p_shader);
 }
@@ -186,10 +195,6 @@ void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_
 
 	switch (p_value.get_type()) {
 		case Variant::COLOR: {
-			VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-			if (!editor) {
-				break;
-			}
 			button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
 
 			Callable ce = callable_mp(editor, &VisualShaderEditor::_draw_color_over_button);
@@ -337,10 +342,6 @@ void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_u
 }
 
 void VisualShaderGraphPlugin::update_theme() {
-	VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-	if (!editor) {
-		return;
-	}
 	vector_expanded_color[0] = editor->get_theme_color(SNAME("axis_x_color"), SNAME("Editor")); // red
 	vector_expanded_color[1] = editor->get_theme_color(SNAME("axis_y_color"), SNAME("Editor")); // green
 	vector_expanded_color[2] = editor->get_theme_color(SNAME("axis_z_color"), SNAME("Editor")); // blue
@@ -351,10 +352,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
 	if (!visual_shader.is_valid() || p_type != visual_shader->get_shader_type()) {
 		return;
 	}
-	VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-	if (!editor) {
-		return;
-	}
 	GraphEdit *graph = editor->graph;
 	if (!graph) {
 		return;
@@ -474,6 +471,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
 		node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
 	}
 
+	Ref<VisualShaderNodeUniformRef> uniform_ref = vsnode;
+	if (uniform_ref.is_valid()) {
+		uniform_ref->set_shader_rid(visual_shader->get_rid());
+		uniform_ref->update_uniform_type();
+	}
+
 	Ref<VisualShaderNodeUniform> uniform = vsnode;
 	HBoxContainer *hb = nullptr;
 
@@ -1035,10 +1038,6 @@ void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id) {
 }
 
 void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
-	VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-	if (!editor) {
-		return;
-	}
 	GraphEdit *graph = editor->graph;
 	if (!graph) {
 		return;
@@ -1055,10 +1054,6 @@ void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_fro
 }
 
 void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
-	VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-	if (!editor) {
-		return;
-	}
 	GraphEdit *graph = editor->graph;
 	if (!graph) {
 		return;
@@ -1085,6 +1080,10 @@ VisualShaderGraphPlugin::~VisualShaderGraphPlugin() {
 
 /////////////////
 
+Vector2 VisualShaderEditor::selection_center;
+List<VisualShaderEditor::CopyItem> VisualShaderEditor::copy_items_buffer;
+List<VisualShader::Connection> VisualShaderEditor::copy_connections_buffer;
+
 void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
 	bool changed = false;
 	if (p_visual_shader) {
@@ -1602,7 +1601,7 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) {
 }
 
 void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
-	VisualShaderNodeUniformRef::clear_uniforms();
+	VisualShaderNodeUniformRef::clear_uniforms(visual_shader->get_rid());
 
 	for (int t = 0; t < VisualShader::TYPE_MAX; t++) {
 		Vector<int> tnodes = visual_shader->get_node_list((VisualShader::Type)t);
@@ -1640,7 +1639,7 @@ void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
 				} else {
 					uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_SAMPLER;
 				}
-				VisualShaderNodeUniformRef::add_uniform(uniform->get_uniform_name(), uniform_type);
+				VisualShaderNodeUniformRef::add_uniform(visual_shader->get_rid(), uniform->get_uniform_name(), uniform_type);
 			}
 		}
 	}
@@ -2645,7 +2644,6 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
 			_setup_node(vsn, p_ops);
 		}
 		VisualShaderNodeUniformRef *uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn);
-
 		if (uniform_ref && to_node != -1 && to_slot != -1) {
 			VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot);
 			bool success = false;
@@ -4644,10 +4642,7 @@ void VisualShaderEditor::_bind_methods() {
 	ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
 }
 
-VisualShaderEditor *VisualShaderEditor::singleton = nullptr;
-
 VisualShaderEditor::VisualShaderEditor() {
-	singleton = this;
 	ShaderLanguage::get_keyword_list(&keyword_list);
 
 	graph = memnew(GraphEdit);
@@ -5635,9 +5630,11 @@ VisualShaderEditor::VisualShaderEditor() {
 
 	Ref<VisualShaderNodePluginDefault> default_plugin;
 	default_plugin.instantiate();
+	default_plugin->set_editor(this);
 	add_plugin(default_plugin);
 
 	graph_plugin.instantiate();
+	graph_plugin->set_editor(this);
 
 	property_editor = memnew(CustomPropertyEditor);
 	add_child(property_editor);
@@ -5648,6 +5645,7 @@ VisualShaderEditor::VisualShaderEditor() {
 class VisualShaderNodePluginInputEditor : public OptionButton {
 	GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);
 
+	VisualShaderEditor *editor = nullptr;
 	Ref<VisualShaderNodeInput> input;
 
 public:
@@ -5660,13 +5658,11 @@ public:
 	}
 
 	void _item_selected(int p_item) {
-		VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-		if (editor) {
-			editor->call_deferred(SNAME("_input_select_item"), input, get_item_text(p_item));
-		}
+		editor->call_deferred(SNAME("_input_select_item"), input, get_item_text(p_item));
 	}
 
-	void setup(const Ref<VisualShaderNodeInput> &p_input) {
+	void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeInput> &p_input) {
+		editor = p_editor;
 		input = p_input;
 		Ref<Texture2D> type_icon[] = {
 			EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
@@ -5699,6 +5695,7 @@ public:
 class VisualShaderNodePluginVaryingEditor : public OptionButton {
 	GDCLASS(VisualShaderNodePluginVaryingEditor, OptionButton);
 
+	VisualShaderEditor *editor = nullptr;
 	Ref<VisualShaderNodeVarying> varying;
 
 public:
@@ -5709,13 +5706,11 @@ public:
 	}
 
 	void _item_selected(int p_item) {
-		VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-		if (editor) {
-			editor->call_deferred(SNAME("_varying_select_item"), varying, get_item_text(p_item));
-		}
+		editor->call_deferred(SNAME("_varying_select_item"), varying, get_item_text(p_item));
 	}
 
-	void setup(const Ref<VisualShaderNodeVarying> &p_varying, VisualShader::Type p_type) {
+	void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeVarying> &p_varying, VisualShader::Type p_type) {
+		editor = p_editor;
 		varying = p_varying;
 
 		Ref<Texture2D> type_icon[] = {
@@ -5776,6 +5771,7 @@ public:
 class VisualShaderNodePluginUniformRefEditor : public OptionButton {
 	GDCLASS(VisualShaderNodePluginUniformRefEditor, OptionButton);
 
+	VisualShaderEditor *editor = nullptr;
 	Ref<VisualShaderNodeUniformRef> uniform_ref;
 
 public:
@@ -5788,13 +5784,11 @@ public:
 	}
 
 	void _item_selected(int p_item) {
-		VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-		if (editor) {
-			editor->call_deferred(SNAME("_uniform_select_item"), uniform_ref, get_item_text(p_item));
-		}
+		editor->call_deferred(SNAME("_uniform_select_item"), uniform_ref, get_item_text(p_item));
 	}
 
-	void setup(const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) {
+	void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) {
+		editor = p_editor;
 		uniform_ref = p_uniform_ref;
 
 		Ref<Texture2D> type_icon[] = {
@@ -5828,6 +5822,7 @@ public:
 
 class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
 	GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
+	VisualShaderEditor *editor = nullptr;
 	Ref<Resource> parent_resource;
 	int node_id = 0;
 	VisualShader::Type shader_type;
@@ -5861,13 +5856,10 @@ public:
 			}
 		}
 		if (p_property != "constant") {
-			VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-			if (editor) {
-				VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
-				if (graph_plugin) {
-					undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
-					undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
-				}
+			VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
+			if (graph_plugin) {
+				undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
+				undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
 			}
 		}
 		undo_redo->commit_action();
@@ -5903,7 +5895,8 @@ public:
 		}
 	}
 
-	void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, const HashMap<StringName, String> &p_overrided_names, Ref<VisualShaderNode> p_node) {
+	void setup(VisualShaderEditor *p_editor, Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, const HashMap<StringName, String> &p_overrided_names, Ref<VisualShaderNode> p_node) {
+		editor = p_editor;
 		parent_resource = p_parent_resource;
 		updating = false;
 		node = p_node;
@@ -5956,19 +5949,19 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
 
 	if (p_shader.is_valid() && (p_node->is_class("VisualShaderNodeVaryingGetter") || p_node->is_class("VisualShaderNodeVaryingSetter"))) {
 		VisualShaderNodePluginVaryingEditor *editor = memnew(VisualShaderNodePluginVaryingEditor);
-		editor->setup(p_node, p_shader->get_shader_type());
+		editor->setup(vseditor, p_node, p_shader->get_shader_type());
 		return editor;
 	}
 
 	if (p_node->is_class("VisualShaderNodeUniformRef")) {
 		VisualShaderNodePluginUniformRefEditor *editor = memnew(VisualShaderNodePluginUniformRefEditor);
-		editor->setup(p_node);
+		editor->setup(vseditor, p_node);
 		return editor;
 	}
 
 	if (p_node->is_class("VisualShaderNodeInput")) {
 		VisualShaderNodePluginInputEditor *editor = memnew(VisualShaderNodePluginInputEditor);
-		editor->setup(p_node);
+		editor->setup(vseditor, p_node);
 		return editor;
 	}
 
@@ -6023,22 +6016,22 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
 		properties.push_back(pinfo[i].name);
 	}
 	VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
-	editor->setup(p_parent_resource, editors, properties, p_node->get_editable_properties_names(), p_node);
+	editor->setup(vseditor, p_parent_resource, editors, properties, p_node->get_editable_properties_names(), p_node);
 	return editor;
 }
 
 void EditorPropertyShaderMode::_option_selected(int p_which) {
-	VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
-	if (!editor) {
+	Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object()));
+	if (visual_shader->get_mode() == p_which) {
 		return;
 	}
 
-	//will not use this, instead will do all the logic setting manually
-	//emit_signal(SNAME("property_changed"), get_edited_property(), p_which);
-
-	Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object()));
-
-	if (visual_shader->get_mode() == p_which) {
+	ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
+	if (!shader_editor) {
+		return;
+	}
+	VisualShaderEditor *editor = shader_editor->get_visual_shader_editor(visual_shader);
+	if (!editor) {
 		return;
 	}
 
@@ -6145,10 +6138,10 @@ bool EditorInspectorShaderModePlugin::can_handle(Object *p_object) {
 
 bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
 	if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) {
-		EditorPropertyShaderMode *editor = memnew(EditorPropertyShaderMode);
+		EditorPropertyShaderMode *mode_editor = memnew(EditorPropertyShaderMode);
 		Vector<String> options = p_hint_text.split(",");
-		editor->setup(options);
-		add_property_editor(p_path, editor);
+		mode_editor->setup(options);
+		add_property_editor(p_path, mode_editor);
 
 		return true;
 	}

+ 12 - 6
editor/plugins/visual_shader_editor_plugin.h

@@ -42,15 +42,21 @@
 #include "scene/gui/tree.h"
 #include "scene/resources/visual_shader.h"
 
+class VisualShaderEditor;
+
 class VisualShaderNodePlugin : public RefCounted {
 	GDCLASS(VisualShaderNodePlugin, RefCounted);
 
+protected:
+	VisualShaderEditor *vseditor = nullptr;
+
 protected:
 	static void _bind_methods();
 
 	GDVIRTUAL2RC(Object *, _create_editor, Ref<Resource>, Ref<VisualShaderNode>)
 
 public:
+	void set_editor(VisualShaderEditor *p_editor);
 	virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
 };
 
@@ -58,6 +64,8 @@ class VisualShaderGraphPlugin : public RefCounted {
 	GDCLASS(VisualShaderGraphPlugin, RefCounted);
 
 private:
+	VisualShaderEditor *editor = nullptr;
+
 	struct InputPort {
 		Button *default_input_button = nullptr;
 	};
@@ -91,6 +99,7 @@ protected:
 	static void _bind_methods();
 
 public:
+	void set_editor(VisualShaderEditor *p_editor);
 	void register_shader(VisualShader *p_visual_shader);
 	void set_connections(const List<VisualShader::Connection> &p_connections);
 	void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node);
@@ -324,8 +333,6 @@ class VisualShaderEditor : public VBoxContainer {
 	void _update_preview();
 	String _get_description(int p_idx);
 
-	static VisualShaderEditor *singleton;
-
 	struct DragOp {
 		VisualShader::Type type = VisualShader::Type::TYPE_MAX;
 		int node = 0;
@@ -403,9 +410,9 @@ class VisualShaderEditor : public VBoxContainer {
 
 	void _duplicate_nodes();
 
-	Vector2 selection_center;
-	List<CopyItem> copy_items_buffer;
-	List<VisualShader::Connection> copy_connections_buffer;
+	static Vector2 selection_center;
+	static List<CopyItem> copy_items_buffer;
+	static List<VisualShader::Connection> copy_connections_buffer;
 
 	void _clear_copy_buffer();
 	void _copy_nodes(bool p_cut);
@@ -482,7 +489,6 @@ public:
 	void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
 	void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
 
-	static VisualShaderEditor *get_singleton() { return singleton; }
 	VisualShaderGraphPlugin *get_graph_plugin() { return graph_plugin.ptr(); }
 
 	void clear_custom_types();

+ 39 - 18
scene/resources/visual_shader.cpp

@@ -30,6 +30,7 @@
 
 #include "visual_shader.h"
 
+#include "core/templates/rb_map.h"
 #include "core/templates/vmap.h"
 #include "servers/rendering/shader_types.h"
 #include "visual_shader_nodes.h"
@@ -3189,18 +3190,18 @@ VisualShaderNodeInput::VisualShaderNodeInput() {
 
 ////////////// UniformRef
 
-List<VisualShaderNodeUniformRef::Uniform> uniforms;
+RBMap<RID, List<VisualShaderNodeUniformRef::Uniform>> uniforms;
 
-void VisualShaderNodeUniformRef::add_uniform(const String &p_name, UniformType p_type) {
-	uniforms.push_back({ p_name, p_type });
+void VisualShaderNodeUniformRef::add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type) {
+	uniforms[p_shader_rid].push_back({ p_name, p_type });
 }
 
-void VisualShaderNodeUniformRef::clear_uniforms() {
-	uniforms.clear();
+void VisualShaderNodeUniformRef::clear_uniforms(RID p_shader_rid) {
+	uniforms[p_shader_rid].clear();
 }
 
-bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) {
-	for (const VisualShaderNodeUniformRef::Uniform &E : uniforms) {
+bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_name) {
+	for (const VisualShaderNodeUniformRef::Uniform &E : uniforms[p_shader_rid]) {
 		if (E.name == p_name) {
 			return true;
 		}
@@ -3313,14 +3314,24 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const {
 	return "";
 }
 
+void VisualShaderNodeUniformRef::set_shader_rid(const RID &p_shader_rid) {
+	shader_rid = p_shader_rid;
+}
+
 void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) {
 	uniform_name = p_name;
+	if (shader_rid.is_valid()) {
+		update_uniform_type();
+	}
+	emit_changed();
+}
+
+void VisualShaderNodeUniformRef::update_uniform_type() {
 	if (uniform_name != "[None]") {
 		uniform_type = get_uniform_type_by_name(uniform_name);
 	} else {
 		uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
 	}
-	emit_changed();
 }
 
 String VisualShaderNodeUniformRef::get_uniform_name() const {
@@ -3328,35 +3339,45 @@ String VisualShaderNodeUniformRef::get_uniform_name() const {
 }
 
 int VisualShaderNodeUniformRef::get_uniforms_count() const {
-	return uniforms.size();
+	ERR_FAIL_COND_V(!shader_rid.is_valid(), 0);
+
+	return uniforms[shader_rid].size();
 }
 
 String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const {
-	if (p_idx >= 0 && p_idx < uniforms.size()) {
-		return uniforms[p_idx].name;
+	ERR_FAIL_COND_V(!shader_rid.is_valid(), String());
+
+	if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+		return uniforms[shader_rid][p_idx].name;
 	}
 	return "";
 }
 
 VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const {
-	for (int i = 0; i < uniforms.size(); i++) {
-		if (uniforms[i].name == p_name) {
-			return uniforms[i].type;
+	ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT);
+
+	for (int i = 0; i < uniforms[shader_rid].size(); i++) {
+		if (uniforms[shader_rid][i].name == p_name) {
+			return uniforms[shader_rid][i].type;
 		}
 	}
 	return UniformType::UNIFORM_TYPE_FLOAT;
 }
 
 VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const {
-	if (p_idx >= 0 && p_idx < uniforms.size()) {
-		return uniforms[p_idx].type;
+	ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT);
+
+	if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+		return uniforms[shader_rid][p_idx].type;
 	}
 	return UniformType::UNIFORM_TYPE_FLOAT;
 }
 
 VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const {
-	if (p_idx >= 0 && p_idx < uniforms.size()) {
-		switch (uniforms[p_idx].type) {
+	ERR_FAIL_COND_V(!shader_rid.is_valid(), PORT_TYPE_SCALAR);
+
+	if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+		switch (uniforms[shader_rid][p_idx].type) {
 			case UniformType::UNIFORM_TYPE_FLOAT:
 				return PORT_TYPE_SCALAR;
 			case UniformType::UNIFORM_TYPE_INT:

+ 8 - 3
scene/resources/visual_shader.h

@@ -561,6 +561,7 @@ public:
 	};
 
 private:
+	RID shader_rid;
 	String uniform_name = "[None]";
 	UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
 
@@ -568,9 +569,9 @@ protected:
 	static void _bind_methods();
 
 public:
-	static void add_uniform(const String &p_name, UniformType p_type);
-	static void clear_uniforms();
-	static bool has_uniform(const String &p_name);
+	static void add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type);
+	static void clear_uniforms(RID p_shader_rid);
+	static bool has_uniform(RID p_shader_rid, const String &p_name);
 
 public:
 	virtual String get_caption() const override;
@@ -583,9 +584,13 @@ public:
 	virtual PortType get_output_port_type(int p_port) const override;
 	virtual String get_output_port_name(int p_port) const override;
 
+	void set_shader_rid(const RID &p_shader);
+
 	void set_uniform_name(const String &p_name);
 	String get_uniform_name() const;
 
+	void update_uniform_type();
+
 	void _set_uniform_type(int p_uniform_type);
 	int _get_uniform_type() const;