diff options
Diffstat (limited to 'scene/resources/visual_shader_nodes.cpp')
| -rw-r--r-- | scene/resources/visual_shader_nodes.cpp | 279 |
1 files changed, 212 insertions, 67 deletions
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index d6200059f6..e7cc78cb3a 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -242,6 +242,13 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port } +bool VisualShaderNodeColorConstant::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeColorConstant::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 += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.r, constant.g, constant.b) + ";\n"; @@ -455,6 +462,13 @@ String VisualShaderNodeTexture::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeTexture::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const { if (p_port == 0) { return "default"; @@ -775,7 +789,7 @@ void VisualShaderNodeTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_SCREEN); @@ -917,6 +931,13 @@ String VisualShaderNodeSample3D::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeSample3D::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const { if (p_port == 0) { return "default"; @@ -1168,6 +1189,13 @@ String VisualShaderNodeCubemap::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeCubemap::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + 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"); @@ -1308,7 +1336,7 @@ void VisualShaderNodeCubemap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_PORT); @@ -1409,7 +1437,7 @@ void VisualShaderNodeFloatOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,ATan2,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1506,7 +1534,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,Sub,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"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1615,7 +1643,7 @@ 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); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Cross,Atan2,Reflect,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,Cross,ATan2,Reflect,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1785,7 +1813,7 @@ void VisualShaderNodeColorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,SoftLight,HardLight"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,Soft Light,Hard Light"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_SCREEN); BIND_ENUM_CONSTANT(OP_DIFFERENCE); @@ -2742,8 +2770,6 @@ int VisualShaderNodeClamp::get_input_port_count() const { VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_FLOAT: - return PORT_TYPE_SCALAR; case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; case OP_TYPE_VECTOR: @@ -2771,8 +2797,6 @@ int VisualShaderNodeClamp::get_output_port_count() const { VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_FLOAT: - return PORT_TYPE_SCALAR; case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; case OP_TYPE_VECTOR: @@ -2954,18 +2978,11 @@ int VisualShaderNodeStep::get_input_port_count() const { VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: - switch (p_port) { - case 0: - return PORT_TYPE_SCALAR; - case 1: - return PORT_TYPE_VECTOR; - default: - break; + if (p_port == 1) { + return PORT_TYPE_VECTOR; } break; default: @@ -2989,8 +3006,6 @@ int VisualShaderNodeStep::get_output_port_count() const { VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: @@ -3032,7 +3047,7 @@ void VisualShaderNodeStep::set_op_type(OpType p_op_type) { set_input_port_default_value(0, 0.0); // edge } if (op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(1, 0.0); // x + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x } break; default: @@ -3085,20 +3100,11 @@ int VisualShaderNodeSmoothStep::get_input_port_count() const { VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: - switch (p_port) { - case 0: - return PORT_TYPE_SCALAR; // edge0 - case 1: - return PORT_TYPE_SCALAR; // edge1 - case 2: - return PORT_TYPE_VECTOR; // x - default: - break; + if (p_port == 2) { + return PORT_TYPE_VECTOR; // x } break; default: @@ -3124,8 +3130,6 @@ int VisualShaderNodeSmoothStep::get_output_port_count() const { VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: @@ -3319,16 +3323,11 @@ int VisualShaderNodeMix::get_input_port_count() const { VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: - if (p_port == 2) { - return PORT_TYPE_VECTOR; - } return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: if (p_port == 2) { - return PORT_TYPE_SCALAR; + break; } return PORT_TYPE_VECTOR; default: @@ -3353,8 +3352,6 @@ int VisualShaderNodeMix::get_output_port_count() const { VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_SCALAR: - return PORT_TYPE_SCALAR; case OP_TYPE_VECTOR: return PORT_TYPE_VECTOR; case OP_TYPE_VECTOR_SCALAR: @@ -3775,6 +3772,10 @@ bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) cons return true; // all qualifiers are supported } +bool VisualShaderNodeFloatUniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("hint"); @@ -3926,7 +3927,7 @@ void VisualShaderNodeIntUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); - ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); @@ -3942,6 +3943,10 @@ bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const return true; // all qualifiers are supported } +bool VisualShaderNodeIntUniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("hint"); @@ -4050,6 +4055,10 @@ bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) co return true; // all qualifiers are supported } +bool VisualShaderNodeBooleanUniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("default_value_enabled"); @@ -4144,6 +4153,10 @@ bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) cons return true; // all qualifiers are supported } +bool VisualShaderNodeColorUniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("default_value_enabled"); @@ -4240,6 +4253,10 @@ bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const return true; // all qualifiers are supported } +bool VisualShaderNodeVec3Uniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("default_value_enabled"); @@ -4340,6 +4357,10 @@ bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) return true; // all qualifiers are supported } +bool VisualShaderNodeTransformUniform::is_convertible_to_constant() const { + return true; // conversion is allowed +} + Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const { Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); props.push_back("default_value_enabled"); @@ -4494,7 +4515,7 @@ 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); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap,Aniso"), "set_texture_type", "get_texture_type"); + 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"); BIND_ENUM_CONSTANT(TYPE_DATA); @@ -4525,6 +4546,10 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co return false; } +bool VisualShaderNodeTextureUniform::is_convertible_to_constant() const { + return false; // conversion is not allowed +} + VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { simple_decl = false; } @@ -4540,9 +4565,7 @@ int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { } VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_VECTOR; - } else if (p_port == 1) { + if (p_port == 0 || p_port == 1) { return PORT_TYPE_VECTOR; } return PORT_TYPE_SCALAR; @@ -4665,16 +4688,18 @@ String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mod switch (texture_type) { case TYPE_DATA: - if (color_default == COLOR_DEFAULT_BLACK) + if (color_default == COLOR_DEFAULT_BLACK) { code += " : hint_black;\n"; - else + } else { code += ";\n"; + } break; case TYPE_COLOR: - if (color_default == COLOR_DEFAULT_BLACK) + if (color_default == COLOR_DEFAULT_BLACK) { code += " : hint_black_albedo;\n"; - else + } else { code += " : hint_albedo;\n"; + } break; case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; @@ -4733,16 +4758,18 @@ String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, Vi switch (texture_type) { case TYPE_DATA: - if (color_default == COLOR_DEFAULT_BLACK) + if (color_default == COLOR_DEFAULT_BLACK) { code += " : hint_black;\n"; - else + } else { code += ";\n"; + } break; case TYPE_COLOR: - if (color_default == COLOR_DEFAULT_BLACK) + if (color_default == COLOR_DEFAULT_BLACK) { code += " : hint_black_albedo;\n"; - else + } else { code += " : hint_albedo;\n"; + } break; case TYPE_NORMAL_MAP: code += " : hint_normal;\n"; @@ -4923,8 +4950,6 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int } if (p_port == 1 || p_port == 2) { switch (op_type) { - case OP_TYPE_FLOAT: - return PORT_TYPE_SCALAR; case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; case OP_TYPE_VECTOR: @@ -4959,8 +4984,6 @@ int VisualShaderNodeSwitch::get_output_port_count() const { VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const { switch (op_type) { - case OP_TYPE_FLOAT: - return PORT_TYPE_SCALAR; case OP_TYPE_INT: return PORT_TYPE_SCALAR_INT; case OP_TYPE_VECTOR: @@ -5238,9 +5261,6 @@ int VisualShaderNodeCompare::get_input_port_count() const { } 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; @@ -5252,8 +5272,9 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i return PORT_TYPE_BOOLEAN; case CTYPE_TRANSFORM: return PORT_TYPE_TRANSFORM; + default: + return PORT_TYPE_SCALAR; } - return PORT_TYPE_VECTOR; } String VisualShaderNodeCompare::get_input_port_name(int p_port) const { @@ -5472,10 +5493,10 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const { - if (op_type == OP_TYPE_SCALAR) { - return PORT_TYPE_SCALAR; + if (op_type == OP_TYPE_VECTOR) { + return PORT_TYPE_VECTOR; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_SCALAR; } String VisualShaderNodeMultiplyAdd::get_input_port_name(int p_port) const { @@ -5558,3 +5579,127 @@ VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() { set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); } + +////////////// Billboard + +String VisualShaderNodeBillboard::get_caption() const { + return "GetBillboardMatrix"; +} + +int VisualShaderNodeBillboard::get_input_port_count() const { + return 0; +} + +VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeBillboard::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeBillboard::get_output_port_count() const { + return 1; +} + +VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_output_port_type(int p_port) const { + return PORT_TYPE_TRANSFORM; +} + +String VisualShaderNodeBillboard::get_output_port_name(int p_port) const { + return "model_view_matrix"; +} + +String VisualShaderNodeBillboard::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; + + switch (billboard_type) { + case BILLBOARD_TYPE_ENABLED: + code += "\t{\n"; + code += "\t\tmat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], CAMERA_MATRIX[1], CAMERA_MATRIX[2], WORLD_MATRIX[3]);\n"; + if (keep_scale) { + code += "\t\t__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 += "\t\t" + p_output_vars[0] + " = __mvm;\n"; + code += "\t}\n"; + break; + case BILLBOARD_TYPE_FIXED_Y: + code += "\t{\n"; + code += "\t\tmat4 __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"; + if (keep_scale) { + code += "\t\t__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"; + } else { + code += "\t\t__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 += "\t\t" + p_output_vars[0] + " = __mvm;\n"; + code += "\t}\n"; + break; + case BILLBOARD_TYPE_PARTICLES: + code += "\t{\n"; + code += "\t\tmat4 __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 += "\t\t__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 += "\t\t" + p_output_vars[0] + " = INV_CAMERA_MATRIX * __wm;\n"; + code += "\t}\n"; + break; + default: + code += "\t" + p_output_vars[0] + " = mat4(1.0);\n"; + break; + } + + return code; +} + +bool VisualShaderNodeBillboard::is_show_prop_names() const { + return true; +} + +void VisualShaderNodeBillboard::set_billboard_type(BillboardType p_billboard_type) { + ERR_FAIL_INDEX((int)p_billboard_type, BILLBOARD_TYPE_MAX); + billboard_type = p_billboard_type; + simple_decl = bool(billboard_type == BILLBOARD_TYPE_DISABLED); + set_disabled(simple_decl); + emit_changed(); +} + +VisualShaderNodeBillboard::BillboardType VisualShaderNodeBillboard::get_billboard_type() const { + return billboard_type; +} + +void VisualShaderNodeBillboard::set_keep_scale_enabled(bool p_enabled) { + keep_scale = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeBillboard::is_keep_scale_enabled() const { + return keep_scale; +} + +Vector<StringName> VisualShaderNodeBillboard::get_editable_properties() const { + Vector<StringName> props; + props.push_back("billboard_type"); + if (billboard_type == BILLBOARD_TYPE_ENABLED || billboard_type == BILLBOARD_TYPE_FIXED_Y) { + props.push_back("keep_scale"); + } + return props; +} + +void VisualShaderNodeBillboard::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_billboard_type", "billboard_type"), &VisualShaderNodeBillboard::set_billboard_type); + ClassDB::bind_method(D_METHOD("get_billboard_type"), &VisualShaderNodeBillboard::get_billboard_type); + + ClassDB::bind_method(D_METHOD("set_keep_scale_enabled", "enabled"), &VisualShaderNodeBillboard::set_keep_scale_enabled); + ClassDB::bind_method(D_METHOD("is_keep_scale_enabled"), &VisualShaderNodeBillboard::is_keep_scale_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_type", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particles"), "set_billboard_type", "get_billboard_type"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_scale"), "set_keep_scale_enabled", "is_keep_scale_enabled"); + + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_DISABLED); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_ENABLED); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_FIXED_Y); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_PARTICLES); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_MAX); +} + +VisualShaderNodeBillboard::VisualShaderNodeBillboard() { + simple_decl = false; +} |