diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-30 10:03:49 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-30 10:03:49 +0100 |
commit | 38f8411ed82e72380c9ca77bf242e41277e026bb (patch) | |
tree | 8bc9155614f4e01e6bf6b04fd6014e80e0fc5306 /scene/3d | |
parent | 62b0bfd343fec874765c2d3801cb05bf97ecada3 (diff) | |
parent | 1c774a608314f4915791c9d9e4ab5d9c5485813f (diff) |
Merge pull request #71964 from bruvzg/mat_key
Fix unsafe murmur3 hash use for the default material keys, expose alpha hash transparency mode for default materials and Label3D and Sprite3D.
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/label_3d.cpp | 32 | ||||
-rw-r--r-- | scene/3d/label_3d.h | 8 | ||||
-rw-r--r-- | scene/3d/sprite_3d.cpp | 55 | ||||
-rw-r--r-- | scene/3d/sprite_3d.h | 12 |
4 files changed, 98 insertions, 9 deletions
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index d0f71768d2..6a9b8c9ac4 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -109,6 +109,9 @@ void Label3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &Label3D::set_alpha_scissor_threshold); ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &Label3D::get_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &Label3D::set_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &Label3D::get_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &Label3D::set_texture_filter); ClassDB::bind_method(D_METHOD("get_texture_filter"), &Label3D::get_texture_filter); @@ -127,8 +130,9 @@ void Label3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE); - ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority"); @@ -162,6 +166,7 @@ void Label3D::_bind_methods() { BIND_ENUM_CONSTANT(ALPHA_CUT_DISABLED); BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD); BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS); + BIND_ENUM_CONSTANT(ALPHA_CUT_HASH); } void Label3D::_validate_property(PropertyInfo &p_property) const { @@ -350,13 +355,23 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset, RS::get_singleton()->material_set_param(surf.material, "uv2_offset", Vector3(0, 0, 0)); RS::get_singleton()->material_set_param(surf.material, "uv2_scale", Vector3(1, 1, 1)); RS::get_singleton()->material_set_param(surf.material, "alpha_scissor_threshold", alpha_scissor_threshold); + RS::get_singleton()->material_set_param(surf.material, "alpha_hash_scale", alpha_hash_scale); if (msdf) { RS::get_singleton()->material_set_param(surf.material, "msdf_pixel_range", TS->font_get_msdf_pixel_range(p_glyph.font_rid)); RS::get_singleton()->material_set_param(surf.material, "msdf_outline_size", p_outline_size); } + BaseMaterial3D::Transparency mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA; + if (get_alpha_cut_mode() == ALPHA_CUT_DISCARD) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_SCISSOR; + } else if (get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS; + } else if (get_alpha_cut_mode() == ALPHA_CUT_HASH) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_HASH; + } + RID shader_rid; - StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), true, get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, &shader_rid); + StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, msdf, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), texture_filter, &shader_rid); RS::get_singleton()->material_set_shader(surf.material, shader_rid); RS::get_singleton()->material_set_param(surf.material, "texture_albedo", tex); @@ -906,7 +921,7 @@ StandardMaterial3D::BillboardMode Label3D::get_billboard_mode() const { } void Label3D::set_alpha_cut_mode(AlphaCutMode p_mode) { - ERR_FAIL_INDEX(p_mode, 3); + ERR_FAIL_INDEX(p_mode, ALPHA_CUT_MAX); if (alpha_cut != p_mode) { alpha_cut = p_mode; _queue_update(); @@ -929,6 +944,17 @@ Label3D::AlphaCutMode Label3D::get_alpha_cut_mode() const { return alpha_cut; } +void Label3D::set_alpha_hash_scale(float p_hash_scale) { + if (alpha_hash_scale != p_hash_scale) { + alpha_hash_scale = p_hash_scale; + _queue_update(); + } +} + +float Label3D::get_alpha_hash_scale() const { + return alpha_hash_scale; +} + void Label3D::set_alpha_scissor_threshold(float p_threshold) { if (alpha_scissor_threshold != p_threshold) { alpha_scissor_threshold = p_threshold; diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h index 96cc941209..576735840a 100644 --- a/scene/3d/label_3d.h +++ b/scene/3d/label_3d.h @@ -51,7 +51,9 @@ public: enum AlphaCutMode { ALPHA_CUT_DISABLED, ALPHA_CUT_DISCARD, - ALPHA_CUT_OPAQUE_PREPASS + ALPHA_CUT_OPAQUE_PREPASS, + ALPHA_CUT_HASH, + ALPHA_CUT_MAX }; private: @@ -59,6 +61,7 @@ private: bool flags[FLAG_MAX] = {}; AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; float alpha_scissor_threshold = 0.5; + float alpha_hash_scale = 1.0; AABB aabb; @@ -228,6 +231,9 @@ public: void set_alpha_scissor_threshold(float p_threshold); float get_alpha_scissor_threshold() const; + void set_alpha_hash_scale(float p_hash_scale); + float get_alpha_hash_scale() const; + void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode); StandardMaterial3D::BillboardMode get_billboard_mode() const; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 9712df0936..041ca7707b 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -245,8 +245,25 @@ void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, RS::get_singleton()->mesh_set_custom_aabb(mesh_new, aabb_new); set_aabb(aabb_new); + RS::get_singleton()->material_set_param(get_material(), "alpha_scissor_threshold", alpha_scissor_threshold); + RS::get_singleton()->material_set_param(get_material(), "alpha_hash_scale", alpha_hash_scale); + + BaseMaterial3D::Transparency mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_DISABLED; + if (get_draw_flag(FLAG_TRANSPARENT)) { + if (get_alpha_cut_mode() == ALPHA_CUT_DISCARD) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_SCISSOR; + } else if (get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS; + } else if (get_alpha_cut_mode() == ALPHA_CUT_HASH) { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA_HASH; + } else { + mat_transparency = BaseMaterial3D::Transparency::TRANSPARENCY_ALPHA; + } + } + RID shader_rid; - StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid); + StandardMaterial3D::get_material_for_2d(get_draw_flag(FLAG_SHADED), mat_transparency, get_draw_flag(FLAG_DOUBLE_SIDED), get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y, false, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), get_texture_filter(), &shader_rid); + if (last_shader != shader_rid) { RS::get_singleton()->material_set_shader(get_material(), shader_rid); last_shader = shader_rid; @@ -433,7 +450,7 @@ bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const { } void SpriteBase3D::set_alpha_cut_mode(AlphaCutMode p_mode) { - ERR_FAIL_INDEX(p_mode, 3); + ERR_FAIL_INDEX(p_mode, ALPHA_CUT_MAX); alpha_cut = p_mode; _queue_redraw(); } @@ -442,6 +459,28 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const { return alpha_cut; } +void SpriteBase3D::set_alpha_hash_scale(float p_hash_scale) { + if (alpha_hash_scale != p_hash_scale) { + alpha_hash_scale = p_hash_scale; + _queue_redraw(); + } +} + +float SpriteBase3D::get_alpha_hash_scale() const { + return alpha_hash_scale; +} + +void SpriteBase3D::set_alpha_scissor_threshold(float p_threshold) { + if (alpha_scissor_threshold != p_threshold) { + alpha_scissor_threshold = p_threshold; + _queue_redraw(); + } +} + +float SpriteBase3D::get_alpha_scissor_threshold() const { + return alpha_scissor_threshold; +} + void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) { ERR_FAIL_INDEX(p_mode, 3); // Cannot use BILLBOARD_PARTICLES. billboard_mode = p_mode; @@ -494,6 +533,12 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alpha_cut_mode", "mode"), &SpriteBase3D::set_alpha_cut_mode); ClassDB::bind_method(D_METHOD("get_alpha_cut_mode"), &SpriteBase3D::get_alpha_cut_mode); + ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpriteBase3D::set_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpriteBase3D::get_alpha_scissor_threshold); + + ClassDB::bind_method(D_METHOD("set_alpha_hash_scale", "threshold"), &SpriteBase3D::set_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("get_alpha_hash_scale"), &SpriteBase3D::get_alpha_hash_scale); + ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpriteBase3D::set_billboard_mode); ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpriteBase3D::get_billboard_mode); @@ -519,7 +564,9 @@ void SpriteBase3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE); - ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass,Alpha Hash"), "set_alpha_cut_mode", "get_alpha_cut_mode"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); @@ -533,6 +580,7 @@ void SpriteBase3D::_bind_methods() { BIND_ENUM_CONSTANT(ALPHA_CUT_DISABLED); BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD); BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS); + BIND_ENUM_CONSTANT(ALPHA_CUT_HASH); } SpriteBase3D::SpriteBase3D() { @@ -550,7 +598,6 @@ SpriteBase3D::SpriteBase3D() { RS::get_singleton()->material_set_param(material, "uv1_scale", Vector3(1, 1, 1)); RS::get_singleton()->material_set_param(material, "uv2_offset", Vector3(0, 0, 0)); RS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1)); - RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.5); mesh = RenderingServer::get_singleton()->mesh_create(); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index d0fd767d89..873c321878 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -53,7 +53,9 @@ public: enum AlphaCutMode { ALPHA_CUT_DISABLED, ALPHA_CUT_DISCARD, - ALPHA_CUT_OPAQUE_PREPASS + ALPHA_CUT_OPAQUE_PREPASS, + ALPHA_CUT_HASH, + ALPHA_CUT_MAX }; private: @@ -85,6 +87,8 @@ private: bool flags[FLAG_MAX] = {}; AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; + float alpha_scissor_threshold = 0.5; + float alpha_hash_scale = 1.0; StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; StandardMaterial3D::TextureFilter texture_filter = StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; bool pending_update = false; @@ -143,6 +147,12 @@ public: void set_alpha_cut_mode(AlphaCutMode p_mode); AlphaCutMode get_alpha_cut_mode() const; + void set_alpha_scissor_threshold(float p_threshold); + float get_alpha_scissor_threshold() const; + + void set_alpha_hash_scale(float p_hash_scale); + float get_alpha_hash_scale() const; + void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode); StandardMaterial3D::BillboardMode get_billboard_mode() const; |