diff options
Diffstat (limited to 'scene/resources/visual_shader_nodes.cpp')
-rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 746edc65b0..06f18472ce 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -2968,6 +2968,98 @@ VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { color_default = COLOR_DEFAULT_WHITE; } +////////////// Texture Uniform (Triplanar) + +String VisualShaderNodeTextureUniformTriplanar::get_caption() const { + return "TextureUniformTriplanar"; +} + +int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { + return 2; +} + +VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "weights"; + } else if (p_port == 1) { + return "pos"; + } + return ""; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "\tvec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; + code += "\t\tvec4 samp = vec4(0.0);\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n"; + code += "\t\treturn samp;\n"; + code += "\t}\n"; + code += "\n"; + code += "\tuniform vec3 triplanar_scale = vec3(1.0, 1.0, 1.0);\n"; + code += "\tuniform vec3 triplanar_offset;\n"; + code += "\tuniform float triplanar_sharpness = 0.5;\n"; + code += "\n"; + code += "\tvarying vec3 triplanar_power_normal;\n"; + code += "\tvarying vec3 triplanar_pos;\n"; + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + if (p_type == VisualShader::TYPE_VERTEX) { + + code += "\t// TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "\t\ttriplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; + code += "\t\ttriplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; + code += "\t\ttriplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; + code += "\t\ttriplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + } + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::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 id = get_uniform_name(); + String code = "\t{\n"; + + if (p_input_vars[0] == String() && p_input_vars[1] == String()) { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal, triplanar_pos );\n"; + } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) { + code += "\t\tvec4 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()) { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal," + p_input_vars[1] + " );\n"; + } else { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n"; + } + + code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n"; + code += "\t\t" + p_output_vars[1] + " = n_tex_read.a;\n"; + code += "\t}\n"; + + return code; +} + +VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { +} + ////////////// CubeMap Uniform String VisualShaderNodeCubeMapUniform::get_caption() const { @@ -3200,3 +3292,317 @@ VisualShaderNodeFresnel::VisualShaderNodeFresnel() { set_input_port_default_value(2, false); set_input_port_default_value(3, 1.0); } + +////////////// Is + +String VisualShaderNodeIs::get_caption() const { + + return "Is"; +} + +int VisualShaderNodeIs::get_input_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const { + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeIs::get_input_port_name(int p_port) const { + + return ""; +} + +int VisualShaderNodeIs::get_output_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const { + + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeIs::get_output_port_name(int p_port) const { + + return ""; +} + +String VisualShaderNodeIs::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 *funcs[FUNC_IS_NAN + 1] = { + "isinf($)", + "isnan($)" + }; + + String code; + code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + return code; +} + +void VisualShaderNodeIs::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const { + + return func; +} + +Vector<StringName> VisualShaderNodeIs::get_editable_properties() const { + + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeIs::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Inf,NaN"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_IS_INF); + BIND_ENUM_CONSTANT(FUNC_IS_NAN); +} + +VisualShaderNodeIs::VisualShaderNodeIs() { + + func = FUNC_IS_INF; + set_input_port_default_value(0, 0.0); +} + +////////////// Compare + +String VisualShaderNodeCompare::get_caption() const { + + return "Compare"; +} + +int VisualShaderNodeCompare::get_input_port_count() const { + + if (ctype == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) { + return 3; + } + return 2; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const { + + if (p_port == 2) + return PORT_TYPE_SCALAR; + switch (ctype) { + case CTYPE_SCALAR: + return PORT_TYPE_SCALAR; + case CTYPE_VECTOR: + return PORT_TYPE_VECTOR; + case CTYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case CTYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + } + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeCompare::get_input_port_name(int p_port) const { + if (p_port == 0) + return "a"; + else if (p_port == 1) + return "b"; + else if (p_port == 2) + return "tolerance"; + return ""; +} + +int VisualShaderNodeCompare::get_output_port_count() const { + return 1; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(int p_port) const { + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeCompare::get_output_port_name(int p_port) const { + if (p_port == 0) + return "result"; + return ""; +} + +String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + + if (ctype == CTYPE_BOOLEAN || ctype == CTYPE_TRANSFORM) { + if (func > FUNC_NOT_EQUAL) { + return TTR("Invalid comparsion function for that type."); + } + } + + return ""; +} + +String VisualShaderNodeCompare::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 *ops[FUNC_LESS_THAN_EQUAL + 1] = { + "==", + "!=", + ">", + ">=", + "<", + "<=", + }; + + static const char *funcs[FUNC_LESS_THAN_EQUAL + 1] = { + "equal($)", + "notEqual($)", + "greaterThan($)", + "greaterThanEqual($)", + "lessThan($)", + "lessThanEqual($)", + }; + + static const char *conds[COND_ANY + 1] = { + "all($)", + "any($)", + }; + + String code; + switch (ctype) { + case CTYPE_SCALAR: + if (func == FUNC_EQUAL) { + code += "\t" + p_output_vars[0] + "=(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else if (func == FUNC_NOT_EQUAL) { + code += "\t" + p_output_vars[0] + "=!(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else { + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + } + break; + + case CTYPE_VECTOR: + code += "\t{\n"; + code += "\t\tbvec3 _bv=" + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; + code += "\t\t" + p_output_vars[0] + "=" + String(conds[condition]).replace("$", "_bv") + ";\n"; + code += "\t}\n"; + break; + + case CTYPE_BOOLEAN: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + case CTYPE_TRANSFORM: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + default: + break; + } + return code; +} + +void VisualShaderNodeCompare::set_comparsion_type(ComparsionType p_type) { + + ctype = p_type; + + switch (ctype) { + case CTYPE_SCALAR: + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + 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)); + break; + case CTYPE_BOOLEAN: + set_input_port_default_value(0, false); + set_input_port_default_value(1, false); + break; + case CTYPE_TRANSFORM: + set_input_port_default_value(0, Transform()); + set_input_port_default_value(1, Transform()); + break; + } + emit_changed(); +} + +VisualShaderNodeCompare::ComparsionType VisualShaderNodeCompare::get_comparsion_type() const { + + return ctype; +} + +void VisualShaderNodeCompare::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const { + + return func; +} + +void VisualShaderNodeCompare::set_condition(Condition p_cond) { + + condition = p_cond; + emit_changed(); +} + +VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const { + + return condition; +} + +Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const { + Vector<StringName> props; + props.push_back("type"); + props.push_back("function"); + if (ctype == CTYPE_VECTOR) + props.push_back("condition"); + return props; +} + +void VisualShaderNodeCompare::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_comparsion_type", "type"), &VisualShaderNodeCompare::set_comparsion_type); + ClassDB::bind_method(D_METHOD("get_comparsion_type"), &VisualShaderNodeCompare::get_comparsion_type); + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeCompare::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeCompare::get_function); + + 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, "Scalar,Vector,Boolean,Transform"), "set_comparsion_type", "get_comparsion_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_VECTOR); + BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); + BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); + + BIND_ENUM_CONSTANT(FUNC_EQUAL); + BIND_ENUM_CONSTANT(FUNC_NOT_EQUAL); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN_EQUAL); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN_EQUAL); + + BIND_ENUM_CONSTANT(COND_ALL); + BIND_ENUM_CONSTANT(COND_ANY); +} + +VisualShaderNodeCompare::VisualShaderNodeCompare() { + ctype = CTYPE_SCALAR; + func = FUNC_EQUAL; + condition = COND_ALL; + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, CMP_EPSILON); +} |