From 5b0fe7880e122d6f35e636d56be7d2d8b74aaa8c Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Mon, 3 Jan 2022 22:07:18 +0300 Subject: [PATCH] [3.x] Add hints and default values to the uniform nodes in visual shader --- .../VisualShaderNodeBooleanUniform.xml | 8 + doc/classes/VisualShaderNodeColorUniform.xml | 8 + doc/classes/VisualShaderNodeScalarUniform.xml | 32 ++ .../VisualShaderNodeTransformUniform.xml | 8 + doc/classes/VisualShaderNodeVec3Uniform.xml | 8 + .../plugins/visual_shader_editor_plugin.cpp | 79 ++-- scene/resources/visual_shader.cpp | 8 + scene/resources/visual_shader.h | 3 + scene/resources/visual_shader_nodes.cpp | 351 +++++++++++++++++- scene/resources/visual_shader_nodes.h | 138 ++++++- 10 files changed, 595 insertions(+), 48 deletions(-) diff --git a/doc/classes/VisualShaderNodeBooleanUniform.xml b/doc/classes/VisualShaderNodeBooleanUniform.xml index e2ab5cb28f2..80e18bf3f2e 100644 --- a/doc/classes/VisualShaderNodeBooleanUniform.xml +++ b/doc/classes/VisualShaderNodeBooleanUniform.xml @@ -10,6 +10,14 @@ + + + A default value to be assigned within the shader. + + + Enables usage of the [member default_value]. + + diff --git a/doc/classes/VisualShaderNodeColorUniform.xml b/doc/classes/VisualShaderNodeColorUniform.xml index 6f2a3e88f97..744199814d9 100644 --- a/doc/classes/VisualShaderNodeColorUniform.xml +++ b/doc/classes/VisualShaderNodeColorUniform.xml @@ -10,6 +10,14 @@ + + + A default value to be assigned within the shader. + + + Enables usage of the [member default_value]. + + diff --git a/doc/classes/VisualShaderNodeScalarUniform.xml b/doc/classes/VisualShaderNodeScalarUniform.xml index c43b6983a23..f4870d03020 100644 --- a/doc/classes/VisualShaderNodeScalarUniform.xml +++ b/doc/classes/VisualShaderNodeScalarUniform.xml @@ -8,6 +8,38 @@ + + + A default value to be assigned within the shader. + + + Enables usage of the [member default_value]. + + + A hint applied to the uniform, which controls the values it can take when set through the inspector. + + + Minimum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. + + + Maximum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. + + + Step (increment) value for the range hint with step. Used if [member hint] is set to [constant HINT_RANGE_STEP]. + + + + No hint used. + + + A range hint for scalar value, which limits possible input values between [member min] and [member max]. Translated to [code]hint_range(min, max)[/code] in shader code. + + + A range hint for scalar value with step, which limits possible input values between [member min] and [member max], with a step (increment) of [member step]). Translated to [code]hint_range(min, max, step)[/code] in shader code. + + + Represents the size of the [enum Hint] enum. + diff --git a/doc/classes/VisualShaderNodeTransformUniform.xml b/doc/classes/VisualShaderNodeTransformUniform.xml index 9f96c5d757f..306f031b28e 100644 --- a/doc/classes/VisualShaderNodeTransformUniform.xml +++ b/doc/classes/VisualShaderNodeTransformUniform.xml @@ -10,6 +10,14 @@ + + + A default value to be assigned within the shader. + + + Enables usage of the [member default_value]. + + diff --git a/doc/classes/VisualShaderNodeVec3Uniform.xml b/doc/classes/VisualShaderNodeVec3Uniform.xml index 3c2208b8351..2f940e0418c 100644 --- a/doc/classes/VisualShaderNodeVec3Uniform.xml +++ b/doc/classes/VisualShaderNodeVec3Uniform.xml @@ -10,6 +10,14 @@ + + + A default value to be assigned within the shader. + + + Enables usage of the [member default_value]. + + diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 019fc89a5d4..fb24426e0ed 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -589,21 +589,25 @@ void VisualShaderEditor::_update_graph() { } Ref uniform = vsnode; + HBoxContainer *uniform_hbox = nullptr; + if (uniform.is_valid()) { graph->add_child(node); _update_created_node(node); LineEdit *uniform_name = memnew(LineEdit); + uniform_name->set_h_size_flags(SIZE_EXPAND_FILL); uniform_name->set_text(uniform->get_uniform_name()); - node->add_child(uniform_name); uniform_name->connect("text_entered", this, "_line_edit_changed", varray(uniform_name, nodes[n_i])); uniform_name->connect("focus_exited", this, "_line_edit_focus_out", varray(uniform_name, nodes[n_i])); - if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { - //shortcut - 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]); - continue; + if (vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { + uniform_hbox = memnew(HBoxContainer); + uniform_hbox->add_constant_override("separation", 7 * EDSCALE); + uniform_hbox->add_child(uniform_name); + node->add_child(uniform_hbox); + } else { + node->add_child(uniform_name); } port_offset++; } @@ -615,12 +619,14 @@ void VisualShaderEditor::_update_graph() { } } - if (custom_editor && 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 - } else if (custom_editor) { - port_offset++; - node->add_child(custom_editor); - custom_editor = nullptr; + if (custom_editor) { + if (uniform_hbox == nullptr && 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 + } else { + port_offset++; + node->add_child(custom_editor); + custom_editor = nullptr; + } } if (is_group) { @@ -675,8 +681,15 @@ void VisualShaderEditor::_update_graph() { port_right = vsnode->get_output_port_type(i); } - HBoxContainer *hb = memnew(HBoxContainer); - hb->add_constant_override("separation", 7 * EDSCALE); + HBoxContainer *hb = nullptr; + bool is_uniform_hbox = false; + if (i == 0 && uniform_hbox != nullptr) { + hb = uniform_hbox; + is_uniform_hbox = true; + } else { + hb = memnew(HBoxContainer); + hb->add_constant_override("separation", 7 * EDSCALE); + } Variant default_value; @@ -756,7 +769,7 @@ void VisualShaderEditor::_update_graph() { } } - if (!is_group) { + if (!is_group && !is_uniform_hbox) { hb->add_spacer(); } @@ -786,10 +799,12 @@ void VisualShaderEditor::_update_graph() { type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); type_box->connect("item_selected", this, "_change_output_port_type", varray(nodes[n_i], i), CONNECT_DEFERRED); } else { - Label *label = memnew(Label); - label->set_text(name_right); - label->add_style_override("normal", label_style); //more compact - hb->add_child(label); + if (name_right != "") { + Label *label = memnew(Label); + label->set_text(name_right); + label->add_style_override("normal", label_style); //more compact + hb->add_child(label); + } } } } @@ -816,9 +831,12 @@ void VisualShaderEditor::_update_graph() { port_offset++; } - node->add_child(hb); - - node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); + int idx = 0; + if (!is_uniform_hbox) { + node->add_child(hb); + idx = i + port_offset; + } + node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); } if (vsnode->get_output_port_for_preview() >= 0) { @@ -3046,9 +3064,9 @@ public: } else { undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr()); } - undo_redo->add_do_method(this, "_refresh_request"); - undo_redo->add_undo_method(this, "_refresh_request"); } + undo_redo->add_do_method(this, "_refresh_request"); + undo_redo->add_undo_method(this, "_refresh_request"); undo_redo->commit_action(); updating = false; @@ -3086,7 +3104,18 @@ public: properties = p_properties; for (int i = 0; i < p_properties.size(); i++) { - add_child(p_properties[i]); + HBoxContainer *hbox = memnew(HBoxContainer); + hbox->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(hbox); + + if (p_node->is_show_prop_names()) { + Label *prop_name = memnew(Label); + prop_name->set_text(String(p_names[i]).capitalize() + ":"); + hbox->add_child(prop_name); + } + + p_properties[i]->set_h_size_flags(SIZE_EXPAND_FILL); + hbox->add_child(p_properties[i]); bool res_prop = Object::cast_to(p_properties[i]); if (res_prop) { diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index cba662b7386..d54725b74a9 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -96,6 +96,10 @@ bool VisualShaderNode::is_code_generated() const { return true; } +bool VisualShaderNode::is_show_prop_names() const { + return false; +} + Vector VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { return Vector(); } @@ -2334,6 +2338,10 @@ void VisualShaderNodeUniform::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name"); } +bool VisualShaderNodeUniform::is_show_prop_names() const { + return true; +} + VisualShaderNodeUniform::VisualShaderNodeUniform() { } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 9fd9187130e..d34fb13b6e9 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -221,6 +221,7 @@ public: virtual bool is_generate_input_var(int p_port) const; virtual bool is_code_generated() const; + virtual bool is_show_prop_names() const; virtual Vector get_editable_properties() const; @@ -388,6 +389,8 @@ public: void set_global_code_generated(bool p_enabled); bool is_global_code_generated() const; + virtual bool is_show_prop_names() const; + void set_uniform_name(const String &p_name); String get_uniform_name() const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index e2b62c194cc..e3e88693f55 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3019,14 +3019,152 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { } String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - return "uniform float " + get_uniform_name() + ";\n"; + String code = "uniform float " + get_uniform_name(); + if (hint == HINT_RANGE) { + code += " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; + } else if (hint == HINT_RANGE_STEP) { + code += " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; + } + if (default_value_enabled) { + code += " = " + rtos(default_value); + } + code += ";\n"; + return code; } String VisualShaderNodeScalarUniform::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"; } +void VisualShaderNodeScalarUniform::set_hint(Hint p_hint) { + ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX)); + if (hint == p_hint) { + return; + } + hint = p_hint; + emit_changed(); +} + +VisualShaderNodeScalarUniform::Hint VisualShaderNodeScalarUniform::get_hint() const { + return hint; +} + +void VisualShaderNodeScalarUniform::set_min(float p_value) { + if (Math::is_equal_approx(hint_range_min, p_value)) { + return; + } + hint_range_min = p_value; + emit_changed(); +} + +float VisualShaderNodeScalarUniform::get_min() const { + return hint_range_min; +} + +void VisualShaderNodeScalarUniform::set_max(float p_value) { + if (Math::is_equal_approx(hint_range_max, p_value)) { + return; + } + hint_range_max = p_value; + emit_changed(); +} + +float VisualShaderNodeScalarUniform::get_max() const { + return hint_range_max; +} + +void VisualShaderNodeScalarUniform::set_step(float p_value) { + if (Math::is_equal_approx(hint_range_step, p_value)) { + return; + } + hint_range_step = p_value; + emit_changed(); +} + +float VisualShaderNodeScalarUniform::get_step() const { + return hint_range_step; +} + +void VisualShaderNodeScalarUniform::set_default_value_enabled(bool p_default_value_enabled) { + if (default_value_enabled == p_default_value_enabled) { + return; + } + default_value_enabled = p_default_value_enabled; + emit_changed(); +} + +bool VisualShaderNodeScalarUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeScalarUniform::set_default_value(float p_default_value) { + if (Math::is_equal_approx(default_value, p_default_value)) { + return; + } + default_value = p_default_value; + emit_changed(); +} + +float VisualShaderNodeScalarUniform::get_default_value() const { + return default_value; +} + +Vector VisualShaderNodeScalarUniform::get_editable_properties() const { + Vector props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("hint"); + if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { + props.push_back("min"); + props.push_back("max"); + } + if (hint == HINT_RANGE_STEP) { + props.push_back("step"); + } + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + +void VisualShaderNodeScalarUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeScalarUniform::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeScalarUniform::get_hint); + + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeScalarUniform::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeScalarUniform::get_min); + + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeScalarUniform::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeScalarUniform::get_max); + + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeScalarUniform::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeScalarUniform::get_step); + + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeScalarUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeScalarUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeScalarUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeScalarUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "min"), "set_min", "get_min"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "max"), "set_max", "get_max"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_value"), "set_default_value", "get_default_value"); + + BIND_ENUM_CONSTANT(HINT_NONE); + BIND_ENUM_CONSTANT(HINT_RANGE); + BIND_ENUM_CONSTANT(HINT_RANGE_STEP); + BIND_ENUM_CONSTANT(HINT_MAX); +} + VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() { + hint = HINT_NONE; + hint_range_min = 0.0f; + hint_range_max = 1.0f; + hint_range_step = 0.1f; + default_value_enabled = false; + default_value = 0.0f; } ////////////// Boolean Uniform @@ -3060,14 +3198,69 @@ 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 { - return "uniform bool " + get_uniform_name() + ";\n"; + String code = "uniform bool " + get_uniform_name(); + if (default_value_enabled) { + if (default_value) { + code += " = true"; + } else { + code += " = false"; + } + } + code += ";\n"; + return code; } 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"; } +void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_default_value_enabled) { + if (default_value_enabled == p_default_value_enabled) { + return; + } + default_value_enabled = p_default_value_enabled; + emit_changed(); +} + +bool VisualShaderNodeBooleanUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeBooleanUniform::set_default_value(bool p_default_value) { + if (default_value == p_default_value) { + return; + } + default_value = p_default_value; + emit_changed(); +} + +bool VisualShaderNodeBooleanUniform::get_default_value() const { + return default_value; +} + +void VisualShaderNodeBooleanUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value"); +} + +Vector VisualShaderNodeBooleanUniform::get_editable_properties() const { + Vector props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() { + default_value_enabled = false; + default_value = false; } ////////////// Color Uniform @@ -3101,7 +3294,12 @@ 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 { - return "uniform vec4 " + get_uniform_name() + " : hint_color;\n"; + String code = "uniform vec4 " + get_uniform_name() + " : hint_color"; + if (default_value_enabled) { + code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a); + } + code += ";\n"; + return code; } 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 { @@ -3110,7 +3308,53 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh return code; } +void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { + if (default_value_enabled == p_enabled) { + return; + } + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeColorUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { + if (default_value.is_equal_approx(p_value)) { + return; + } + default_value = p_value; + emit_changed(); +} + +Color VisualShaderNodeColorUniform::get_default_value() const { + return default_value; +} + +void VisualShaderNodeColorUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value"); +} + +Vector VisualShaderNodeColorUniform::get_editable_properties() const { + Vector props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() { + default_value_enabled = false; + default_value = Color(1.0, 1.0, 1.0, 1.0); } ////////////// Vector Uniform @@ -3144,14 +3388,58 @@ 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 { - return "uniform vec3 " + get_uniform_name() + ";\n"; + String code = "uniform vec3 " + get_uniform_name(); + if (default_value_enabled) { + code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z); + } + code += ";\n"; + return code; } 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"; } +void VisualShaderNodeVec3Uniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeVec3Uniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeVec3Uniform::set_default_value(const Vector3 &p_value) { + default_value = p_value; + emit_changed(); +} + +Vector3 VisualShaderNodeVec3Uniform::get_default_value() const { + return default_value; +} + +void VisualShaderNodeVec3Uniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Uniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Uniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Uniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Uniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value"); +} + +Vector VisualShaderNodeVec3Uniform::get_editable_properties() const { + Vector props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() { + default_value_enabled = false; } ////////////// Transform Uniform @@ -3185,14 +3473,63 @@ 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 { - return "uniform mat4 " + get_uniform_name() + ";\n"; + String code = "uniform mat4 " + get_uniform_name(); + if (default_value_enabled) { + Vector3 row0 = default_value.basis.get_row(0); + Vector3 row1 = default_value.basis.get_row(1); + Vector3 row2 = default_value.basis.get_row(2); + Vector3 origin = default_value.origin; + code += " = mat4(" + vformat("vec4(%.6f, %.6f, %.6f, 0.0)", row0.x, row0.y, row0.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row1.x, row1.y, row1.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row2.x, row2.y, row2.z) + vformat(", vec4(%.6f, %.6f, %.6f, 1.0)", origin.x, origin.y, origin.z) + ")"; + } + code += ";\n"; + return code; } 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"; } +void VisualShaderNodeTransformUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeTransformUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeTransformUniform::set_default_value(const Transform &p_value) { + default_value = p_value; + emit_changed(); +} + +Transform VisualShaderNodeTransformUniform::get_default_value() const { + return default_value; +} + +void VisualShaderNodeTransformUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "default_value"), "set_default_value", "get_default_value"); +} + +Vector VisualShaderNodeTransformUniform::get_editable_properties() const { + Vector props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() { + default_value_enabled = false; + default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0); } ////////////// Texture Uniform @@ -3247,6 +3584,10 @@ bool VisualShaderNodeTextureUniform::is_code_generated() const { return is_output_port_connected(0) || is_output_port_connected(1); // rgb or alpha } +bool VisualShaderNodeTextureUniform::is_show_prop_names() const { + return false; +} + String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = "uniform sampler2D " + get_uniform_name(); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index d0b1e765b97..c6e4b20df5c 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1302,26 +1302,23 @@ class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform); public: - virtual String get_caption() const; + enum Hint { + HINT_NONE, + HINT_RANGE, + HINT_RANGE_STEP, + HINT_MAX, + }; - virtual int get_input_port_count() const; - virtual PortType get_input_port_type(int p_port) const; - virtual String get_input_port_name(int p_port) const; +private: + Hint hint = HINT_NONE; + float hint_range_min; + float hint_range_max; + float hint_range_step; + bool default_value_enabled; + float default_value; - virtual int get_output_port_count() const; - virtual PortType get_output_port_type(int p_port) const; - virtual String get_output_port_name(int p_port) 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 - - VisualShaderNodeScalarUniform(); -}; - -/////////////////////////////////////// - -class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform); +protected: + static void _bind_methods(); public: virtual String get_caption() const; @@ -1337,6 +1334,65 @@ public: 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 + void set_hint(Hint p_hint); + Hint get_hint() const; + + void set_min(float p_value); + float get_min() const; + + void set_max(float p_value); + float get_max() const; + + void set_step(float p_value); + float get_step() const; + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(float p_value); + float get_default_value() const; + + virtual Vector get_editable_properties() const; + + VisualShaderNodeScalarUniform(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeScalarUniform::Hint) + +/////////////////////////////////////// + +class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform { + GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform); + +private: + bool default_value_enabled; + bool default_value; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) 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 + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(bool p_value); + bool get_default_value() const; + + virtual Vector get_editable_properties() const; + VisualShaderNodeBooleanUniform(); }; @@ -1345,6 +1401,13 @@ public: class VisualShaderNodeColorUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform); +private: + bool default_value_enabled; + Color default_value; + +protected: + static void _bind_methods(); + public: virtual String get_caption() const; @@ -1359,6 +1422,14 @@ public: 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 + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Color &p_value); + Color get_default_value() const; + + virtual Vector get_editable_properties() const; + VisualShaderNodeColorUniform(); }; @@ -1367,6 +1438,13 @@ public: class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform); +private: + bool default_value_enabled; + Vector3 default_value; + +protected: + static void _bind_methods(); + public: virtual String get_caption() const; @@ -1381,6 +1459,14 @@ public: 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 + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Vector3 &p_value); + Vector3 get_default_value() const; + + virtual Vector get_editable_properties() const; + VisualShaderNodeVec3Uniform(); }; @@ -1389,6 +1475,13 @@ public: class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform); +private: + bool default_value_enabled; + Transform default_value; + +protected: + static void _bind_methods(); + public: virtual String get_caption() const; @@ -1403,6 +1496,14 @@ public: 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 + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Transform &p_value); + Transform get_default_value() const; + + virtual Vector get_editable_properties() const; + VisualShaderNodeTransformUniform(); }; @@ -1447,6 +1548,7 @@ public: 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 bool is_code_generated() const; + virtual bool is_show_prop_names() const; Vector get_editable_properties() const;