瀏覽代碼

Added uniform qualifiers to visual shaders

Yuri Roubinsky 5 年之前
父節點
當前提交
082542b525

+ 10 - 3
editor/plugins/visual_shader_editor_plugin.cpp

@@ -546,6 +546,10 @@ void VisualShaderEditor::_update_graph() {
 		Ref<VisualShaderNodeUniform> uniform = vsnode;
 		Ref<VisualShaderNodeUniform> uniform = vsnode;
 		Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode;
 		Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode;
 		Ref<VisualShaderNodeIntUniform> int_uniform = vsnode;
 		Ref<VisualShaderNodeIntUniform> int_uniform = vsnode;
+		Ref<VisualShaderNodeVec3Uniform> vec3_uniform = vsnode;
+		Ref<VisualShaderNodeColorUniform> color_uniform = vsnode;
+		Ref<VisualShaderNodeBooleanUniform> bool_uniform = vsnode;
+		Ref<VisualShaderNodeTransformUniform> transform_uniform = vsnode;
 		if (uniform.is_valid()) {
 		if (uniform.is_valid()) {
 			graph->add_child(node);
 			graph->add_child(node);
 			_update_created_node(node);
 			_update_created_node(node);
@@ -571,7 +575,7 @@ void VisualShaderEditor::_update_graph() {
 				//shortcut
 				//shortcut
 				VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
 				VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
 				node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]);
 				node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]);
-				if (!float_uniform.is_valid() && !int_uniform.is_valid()) {
+				if (!float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !color_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid()) {
 					continue;
 					continue;
 				}
 				}
 			}
 			}
@@ -585,13 +589,16 @@ void VisualShaderEditor::_update_graph() {
 			}
 			}
 		}
 		}
 
 
-		if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
+		if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
 			//will be embedded in first port
 			//will be embedded in first port
 		} else if (custom_editor) {
 		} else if (custom_editor) {
 
 
 			port_offset++;
 			port_offset++;
 			node->add_child(custom_editor);
 			node->add_child(custom_editor);
-			if (float_uniform.is_valid() || int_uniform.is_valid()) {
+			if (color_uniform.is_valid()) {
+				custom_editor->call_deferred("_show_prop_names", true);
+			}
+			if (float_uniform.is_valid() || int_uniform.is_valid() || vec3_uniform.is_valid() || bool_uniform.is_valid() || transform_uniform.is_valid()) {
 				custom_editor->call_deferred("_show_prop_names", true);
 				custom_editor->call_deferred("_show_prop_names", true);
 				continue;
 				continue;
 			}
 			}

+ 41 - 0
scene/resources/visual_shader.cpp

@@ -2156,12 +2156,43 @@ String VisualShaderNodeUniform::get_uniform_name() const {
 	return uniform_name;
 	return uniform_name;
 }
 }
 
 
+void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p_qual) {
+	qualifier = p_qual;
+	emit_changed();
+}
+
+VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() const {
+	return qualifier;
+}
+
 void VisualShaderNodeUniform::_bind_methods() {
 void VisualShaderNodeUniform::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
 	ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
 	ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
 	ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
 
 
+	ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeUniform::set_qualifier);
+	ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeUniform::get_qualifier);
+
 	ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name");
 	ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier");
+
+	BIND_ENUM_CONSTANT(QUAL_NONE);
+	BIND_ENUM_CONSTANT(QUAL_GLOBAL);
+	BIND_ENUM_CONSTANT(QUAL_INSTANCE);
+}
+
+String VisualShaderNodeUniform::_get_qual_str() const {
+	if (is_qualifier_supported(qualifier)) {
+		switch (qualifier) {
+			case QUAL_NONE:
+				break;
+			case QUAL_GLOBAL:
+				return "global ";
+			case QUAL_INSTANCE:
+				return "instance ";
+		}
+	}
+	return String();
 }
 }
 
 
 String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
 String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
@@ -2171,11 +2202,21 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T
 	if (keyword_list.find(uniform_name)) {
 	if (keyword_list.find(uniform_name)) {
 		return TTR("Uniform name cannot be equal to a shader keyword. Choose another name.");
 		return TTR("Uniform name cannot be equal to a shader keyword. Choose another name.");
 	}
 	}
+	if (!is_qualifier_supported(qualifier)) {
+		return "This uniform type does not support that qualifier.";
+	}
 
 
 	return String();
 	return String();
 }
 }
 
 
+Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const {
+	Vector<StringName> props;
+	props.push_back("qualifier");
+	return props;
+}
+
 VisualShaderNodeUniform::VisualShaderNodeUniform() {
 VisualShaderNodeUniform::VisualShaderNodeUniform() {
+	qualifier = QUAL_NONE;
 }
 }
 
 
 ////////////// GroupBase
 ////////////// GroupBase

+ 17 - 0
scene/resources/visual_shader.h

@@ -369,21 +369,38 @@ public:
 class VisualShaderNodeUniform : public VisualShaderNode {
 class VisualShaderNodeUniform : public VisualShaderNode {
 	GDCLASS(VisualShaderNodeUniform, VisualShaderNode);
 	GDCLASS(VisualShaderNodeUniform, VisualShaderNode);
 
 
+public:
+	enum Qualifier {
+		QUAL_NONE,
+		QUAL_GLOBAL,
+		QUAL_INSTANCE,
+	};
+
 private:
 private:
 	String uniform_name;
 	String uniform_name;
+	Qualifier qualifier;
 
 
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
+	String _get_qual_str() const;
 
 
 public:
 public:
 	void set_uniform_name(const String &p_name);
 	void set_uniform_name(const String &p_name);
 	String get_uniform_name() const;
 	String get_uniform_name() const;
 
 
+	void set_qualifier(Qualifier p_qual);
+	Qualifier get_qualifier() const;
+
+	virtual bool is_qualifier_supported(Qualifier p_qual) const = 0;
+
+	virtual Vector<StringName> get_editable_properties() const;
 	virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
 	virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
 
 
 	VisualShaderNodeUniform();
 	VisualShaderNodeUniform();
 };
 };
 
 
+VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier)
+
 class VisualShaderNodeGroupBase : public VisualShaderNode {
 class VisualShaderNodeGroupBase : public VisualShaderNode {
 	GDCLASS(VisualShaderNodeGroupBase, VisualShaderNode);
 	GDCLASS(VisualShaderNodeGroupBase, VisualShaderNode);
 
 

+ 51 - 15
scene/resources/visual_shader_nodes.cpp

@@ -3283,11 +3283,11 @@ String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const {
 
 
 String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 	if (hint == HINT_RANGE) {
 	if (hint == HINT_RANGE) {
-		return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
+		return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
 	} else if (hint == HINT_RANGE_STEP) {
 	} else if (hint == HINT_RANGE_STEP) {
-		return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
+		return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
 	}
 	}
-	return "uniform float " + get_uniform_name() + ";\n";
+	return _get_qual_str() + "uniform float " + get_uniform_name() + ";\n";
 }
 }
 
 
 String VisualShaderNodeFloatUniform::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 VisualShaderNodeFloatUniform::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 {
@@ -3353,8 +3353,12 @@ void VisualShaderNodeFloatUniform::_bind_methods() {
 	BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
 	BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
 }
 }
 
 
+bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const {
 Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const {
-	Vector<StringName> props;
+	Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
 	props.push_back("hint");
 	props.push_back("hint");
 	if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
 	if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
 		props.push_back("min");
 		props.push_back("min");
@@ -3405,11 +3409,11 @@ String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const {
 
 
 String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 	if (hint == HINT_RANGE) {
 	if (hint == HINT_RANGE) {
-		return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
+		return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
 	} else if (hint == HINT_RANGE_STEP) {
 	} else if (hint == HINT_RANGE_STEP) {
-		return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
+		return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
 	}
 	}
-	return "uniform int " + get_uniform_name() + ";\n";
+	return _get_qual_str() + "uniform int " + get_uniform_name() + ";\n";
 }
 }
 
 
 String VisualShaderNodeIntUniform::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 VisualShaderNodeIntUniform::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 {
@@ -3475,8 +3479,12 @@ void VisualShaderNodeIntUniform::_bind_methods() {
 	BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
 	BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
 }
 }
 
 
+bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
 Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
-	Vector<StringName> props;
+	Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
 	props.push_back("hint");
 	props.push_back("hint");
 	if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
 	if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
 		props.push_back("min");
 		props.push_back("min");
@@ -3526,13 +3534,17 @@ String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const {
 }
 }
 
 
 String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-	return "uniform bool " + get_uniform_name() + ";\n";
+	return _get_qual_str() + "uniform bool " + get_uniform_name() + ";\n";
 }
 }
 
 
 String VisualShaderNodeBooleanUniform::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 VisualShaderNodeBooleanUniform::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 {
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 }
 }
 
 
+bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() {
 VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() {
 }
 }
 
 
@@ -3568,7 +3580,7 @@ String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
 
 
 String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 
 
-	return "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
+	return _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
 }
 }
 
 
 String VisualShaderNodeColorUniform::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 VisualShaderNodeColorUniform::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 {
@@ -3577,6 +3589,10 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh
 	return code;
 	return code;
 }
 }
 
 
+bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
 VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
 }
 }
 
 
@@ -3611,13 +3627,17 @@ String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
 }
 }
 
 
 String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-	return "uniform vec3 " + get_uniform_name() + ";\n";
+	return _get_qual_str() + "uniform vec3 " + get_uniform_name() + ";\n";
 }
 }
 
 
 String VisualShaderNodeVec3Uniform::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 VisualShaderNodeVec3Uniform::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 {
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 }
 }
 
 
+bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
 VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
 }
 }
 
 
@@ -3652,13 +3672,17 @@ String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const
 }
 }
 
 
 String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-	return "uniform mat4 " + get_uniform_name() + ";\n";
+	return _get_qual_str() + "uniform mat4 " + get_uniform_name() + ";\n";
 }
 }
 
 
 String VisualShaderNodeTransformUniform::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 VisualShaderNodeTransformUniform::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 {
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 	return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
 }
 }
 
 
+bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const {
+	return true; // all qualifiers are supported
+}
+
 VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
 VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
 }
 }
 
 
@@ -3713,7 +3737,7 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
 }
 }
 
 
 String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-	String code = "uniform sampler2D " + get_uniform_name();
+	String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name();
 
 
 	switch (texture_type) {
 	switch (texture_type) {
 		case TYPE_DATA:
 		case TYPE_DATA:
@@ -3778,7 +3802,7 @@ VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get
 }
 }
 
 
 Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const {
 Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const {
-	Vector<StringName> props;
+	Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
 	props.push_back("texture_type");
 	props.push_back("texture_type");
 	props.push_back("color_default");
 	props.push_back("color_default");
 	return props;
 	return props;
@@ -3810,6 +3834,18 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c
 	return "";
 	return "";
 }
 }
 
 
+bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const {
+	switch (p_qual) {
+		case Qualifier::QUAL_NONE:
+			return true;
+		case Qualifier::QUAL_GLOBAL:
+			return true;
+		case Qualifier::QUAL_INSTANCE:
+			return false;
+	}
+	return false;
+}
+
 VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
 VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
 	texture_type = TYPE_DATA;
 	texture_type = TYPE_DATA;
 	color_default = COLOR_DEFAULT_WHITE;
 	color_default = COLOR_DEFAULT_WHITE;
@@ -3952,7 +3988,7 @@ String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) c
 }
 }
 
 
 String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
 String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-	String code = "uniform samplerCube " + get_uniform_name();
+	String code = _get_qual_str() + "uniform samplerCube " + get_uniform_name();
 
 
 	switch (texture_type) {
 	switch (texture_type) {
 		case TYPE_DATA:
 		case TYPE_DATA:

+ 14 - 0
scene/resources/visual_shader_nodes.h

@@ -1457,6 +1457,8 @@ public:
 	void set_step(float p_value);
 	void set_step(float p_value);
 	float get_step() const;
 	float get_step() const;
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	virtual Vector<StringName> get_editable_properties() const;
 	virtual Vector<StringName> get_editable_properties() const;
 
 
 	VisualShaderNodeFloatUniform();
 	VisualShaderNodeFloatUniform();
@@ -1509,6 +1511,8 @@ public:
 	void set_step(int p_value);
 	void set_step(int p_value);
 	int get_step() const;
 	int get_step() const;
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	virtual Vector<StringName> get_editable_properties() const;
 	virtual Vector<StringName> get_editable_properties() const;
 
 
 	VisualShaderNodeIntUniform();
 	VisualShaderNodeIntUniform();
@@ -1535,6 +1539,8 @@ public:
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	VisualShaderNodeBooleanUniform();
 	VisualShaderNodeBooleanUniform();
 };
 };
 
 
@@ -1557,6 +1563,8 @@ public:
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	VisualShaderNodeColorUniform();
 	VisualShaderNodeColorUniform();
 };
 };
 
 
@@ -1579,6 +1587,8 @@ public:
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	VisualShaderNodeVec3Uniform();
 	VisualShaderNodeVec3Uniform();
 };
 };
 
 
@@ -1601,6 +1611,8 @@ public:
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 	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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	VisualShaderNodeTransformUniform();
 	VisualShaderNodeTransformUniform();
 };
 };
 
 
@@ -1652,6 +1664,8 @@ public:
 	void set_color_default(ColorDefault p_default);
 	void set_color_default(ColorDefault p_default);
 	ColorDefault get_color_default() const;
 	ColorDefault get_color_default() const;
 
 
+	bool is_qualifier_supported(Qualifier p_qual) const;
+
 	VisualShaderNodeTextureUniform();
 	VisualShaderNodeTextureUniform();
 };
 };