summaryrefslogtreecommitdiffstats
path: root/editor/plugins/visual_shader_editor_plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins/visual_shader_editor_plugin.cpp')
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp867
1 files changed, 601 insertions, 266 deletions
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index acc77bd098..fb91cbb866 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -44,6 +44,7 @@
#include "scene/gui/panel.h"
#include "scene/main/window.h"
#include "scene/resources/visual_shader_nodes.h"
+#include "scene/resources/visual_shader_particle_nodes.h"
#include "scene/resources/visual_shader_sdf_nodes.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"
@@ -71,13 +72,13 @@ const int MAX_FLOAT_CONST_DEFS = sizeof(float_constant_defs) / sizeof(FloatConst
Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (get_script_instance()) {
- return get_script_instance()->call("create_editor", p_parent_resource, p_node);
+ return get_script_instance()->call("_create_editor", p_parent_resource, p_node);
}
return nullptr;
}
void VisualShaderNodePlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
+ BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
}
///////////////////
@@ -109,6 +110,7 @@ void VisualShaderGraphPlugin::_bind_methods() {
ClassDB::bind_method("set_uniform_name", &VisualShaderGraphPlugin::set_uniform_name);
ClassDB::bind_method("set_expression", &VisualShaderGraphPlugin::set_expression);
ClassDB::bind_method("update_curve", &VisualShaderGraphPlugin::update_curve);
+ ClassDB::bind_method("update_curve3", &VisualShaderGraphPlugin::update_curve3);
ClassDB::bind_method("update_constant", &VisualShaderGraphPlugin::update_constant);
}
@@ -210,9 +212,19 @@ void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_
}
void VisualShaderGraphPlugin::update_curve(int p_node_id) {
- if (links.has(p_node_id) && links[p_node_id].curve_editor) {
+ if (links.has(p_node_id) && links[p_node_id].curve_editors[0]) {
if (((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) {
- links[p_node_id].curve_editor->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve());
+ links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve());
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::update_curve3(int p_node_id) {
+ if (links.has(p_node_id) && links[p_node_id].curve_editors[0] && links[p_node_id].curve_editors[1] && links[p_node_id].curve_editors[2]) {
+ if (((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture().is_valid()) {
+ links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_x());
+ links[p_node_id].curve_editors[1]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_y());
+ links[p_node_id].curve_editors[2]->set_curve(((VisualShaderNodeCurve3Texture *)links[p_node_id].visual_node)->get_texture()->get_curve_z());
}
}
}
@@ -264,8 +276,8 @@ void VisualShaderGraphPlugin::register_expression_edit(int p_node_id, CodeEdit *
links[p_node_id].expression_edit = p_expression_edit;
}
-void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, CurveEditor *p_curve_editor) {
- links[p_node_id].curve_editor = p_curve_editor;
+void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, int p_index, CurveEditor *p_curve_editor) {
+ links[p_node_id].curve_editors[p_index] = p_curve_editor;
}
void VisualShaderGraphPlugin::update_uniform_refs() {
@@ -311,7 +323,7 @@ void VisualShaderGraphPlugin::make_dirty(bool p_enabled) {
}
void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) {
- links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, nullptr });
+ links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } });
}
void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) {
@@ -322,6 +334,12 @@ void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_u
links[p_node_id].uniform_name = p_uniform_name;
}
+void VisualShaderGraphPlugin::update_theme() {
+ vector_expanded_color[0] = VisualShaderEditor::get_singleton()->get_theme_color("axis_x_color", "Editor"); // red
+ vector_expanded_color[1] = VisualShaderEditor::get_singleton()->get_theme_color("axis_y_color", "Editor"); // green
+ vector_expanded_color[2] = VisualShaderEditor::get_singleton()->get_theme_color("axis_z_color", "Editor"); // blue
+}
+
void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (p_type != visual_shader->get_shader_type()) {
return;
@@ -340,6 +358,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
Color(1.0, 1.0, 0.0), // sampler
};
+ static const String vector_expanded_name[3] = {
+ "red",
+ "green",
+ "blue"
+ };
+
Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id);
Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(vsnode.ptr());
@@ -349,6 +373,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr());
bool is_group = !group_node.is_null();
+ bool is_comment = false;
+
Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr());
bool is_expression = !expression_node.is_null();
String expression = "";
@@ -392,17 +418,22 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (is_resizable) {
Ref<VisualShaderNodeComment> comment_node = Object::cast_to<VisualShaderNodeComment>(vsnode.ptr());
if (comment_node.is_valid()) {
+ is_comment = true;
node->set_comment(true);
Label *comment_label = memnew(Label);
node->add_child(comment_label);
comment_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
comment_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- comment_label->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_STOP);
comment_label->set_text(comment_node->get_description());
}
}
+ Ref<VisualShaderNodeParticleEmit> emit = vsnode;
+ if (emit.is_valid()) {
+ node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
+ }
+
Ref<VisualShaderNodeUniform> uniform = vsnode;
if (uniform.is_valid()) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
@@ -412,7 +443,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
register_uniform_name(p_id, uniform_name);
uniform_name->set_text(uniform->get_uniform_name());
node->add_child(uniform_name);
- uniform_name->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id));
+ uniform_name->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id));
uniform_name->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_focus_out), varray(uniform_name, p_id));
if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") {
@@ -452,6 +483,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
custom_editor = hbox;
}
+ Ref<VisualShaderNodeCurve3Texture> curve3 = vsnode;
+ if (curve3.is_valid()) {
+ if (curve3->get_texture().is_valid() && !curve3->get_texture()->is_connected("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve3))) {
+ curve3->get_texture()->connect("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve3), varray(p_id));
+ }
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ custom_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hbox->add_child(custom_editor);
+ custom_editor = hbox;
+ }
+
Ref<VisualShaderNodeFloatConstant> float_const = vsnode;
if (float_const.is_valid()) {
HBoxContainer *hbox = memnew(HBoxContainer);
@@ -475,19 +518,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
port_offset++;
node->add_child(custom_editor);
- if (curve.is_valid()) {
+ bool is_curve = curve.is_valid() || curve3.is_valid();
+
+ if (is_curve) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
VisualShaderEditor::get_singleton()->_update_created_node(node);
- CurveEditor *curve_editor = memnew(CurveEditor);
- node->add_child(curve_editor);
- register_curve_editor(p_id, curve_editor);
- curve_editor->set_custom_minimum_size(Size2(300, 0));
- curve_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- if (curve->get_texture().is_valid()) {
- curve_editor->set_curve(curve->get_texture()->get_curve());
- }
-
TextureButton *preview = memnew(TextureButton);
preview->set_toggle_mode(true);
preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
@@ -499,12 +535,59 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, 0), CONNECT_DEFERRED);
custom_editor->add_child(preview);
+ if (vsnode->get_output_port_for_preview() >= 0) {
+ show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview());
+ }
+ }
+
+ if (curve.is_valid()) {
+ CurveEditor *curve_editor = memnew(CurveEditor);
+ node->add_child(curve_editor);
+ register_curve_editor(p_id, 0, curve_editor);
+ curve_editor->set_custom_minimum_size(Size2(300, 0));
+ curve_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve->get_texture().is_valid()) {
+ curve_editor->set_curve(curve->get_texture()->get_curve());
+ }
+ }
+
+ if (curve3.is_valid()) {
+ CurveEditor *curve_editor_x = memnew(CurveEditor);
+ node->add_child(curve_editor_x);
+ register_curve_editor(p_id, 0, curve_editor_x);
+ curve_editor_x->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_x->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_x->set_curve(curve3->get_texture()->get_curve_x());
+ }
+
+ CurveEditor *curve_editor_y = memnew(CurveEditor);
+ node->add_child(curve_editor_y);
+ register_curve_editor(p_id, 1, curve_editor_y);
+ curve_editor_y->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_y->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_y->set_curve(curve3->get_texture()->get_curve_y());
+ }
+
+ CurveEditor *curve_editor_z = memnew(CurveEditor);
+ node->add_child(curve_editor_z);
+ register_curve_editor(p_id, 2, curve_editor_z);
+ curve_editor_z->set_custom_minimum_size(Size2(300, 0));
+ curve_editor_z->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ if (curve3->get_texture().is_valid()) {
+ curve_editor_z->set_curve(curve3->get_texture()->get_curve_z());
+ }
+ }
+
+ if (is_curve) {
VisualShaderNode::PortType port_left = vsnode->get_input_port_type(0);
VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
node->set_slot(0, true, port_left, type_color[port_left], true, port_right, type_color[port_right]);
VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size);
}
+
if (vsnode->is_use_prop_slots()) {
return;
}
@@ -551,13 +634,32 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
}
- for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) {
+ int output_port_count = 0;
+ for (int i = 0; i < vsnode->get_output_port_count(); i++) {
+ if (vsnode->_is_output_port_expanded(i)) {
+ if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
+ output_port_count += 3;
+ }
+ }
+ output_port_count++;
+ }
+ int max_ports = MAX(vsnode->get_input_port_count(), output_port_count);
+ VisualShaderNode::PortType expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
+ int expanded_port_counter = 0;
+
+ for (int i = 0, j = 0; i < max_ports; i++, j++) {
+ if (expanded_type == VisualShaderNode::PORT_TYPE_VECTOR && expanded_port_counter >= 3) {
+ expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
+ expanded_port_counter = 0;
+ i -= 3;
+ }
+
if (vsnode->is_port_separator(i)) {
node->add_child(memnew(HSeparator));
port_offset++;
}
- bool valid_left = i < vsnode->get_input_port_count();
+ bool valid_left = j < vsnode->get_input_port_count();
VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR;
bool port_left_used = false;
String name_left;
@@ -565,18 +667,24 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
name_left = vsnode->get_input_port_name(i);
port_left = vsnode->get_input_port_type(i);
for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
- if (E->get().to_node == p_id && E->get().to_port == i) {
+ if (E->get().to_node == p_id && E->get().to_port == j) {
port_left_used = true;
}
}
}
- bool valid_right = i < vsnode->get_output_port_count();
+ bool valid_right = true;
VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR;
String name_right;
- if (valid_right) {
- name_right = vsnode->get_output_port_name(i);
- port_right = vsnode->get_output_port_type(i);
+
+ if (expanded_type == VisualShaderNode::PORT_TYPE_SCALAR) {
+ valid_right = i < vsnode->get_output_port_count();
+ if (valid_right) {
+ name_right = vsnode->get_output_port_name(i);
+ port_right = vsnode->get_output_port_type(i);
+ }
+ } else {
+ name_right = vector_expanded_name[expanded_port_counter++];
}
HBoxContainer *hb = memnew(HBoxContainer);
@@ -621,7 +729,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
name_box->set_text(name_left);
- name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
+ name_box->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false), CONNECT_DEFERRED);
Button *remove_btn = memnew(Button);
@@ -662,7 +770,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
name_box->set_text(name_right);
- name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
+ name_box->connect("text_submitted", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED);
name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true), CONNECT_DEFERRED);
OptionButton *type_box = memnew(OptionButton);
@@ -684,17 +792,29 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
}
- if (valid_right && visual_shader->get_shader_type() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) {
- TextureButton *preview = memnew(TextureButton);
- preview->set_toggle_mode(true);
- preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
- preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
- preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
+ if (valid_right) {
+ if (vsnode->is_output_port_expandable(i)) {
+ TextureButton *expand = memnew(TextureButton);
+ expand->set_toggle_mode(true);
+ expand->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiTreeArrowDown", "EditorIcons"));
+ expand->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiTreeArrowRight", "EditorIcons"));
+ expand->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
+ expand->set_pressed(vsnode->_is_output_port_expanded(i));
+ expand->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_expand_output_port), varray(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED);
+ hb->add_child(expand);
+ }
+ if (visual_shader->get_shader_type() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) {
+ TextureButton *preview = memnew(TextureButton);
+ preview->set_toggle_mode(true);
+ preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
+ preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
+ preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
- register_output_port(p_id, i, preview);
+ register_output_port(p_id, j, preview);
- preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, i), CONNECT_DEFERRED);
- hb->add_child(preview);
+ preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, j), CONNECT_DEFERRED);
+ hb->add_child(preview);
+ }
}
if (is_group) {
@@ -706,7 +826,40 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
node->add_child(hb);
+ if (expanded_type != VisualShaderNode::PORT_TYPE_SCALAR) {
+ continue;
+ }
+
node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
+
+ if (vsnode->_is_output_port_expanded(i)) {
+ if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
+
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+ port_offset++;
+
+ valid_left = (i + 3) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 3);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR;
+ }
+ }
}
if (vsnode->get_output_port_for_preview() >= 0) {
@@ -728,14 +881,15 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (is_expression) {
CodeEdit *expression_box = memnew(CodeEdit);
Ref<CodeHighlighter> expression_syntax_highlighter;
- expression_syntax_highlighter.instance();
- expression_node->set_control(expression_box, 0);
+ expression_syntax_highlighter.instantiate();
+ expression_node->set_ctrl_pressed(expression_box, 0);
node->add_child(expression_box);
register_expression_edit(p_id, expression_box);
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color");
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
@@ -746,7 +900,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
expression_box->add_theme_color_override("background_color", background_color);
for (List<String>::Element *E = VisualShaderEditor::get_singleton()->keyword_list.front(); E; E = E->next()) {
- expression_syntax_highlighter->add_keyword_color(E->get(), keyword_color);
+ if (ShaderLanguage::is_control_flow_keyword(E->get())) {
+ expression_syntax_highlighter->add_keyword_color(E->get(), control_flow_keyword_color);
+ } else {
+ expression_syntax_highlighter->add_keyword_color(E->get(), keyword_color);
+ }
}
expression_box->add_theme_font_override("font", VisualShaderEditor::get_singleton()->get_theme_font("expression", "EditorFonts"));
@@ -759,6 +917,10 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
expression_syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
expression_syntax_highlighter->add_color_region("//", "", comment_color, true);
+ expression_box->clear_comment_delimiters();
+ expression_box->add_comment_delimiter("/*", "*/", false);
+ expression_box->add_comment_delimiter("//", "", true);
+
expression_box->set_text(expression);
expression_box->set_context_menu_enabled(false);
expression_box->set_draw_line_numbers(true);
@@ -768,6 +930,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (!uniform.is_valid()) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
+ if (is_comment) {
+ VisualShaderEditor::get_singleton()->graph->move_child(node, 0); // to prevents a bug where comment node overlaps its content
+ }
VisualShaderEditor::get_singleton()->_update_created_node(node);
if (is_resizable) {
VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size);
@@ -786,6 +951,7 @@ 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) {
if (visual_shader->get_shader_type() == p_type) {
VisualShaderEditor::get_singleton()->graph->connect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ connections.push_back({ p_from_node, p_from_port, p_to_node, p_to_port });
if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr) {
links[p_to_node].input_ports[p_to_port].default_input_button->hide();
}
@@ -795,6 +961,12 @@ 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) {
if (visual_shader->get_shader_type() == p_type) {
VisualShaderEditor::get_singleton()->graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
+ if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
+ connections.erase(E);
+ break;
+ }
+ }
if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr && links[p_to_node].visual_node->get_input_port_default_value(p_to_port).get_type() != Variant::NIL) {
links[p_to_node].input_ports[p_to_port].default_input_button->show();
set_input_port_default_value(p_type, p_to_node, p_to_port, links[p_to_node].visual_node->get_input_port_default_value(p_to_port));
@@ -917,13 +1089,13 @@ bool VisualShaderEditor::_is_available(int p_mode) {
if (p_mode != -1) {
switch (current_mode) {
- case 0: // Vertex or Emit
+ case 0: // Vertex / Emit
current_mode = 1;
break;
- case 1: // Fragment or Process
+ case 1: // Fragment / Process
current_mode = 2;
break;
- case 2: // Light or End
+ case 2: // Light / Collide
current_mode = 4;
break;
default:
@@ -951,7 +1123,7 @@ void VisualShaderEditor::update_custom_nodes() {
Ref<Script> script = Ref<Script>(res);
Ref<VisualShaderNodeCustom> ref;
- ref.instance();
+ ref.instantiate();
ref->set_script(script);
String name;
@@ -1125,7 +1297,7 @@ void VisualShaderEditor::_update_options_menu() {
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon("bool", "EditorIcons"));
break;
case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform", "EditorIcons"));
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform3D", "EditorIcons"));
break;
case VisualShaderNode::PORT_TYPE_SAMPLER:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon("ImageTexture", "EditorIcons"));
@@ -1139,22 +1311,29 @@ void VisualShaderEditor::_update_options_menu() {
void VisualShaderEditor::_set_mode(int p_which) {
if (p_which == VisualShader::MODE_SKY) {
- edit_type_standart->set_visible(false);
+ edit_type_standard->set_visible(false);
edit_type_particles->set_visible(false);
edit_type_sky->set_visible(true);
edit_type = edit_type_sky;
+ custom_mode_box->set_visible(false);
mode = MODE_FLAGS_SKY;
} else if (p_which == VisualShader::MODE_PARTICLES) {
- edit_type_standart->set_visible(false);
+ edit_type_standard->set_visible(false);
edit_type_particles->set_visible(true);
edit_type_sky->set_visible(false);
edit_type = edit_type_particles;
+ if ((edit_type->get_selected() + 3) > VisualShader::TYPE_PROCESS) {
+ custom_mode_box->set_visible(false);
+ } else {
+ custom_mode_box->set_visible(true);
+ }
mode = MODE_FLAGS_PARTICLES;
} else {
edit_type_particles->set_visible(false);
- edit_type_standart->set_visible(true);
+ edit_type_standard->set_visible(true);
edit_type_sky->set_visible(false);
- edit_type = edit_type_standart;
+ edit_type = edit_type_standard;
+ custom_mode_box->set_visible(false);
mode = MODE_FLAGS_SPATIAL_CANVASITEM;
}
visual_shader->set_shader_type(get_current_shader_type());
@@ -1175,26 +1354,15 @@ void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) {
}
void VisualShaderEditor::_update_created_node(GraphNode *node) {
- if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
- Ref<StyleBoxFlat> sb = node->get_theme_stylebox("frame", "GraphNode");
- Color c = sb->get_border_color();
- Color ic;
- Color mono_color;
- if (((c.r + c.g + c.b) / 3) < 0.7) {
- mono_color = Color(1.0, 1.0, 1.0);
- ic = Color(0.0, 0.0, 0.0, 0.7);
- } else {
- mono_color = Color(0.0, 0.0, 0.0);
- ic = Color(1.0, 1.0, 1.0, 0.7);
- }
- mono_color.a = 0.85;
- c = mono_color;
+ const Ref<StyleBoxFlat> sb = node->get_theme_stylebox("frame", "GraphNode");
+ Color c = sb->get_border_color();
+ const Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85);
+ c = mono_color;
- node->add_theme_color_override("title_color", c);
- c.a = 0.7;
- node->add_theme_color_override("close_color", c);
- node->add_theme_color_override("resizer_color", ic);
- }
+ node->add_theme_color_override("title_color", c);
+ c.a = 0.7;
+ node->add_theme_color_override("close_color", c);
+ node->add_theme_color_override("resizer_color", c);
}
void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
@@ -1294,6 +1462,7 @@ void VisualShaderEditor::_update_graph() {
graph_plugin->clear_links();
graph_plugin->make_dirty(true);
+ graph_plugin->update_theme();
for (int n_i = 0; n_i < nodes.size(); n_i++) {
graph_plugin->add_node(type, nodes[n_i]);
@@ -1317,9 +1486,9 @@ void VisualShaderEditor::_update_graph() {
VisualShader::Type VisualShaderEditor::get_current_shader_type() const {
VisualShader::Type type;
if (mode & MODE_FLAGS_PARTICLES) {
- type = VisualShader::Type(edit_type->get_selected() + 3);
+ type = VisualShader::Type(edit_type->get_selected() + 3 + (custom_mode_enabled ? 3 : 0));
} else if (mode & MODE_FLAGS_SKY) {
- type = VisualShader::Type(edit_type->get_selected() + 6);
+ type = VisualShader::Type(edit_type->get_selected() + 8);
} else {
type = VisualShader::Type(edit_type->get_selected());
}
@@ -1442,6 +1611,92 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *
undo_redo->commit_action();
}
+void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expand) {
+ VisualShader::Type type = get_current_shader_type();
+
+ Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
+ ERR_FAIL_COND(!node.is_valid());
+
+ if (p_expand) {
+ undo_redo->create_action(TTR("Expand Output Port"));
+ } else {
+ undo_redo->create_action(TTR("Shrink Output Port"));
+ }
+
+ undo_redo->add_do_method(node.ptr(), "_set_output_port_expanded", p_port, p_expand);
+ undo_redo->add_undo_method(node.ptr(), "_set_output_port_expanded", p_port, !p_expand);
+
+ int type_size = 0;
+ if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_VECTOR) {
+ type_size = 3;
+ }
+
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ int from_node = E->get().from_node;
+ int from_port = E->get().from_port;
+ int to_node = E->get().to_node;
+ int to_port = E->get().to_port;
+
+ if (from_node == p_node) {
+ if (p_expand) {
+ if (from_port > p_port) { // reconnect ports after expanded ports
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port + type_size, to_node, to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port + type_size, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port);
+ }
+ } else {
+ if (from_port > p_port + type_size) { // reconnect ports after expanded ports
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port);
+ } else if (from_port > p_port) { // disconnect component ports
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
+ }
+ }
+ }
+ }
+
+ int preview_port = node->get_output_port_for_preview();
+ if (p_expand) {
+ if (preview_port > p_port) {
+ undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", preview_port + type_size);
+ undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port);
+ }
+ } else {
+ if (preview_port > p_port + type_size) {
+ undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", preview_port - type_size);
+ undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port);
+ }
+ }
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->commit_action();
+}
+
void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
@@ -1590,7 +1845,7 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p
Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(node.ptr());
Control *text_box = nullptr;
if (!expression_node.is_null()) {
- text_box = expression_node->get_control(0);
+ text_box = expression_node->is_ctrl_pressed(0);
if (text_box) {
text_box->set_custom_minimum_size(Size2(0, 0));
}
@@ -1670,7 +1925,7 @@ void VisualShaderEditor::_comment_title_text_changed(const String &p_new_text) {
comment_title_change_popup->set_size(Size2(-1, -1));
}
-void VisualShaderEditor::_comment_title_text_entered(const String &p_new_text) {
+void VisualShaderEditor::_comment_title_text_submitted(const String &p_new_text) {
comment_title_change_popup->hide();
}
@@ -1818,47 +2073,6 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node,
editing_port = p_port;
}
-void VisualShaderEditor::_add_custom_node(const String &p_path) {
- int idx = -1;
-
- for (int i = custom_node_option_idx; i < add_options.size(); i++) {
- if (add_options[i].script.is_valid()) {
- if (add_options[i].script->get_path() == p_path) {
- idx = i;
- break;
- }
- }
- }
- if (idx != -1) {
- _add_node(idx);
- }
-}
-
-void VisualShaderEditor::_add_cubemap_node(const String &p_path) {
- VisualShaderNodeCubemap *cubemap = (VisualShaderNodeCubemap *)_add_node(cubemap_node_option_idx, -1);
- cubemap->set_cube_map(ResourceLoader::load(p_path));
-}
-
-void VisualShaderEditor::_add_texture2d_node(const String &p_path) {
- VisualShaderNodeTexture *texture2d = (VisualShaderNodeTexture *)_add_node(texture2d_node_option_idx, -1);
- texture2d->set_texture(ResourceLoader::load(p_path));
-}
-
-void VisualShaderEditor::_add_texture2d_array_node(const String &p_path) {
- VisualShaderNodeTexture2DArray *texture2d_array = (VisualShaderNodeTexture2DArray *)_add_node(texture2d_array_node_option_idx, -1);
- texture2d_array->set_texture_array(ResourceLoader::load(p_path));
-}
-
-void VisualShaderEditor::_add_texture3d_node(const String &p_path) {
- VisualShaderNodeTexture3D *texture3d = (VisualShaderNodeTexture3D *)_add_node(texture3d_node_option_idx, -1);
- texture3d->set_texture(ResourceLoader::load(p_path));
-}
-
-void VisualShaderEditor::_add_curve_node(const String &p_path) {
- VisualShaderNodeCurveTexture *curve = (VisualShaderNodeCurveTexture *)_add_node(curve_node_option_idx, -1);
- curve->set_texture(ResourceLoader::load(p_path));
-}
-
void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
// FLOAT_OP
{
@@ -1950,6 +2164,16 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
}
}
+ //UV_FUNC
+ {
+ VisualShaderNodeUVFunc *uvFunc = Object::cast_to<VisualShaderNodeUVFunc>(p_node);
+
+ if (uvFunc) {
+ uvFunc->set_function((VisualShaderNodeUVFunc::Function)p_op_idx);
+ return;
+ }
+ }
+
// IS
{
VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node);
@@ -2047,16 +2271,18 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
}
}
-VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
- ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr);
+void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_path, int p_node_idx) {
+ ERR_FAIL_INDEX(p_idx, add_options.size());
+
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNode> vsnode;
bool is_custom = add_options[p_idx].is_custom;
if (!is_custom && add_options[p_idx].type != String()) {
- VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
- ERR_FAIL_COND_V(!vsn, nullptr);
+ VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(add_options[p_idx].type));
+ ERR_FAIL_COND(!vsn);
VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn);
@@ -2076,12 +2302,35 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
}
}
+ 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;
+
+ for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) {
+ if (uniform_ref->get_port_type_by_index(i) == input_port_type) {
+ uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i));
+ success = true;
+ break;
+ }
+ }
+ if (!success) {
+ for (int i = 0; i < uniform_ref->get_uniforms_count(); i++) {
+ if (visual_shader->is_port_types_compatible(uniform_ref->get_port_type_by_index(i), input_port_type)) {
+ uniform_ref->set_uniform_name(uniform_ref->get_uniform_name_by_index(i));
+ break;
+ }
+ }
+ }
+ }
+
vsnode = Ref<VisualShaderNode>(vsn);
} else {
- ERR_FAIL_COND_V(add_options[p_idx].script.is_null(), nullptr);
+ ERR_FAIL_COND(add_options[p_idx].script.is_null());
String base_type = add_options[p_idx].script->get_instance_base_type();
- VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(base_type));
- ERR_FAIL_COND_V(!vsn, nullptr);
+ VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(base_type));
+ ERR_FAIL_COND(!vsn);
vsnode = Ref<VisualShaderNode>(vsn);
vsnode->set_script(add_options[p_idx].script);
}
@@ -2096,11 +2345,13 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
}
saved_node_pos_dirty = false;
- VisualShader::Type type = get_current_shader_type();
-
int id_to_use = visual_shader->get_valid_node_id(type);
- undo_redo->create_action(TTR("Add Node to Visual Shader"));
+ if (p_resource_path.is_empty()) {
+ undo_redo->create_action(TTR("Add Node to Visual Shader"));
+ } else {
+ id_to_use += p_node_idx;
+ }
undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, vsnode, position, id_to_use);
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_to_use);
undo_redo->add_do_method(graph_plugin.ptr(), "add_node", type, id_to_use);
@@ -2157,6 +2408,13 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot);
undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot);
} else {
+ // Need to setting up Input node properly before committing since `is_port_types_compatible` (calling below) is using `mode` and `shader_type`.
+ VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsnode.ptr());
+ if (input) {
+ input->set_shader_mode(visual_shader->get_mode());
+ input->set_shader_type(visual_shader->get_shader_type());
+ }
+
// Attempting to connect to the first correct port.
for (int i = 0; i < vsnode->get_output_port_count(); i++) {
if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) {
@@ -2215,8 +2473,35 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
graph_plugin->call_deferred("update_curve", id_to_use);
}
- undo_redo->commit_action();
- return vsnode.ptr();
+ VisualShaderNodeCurve3Texture *curve3 = Object::cast_to<VisualShaderNodeCurve3Texture>(vsnode.ptr());
+ if (curve3) {
+ graph_plugin->call_deferred("update_curve3", id_to_use);
+ }
+
+ if (p_resource_path.is_empty()) {
+ undo_redo->commit_action();
+ } else {
+ //post-initialization
+
+ VisualShaderNodeTexture *texture2d = Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr());
+ VisualShaderNodeTexture3D *texture3d = Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr());
+
+ if (texture2d || texture3d || curve || curve3) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path));
+ return;
+ }
+
+ VisualShaderNodeCubemap *cubemap = Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr());
+ if (cubemap) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_cube_map", ResourceLoader::load(p_resource_path));
+ return;
+ }
+
+ VisualShaderNodeTexture2DArray *texture2d_array = Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr());
+ if (texture2d_array) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_texture_array", ResourceLoader::load(p_resource_path));
+ }
+ }
}
void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) {
@@ -2433,7 +2718,7 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) {
for (Set<int>::Element *E = current_set.front(); E; E = E->next()) {
int node_id = E->get();
Ref<VisualShaderNode> node = visual_shader->get_node(type_id, node_id);
- bool catched = false;
+ bool caught = false;
Variant var;
// float
@@ -2442,112 +2727,112 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) {
if (float_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform");
var = float_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr());
if (float_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant");
var = float_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
// int
- if (!catched) {
+ if (!caught) {
if (!p_vice_versa) {
Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr());
if (int_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform");
var = int_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr());
if (int_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant");
var = int_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
}
// boolean
- if (!catched) {
+ if (!caught) {
if (!p_vice_versa) {
Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr());
if (boolean_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform");
var = boolean_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr());
if (boolean_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant");
var = boolean_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
}
// vec3
- if (!catched) {
+ if (!caught) {
if (!p_vice_versa) {
Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr());
if (vec3_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform");
var = vec3_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr());
if (vec3_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant");
var = vec3_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
}
// color
- if (!catched) {
+ if (!caught) {
if (!p_vice_versa) {
Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr());
if (color_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform");
var = color_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr());
if (color_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant");
var = color_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
}
// transform
- if (!catched) {
+ if (!caught) {
if (!p_vice_versa) {
Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr());
if (transform_const.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform");
var = transform_const->get_constant();
- catched = true;
+ caught = true;
}
} else {
Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr());
if (transform_uniform.is_valid()) {
_replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant");
var = transform_uniform->get_default_value();
- catched = true;
+ caught = true;
}
}
}
- ERR_CONTINUE(!catched);
+ ERR_CONTINUE(!caught);
int preview_port = node->get_output_port_for_preview();
if (!p_vice_versa) {
@@ -2768,10 +3053,10 @@ void VisualShaderEditor::_notification(int p_what) {
// collapse tree by default
- TreeItem *category = members->get_root()->get_children();
+ TreeItem *category = members->get_root()->get_first_child();
while (category) {
category->set_collapsed(true);
- TreeItem *sub_category = category->get_children();
+ TreeItem *sub_category = category->get_first_child();
while (sub_category) {
sub_category->set_collapsed(true);
sub_category = sub_category->get_next();
@@ -2792,9 +3077,6 @@ void VisualShaderEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
highend_label->set_modulate(get_theme_color("vulkan_color", "Editor"));
- error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
- error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
-
node_filter->set_right_icon(Control::get_theme_icon("Search", "EditorIcons"));
preview_shader->set_icon(Control::get_theme_icon("Shader", "EditorIcons"));
@@ -2803,6 +3085,7 @@ void VisualShaderEditor::_notification(int p_what) {
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color");
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
@@ -2812,7 +3095,11 @@ void VisualShaderEditor::_notification(int p_what) {
preview_text->add_theme_color_override("background_color", background_color);
for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
- syntax_highlighter->add_keyword_color(E->get(), keyword_color);
+ if (ShaderLanguage::is_control_flow_keyword(E->get())) {
+ syntax_highlighter->add_keyword_color(E->get(), control_flow_keyword_color);
+ } else {
+ syntax_highlighter->add_keyword_color(E->get(), keyword_color);
+ }
}
preview_text->add_theme_font_override("font", get_theme_font("expression", "EditorFonts"));
@@ -2826,9 +3113,14 @@ void VisualShaderEditor::_notification(int p_what) {
syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
syntax_highlighter->add_color_region("//", "", comment_color, true);
- error_text->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts"));
- error_text->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts"));
- error_text->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
+ preview_text->clear_comment_delimiters();
+ preview_text->add_comment_delimiter("/*", "*/", false);
+ preview_text->add_comment_delimiter("//", "", true);
+
+ error_panel->add_theme_style_override("panel", get_theme_stylebox("panel", "Panel"));
+ error_label->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts"));
+ error_label->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts"));
+ error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
}
tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Tools", "EditorIcons"));
@@ -3050,8 +3342,18 @@ void VisualShaderEditor::_mode_selected(int p_id) {
int offset = 0;
if (mode & MODE_FLAGS_PARTICLES) {
offset = 3;
+ if (p_id + offset > VisualShader::TYPE_PROCESS) {
+ custom_mode_box->set_visible(false);
+ custom_mode_enabled = false;
+ } else {
+ custom_mode_box->set_visible(true);
+ if (custom_mode_box->is_pressed()) {
+ custom_mode_enabled = true;
+ offset += 3;
+ }
+ }
} else if (mode & MODE_FLAGS_SKY) {
- offset = 6;
+ offset = 8;
}
visual_shader->set_shader_type(VisualShader::Type(p_id + offset));
@@ -3059,6 +3361,21 @@ void VisualShaderEditor::_mode_selected(int p_id) {
_update_graph();
}
+void VisualShaderEditor::_custom_mode_toggled(bool p_enabled) {
+ if (!(mode & MODE_FLAGS_PARTICLES)) {
+ return;
+ }
+ custom_mode_enabled = p_enabled;
+ int id = edit_type->get_selected() + 3;
+ if (p_enabled) {
+ visual_shader->set_shader_type(VisualShader::Type(id + 3));
+ } else {
+ visual_shader->set_shader_type(VisualShader::Type(id));
+ }
+ _update_options_menu();
+ _update_graph();
+}
+
void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, String p_name) {
String prev_name = p_input->get_input_name();
@@ -3211,14 +3528,14 @@ void VisualShaderEditor::_member_cancel() {
}
void VisualShaderEditor::_tools_menu_option(int p_idx) {
- TreeItem *category = members->get_root()->get_children();
+ TreeItem *category = members->get_root()->get_first_child();
switch (p_idx) {
case EXPAND_ALL:
while (category) {
category->set_collapsed(false);
- TreeItem *sub_category = category->get_children();
+ TreeItem *sub_category = category->get_first_child();
while (sub_category) {
sub_category->set_collapsed(false);
sub_category = sub_category->get_next();
@@ -3232,7 +3549,7 @@ void VisualShaderEditor::_tools_menu_option(int p_idx) {
while (category) {
category->set_collapsed(true);
- TreeItem *sub_category = category->get_children();
+ TreeItem *sub_category = category->get_first_child();
while (sub_category) {
sub_category->set_collapsed(true);
sub_category = sub_category->get_next();
@@ -3334,47 +3651,60 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
saved_node_pos_dirty = true;
_add_node(idx, add_options[idx].sub_func);
} else if (d.has("files")) {
+ undo_redo->create_action(TTR("Add Node(s) to Visual Shader"));
+
if (d["files"].get_type() == Variant::PACKED_STRING_ARRAY) {
- int j = 0;
PackedStringArray arr = d["files"];
for (int i = 0; i < arr.size(); i++) {
String type = ResourceLoader::get_resource_type(arr[i]);
if (type == "GDScript") {
Ref<Script> script = ResourceLoader::load(arr[i]);
if (script->get_instance_base_type() == "VisualShaderNodeCustom") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_custom_node(arr[i]);
- j++;
+
+ int idx = -1;
+
+ for (int j = custom_node_option_idx; j < add_options.size(); j++) {
+ if (add_options[j].script.is_valid()) {
+ if (add_options[j].script->get_path() == arr[i]) {
+ idx = j;
+ break;
+ }
+ }
+ }
+ if (idx != -1) {
+ _add_node(idx, -1, arr[i], i);
+ }
}
} else if (type == "CurveTexture") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_curve_node(arr[i]);
- j++;
+ _add_node(curve_node_option_idx, -1, arr[i], i);
+ } else if (type == "Curve3Texture") {
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
+ saved_node_pos_dirty = true;
+ _add_node(curve3_node_option_idx, -1, arr[i], i);
} else if (ClassDB::get_parent_class(type) == "Texture2D") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_texture2d_node(arr[i]);
- j++;
+ _add_node(texture2d_node_option_idx, -1, arr[i], i);
} else if (type == "Texture2DArray") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_texture2d_array_node(arr[i]);
- j++;
+ _add_node(texture2d_array_node_option_idx, -1, arr[i], i);
} else if (ClassDB::get_parent_class(type) == "Texture3D") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_texture3d_node(arr[i]);
- j++;
+ _add_node(texture3d_node_option_idx, -1, arr[i], i);
} else if (type == "Cubemap") {
- saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE);
+ saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_cubemap_node(arr[i]);
- j++;
+ _add_node(cubemap_node_option_idx, -1, arr[i], i);
}
}
}
+ undo_redo->commit_action();
}
}
}
@@ -3430,17 +3760,18 @@ void VisualShaderEditor::_update_preview() {
Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type);
for (int i = 0; i < preview_text->get_line_count(); i++) {
- preview_text->set_line_as_marked(i, false);
+ preview_text->set_line_background_color(i, Color(0, 0, 0, 0));
}
if (err != OK) {
- preview_text->set_line_as_marked(sl.get_error_line() - 1, true);
- error_text->set_visible(true);
+ Color error_line_color = EDITOR_GET("text_editor/highlighting/mark_color");
+ preview_text->set_line_background_color(sl.get_error_line() - 1, error_line_color);
+ error_panel->show();
String text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
- error_text->set_text(text);
+ error_label->set_text(text);
shader_error = true;
} else {
- error_text->set_visible(false);
+ error_panel->hide();
shader_error = false;
}
}
@@ -3470,10 +3801,11 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected);
ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant);
ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform);
+ ClassDB::bind_method("_expand_output_port", &VisualShaderEditor::_expand_output_port);
- ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
- ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
- ClassDB::bind_method(D_METHOD("drop_data_fw"), &VisualShaderEditor::drop_data_fw);
+ ClassDB::bind_method(D_METHOD("_get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
+ ClassDB::bind_method(D_METHOD("_can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
+ ClassDB::bind_method(D_METHOD("_drop_data_fw"), &VisualShaderEditor::drop_data_fw);
ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
}
@@ -3546,17 +3878,23 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->add_child(vs);
graph->get_zoom_hbox()->move_child(vs, 0);
- edit_type_standart = memnew(OptionButton);
- edit_type_standart->add_item(TTR("Vertex"));
- edit_type_standart->add_item(TTR("Fragment"));
- edit_type_standart->add_item(TTR("Light"));
- edit_type_standart->select(1);
- edit_type_standart->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
+ custom_mode_box = memnew(CheckBox);
+ custom_mode_box->set_text(TTR("Custom"));
+ custom_mode_box->set_pressed(false);
+ custom_mode_box->set_visible(false);
+ custom_mode_box->connect("toggled", callable_mp(this, &VisualShaderEditor::_custom_mode_toggled));
+
+ edit_type_standard = memnew(OptionButton);
+ edit_type_standard->add_item(TTR("Vertex"));
+ edit_type_standard->add_item(TTR("Fragment"));
+ edit_type_standard->add_item(TTR("Light"));
+ edit_type_standard->select(1);
+ edit_type_standard->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
edit_type_particles = memnew(OptionButton);
- edit_type_particles->add_item(TTR("Emit"));
+ edit_type_particles->add_item(TTR("Start"));
edit_type_particles->add_item(TTR("Process"));
- edit_type_particles->add_item(TTR("End"));
+ edit_type_particles->add_item(TTR("Collide"));
edit_type_particles->select(0);
edit_type_particles->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
@@ -3565,14 +3903,16 @@ VisualShaderEditor::VisualShaderEditor() {
edit_type_sky->select(0);
edit_type_sky->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
- edit_type = edit_type_standart;
+ edit_type = edit_type_standard;
+ graph->get_zoom_hbox()->add_child(custom_mode_box);
+ graph->get_zoom_hbox()->move_child(custom_mode_box, 0);
+ graph->get_zoom_hbox()->add_child(edit_type_standard);
+ graph->get_zoom_hbox()->move_child(edit_type_standard, 0);
graph->get_zoom_hbox()->add_child(edit_type_particles);
graph->get_zoom_hbox()->move_child(edit_type_particles, 0);
graph->get_zoom_hbox()->add_child(edit_type_sky);
graph->get_zoom_hbox()->move_child(edit_type_sky, 0);
- graph->get_zoom_hbox()->add_child(edit_type_standart);
- graph->get_zoom_hbox()->move_child(edit_type_standart, 0);
add_node = memnew(Button);
add_node->set_flat(true);
@@ -3601,19 +3941,23 @@ VisualShaderEditor::VisualShaderEditor() {
preview_vbox = memnew(VBoxContainer);
preview_window->add_child(preview_vbox);
+ preview_vbox->add_theme_constant_override("separation", 0);
preview_text = memnew(CodeEdit);
- syntax_highlighter.instance();
+ syntax_highlighter.instantiate();
preview_vbox->add_child(preview_text);
preview_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
preview_text->set_syntax_highlighter(syntax_highlighter);
preview_text->set_draw_line_numbers(true);
preview_text->set_readonly(true);
- error_text = memnew(Label);
- preview_vbox->add_child(error_text);
- error_text->set_autowrap(true);
- error_text->set_visible(false);
+ error_panel = memnew(PanelContainer);
+ preview_vbox->add_child(error_panel);
+ error_panel->set_visible(false);
+
+ error_label = memnew(Label);
+ error_panel->add_child(error_label);
+ error_label->set_autowrap(true);
///////////////////////////////////////
// POPUP MENU
@@ -3709,7 +4053,7 @@ VisualShaderEditor::VisualShaderEditor() {
comment_title_change_edit = memnew(LineEdit);
comment_title_change_edit->set_expand_to_text_length_enabled(true);
comment_title_change_edit->connect("text_changed", callable_mp(this, &VisualShaderEditor::_comment_title_text_changed));
- comment_title_change_edit->connect("text_entered", callable_mp(this, &VisualShaderEditor::_comment_title_text_entered));
+ comment_title_change_edit->connect("text_submitted", callable_mp(this, &VisualShaderEditor::_comment_title_text_submitted));
comment_title_change_popup->add_child(comment_title_change_edit);
comment_title_change_edit->set_size(Size2(-1, -1));
comment_title_change_popup->set_size(Size2(-1, -1));
@@ -3788,9 +4132,10 @@ VisualShaderEditor::VisualShaderEditor() {
// INPUT
+ const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
+
// SPATIAL-FOR-ALL
- const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
@@ -3809,6 +4154,23 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
+ // PARTICLES-FOR-ALL
+
+ add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), "attractor_force", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Index", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("LifeTime", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+
/////////////////
add_options.push_back(AddOption("Input", "Input", "Common", "VisualShaderNodeInput", TTR("Input parameter.")));
@@ -3821,11 +4183,12 @@ VisualShaderEditor::VisualShaderEditor() {
const String input_param_for_sky_shader_mode = TTR("'%s' input parameter for sky shader mode.");
const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode.");
const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode.");
- const String input_param_for_emit_shader_mode = TTR("'%s' input parameter for emit shader mode.");
+ const String input_param_for_start_shader_mode = TTR("'%s' input parameter for start shader mode.");
const String input_param_for_process_shader_mode = TTR("'%s' input parameter for process shader mode.");
- const String input_param_for_end_shader_mode = TTR("'%s' input parameter for end shader mode.");
- const String input_param_for_emit_and_process_shader_mode = TTR("'%s' input parameter for emit and process shader mode.");
- const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode.");
+ const String input_param_for_collide_shader_mode = TTR("'%s' input parameter for collide shader mode.");
+ const String input_param_for_start_and_process_shader_mode = TTR("'%s' input parameter for start and process shader modes.");
+ const String input_param_for_process_and_collide_shader_mode = TTR("'%s' input parameter for process and collide shader modes.");
+ const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader modes.");
add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
@@ -3902,50 +4265,6 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- // PARTICLES INPUTS
-
- add_options.push_back(AddOption("Active", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Alpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CustomAlpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Delta", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmissionTransform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Index", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("LifeTime", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Restart", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Time", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Transform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
-
- add_options.push_back(AddOption("Active", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Alpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CustomAlpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Delta", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmissionTransform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Index", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("LifeTime", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Restart", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Time", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Transform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
-
- add_options.push_back(AddOption("Active", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Alpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CustomAlpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Delta", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmissionTransform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Index", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("LifeTime", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Restart", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Time", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Transform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
-
// SKY INPUTS
add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
@@ -3978,6 +4297,22 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ // PARTICLES
+
+ add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), "collision_depth", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), "collision_normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+
+ add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", "A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters.", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+
+ add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+
+ add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+
// SCALAR
add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -4065,16 +4400,22 @@ VisualShaderEditor::VisualShaderEditor() {
// TEXTURES
+ add_options.push_back(AddOption("UVFunc", "Textures", "Common", "VisualShaderNodeUVFunc", TTR("Function to be applied on texture coordinates."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+
cubemap_node_option_idx = add_options.size();
add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
curve_node_option_idx = add_options.size();
add_options.push_back(AddOption("CurveTexture", "Textures", "Functions", "VisualShaderNodeCurveTexture", TTR("Perform the curve texture lookup."), -1, -1));
+ curve3_node_option_idx = add_options.size();
+ add_options.push_back(AddOption("CurveTexture3", "Textures", "Functions", "VisualShaderNodeCurve3Texture", TTR("Perform the ternary curve texture lookup."), -1, -1));
texture2d_node_option_idx = add_options.size();
add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1));
texture2d_array_node_option_idx = add_options.size();
add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1));
texture3d_node_option_idx = add_options.size();
add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1));
+ add_options.push_back(AddOption("UVPanning", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply panning function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_PANNING, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("UVScaling", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply scaling function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_SCALING, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1));
@@ -4091,6 +4432,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("TransformDecompose", "Transform", "Composition", "VisualShaderNodeTransformDecompose", TTR("Decomposes transform to four vectors.")));
add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("GetBillboardMatrix", "Transform", "Functions", "VisualShaderNodeBillboard", TTR("Calculates how the object should face the camera to be applied on Model View Matrix output port for 3D objects."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
@@ -4193,20 +4535,13 @@ VisualShaderEditor::VisualShaderEditor() {
_update_options_menu();
- error_panel = memnew(PanelContainer);
- add_child(error_panel);
- error_label = memnew(Label);
- error_panel->add_child(error_label);
- error_label->set_text("eh");
- error_panel->hide();
-
undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<VisualShaderNodePluginDefault> default_plugin;
- default_plugin.instance();
+ default_plugin.instantiate();
add_plugin(default_plugin);
- graph_plugin.instance();
+ graph_plugin.instantiate();
property_editor = memnew(CustomPropertyEditor);
add_child(property_editor);
@@ -4280,7 +4615,7 @@ public:
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("int", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Vector3", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("bool", "EditorIcons"),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform", "EditorIcons"),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform3D", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("ImageTexture", "EditorIcons"),
};
@@ -4325,7 +4660,7 @@ public:
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("int", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("bool", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Vector3", "EditorIcons"),
- EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform", "EditorIcons"),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Transform3D", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Color", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon("ImageTexture", "EditorIcons"),
};
@@ -4516,7 +4851,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
if (Object::cast_to<EditorPropertyResource>(prop)) {
Object::cast_to<EditorPropertyResource>(prop)->set_use_sub_inspector(false);
prop->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- } else if (Object::cast_to<EditorPropertyTransform>(prop) || Object::cast_to<EditorPropertyVector3>(prop)) {
+ } else if (Object::cast_to<EditorPropertyTransform3D>(prop) || Object::cast_to<EditorPropertyVector3>(prop)) {
prop->set_custom_minimum_size(Size2(250 * EDSCALE, 0));
} else if (Object::cast_to<EditorPropertyFloat>(prop)) {
prop->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
@@ -4633,7 +4968,7 @@ void EditorInspectorShaderModePlugin::parse_begin(Object *p_object) {
//do none
}
-bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
+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);
Vector<String> options = p_hint_text.split(",");
@@ -4661,14 +4996,14 @@ void VisualShaderNodePortPreview::_shader_changed() {
String shader_code = shader->generate_preview_shader(type, node, port, default_textures);
Ref<Shader> preview_shader;
- preview_shader.instance();
+ preview_shader.instantiate();
preview_shader->set_code(shader_code);
for (int i = 0; i < default_textures.size(); i++) {
preview_shader->set_default_texture_param(default_textures[i].name, default_textures[i].param);
}
Ref<ShaderMaterial> material;
- material.instance();
+ material.instantiate();
material->set_shader(preview_shader);
//find if a material is also being edited and copy parameters to this one
@@ -4753,7 +5088,7 @@ Ref<Resource> VisualShaderConversionPlugin::convert(const Ref<Resource> &p_resou
ERR_FAIL_COND_V(!vshader.is_valid(), Ref<Resource>());
Ref<Shader> shader;
- shader.instance();
+ shader.instantiate();
String code = vshader->get_code();
shader->set_code(code);