diff options
Diffstat (limited to 'scene/resources/visual_shader_nodes.cpp')
-rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 1863 |
1 files changed, 1296 insertions, 567 deletions
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index e45dfdcb1b..c34aca32dc 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +30,65 @@ #include "visual_shader_nodes.h" +////////////// Vector Base + +VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; + } + return PORT_TYPE_SCALAR; +} + +VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; + } + return PORT_TYPE_SCALAR; +} + +void VisualShaderNodeVectorBase::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + op_type = p_op_type; + emit_changed(); +} + +VisualShaderNodeVectorBase::OpType VisualShaderNodeVectorBase::get_op_type() const { + return op_type; +} + +void VisualShaderNodeVectorBase::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeVectorBase::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeVectorBase::get_op_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Vector2,Vector3"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); +} + +Vector<StringName> VisualShaderNodeVectorBase::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; +} + +VisualShaderNodeVectorBase::VisualShaderNodeVectorBase() { +} + ////////////// Constants Base VisualShaderNodeConstant::VisualShaderNodeConstant() { @@ -232,7 +291,7 @@ int VisualShaderNodeColorConstant::get_input_port_count() const { } VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const { @@ -244,7 +303,7 @@ int VisualShaderNodeColorConstant::get_output_port_count() const { } VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR; } String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { @@ -294,10 +353,72 @@ void VisualShaderNodeColorConstant::_bind_methods() { VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() { } -////////////// Vector +////////////// Vector2 + +String VisualShaderNodeVec2Constant::get_caption() const { + return "Vector2Constant"; +} + +int VisualShaderNodeVec2Constant::get_input_port_count() const { + return 0; +} + +VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeVec2Constant::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeVec2Constant::get_output_port_count() const { + return 1; +} + +VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeVec2Constant::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeVec2Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + vformat("vec2(%.6f, %.6f)", constant.x, constant.y) + ";\n"; +} + +void VisualShaderNodeVec2Constant::set_constant(const Vector2 &p_constant) { + if (constant.is_equal_approx(p_constant)) { + return; + } + constant = p_constant; + emit_changed(); +} + +Vector2 VisualShaderNodeVec2Constant::get_constant() const { + return constant; +} + +Vector<StringName> VisualShaderNodeVec2Constant::get_editable_properties() const { + Vector<StringName> props; + props.push_back("constant"); + return props; +} + +void VisualShaderNodeVec2Constant::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeVec2Constant::set_constant); + ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec2Constant::get_constant); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant"), "set_constant", "get_constant"); +} + +VisualShaderNodeVec2Constant::VisualShaderNodeVec2Constant() { +} + +////////////// Vector3 String VisualShaderNodeVec3Constant::get_caption() const { - return "VectorConstant"; + return "Vector3Constant"; } int VisualShaderNodeVec3Constant::get_input_port_count() const { @@ -305,7 +426,7 @@ int VisualShaderNodeVec3Constant::get_input_port_count() const { } VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const { @@ -317,7 +438,7 @@ int VisualShaderNodeVec3Constant::get_output_port_count() const { } VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const { @@ -367,7 +488,7 @@ int VisualShaderNodeTransformConstant::get_input_port_count() const { } VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const { @@ -439,7 +560,7 @@ int VisualShaderNodeTexture::get_input_port_count() const { VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const { switch (p_port) { case 0: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_2D; case 1: return PORT_TYPE_SCALAR; case 2: @@ -470,7 +591,7 @@ VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type( if (p_port == 0 && source == SOURCE_DEPTH) { return PORT_TYPE_SCALAR; } - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR; } String VisualShaderNodeTexture::get_output_port_name(int p_port) const { @@ -487,22 +608,19 @@ bool VisualShaderNodeTexture::is_output_port_expandable(int p_port) const { return false; } -String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const { - if (p_port == 0) { - return "default"; +bool VisualShaderNodeTexture::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } } - return ""; -} - -static String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) { - static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt" }; - return p_name + "_" + String(typepf[p_type]) + "_" + itos(p_id); + return false; } Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "tex"); - dtp.param = texture; + dtp.params.push_back(texture); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -531,8 +649,8 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade String VisualShaderNodeTexture::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 default_uv; - if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { - default_uv = "UV.xy"; + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + default_uv = "UV"; } else { default_uv = "vec2(0.0)"; } @@ -540,19 +658,19 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_TEXTURE) { String id = make_unique_id(p_type, p_id, "tex"); String code; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod - code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; + code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { - code += " vec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; + code += " vec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += " " + p_output_vars[0] + " = " + id + "_read.rgb;\n"; @@ -565,22 +683,22 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code; code += " {\n"; - if (id == String()) { + if (id.is_empty()) { code += " vec4 " + id + "_tex_read = vec4(0.0);\n"; } else { - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod - code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; + code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { - code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; + code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += " " + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; @@ -592,19 +710,19 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. + if (p_input_vars[0].is_empty() || p_for_preview) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", 0.0 );\n"; } else { code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod - code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, 0.0);\n"; + code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", 0.0);\n"; } else { - code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; + code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += " " + p_output_vars[0] + " = _tex_read.rgb;\n"; @@ -615,19 +733,19 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = texture(TEXTURE, " + default_uv + ");\n"; } else { code += " vec4 _tex_read = textureLod(TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod - code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ".xy);\n"; + code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ");\n"; } else { - code += " vec4 _tex_read = textureLod(TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; + code += " vec4 _tex_read = textureLod(TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += " " + p_output_vars[0] + " = _tex_read.rgb;\n"; @@ -638,15 +756,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + default_uv + ");\n"; } else { code += " vec4 _tex_read = textureLod(NORMAL_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 _tex_read = texture(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy);\n"; } else { @@ -671,15 +789,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) { String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " float _depth = texture(DEPTH_TEXTURE, " + default_uv + ").r;\n"; } else { code += " float _depth = textureLod(DEPTH_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ").r;\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " float _depth = texture(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy).r;\n"; } else { @@ -888,7 +1006,7 @@ String VisualShaderNodeCurveTexture::generate_global(Shader::Mode p_mode, Visual } String VisualShaderNodeCurveTexture::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 { - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { return " " + p_output_vars[0] + " = 0.0;\n"; } String id = make_unique_id(p_type, p_id, "curve"); @@ -900,7 +1018,7 @@ String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualSh Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "curve"); - dtp.param = texture; + dtp.params.push_back(texture); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -918,6 +1036,7 @@ bool VisualShaderNodeCurveTexture::is_use_prop_slots() const { } VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() { + set_input_port_default_value(0, 0.0); simple_decl = true; allow_v_resize = false; } @@ -945,7 +1064,7 @@ int VisualShaderNodeCurveXYZTexture::get_output_port_count() const { } VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeCurveXYZTexture::get_output_port_name(int p_port) const { @@ -972,7 +1091,7 @@ String VisualShaderNodeCurveXYZTexture::generate_global(Shader::Mode p_mode, Vis } String VisualShaderNodeCurveXYZTexture::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 { - if (p_input_vars[0] == String()) { + if (p_input_vars[0].is_empty()) { return " " + p_output_vars[0] + " = vec3(0.0);\n"; } String id = make_unique_id(p_type, p_id, "curve3d"); @@ -984,7 +1103,7 @@ String VisualShaderNodeCurveXYZTexture::generate_code(Shader::Mode p_mode, Visua Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveXYZTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "curve3d"); - dtp.param = texture; + dtp.params.push_back(texture); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -1002,6 +1121,7 @@ bool VisualShaderNodeCurveXYZTexture::is_use_prop_slots() const { } VisualShaderNodeCurveXYZTexture::VisualShaderNodeCurveXYZTexture() { + set_input_port_default_value(0, 0.0); simple_decl = true; allow_v_resize = false; } @@ -1015,7 +1135,7 @@ int VisualShaderNodeSample3D::get_input_port_count() const { VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_input_port_type(int p_port) const { switch (p_port) { case 0: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; case 1: return PORT_TYPE_SCALAR; case 2: @@ -1041,7 +1161,7 @@ int VisualShaderNodeSample3D::get_output_port_count() const { } VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR; } String VisualShaderNodeSample3D::get_output_port_name(int p_port) const { @@ -1055,16 +1175,18 @@ bool VisualShaderNodeSample3D::is_output_port_expandable(int p_port) const { return false; } -String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const { - if (p_port == 0) { - return "default"; +bool VisualShaderNodeSample3D::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } } - return ""; + return false; } String VisualShaderNodeSample3D::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 default_uv; - if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { default_uv = "vec3(UV, 0.0)"; } else { default_uv = "vec3(0.0)"; @@ -1079,14 +1201,14 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader } else { id = p_input_vars[2]; } - if (id != String()) { - if (p_input_vars[0] == String()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (!id.is_empty()) { + if (p_input_vars[0].is_empty()) { // Use UV by default. + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { @@ -1165,7 +1287,7 @@ String VisualShaderNodeTexture2DArray::get_input_port_name(int p_port) const { Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture2DArray::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "tex3d"); - dtp.param = texture_array; + dtp.params.push_back(texture_array); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -1222,7 +1344,7 @@ String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const { Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "tex3d"); - dtp.param = texture; + dtp.params.push_back(texture); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -1276,7 +1398,7 @@ int VisualShaderNodeCubemap::get_input_port_count() const { VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_input_port_type(int p_port) const { switch (p_port) { case 0: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; case 1: return PORT_TYPE_SCALAR; case 2: @@ -1304,7 +1426,7 @@ int VisualShaderNodeCubemap::get_output_port_count() const { } VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR; } String VisualShaderNodeCubemap::get_output_port_name(int p_port) const { @@ -1321,7 +1443,7 @@ bool VisualShaderNodeCubemap::is_output_port_expandable(int p_port) const { Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "cube"); - dtp.param = cube_map; + dtp.params.push_back(cube_map); Vector<VisualShader::DefaultTextureParam> ret; ret.push_back(dtp); return ret; @@ -1349,7 +1471,7 @@ String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShade String VisualShaderNodeCubemap::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 default_uv; - if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { default_uv = "vec3(UV, 0.0)"; } else { default_uv = "vec3(0.0)"; @@ -1367,7 +1489,7 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: code += " {\n"; - if (id == String()) { + if (id.is_empty()) { code += " vec4 " + id + "_read = vec4(0.0);\n"; code += " " + p_output_vars[0] + " = " + id + "_read.rgb;\n"; code += " " + p_output_vars[1] + " = " + id + "_read.a;\n"; @@ -1375,15 +1497,15 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: return code; } - if (p_input_vars[0] == String()) { // Use UV by default. + if (p_input_vars[0].is_empty()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[1].is_empty()) { code += " vec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + " );\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { @@ -1396,11 +1518,13 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: return code; } -String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const { - if (p_port == 0) { - return "default"; +bool VisualShaderNodeCubemap::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } } - return ""; + return false; } void VisualShaderNodeCubemap::set_source(Source p_source) { @@ -1650,6 +1774,21 @@ String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::T case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_BITWISE_AND: + code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_OR: + code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_XOR: + code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_LEFT_SHIFT: + code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n"; + break; + case OP_BITWISE_RIGHT_SHIFT: + code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n"; + break; default: break; } @@ -1680,7 +1819,7 @@ void VisualShaderNodeIntOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1689,6 +1828,11 @@ void VisualShaderNodeIntOp::_bind_methods() { BIND_ENUM_CONSTANT(OP_MOD); BIND_ENUM_CONSTANT(OP_MAX); BIND_ENUM_CONSTANT(OP_MIN); + BIND_ENUM_CONSTANT(OP_BITWISE_AND); + BIND_ENUM_CONSTANT(OP_BITWISE_OR); + BIND_ENUM_CONSTANT(OP_BITWISE_XOR); + BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT); + BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT); BIND_ENUM_CONSTANT(OP_ENUM_SIZE); } @@ -1707,10 +1851,6 @@ int VisualShaderNodeVectorOp::get_input_port_count() const { return 2; } -VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -1719,12 +1859,8 @@ int VisualShaderNodeVectorOp::get_output_port_count() const { return 1; } -VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const { - return "op"; //no output port means the editor will be used as port + return "op"; } String VisualShaderNodeVectorOp::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 { @@ -1755,13 +1891,21 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_CROSS: - code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + if (op_type == OP_TYPE_VECTOR_2D) { // not supported + code += "vec2(0.0);\n"; + } else { + code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + } break; case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_REFLECT: - code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + if (op_type == OP_TYPE_VECTOR_2D) { // not supported + code += "vec2(0.0);\n"; + } else { + code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + } break; case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; @@ -1773,6 +1917,27 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader return code; } +void VisualShaderNodeVectorOp::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + void VisualShaderNodeVectorOp::set_operator(Operator p_op) { ERR_FAIL_INDEX(int(p_op), int(OP_ENUM_SIZE)); if (op == p_op) { @@ -1787,11 +1952,27 @@ VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() cons } Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const { - Vector<StringName> props; + Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties(); props.push_back("operator"); return props; } +String VisualShaderNodeVectorOp::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + bool invalid_type = false; + + if (op_type == OP_TYPE_VECTOR_2D) { + if (op == OP_CROSS || op == OP_REFLECT) { + invalid_type = true; + } + } + + if (invalid_type) { + return TTR("Invalid operator for that type."); + } + + return String(); +} + void VisualShaderNodeVectorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator); @@ -1814,8 +1995,18 @@ void VisualShaderNodeVectorOp::_bind_methods() { } VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() { - set_input_port_default_value(0, Vector3()); - set_input_port_default_value(1, Vector3()); + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2()); + set_input_port_default_value(1, Vector2()); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3()); + set_input_port_default_value(1, Vector3()); + } break; + default: + break; + } } ////////////// Color Op @@ -1829,7 +2020,7 @@ int VisualShaderNodeColorOp::get_input_port_count() const { } VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorOp::get_input_port_name(int p_port) const { @@ -1841,7 +2032,7 @@ int VisualShaderNodeColorOp::get_output_port_count() const { } VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorOp::get_output_port_name(int p_port) const { @@ -2102,7 +2293,7 @@ int VisualShaderNodeTransformVecMult::get_input_port_count() const { } VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR; + return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const { @@ -2114,7 +2305,7 @@ int VisualShaderNodeTransformVecMult::get_output_port_count() const { } VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const { @@ -2336,7 +2527,8 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader: static const char *functions[FUNC_MAX] = { "abs($)", "-($)", - "sign($)" + "sign($)", + "~($)" }; return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n"; @@ -2365,11 +2557,12 @@ void VisualShaderNodeIntFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign,Bitwise NOT"), "set_function", "get_function"); BIND_ENUM_CONSTANT(FUNC_ABS); BIND_ENUM_CONSTANT(FUNC_NEGATE); BIND_ENUM_CONSTANT(FUNC_SIGN); + BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT); BIND_ENUM_CONSTANT(FUNC_MAX); } @@ -2387,10 +2580,6 @@ int VisualShaderNodeVectorFunc::get_input_port_count() const { return 1; } -VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const { return ""; } @@ -2399,22 +2588,18 @@ int VisualShaderNodeVectorFunc::get_output_port_count() const { return 1; } -VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const { - return ""; //no output port means the editor will be used as port + return "result"; } String VisualShaderNodeVectorFunc::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 { - static const char *vec_func_id[FUNC_MAX] = { + static const char *funcs[FUNC_MAX] = { "normalize($)", - "max(min($, vec3(1.0)), vec3(0.0))", + "", // FUNC_SATURATE "-($)", "1.0 / ($)", - "", - "", + "", // FUNC_RGB2HSV + "", // FUNC_HSV2RGB "abs($)", "acos($)", "acosh($)", @@ -2443,12 +2628,37 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad "tan($)", "tanh($)", "trunc($)", - "vec3(1.0, 1.0, 1.0) - $" + "" // FUNC_ONEMINUS }; + if (func == FUNC_SATURATE) { + String code; + + if (op_type == OP_TYPE_VECTOR_2D) { + code = "max(min($, vec2(1.0)), vec2(0.0))"; + } else { + code = "max(min($, vec3(1.0)), vec3(0.0))"; + } + return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n"; + } + + if (func == FUNC_ONEMINUS) { + String code; + + if (op_type == OP_TYPE_VECTOR_2D) { + code = "vec2(1.0, 1.0) - $"; + } else { + code = "vec3(1.0, 1.0, 1.0) - $"; + } + return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n"; + } + String code; if (func == FUNC_RGB2HSV) { + if (op_type == OP_TYPE_VECTOR_2D) { // not supported + return " " + p_output_vars[0] + " = vec2(0.0);\n"; + } code += " {\n"; code += " vec3 c = " + p_input_vars[0] + ";\n"; code += " vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n"; @@ -2459,6 +2669,9 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad code += " " + p_output_vars[0] + " = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; code += " }\n"; } else if (func == FUNC_HSV2RGB) { + if (op_type == OP_TYPE_VECTOR_2D) { // not supported + return " " + p_output_vars[0] + " = vec2(0.0);\n"; + } code += " {\n"; code += " vec3 c = " + p_input_vars[0] + ";\n"; code += " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"; @@ -2467,12 +2680,31 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad code += " }\n"; } else { - code += " " + p_output_vars[0] + " = " + String(vec_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; + code += " " + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; } return code; } +void VisualShaderNodeVectorFunc::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + void VisualShaderNodeVectorFunc::set_function(Function p_func) { ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX)); if (func == p_func) { @@ -2494,11 +2726,27 @@ VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function() } Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const { - Vector<StringName> props; + Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties(); props.push_back("function"); return props; } +String VisualShaderNodeVectorFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + bool invalid_type = false; + + if (op_type == OP_TYPE_VECTOR_2D) { + if (func == FUNC_RGB2HSV || func == FUNC_HSV2RGB) { + invalid_type = true; + } + } + + if (invalid_type) { + return TTR("Invalid function for that type."); + } + + return String(); +} + void VisualShaderNodeVectorFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function); @@ -2544,7 +2792,16 @@ void VisualShaderNodeVectorFunc::_bind_methods() { } VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() { - set_input_port_default_value(0, Vector3()); + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2()); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3()); + } break; + default: + break; + } } ////////////// ColorFunc @@ -2558,7 +2815,7 @@ int VisualShaderNodeColorFunc::get_input_port_count() const { } VisualShaderNodeColorFunc::PortType VisualShaderNodeColorFunc::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorFunc::get_input_port_name(int p_port) const { @@ -2570,7 +2827,7 @@ int VisualShaderNodeColorFunc::get_output_port_count() const { } VisualShaderNodeColorFunc::PortType VisualShaderNodeColorFunc::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorFunc::get_output_port_name(int p_port) const { @@ -2586,8 +2843,7 @@ String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShade code += " vec3 c = " + p_input_vars[0] + ";\n"; code += " float max1 = max(c.r, c.g);\n"; code += " float max2 = max(max1, c.b);\n"; - code += " float max3 = max(max1, max2);\n"; - code += " " + p_output_vars[0] + " = vec3(max3, max3, max3);\n"; + code += " " + p_output_vars[0] + " = vec3(max2, max2, max2);\n"; code += " }\n"; break; case FUNC_SEPIA: @@ -2729,11 +2985,11 @@ int VisualShaderNodeUVFunc::get_input_port_count() const { VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_input_port_type(int p_port) const { switch (p_port) { case 0: - [[fallthrough]]; // uv + return PORT_TYPE_VECTOR_2D; // uv case 1: - return PORT_TYPE_VECTOR; // scale + return PORT_TYPE_VECTOR_2D; // scale case 2: - return PORT_TYPE_VECTOR; // offset & pivot + return PORT_TYPE_VECTOR_2D; // offset & pivot default: break; } @@ -2762,11 +3018,13 @@ String VisualShaderNodeUVFunc::get_input_port_name(int p_port) const { return ""; } -String VisualShaderNodeUVFunc::get_input_port_default_hint(int p_port) const { - if (p_port == 0) { - return "UV"; +bool VisualShaderNodeUVFunc::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } } - return ""; + return false; } int VisualShaderNodeUVFunc::get_output_port_count() const { @@ -2774,7 +3032,7 @@ int VisualShaderNodeUVFunc::get_output_port_count() const { } VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeUVFunc::get_output_port_name(int p_port) const { @@ -2790,7 +3048,11 @@ String VisualShaderNodeUVFunc::generate_code(Shader::Mode p_mode, VisualShader:: String uv; if (p_input_vars[0].is_empty()) { - uv = "vec3(UV.xy, 0.0)"; + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + uv = "UV"; + } else { + uv = "vec2(0.0)"; + } } else { uv = vformat("%s", p_input_vars[0]); } @@ -2816,9 +3078,9 @@ void VisualShaderNodeUVFunc::set_function(VisualShaderNodeUVFunc::Function p_fun return; } if (p_func == FUNC_PANNING) { - set_input_port_default_value(2, Vector3()); // offset + set_input_port_default_value(2, Vector2()); // offset } else { // FUNC_SCALING - set_input_port_default_value(2, Vector3(0.5, 0.5, 0.0)); // pivot + set_input_port_default_value(2, Vector2(0.5, 0.5)); // pivot } func = p_func; emit_changed(); @@ -2846,8 +3108,8 @@ void VisualShaderNodeUVFunc::_bind_methods() { } VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() { - set_input_port_default_value(1, Vector3(1.0, 1.0, 0.0)); // scale - set_input_port_default_value(2, Vector3()); // offset + set_input_port_default_value(1, Vector2(1.0, 1.0)); // scale + set_input_port_default_value(2, Vector2()); // offset } ////////////// Dot Product @@ -2861,7 +3123,7 @@ int VisualShaderNodeDotProduct::get_input_port_count() const { } VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const { @@ -2899,10 +3161,6 @@ int VisualShaderNodeVectorLen::get_input_port_count() const { return 1; } -VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const { return ""; } @@ -2919,12 +3177,31 @@ String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const { return "length"; } +void VisualShaderNodeVectorLen::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return " " + p_output_vars[0] + " = length(" + p_input_vars[0] + ");\n"; } VisualShaderNodeVectorLen::VisualShaderNodeVectorLen() { - set_input_port_default_value(0, Vector3()); + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); } ////////////// Determinant @@ -2965,37 +3242,53 @@ VisualShaderNodeDeterminant::VisualShaderNodeDeterminant() { set_input_port_default_value(0, Transform3D()); } -////////////// Scalar Derivative Function +////////////// Derivative Function -String VisualShaderNodeScalarDerivativeFunc::get_caption() const { - return "ScalarDerivativeFunc"; +String VisualShaderNodeDerivativeFunc::get_caption() const { + return "DerivativeFunc"; } -int VisualShaderNodeScalarDerivativeFunc::get_input_port_count() const { +int VisualShaderNodeDerivativeFunc::get_input_port_count() const { return 1; } -VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeScalarDerivativeFunc::get_input_port_type(int p_port) const { +VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarDerivativeFunc::get_input_port_name(int p_port) const { - return ""; +String VisualShaderNodeDerivativeFunc::get_input_port_name(int p_port) const { + return "p"; } -int VisualShaderNodeScalarDerivativeFunc::get_output_port_count() const { +int VisualShaderNodeDerivativeFunc::get_output_port_count() const { return 1; } -VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeScalarDerivativeFunc::get_output_port_type(int p_port) const { +VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarDerivativeFunc::get_output_port_name(int p_port) const { - return ""; +String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const { + return "result"; } -String VisualShaderNodeScalarDerivativeFunc::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 VisualShaderNodeDerivativeFunc::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 { static const char *functions[FUNC_MAX] = { "fwidth($)", "dFdx($)", @@ -3007,84 +3300,33 @@ String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode, return code; } -void VisualShaderNodeScalarDerivativeFunc::set_function(Function p_func) { - ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX)); - if (func == p_func) { +void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX)); + if (op_type == p_op_type) { return; } - func = p_func; + switch (p_op_type) { + case OP_TYPE_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + } break; + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + } break; + default: + break; + } + op_type = p_op_type; emit_changed(); } -VisualShaderNodeScalarDerivativeFunc::Function VisualShaderNodeScalarDerivativeFunc::get_function() const { - return func; -} - -Vector<StringName> VisualShaderNodeScalarDerivativeFunc::get_editable_properties() const { - Vector<StringName> props; - props.push_back("function"); - return props; -} - -void VisualShaderNodeScalarDerivativeFunc::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarDerivativeFunc::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarDerivativeFunc::get_function); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function"); - - BIND_ENUM_CONSTANT(FUNC_SUM); - BIND_ENUM_CONSTANT(FUNC_X); - BIND_ENUM_CONSTANT(FUNC_Y); - BIND_ENUM_CONSTANT(FUNC_MAX); -} - -VisualShaderNodeScalarDerivativeFunc::VisualShaderNodeScalarDerivativeFunc() { - set_input_port_default_value(0, 0.0); -} - -////////////// Vector Derivative Function - -String VisualShaderNodeVectorDerivativeFunc::get_caption() const { - return "VectorDerivativeFunc"; -} - -int VisualShaderNodeVectorDerivativeFunc::get_input_port_count() const { - return 1; -} - -VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorDerivativeFunc::get_input_port_name(int p_port) const { - return ""; -} - -int VisualShaderNodeVectorDerivativeFunc::get_output_port_count() const { - return 1; -} - -VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorDerivativeFunc::get_output_port_name(int p_port) const { - return ""; -} - -String VisualShaderNodeVectorDerivativeFunc::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 { - static const char *functions[FUNC_MAX] = { - "fwidth($)", - "dFdx($)", - "dFdy($)" - }; - - String code; - code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n"; - return code; +VisualShaderNodeDerivativeFunc::OpType VisualShaderNodeDerivativeFunc::get_op_type() const { + return op_type; } -void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) { +void VisualShaderNodeDerivativeFunc::set_function(Function p_func) { ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX)); if (func == p_func) { return; @@ -3093,30 +3335,40 @@ void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) { emit_changed(); } -VisualShaderNodeVectorDerivativeFunc::Function VisualShaderNodeVectorDerivativeFunc::get_function() const { +VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_function() const { return func; } -Vector<StringName> VisualShaderNodeVectorDerivativeFunc::get_editable_properties() const { +Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const { Vector<StringName> props; + props.push_back("op_type"); props.push_back("function"); return props; } -void VisualShaderNodeVectorDerivativeFunc::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorDerivativeFunc::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorDerivativeFunc::get_function); +void VisualShaderNodeDerivativeFunc::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeDerivativeFunc::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeDerivativeFunc::get_op_type); + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function"); + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); + BIND_ENUM_CONSTANT(FUNC_SUM); BIND_ENUM_CONSTANT(FUNC_X); BIND_ENUM_CONSTANT(FUNC_Y); BIND_ENUM_CONSTANT(FUNC_MAX); } -VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() { - set_input_port_default_value(0, Vector3()); +VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() { + set_input_port_default_value(0, 0.0); } ////////////// Clamp @@ -3133,8 +3385,10 @@ VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p switch (op_type) { case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3160,8 +3414,10 @@ VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int switch (op_type) { case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3183,19 +3439,24 @@ void VisualShaderNodeClamp::set_op_type(OpType p_op_type) { } switch (p_op_type) { case OP_TYPE_FLOAT: - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); break; case OP_TYPE_INT: - set_input_port_default_value(0, 0); - set_input_port_default_value(1, 0); - set_input_port_default_value(2, 0); + set_input_port_default_value(0, 0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0, get_input_port_default_value(1)); + set_input_port_default_value(2, 0, get_input_port_default_value(2)); + break; + case OP_TYPE_VECTOR_2D: + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); break; - case OP_TYPE_VECTOR: - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - 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)); + case OP_TYPE_VECTOR_3D: + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); break; default: break; @@ -3218,11 +3479,12 @@ void VisualShaderNodeClamp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeClamp::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); BIND_ENUM_CONSTANT(OP_TYPE_INT); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } @@ -3242,10 +3504,6 @@ int VisualShaderNodeFaceForward::get_input_port_count() const { return 3; } -VisualShaderNodeFaceForward::PortType VisualShaderNodeFaceForward::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeFaceForward::get_input_port_name(int p_port) const { switch (p_port) { case 0: @@ -3263,14 +3521,33 @@ int VisualShaderNodeFaceForward::get_output_port_count() const { return 1; } -VisualShaderNodeFaceForward::PortType VisualShaderNodeFaceForward::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeFaceForward::get_output_port_name(int p_port) const { return ""; } +void VisualShaderNodeFaceForward::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + String VisualShaderNodeFaceForward::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return " " + p_output_vars[0] + " = faceforward(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } @@ -3292,7 +3569,7 @@ int VisualShaderNodeOuterProduct::get_input_port_count() const { } VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeOuterProduct::get_input_port_name(int p_port) const { @@ -3339,11 +3616,18 @@ int VisualShaderNodeStep::get_input_port_count() const { VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: if (p_port == 1) { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_2D; + } + break; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: + if (p_port == 1) { + return PORT_TYPE_VECTOR_3D; } break; default: @@ -3353,12 +3637,13 @@ VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_p } String VisualShaderNodeStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge"; - } else if (p_port == 1) { - return "x"; + switch (p_port) { + case 0: + return "edge"; + case 1: + return "x"; } - return ""; + return String(); } int VisualShaderNodeStep::get_output_port_count() const { @@ -3367,10 +3652,14 @@ int VisualShaderNodeStep::get_output_port_count() const { VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3387,30 +3676,26 @@ void VisualShaderNodeStep::set_op_type(OpType p_op_type) { return; } switch (p_op_type) { - case OP_TYPE_SCALAR: - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(0, 0.0); // edge - } - if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { - set_input_port_default_value(1, 0.0); // x - } - break; - case OP_TYPE_VECTOR: - if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge - } - if (op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x - } - break; - case OP_TYPE_VECTOR_SCALAR: - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(0, 0.0); // edge - } - if (op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x - } - break; + case OP_TYPE_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_2D_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; default: break; } @@ -3436,11 +3721,13 @@ void VisualShaderNodeStep::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeStep::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } @@ -3461,11 +3748,18 @@ int VisualShaderNodeSmoothStep::get_input_port_count() const { VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: + if (p_port == 2) { + return PORT_TYPE_VECTOR_2D; // x + } + break; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: if (p_port == 2) { - return PORT_TYPE_VECTOR; // x + return PORT_TYPE_VECTOR_3D; // x } break; default: @@ -3475,14 +3769,15 @@ VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_ } String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge0"; - } else if (p_port == 1) { - return "edge1"; - } else if (p_port == 2) { - return "x"; + switch (p_port) { + case 0: + return "edge0"; + case 1: + return "edge1"; + case 2: + return "x"; } - return ""; + return String(); } int VisualShaderNodeSmoothStep::get_output_port_count() const { @@ -3491,10 +3786,14 @@ int VisualShaderNodeSmoothStep::get_output_port_count() const { VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3512,31 +3811,29 @@ void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) { } switch (p_op_type) { case OP_TYPE_SCALAR: - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(0, 0.0); // edge0 - set_input_port_default_value(1, 0.0); // edge1 - } - if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { - set_input_port_default_value(2, 0.0); // x - } - break; - case OP_TYPE_VECTOR: - if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge0 - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // edge1 - } - if (op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x - } - break; - case OP_TYPE_VECTOR_SCALAR: - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(0, 0.0); // edge0 - set_input_port_default_value(1, 0.0); // edge1 - } - if (op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x - } + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0 + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1 + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // x + break; + case OP_TYPE_VECTOR_2D: + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // edge0 + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // edge1 + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x + break; + case OP_TYPE_VECTOR_2D_SCALAR: + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0 + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1 + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x + break; + case OP_TYPE_VECTOR_3D: + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // edge0 + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // edge1 + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x + break; + case OP_TYPE_VECTOR_3D_SCALAR: + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0 + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1 + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x break; default: break; @@ -3563,18 +3860,20 @@ void VisualShaderNodeSmoothStep::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeSmoothStep::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); + set_input_port_default_value(0, 0.0); // edge0 + set_input_port_default_value(1, 1.0); // edge1 + set_input_port_default_value(2, 0.5); // x } ////////////// Distance @@ -3587,17 +3886,14 @@ int VisualShaderNodeVectorDistance::get_input_port_count() const { return 2; } -VisualShaderNodeVectorDistance::PortType VisualShaderNodeVectorDistance::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorDistance::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "p0"; - } else if (p_port == 1) { - return "p1"; + switch (p_port) { + case 0: + return "a"; + case 1: + return "b"; } - return ""; + return String(); } int VisualShaderNodeVectorDistance::get_output_port_count() const { @@ -3612,13 +3908,34 @@ String VisualShaderNodeVectorDistance::get_output_port_name(int p_port) const { return ""; } +void VisualShaderNodeVectorDistance::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + String VisualShaderNodeVectorDistance::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return " " + p_output_vars[0] + " = distance(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } VisualShaderNodeVectorDistance::VisualShaderNodeVectorDistance() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // b } ////////////// Refract Vector @@ -3636,18 +3953,19 @@ VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input return PORT_TYPE_SCALAR; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVectorRefract::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "I"; - } else if (p_port == 1) { - return "N"; - } else if (p_port == 2) { - return "eta"; + switch (p_port) { + case 0: + return "I"; + case 1: + return "N"; + case 2: + return "eta"; } - return ""; + return String(); } int VisualShaderNodeVectorRefract::get_output_port_count() const { @@ -3655,7 +3973,7 @@ int VisualShaderNodeVectorRefract::get_output_port_count() const { } VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVectorRefract::get_output_port_name(int p_port) const { @@ -3684,13 +4002,20 @@ int VisualShaderNodeMix::get_input_port_count() const { VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: if (p_port == 2) { break; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: + if (p_port == 2) { + break; + } + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3713,10 +4038,14 @@ int VisualShaderNodeMix::get_output_port_count() const { VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; - case OP_TYPE_VECTOR_SCALAR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_2D_SCALAR: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + case OP_TYPE_VECTOR_3D_SCALAR: + return PORT_TYPE_VECTOR_3D; default: break; } @@ -3733,27 +4062,31 @@ void VisualShaderNodeMix::set_op_type(OpType p_op_type) { return; } switch (p_op_type) { - case OP_TYPE_SCALAR: - set_input_port_default_value(0, 0.0); // a - set_input_port_default_value(1, 1.0); // b - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(2, 0.5); // weight - } - break; - case OP_TYPE_VECTOR: - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b - if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { - set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); // weight - } - break; - case OP_TYPE_VECTOR_SCALAR: - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b - if (op_type == OP_TYPE_VECTOR) { - set_input_port_default_value(2, 0.5); // weight - } - break; + case OP_TYPE_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // a + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // b + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight + } break; + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // weight + } break; + case OP_TYPE_VECTOR_2D_SCALAR: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // weight + } break; + case OP_TYPE_VECTOR_3D_SCALAR: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight + } break; default: break; } @@ -3779,11 +4112,13 @@ void VisualShaderNodeMix::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeMix::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } @@ -3800,7 +4135,15 @@ String VisualShaderNodeVectorCompose::get_caption() const { } int VisualShaderNodeVectorCompose::get_input_port_count() const { - return 3; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return 2; + case OP_TYPE_VECTOR_3D: + return 3; + default: + break; + } + return 0; } VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const { @@ -3808,29 +4151,80 @@ VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input } String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "x"; - } else if (p_port == 1) { - return "y"; - } else { - return "z"; + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + switch (p_port) { + case 0: + return "x"; + case 1: + return "y"; + } + } break; + case OP_TYPE_VECTOR_3D: { + switch (p_port) { + case 0: + return "x"; + case 1: + return "y"; + case 2: + return "z"; + } + } break; + default: + break; } + return String(); } int VisualShaderNodeVectorCompose::get_output_port_count() const { return 1; } -VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const { return "vec"; } +void VisualShaderNodeVectorCompose::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + float p1 = get_input_port_default_value(0); + float p2 = get_input_port_default_value(1); + + set_input_port_default_value(0, p1); + set_input_port_default_value(1, p2); + } break; + case OP_TYPE_VECTOR_3D: { + float p1 = get_input_port_default_value(0); + float p2 = get_input_port_default_value(1); + + set_input_port_default_value(0, p1); + set_input_port_default_value(1, p2); + set_input_port_default_value(2, 0.0); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + String code; + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + code += " " + p_output_vars[0] + " = vec2(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + } break; + case OP_TYPE_VECTOR_3D: { + code += " " + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + } break; + default: + break; + } + return code; } VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() { @@ -3850,7 +4244,7 @@ int VisualShaderNodeTransformCompose::get_input_port_count() const { } VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const { @@ -3897,16 +4291,20 @@ int VisualShaderNodeVectorDecompose::get_input_port_count() const { return 1; } -VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const { return "vec"; } int VisualShaderNodeVectorDecompose::get_output_port_count() const { - return 3; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return 2; + case OP_TYPE_VECTOR_3D: + return 3; + default: + break; + } + return 0; } VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const { @@ -3914,25 +4312,70 @@ VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_o } String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const { - if (p_port == 0) { - return "x"; - } else if (p_port == 1) { - return "y"; - } else { - return "z"; + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + switch (p_port) { + case 0: + return "x"; + case 1: + return "y"; + } + } break; + case OP_TYPE_VECTOR_3D: { + switch (p_port) { + case 0: + return "x"; + case 1: + return "y"; + case 2: + return "z"; + } + } break; + default: + break; } + return String(); +} + +void VisualShaderNodeVectorDecompose::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); } String VisualShaderNodeVectorDecompose::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 += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n"; - code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n"; - code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n"; + switch (op_type) { + case OP_TYPE_VECTOR_2D: { + code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n"; + code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n"; + } break; + case OP_TYPE_VECTOR_3D: { + code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n"; + code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n"; + code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n"; + } break; + default: + break; + } return code; } VisualShaderNodeVectorDecompose::VisualShaderNodeVectorDecompose() { - set_input_port_default_value(0, Vector3()); + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); } ////////////// Transform Decompose @@ -3958,7 +4401,7 @@ int VisualShaderNodeTransformDecompose::get_output_port_count() const { } VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const { @@ -4489,7 +4932,7 @@ int VisualShaderNodeColorUniform::get_input_port_count() const { } VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const { @@ -4501,7 +4944,7 @@ int VisualShaderNodeColorUniform::get_output_port_count() const { } VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR; } String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const { @@ -4582,10 +5025,110 @@ Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() { } -////////////// Vector Uniform +////////////// Vector2 Uniform + +String VisualShaderNodeVec2Uniform::get_caption() const { + return "Vector2Uniform"; +} + +int VisualShaderNodeVec2Uniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_input_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeVec2Uniform::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeVec2Uniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeVec2Uniform::get_output_port_name(int p_port) const { + return String(); +} + +void VisualShaderNodeVec2Uniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeVec2Uniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeVec2Uniform::set_default_value(const Vector2 &p_value) { + default_value = p_value; + emit_changed(); +} + +Vector2 VisualShaderNodeVec2Uniform::get_default_value() const { + return default_value; +} + +String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform vec2 " + get_uniform_name(); + if (default_value_enabled) { + code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y); + } + code += ";\n"; + return code; +} + +String VisualShaderNodeVec2Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +} + +void VisualShaderNodeVec2Uniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Uniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Uniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Uniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Uniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_value"), "set_default_value", "get_default_value"); +} + +bool VisualShaderNodeVec2Uniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeVec2Uniform::is_use_prop_slots() const { + return true; +} + +bool VisualShaderNodeVec2Uniform::is_qualifier_supported(Qualifier p_qual) const { + return true; // all qualifiers are supported +} + +bool VisualShaderNodeVec2Uniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + +Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + +VisualShaderNodeVec2Uniform::VisualShaderNodeVec2Uniform() { +} + +////////////// Vector3 Uniform String VisualShaderNodeVec3Uniform::get_caption() const { - return "VectorUniform"; + return "Vector3Uniform"; } int VisualShaderNodeVec3Uniform::get_input_port_count() const { @@ -4593,7 +5136,7 @@ int VisualShaderNodeVec3Uniform::get_input_port_count() const { } VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const { @@ -4605,7 +5148,7 @@ int VisualShaderNodeVec3Uniform::get_output_port_count() const { } VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const { @@ -4693,7 +5236,7 @@ int VisualShaderNodeTransformUniform::get_input_port_count() const { } VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const { @@ -4800,7 +5343,7 @@ int VisualShaderNodeTextureUniform::get_input_port_count() const { } VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return p_port == 0 ? PORT_TYPE_VECTOR_2D : PORT_TYPE_SCALAR; } String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { @@ -4814,7 +5357,7 @@ int VisualShaderNodeTextureUniform::get_output_port_count() const { VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const { switch (p_port) { case 0: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; case 1: return PORT_TYPE_SCALAR; case 2: @@ -4838,34 +5381,106 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { } String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + bool has_colon = false; String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name(); - switch (texture_type) { - case TYPE_DATA: - if (color_default == COLOR_DEFAULT_BLACK) { - code += " : hint_black;\n"; + // type + { + String type_code; + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) { + type_code = "hint_black"; + } + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) { + type_code = "hint_black_albedo"; + } else { + type_code = "hint_albedo"; + } + break; + case TYPE_NORMAL_MAP: + type_code = "hint_normal"; + break; + case TYPE_ANISOTROPY: + type_code = "hint_anisotropy"; + break; + default: + break; + } + + if (!type_code.is_empty()) { + code += " : " + type_code; + has_colon = true; + } + } + + // filter + { + String filter_code; + + switch (texture_filter) { + case FILTER_NEAREST: + filter_code = "filter_nearest"; + break; + case FILTER_LINEAR: + filter_code = "filter_linear"; + break; + case FILTER_NEAREST_MIPMAP: + filter_code = "filter_nearest_mipmap"; + break; + case FILTER_LINEAR_MIPMAP: + filter_code = "filter_linear_mipmap"; + break; + case FILTER_NEAREST_MIPMAP_ANISOTROPIC: + filter_code = "filter_nearest_mipmap_anisotropic"; + break; + case FILTER_LINEAR_MIPMAP_ANISOTROPIC: + filter_code = "filter_linear_mipmap_anisotropic"; + break; + default: + break; + } + + if (!filter_code.is_empty()) { + if (!has_colon) { + code += " : "; + has_colon = true; } else { - code += ";\n"; + code += ", "; } - break; - case TYPE_COLOR: - if (color_default == COLOR_DEFAULT_BLACK) { - code += " : hint_black_albedo;\n"; + code += filter_code; + } + } + + // repeat + { + String repeat_code; + + switch (texture_repeat) { + case REPEAT_ENABLED: + repeat_code = "repeat_enable"; + break; + case REPEAT_DISABLED: + repeat_code = "repeat_disable"; + break; + default: + break; + } + + if (!repeat_code.is_empty()) { + if (!has_colon) { + code += " : "; } else { - code += " : hint_albedo;\n"; + code += ", "; } - break; - case TYPE_NORMAL_MAP: - code += " : hint_normal;\n"; - break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; - break; - default: - code += ";\n"; - break; + code += repeat_code; + } } + code += ";\n"; return code; } @@ -4875,25 +5490,25 @@ bool VisualShaderNodeTextureUniform::is_code_generated() const { String VisualShaderNodeTextureUniform::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 default_uv; - if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { - default_uv = "UV.xy"; + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + default_uv = "UV"; } else { default_uv = "vec2(0.0)"; } String id = get_uniform_name(); String code = " {\n"; - if (p_input_vars[0] == String()) { // Use UV by default. - if (p_input_vars[1] == String()) { + if (p_input_vars[0].is_empty()) { // Use UV by default. + if (p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { code += " vec4 n_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } - } else if (p_input_vars[1] == String()) { + } else if (p_input_vars[1].is_empty()) { //no lod - code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; + code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { - code += " vec4 n_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; + code += " vec4 n_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += " " + p_output_vars[0] + " = n_tex_read.rgb;\n"; @@ -4928,13 +5543,56 @@ VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get return color_default; } +void VisualShaderNodeTextureUniform::set_texture_filter(TextureFilter p_filter) { + ERR_FAIL_INDEX(int(p_filter), int(FILTER_MAX)); + if (texture_filter == p_filter) { + return; + } + texture_filter = p_filter; + emit_changed(); +} + +VisualShaderNodeTextureUniform::TextureFilter VisualShaderNodeTextureUniform::get_texture_filter() const { + return texture_filter; +} + +void VisualShaderNodeTextureUniform::set_texture_repeat(TextureRepeat p_repeat) { + ERR_FAIL_INDEX(int(p_repeat), int(REPEAT_MAX)); + if (texture_repeat == p_repeat) { + return; + } + texture_repeat = p_repeat; + emit_changed(); +} + +VisualShaderNodeTextureUniform::TextureRepeat VisualShaderNodeTextureUniform::get_texture_repeat() const { + return texture_repeat; +} + Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("texture_type"); - props.push_back("color_default"); + if (texture_type == TYPE_DATA || texture_type == TYPE_COLOR) { + props.push_back("color_default"); + } + props.push_back("texture_filter"); + props.push_back("texture_repeat"); return props; } +bool VisualShaderNodeTextureUniform::is_show_prop_names() const { + return true; +} + +Map<StringName, String> VisualShaderNodeTextureUniform::get_editable_properties_names() const { + Map<StringName, String> names; + names.insert("texture_type", TTR("Type")); + names.insert("color_default", TTR("Default Color")); + names.insert("texture_filter", TTR("Filter")); + names.insert("texture_repeat", TTR("Repeat")); + return names; +} + void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureUniform::set_texture_type); ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureUniform::get_texture_type); @@ -4942,25 +5600,49 @@ void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default); ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default); + ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureUniform::set_texture_filter); + ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureUniform::get_texture_filter); + + ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureUniform::set_texture_repeat); + ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White Default,Black Default"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat"); BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP); - BIND_ENUM_CONSTANT(TYPE_ANISO); + BIND_ENUM_CONSTANT(TYPE_ANISOTROPY); BIND_ENUM_CONSTANT(TYPE_MAX); BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE); BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK); BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX); + + BIND_ENUM_CONSTANT(FILTER_DEFAULT); + BIND_ENUM_CONSTANT(FILTER_NEAREST); + BIND_ENUM_CONSTANT(FILTER_LINEAR); + BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP); + BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP); + BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP_ANISOTROPIC); + BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP_ANISOTROPIC); + BIND_ENUM_CONSTANT(FILTER_MAX); + + BIND_ENUM_CONSTANT(REPEAT_DEFAULT); + BIND_ENUM_CONSTANT(REPEAT_ENABLED); + BIND_ENUM_CONSTANT(REPEAT_DISABLED); + BIND_ENUM_CONSTANT(REPEAT_MAX); } -String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) const { - if (p_port == 0) { - return "default"; +bool VisualShaderNodeTextureUniform::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } } - return ""; + return false; } bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const { @@ -4997,7 +5679,7 @@ int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { if (p_port == 0 || p_port == 1) { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } return PORT_TYPE_SCALAR; } @@ -5011,10 +5693,10 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) return ""; } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; - code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "// " + get_caption() + "\n"; code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; code += " vec4 samp = vec4(0.0);\n"; code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; @@ -5037,11 +5719,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader: String code; if (p_type == VisualShader::TYPE_VERTEX) { - code += " // TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "// " + get_caption() + "\n"; + code += " {\n"; code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + code += " }\n"; } return code; @@ -5051,11 +5735,11 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod String id = get_uniform_name(); String code = " {\n"; - if (p_input_vars[0] == String() && p_input_vars[1] == String()) { + if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n"; - } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) { + } else if (!p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n"; - } else if (p_input_vars[0] == String() && p_input_vars[1] != String()) { + } else if (p_input_vars[0].is_empty() && !p_input_vars[1].is_empty()) { code += " vec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n"; } else { code += " vec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; @@ -5068,13 +5752,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod return code; } -String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int p_port) const { +bool VisualShaderNodeTextureUniformTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const { if (p_port == 0) { - return "default"; + return true; } else if (p_port == 1) { - return "default"; + return true; } - return ""; + return false; } VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { @@ -5110,8 +5794,8 @@ String VisualShaderNodeTexture2DArrayUniform::get_input_port_name(int p_port) co return ""; } -String VisualShaderNodeTexture2DArrayUniform::get_input_port_default_hint(int p_port) const { - return ""; +bool VisualShaderNodeTexture2DArrayUniform::is_input_port_default(int p_port, Shader::Mode p_mode) const { + return false; } String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { @@ -5135,8 +5819,8 @@ String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mod case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5183,8 +5867,8 @@ String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const { return ""; } -String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const { - return ""; +bool VisualShaderNodeTexture3DUniform::is_input_port_default(int p_port, Shader::Mode p_mode) const { + return false; } String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { @@ -5208,8 +5892,8 @@ String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, Vi case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5256,8 +5940,8 @@ String VisualShaderNodeCubemapUniform::get_input_port_name(int p_port) const { return ""; } -String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) const { - return ""; +bool VisualShaderNodeCubemapUniform::is_input_port_default(int p_port, Shader::Mode p_mode) const { + return false; } String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { @@ -5281,8 +5965,8 @@ String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, Visu case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; break; - case TYPE_ANISO: - code += " : hint_aniso;\n"; + case TYPE_ANISOTROPY: + code += " : hint_anisotropy;\n"; break; default: code += ";\n"; @@ -5313,7 +5997,7 @@ VisualShaderNodeIf::PortType VisualShaderNodeIf::get_input_port_type(int p_port) if (p_port == 0 || p_port == 1 || p_port == 2) { return PORT_TYPE_SCALAR; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeIf::get_input_port_name(int p_port) const { @@ -5340,7 +6024,7 @@ int VisualShaderNodeIf::get_output_port_count() const { } VisualShaderNodeIf::PortType VisualShaderNodeIf::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } String VisualShaderNodeIf::get_output_port_name(int p_port) const { @@ -5392,8 +6076,10 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int switch (op_type) { case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; case OP_TYPE_BOOLEAN: return PORT_TYPE_BOOLEAN; case OP_TYPE_TRANSFORM: @@ -5426,8 +6112,10 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(in switch (op_type) { case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; - case OP_TYPE_VECTOR: - return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; case OP_TYPE_BOOLEAN: return PORT_TYPE_BOOLEAN; case OP_TYPE_TRANSFORM: @@ -5449,16 +6137,20 @@ void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) { } switch (p_op_type) { case OP_TYPE_FLOAT: - set_input_port_default_value(1, 1.0); - set_input_port_default_value(2, 0.0); + set_input_port_default_value(1, 1.0, get_input_port_default_value(1)); + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); break; case OP_TYPE_INT: - set_input_port_default_value(1, 1); - set_input_port_default_value(2, 0); + set_input_port_default_value(1, 1, get_input_port_default_value(1)); + set_input_port_default_value(2, 0, get_input_port_default_value(2)); + break; + case OP_TYPE_VECTOR_2D: + set_input_port_default_value(1, Vector2(1.0, 1.0), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector2(0.0, 0.0), get_input_port_default_value(2)); break; - case OP_TYPE_VECTOR: - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + case OP_TYPE_VECTOR_3D: + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0), get_input_port_default_value(2)); break; case OP_TYPE_BOOLEAN: set_input_port_default_value(1, true); @@ -5489,11 +6181,12 @@ void VisualShaderNodeSwitch::_bind_methods() { // static ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3,Boolean,Transform"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); BIND_ENUM_CONSTANT(OP_TYPE_INT); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN); BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM); BIND_ENUM_CONSTANT(OP_TYPE_MAX); @@ -5532,15 +6225,15 @@ int VisualShaderNodeFresnel::get_input_port_count() const { VisualShaderNodeFresnel::PortType VisualShaderNodeFresnel::get_input_port_type(int p_port) const { switch (p_port) { case 0: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; case 1: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; case 2: return PORT_TYPE_BOOLEAN; case 3: return PORT_TYPE_SCALAR; default: - return PORT_TYPE_VECTOR; + return PORT_TYPE_VECTOR_3D; } } @@ -5581,13 +6274,21 @@ bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const { String VisualShaderNodeFresnel::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 normal; String view; - if (p_input_vars[0] == String()) { - normal = "NORMAL"; + if (p_input_vars[0].is_empty()) { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + normal = "NORMAL"; + } else { + normal = "vec3(0.0)"; + } } else { normal = p_input_vars[0]; } - if (p_input_vars[1] == String()) { - view = "VIEW"; + if (p_input_vars[1].is_empty()) { + if (p_mode == Shader::MODE_SPATIAL) { + view = "VIEW"; + } else { + view = "vec3(0.0)"; + } } else { view = p_input_vars[1]; } @@ -5603,13 +6304,17 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader: } } -String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const { +bool VisualShaderNodeFresnel::is_input_port_default(int p_port, Shader::Mode p_mode) const { if (p_port == 0) { - return "default"; + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + return true; + } } else if (p_port == 1) { - return "default"; + if (p_mode == Shader::MODE_SPATIAL) { + return true; + } } - return ""; + return false; } VisualShaderNodeFresnel::VisualShaderNodeFresnel() { @@ -5711,8 +6416,10 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i return PORT_TYPE_SCALAR; case CTYPE_SCALAR_INT: return PORT_TYPE_SCALAR_INT; - case CTYPE_VECTOR: - return PORT_TYPE_VECTOR; + case CTYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case CTYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; case CTYPE_BOOLEAN: return PORT_TYPE_BOOLEAN; case CTYPE_TRANSFORM: @@ -5783,7 +6490,7 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader: String code; switch (comparison_type) { - case CTYPE_SCALAR: + case CTYPE_SCALAR: { if (func == FUNC_EQUAL) { code += " " + p_output_vars[0] + " = (abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");"; } else if (func == FUNC_NOT_EQUAL) { @@ -5791,33 +6498,34 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader: } else { code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n"; } - break; - - case CTYPE_SCALAR_INT: + } break; + case CTYPE_SCALAR_INT: { code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n"; - break; - - case CTYPE_VECTOR: + } break; + case CTYPE_VECTOR_2D: { + code += " {\n"; + code += " bvec2 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; + code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n"; + code += " }\n"; + } break; + case CTYPE_VECTOR_3D: { code += " {\n"; code += " bvec3 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n"; code += " }\n"; - break; - - case CTYPE_BOOLEAN: + } break; + case CTYPE_BOOLEAN: { if (func > FUNC_NOT_EQUAL) { return " " + p_output_vars[0] + " = false;\n"; } code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n"; - break; - - case CTYPE_TRANSFORM: + } break; + case CTYPE_TRANSFORM: { if (func > FUNC_NOT_EQUAL) { return " " + p_output_vars[0] + " = false;\n"; } code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n"; - break; - + } break; default: break; } @@ -5831,18 +6539,23 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_comparison_ty } switch (p_comparison_type) { case CTYPE_SCALAR: - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); simple_decl = true; break; case CTYPE_SCALAR_INT: - set_input_port_default_value(0, 0); - set_input_port_default_value(1, 0); + set_input_port_default_value(0, 0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0, get_input_port_default_value(1)); simple_decl = true; break; - case CTYPE_VECTOR: - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + case CTYPE_VECTOR_2D: + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + simple_decl = false; + break; + case CTYPE_VECTOR_3D: + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); simple_decl = false; break; case CTYPE_BOOLEAN: @@ -5896,7 +6609,7 @@ Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const { Vector<StringName> props; props.push_back("type"); props.push_back("function"); - if (comparison_type == CTYPE_VECTOR) { + if (comparison_type == CTYPE_VECTOR_2D || comparison_type == CTYPE_VECTOR_3D) { props.push_back("condition"); } return props; @@ -5912,13 +6625,14 @@ void VisualShaderNodeCompare::_bind_methods() { ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition); ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function"); ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition"); BIND_ENUM_CONSTANT(CTYPE_SCALAR); BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT); - BIND_ENUM_CONSTANT(CTYPE_VECTOR); + BIND_ENUM_CONSTANT(CTYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(CTYPE_VECTOR_3D); BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); BIND_ENUM_CONSTANT(CTYPE_MAX); @@ -5953,8 +6667,13 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const { - if (op_type == OP_TYPE_VECTOR) { - return PORT_TYPE_VECTOR; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; } return PORT_TYPE_SCALAR; } @@ -5975,11 +6694,15 @@ int VisualShaderNodeMultiplyAdd::get_output_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_output_port_type(int p_port) const { - if (op_type == OP_TYPE_SCALAR) { - return PORT_TYPE_SCALAR; - } else { - return PORT_TYPE_VECTOR; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; } + return PORT_TYPE_SCALAR; } String VisualShaderNodeMultiplyAdd::get_output_port_name(int p_port) const { @@ -5996,16 +6719,21 @@ void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) { return; } switch (p_op_type) { - case OP_TYPE_SCALAR: - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); - break; - case OP_TYPE_VECTOR: - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - 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)); - break; + case OP_TYPE_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); + set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); + } break; + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); + } break; default: break; } @@ -6027,10 +6755,11 @@ void VisualShaderNodeMultiplyAdd::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMultiplyAdd::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMultiplyAdd::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } @@ -6076,29 +6805,29 @@ String VisualShaderNodeBillboard::generate_code(Shader::Mode p_mode, VisualShade switch (billboard_type) { case BILLBOARD_TYPE_ENABLED: code += " {\n"; - code += " mat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], CAMERA_MATRIX[1], CAMERA_MATRIX[2], WORLD_MATRIX[3]);\n"; + code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n"; if (keep_scale) { - code += " __mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } code += " " + p_output_vars[0] + " = __mvm;\n"; code += " }\n"; break; case BILLBOARD_TYPE_FIXED_Y: code += " {\n"; - code += " mat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], WORLD_MATRIX[1], vec4(normalize(cross(CAMERA_MATRIX[0].xyz, WORLD_MATRIX[1].xyz)), 0.0), WORLD_MATRIX[3]);\n"; + code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], MODEL_MATRIX[1], vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, MODEL_MATRIX[1].xyz)), 0.0), MODEL_MATRIX[3]);\n"; if (keep_scale) { - code += " __mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } else { - code += " __mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } code += " " + p_output_vars[0] + " = __mvm;\n"; code += " }\n"; break; case BILLBOARD_TYPE_PARTICLES: code += " {\n"; - code += " mat4 __wm = mat4(normalize(CAMERA_MATRIX[0]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[1]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[2]) * length(WORLD_MATRIX[2]), WORLD_MATRIX[3]);\n"; + code += " mat4 __wm = mat4(normalize(INV_VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), MODEL_MATRIX[3]);\n"; code += " __wm = __wm * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; - code += " " + p_output_vars[0] + " = INV_CAMERA_MATRIX * __wm;\n"; + code += " " + p_output_vars[0] + " = VIEW_MATRIX * __wm;\n"; code += " }\n"; break; default: |