diff --git a/doc/classes/VisualShaderNodeParameter.xml b/doc/classes/VisualShaderNodeParameter.xml index cc1c82b4084..2072ec490d5 100644 --- a/doc/classes/VisualShaderNodeParameter.xml +++ b/doc/classes/VisualShaderNodeParameter.xml @@ -9,6 +9,9 @@ + + The index within 0-15 range, which is used to avoid clashes when shader used on multiple materials. + Name of the parameter, by which it can be accessed through the [ShaderMaterial] properties. @@ -26,7 +29,10 @@ The parameter will be tied to the node with attached [ShaderMaterial] using this shader. - + + The parameter will be tied to the node with attached [ShaderMaterial] using this shader. Enables setting a [member instance_index] property. + + Represents the size of the [enum Qualifier] enum. diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 1d51b2d1c81..00ed83242f7 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -4389,6 +4389,16 @@ VisualShaderNodeParameter::Qualifier VisualShaderNodeParameter::get_qualifier() return qualifier; } +void VisualShaderNodeParameter::set_instance_index(int p_index) { + ERR_FAIL_INDEX(p_index, 16); + instance_index = p_index; + emit_changed(); +} + +int VisualShaderNodeParameter::get_instance_index() const { + return instance_index; +} + void VisualShaderNodeParameter::set_global_code_generated(bool p_enabled) { global_code_generated = p_enabled; } @@ -4415,12 +4425,17 @@ void VisualShaderNodeParameter::_bind_methods() { ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeParameter::set_qualifier); ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeParameter::get_qualifier); + ClassDB::bind_method(D_METHOD("set_instance_index", "instance_index"), &VisualShaderNodeParameter::set_instance_index); + ClassDB::bind_method(D_METHOD("get_instance_index"), &VisualShaderNodeParameter::get_instance_index); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "parameter_name"), "set_parameter_name", "get_parameter_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance,Instance + Index"), "set_qualifier", "get_qualifier"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_index", PROPERTY_HINT_RANGE, "0,15,1"), "set_instance_index", "get_instance_index"); BIND_ENUM_CONSTANT(QUAL_NONE); BIND_ENUM_CONSTANT(QUAL_GLOBAL); BIND_ENUM_CONSTANT(QUAL_INSTANCE); + BIND_ENUM_CONSTANT(QUAL_INSTANCE_INDEX); BIND_ENUM_CONSTANT(QUAL_MAX); } @@ -4431,6 +4446,7 @@ String VisualShaderNodeParameter::_get_qual_str() const { break; case QUAL_GLOBAL: return "global "; + case QUAL_INSTANCE_INDEX: case QUAL_INSTANCE: return "instance "; default: @@ -4454,6 +4470,7 @@ String VisualShaderNodeParameter::get_warning(Shader::Mode p_mode, VisualShader: case QUAL_GLOBAL: qualifier_str = "global"; break; + case QUAL_INSTANCE_INDEX: case QUAL_INSTANCE: qualifier_str = "instance"; break; @@ -4537,6 +4554,9 @@ String VisualShaderNodeParameter::get_warning(Shader::Mode p_mode, VisualShader: Vector VisualShaderNodeParameter::get_editable_properties() const { Vector props; props.push_back("qualifier"); + if (qualifier == QUAL_INSTANCE_INDEX) { + props.push_back("instance_index"); + } return props; } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index bd667ee447b..d3312816ef2 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -597,6 +597,7 @@ public: QUAL_NONE, QUAL_GLOBAL, QUAL_INSTANCE, + QUAL_INSTANCE_INDEX, QUAL_MAX, }; @@ -604,6 +605,7 @@ private: String parameter_name = ""; Qualifier qualifier = QUAL_NONE; bool global_code_generated = false; + int instance_index = 0; protected: static void _bind_methods(); @@ -623,6 +625,9 @@ public: void set_global_code_generated(bool p_enabled); bool is_global_code_generated() const; + void set_instance_index(int p_index); + int get_instance_index() const; + virtual bool is_qualifier_supported(Qualifier p_qual) const = 0; virtual bool is_convertible_to_constant() const = 0; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2002b406887..e4b6f850553 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5213,12 +5213,22 @@ String VisualShaderNodeFloatParameter::get_output_port_name(int p_port) const { String VisualShaderNodeFloatParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; + bool add_comma = true; if (hint == HINT_RANGE) { code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; } else { code += _get_qual_str() + "uniform float " + get_parameter_name(); + add_comma = false; + } + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + if (add_comma) { + code += ", "; + } else { + code += ": "; + } + code += vformat("instance_index(%d)", get_instance_index()); } if (default_value_enabled) { code += " = " + rtos(default_value); @@ -5404,6 +5414,7 @@ String VisualShaderNodeIntParameter::get_output_port_name(int p_port) const { String VisualShaderNodeIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = ""; + bool add_comma = true; if (hint == HINT_RANGE) { code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { @@ -5424,6 +5435,15 @@ String VisualShaderNodeIntParameter::generate_global(Shader::Mode p_mode, Visual code += ")"; } else { code += _get_qual_str() + "uniform int " + get_parameter_name(); + add_comma = false; + } + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + if (add_comma) { + code += ", "; + } else { + code += ": "; + } + code += vformat("instance_index(%d)", get_instance_index()); } if (default_value_enabled) { code += " = " + itos(default_value); @@ -5629,6 +5649,9 @@ String VisualShaderNodeUIntParameter::get_output_port_name(int p_port) const { String VisualShaderNodeUIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform uint " + get_parameter_name(); + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(": instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { code += " = " + itos(default_value); } @@ -5759,6 +5782,9 @@ bool VisualShaderNodeBooleanParameter::get_default_value() const { String VisualShaderNodeBooleanParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform bool " + get_parameter_name(); + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(": instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { if (default_value) { code += " = true"; @@ -5869,6 +5895,9 @@ Color VisualShaderNodeColorParameter::get_default_value() const { String VisualShaderNodeColorParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform vec4 " + get_parameter_name() + " : source_color"; + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(", instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a); } @@ -5965,6 +5994,9 @@ Vector2 VisualShaderNodeVec2Parameter::get_default_value() const { String VisualShaderNodeVec2Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform vec2 " + get_parameter_name(); + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(": instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y); } @@ -6065,6 +6097,9 @@ Vector3 VisualShaderNodeVec3Parameter::get_default_value() const { String VisualShaderNodeVec3Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform vec3 " + get_parameter_name(); + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(": instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z); } @@ -6165,6 +6200,9 @@ Vector4 VisualShaderNodeVec4Parameter::get_default_value() const { String VisualShaderNodeVec4Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = _get_qual_str() + "uniform vec4 " + get_parameter_name(); + if (get_qualifier() == QUAL_INSTANCE_INDEX) { + code += vformat(": instance_index(%d)", get_instance_index()); + } if (default_value_enabled) { code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z, default_value.w); } @@ -6300,7 +6338,7 @@ bool VisualShaderNodeTransformParameter::is_use_prop_slots() const { } bool VisualShaderNodeTransformParameter::is_qualifier_supported(Qualifier p_qual) const { - if (p_qual == Qualifier::QUAL_INSTANCE) { + if (p_qual == Qualifier::QUAL_INSTANCE || p_qual == Qualifier::QUAL_INSTANCE_INDEX) { return false; } return true; @@ -6703,6 +6741,8 @@ bool VisualShaderNodeTextureParameter::is_qualifier_supported(Qualifier p_qual) return true; case Qualifier::QUAL_INSTANCE: return false; + case Qualifier::QUAL_INSTANCE_INDEX: + return false; default: break; }