summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp7
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/visual_shader.cpp2
-rw-r--r--scene/resources/visual_shader_nodes.cpp137
-rw-r--r--scene/resources/visual_shader_nodes.h44
5 files changed, 188 insertions, 4 deletions
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 0eeb104777..71e22afe95 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -1346,9 +1346,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR));
// BOOLEAN
-
- add_options.push_back(AddOption("BooleanConstant", "Boolean", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("BooleanUniform", "Boolean", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
// INPUT
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 87a15bbeda..3148df15dd 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -521,6 +521,8 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTransformUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniform>();
ClassDB::register_class<VisualShaderNodeCubeMapUniform>();
+ ClassDB::register_class<VisualShaderNodeIf>();
+ ClassDB::register_class<VisualShaderNodeSwitch>();
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index fdb6f2ce09..4229147ba2 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -782,7 +782,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = "vec3(" + src_var + ")";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
- inputs[i] = "all(" + src_var + ")";
+ inputs[i] = "all(bvec3(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = src_var + ">0.0?true:false";
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index dac999bf1d..d02902572c 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -2948,3 +2948,140 @@ String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, Visual
VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() {
}
+
+////////////// If
+
+String VisualShaderNodeIf::get_caption() const {
+ return "If";
+}
+
+int VisualShaderNodeIf::get_input_port_count() const {
+ return 6;
+}
+
+VisualShaderNodeIf::PortType VisualShaderNodeIf::get_input_port_type(int p_port) const {
+ if (p_port == 0 || p_port == 1 || p_port == 2) {
+ return PORT_TYPE_SCALAR;
+ }
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeIf::get_input_port_name(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return "a";
+ case 1:
+ return "b";
+ case 2:
+ return "tolerance";
+ case 3:
+ return "a == b";
+ case 4:
+ return "a > b";
+ case 5:
+ return "a < b";
+ default:
+ return "";
+ }
+}
+
+int VisualShaderNodeIf::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeIf::PortType VisualShaderNodeIf::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeIf::get_output_port_name(int p_port) const {
+ return "result";
+}
+
+String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+
+ String code;
+ code += "\tif(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[3] + ";\n";
+ code += "\t}\n";
+ code += "\telse if(" + p_input_vars[0] + "<" + p_input_vars[1] + ")\n"; // a < b
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[5] + ";\n";
+ code += "\t}\n";
+ code += "\telse\n"; // a > b (or a >= b if abs(a - b) < tolerance is false)
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[4] + ";\n";
+ code += "\t}\n";
+ return code;
+}
+
+VisualShaderNodeIf::VisualShaderNodeIf() {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, CMP_EPSILON);
+ set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0));
+}
+
+////////////// Switch
+
+String VisualShaderNodeSwitch::get_caption() const {
+ return "Switch";
+}
+
+int VisualShaderNodeSwitch::get_input_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int p_port) const {
+ if (p_port == 0) {
+ return PORT_TYPE_BOOLEAN;
+ }
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSwitch::get_input_port_name(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return "value";
+ case 1:
+ return "true";
+ case 2:
+ return "false";
+ default:
+ return "";
+ }
+}
+
+int VisualShaderNodeSwitch::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
+ return "result";
+}
+
+String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+
+ String code;
+ code += "\tif(" + p_input_vars[0] + ")\n";
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[1] + ";\n";
+ code += "\t}\n";
+ code += "\telse\n";
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[2] + ";\n";
+ code += "\t}\n";
+ return code;
+}
+
+VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
+ set_input_port_default_value(0, false);
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 28ead64fe2..90c479bd48 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1440,4 +1440,48 @@ public:
VisualShaderNodeCubeMapUniform();
};
+///////////////////////////////////////
+/// IF
+///////////////////////////////////////
+
+class VisualShaderNodeIf : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeIf, VisualShaderNode)
+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_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;
+
+ VisualShaderNodeIf();
+};
+
+///////////////////////////////////////
+/// SWITCH
+///////////////////////////////////////
+
+class VisualShaderNodeSwitch : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSwitch, VisualShaderNode)
+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_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;
+
+ VisualShaderNodeSwitch();
+};
+
#endif // VISUAL_SHADER_NODES_H