Fix unsafe murmur3 hash use for the default material keys, expose alpha hash transparency mode for default materials and Label3D and Sprite3D.
This commit is contained in:
parent
4fa6edc888
commit
1c774a6083
9 changed files with 134 additions and 51 deletions
|
@ -35,6 +35,9 @@
|
||||||
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="Label3D.AlphaCutMode" default="0">
|
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="Label3D.AlphaCutMode" default="0">
|
||||||
The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for possible values.
|
The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for possible values.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="alpha_hash_scale" type="float" setter="set_alpha_hash_scale" getter="get_alpha_hash_scale" default="1.0">
|
||||||
|
The hashing scale for Alpha Hash. Recommended values between [code]0[/code] and [code]2[/code].
|
||||||
|
</member>
|
||||||
<member name="alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold" default="0.5">
|
<member name="alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold" default="0.5">
|
||||||
Threshold at which the alpha scissor will discard values.
|
Threshold at which the alpha scissor will discard values.
|
||||||
</member>
|
</member>
|
||||||
|
@ -152,5 +155,8 @@
|
||||||
This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
|
This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
|
||||||
[b]Note:[/b] When using text with overlapping glyphs (e.g., cursive scripts), this mode might have transparency sorting issues between the main text and the outline.
|
[b]Note:[/b] When using text with overlapping glyphs (e.g., cursive scripts), this mode might have transparency sorting issues between the main text and the outline.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="ALPHA_CUT_HASH" value="3" enum="AlphaCutMode">
|
||||||
|
This mode draws cuts off all values below a spatially-deterministic threshold, the rest will remain opaque.
|
||||||
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -41,6 +41,12 @@
|
||||||
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="SpriteBase3D.AlphaCutMode" default="0">
|
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="SpriteBase3D.AlphaCutMode" default="0">
|
||||||
The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for possible values.
|
The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for possible values.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="alpha_hash_scale" type="float" setter="set_alpha_hash_scale" getter="get_alpha_hash_scale" default="1.0">
|
||||||
|
The hashing scale for Alpha Hash. Recommended values between [code]0[/code] and [code]2[/code].
|
||||||
|
</member>
|
||||||
|
<member name="alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold" default="0.5">
|
||||||
|
Threshold at which the alpha scissor will discard values.
|
||||||
|
</member>
|
||||||
<member name="axis" type="int" setter="set_axis" getter="get_axis" enum="Vector3.Axis" default="2">
|
<member name="axis" type="int" setter="set_axis" getter="get_axis" enum="Vector3.Axis" default="2">
|
||||||
The direction in which the front of the texture faces.
|
The direction in which the front of the texture faces.
|
||||||
</member>
|
</member>
|
||||||
|
@ -118,5 +124,8 @@
|
||||||
<constant name="ALPHA_CUT_OPAQUE_PREPASS" value="2" enum="AlphaCutMode">
|
<constant name="ALPHA_CUT_OPAQUE_PREPASS" value="2" enum="AlphaCutMode">
|
||||||
This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
|
This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="ALPHA_CUT_HASH" value="3" enum="AlphaCutMode">
|
||||||
|
This mode draws cuts off all values below a spatially-deterministic threshold, the rest will remain opaque.
|
||||||
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -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("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("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("set_texture_filter", "mode"), &Label3D::set_texture_filter);
|
||||||
ClassDB::bind_method(D_METHOD("get_texture_filter"), &Label3D::get_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, "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, "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_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_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, "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, "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");
|
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_DISABLED);
|
||||||
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
|
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
|
||||||
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
|
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
|
||||||
|
BIND_ENUM_CONSTANT(ALPHA_CUT_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Label3D::_validate_property(PropertyInfo &p_property) const {
|
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_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, "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_scissor_threshold", alpha_scissor_threshold);
|
||||||
|
RS::get_singleton()->material_set_param(surf.material, "alpha_hash_scale", alpha_hash_scale);
|
||||||
if (msdf) {
|
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_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);
|
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;
|
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_shader(surf.material, shader_rid);
|
||||||
RS::get_singleton()->material_set_param(surf.material, "texture_albedo", tex);
|
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) {
|
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) {
|
if (alpha_cut != p_mode) {
|
||||||
alpha_cut = p_mode;
|
alpha_cut = p_mode;
|
||||||
_queue_update();
|
_queue_update();
|
||||||
|
@ -929,6 +944,17 @@ Label3D::AlphaCutMode Label3D::get_alpha_cut_mode() const {
|
||||||
return alpha_cut;
|
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) {
|
void Label3D::set_alpha_scissor_threshold(float p_threshold) {
|
||||||
if (alpha_scissor_threshold != p_threshold) {
|
if (alpha_scissor_threshold != p_threshold) {
|
||||||
alpha_scissor_threshold = p_threshold;
|
alpha_scissor_threshold = p_threshold;
|
||||||
|
|
|
@ -51,7 +51,9 @@ public:
|
||||||
enum AlphaCutMode {
|
enum AlphaCutMode {
|
||||||
ALPHA_CUT_DISABLED,
|
ALPHA_CUT_DISABLED,
|
||||||
ALPHA_CUT_DISCARD,
|
ALPHA_CUT_DISCARD,
|
||||||
ALPHA_CUT_OPAQUE_PREPASS
|
ALPHA_CUT_OPAQUE_PREPASS,
|
||||||
|
ALPHA_CUT_HASH,
|
||||||
|
ALPHA_CUT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -59,6 +61,7 @@ private:
|
||||||
bool flags[FLAG_MAX] = {};
|
bool flags[FLAG_MAX] = {};
|
||||||
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
|
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
|
||||||
float alpha_scissor_threshold = 0.5;
|
float alpha_scissor_threshold = 0.5;
|
||||||
|
float alpha_hash_scale = 1.0;
|
||||||
|
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
|
|
||||||
|
@ -228,6 +231,9 @@ public:
|
||||||
void set_alpha_scissor_threshold(float p_threshold);
|
void set_alpha_scissor_threshold(float p_threshold);
|
||||||
float get_alpha_scissor_threshold() const;
|
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);
|
void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode);
|
||||||
StandardMaterial3D::BillboardMode get_billboard_mode() const;
|
StandardMaterial3D::BillboardMode get_billboard_mode() const;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
RS::get_singleton()->mesh_set_custom_aabb(mesh_new, aabb_new);
|
||||||
set_aabb(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;
|
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) {
|
if (last_shader != shader_rid) {
|
||||||
RS::get_singleton()->material_set_shader(get_material(), shader_rid);
|
RS::get_singleton()->material_set_shader(get_material(), shader_rid);
|
||||||
last_shader = 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) {
|
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;
|
alpha_cut = p_mode;
|
||||||
_queue_redraw();
|
_queue_redraw();
|
||||||
}
|
}
|
||||||
|
@ -442,6 +459,28 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const {
|
||||||
return alpha_cut;
|
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) {
|
void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) {
|
||||||
ERR_FAIL_INDEX(p_mode, 3); // Cannot use BILLBOARD_PARTICLES.
|
ERR_FAIL_INDEX(p_mode, 3); // Cannot use BILLBOARD_PARTICLES.
|
||||||
billboard_mode = p_mode;
|
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("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("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("set_billboard_mode", "mode"), &SpriteBase3D::set_billboard_mode);
|
||||||
ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpriteBase3D::get_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, "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, "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_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, "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, "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_DISABLED);
|
||||||
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
|
BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
|
||||||
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
|
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
|
||||||
|
BIND_ENUM_CONSTANT(ALPHA_CUT_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteBase3D::SpriteBase3D() {
|
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, "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_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, "uv2_scale", Vector3(1, 1, 1));
|
||||||
RS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.5);
|
|
||||||
|
|
||||||
mesh = RenderingServer::get_singleton()->mesh_create();
|
mesh = RenderingServer::get_singleton()->mesh_create();
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,9 @@ public:
|
||||||
enum AlphaCutMode {
|
enum AlphaCutMode {
|
||||||
ALPHA_CUT_DISABLED,
|
ALPHA_CUT_DISABLED,
|
||||||
ALPHA_CUT_DISCARD,
|
ALPHA_CUT_DISCARD,
|
||||||
ALPHA_CUT_OPAQUE_PREPASS
|
ALPHA_CUT_OPAQUE_PREPASS,
|
||||||
|
ALPHA_CUT_HASH,
|
||||||
|
ALPHA_CUT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -85,6 +87,8 @@ private:
|
||||||
|
|
||||||
bool flags[FLAG_MAX] = {};
|
bool flags[FLAG_MAX] = {};
|
||||||
AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
|
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::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
|
||||||
StandardMaterial3D::TextureFilter texture_filter = StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
|
StandardMaterial3D::TextureFilter texture_filter = StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
|
||||||
bool pending_update = false;
|
bool pending_update = false;
|
||||||
|
@ -143,6 +147,12 @@ public:
|
||||||
void set_alpha_cut_mode(AlphaCutMode p_mode);
|
void set_alpha_cut_mode(AlphaCutMode p_mode);
|
||||||
AlphaCutMode get_alpha_cut_mode() const;
|
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);
|
void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode);
|
||||||
StandardMaterial3D::BillboardMode get_billboard_mode() const;
|
StandardMaterial3D::BillboardMode get_billboard_mode() const;
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ bool RootMotionView::get_zero_y() const {
|
||||||
void RootMotionView::_notification(int p_what) {
|
void RootMotionView::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
immediate_material = StandardMaterial3D::get_material_for_2d(false, true, false, false, false);
|
immediate_material = StandardMaterial3D::get_material_for_2d(false, BaseMaterial3D::TRANSPARENCY_ALPHA, false);
|
||||||
|
|
||||||
first = true;
|
first = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -2316,52 +2316,30 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
|
||||||
return refraction_texture_channel;
|
return refraction_texture_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, RID *r_shader_rid) {
|
Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, RID *r_shader_rid) {
|
||||||
int64_t hash = 0;
|
uint64_t key = 0;
|
||||||
if (p_shaded) {
|
key |= ((int8_t)p_shaded & 0x01) << 0;
|
||||||
hash |= 1 << 0;
|
key |= ((int8_t)p_transparency & 0x07) << 1; // Bits 1-3.
|
||||||
}
|
key |= ((int8_t)p_double_sided & 0x01) << 4;
|
||||||
if (p_transparent) {
|
key |= ((int8_t)p_billboard & 0x01) << 5;
|
||||||
hash |= 1 << 1;
|
key |= ((int8_t)p_billboard_y & 0x01) << 6;
|
||||||
}
|
key |= ((int8_t)p_msdf & 0x01) << 7;
|
||||||
if (p_cut_alpha) {
|
key |= ((int8_t)p_no_depth & 0x01) << 8;
|
||||||
hash |= 1 << 2;
|
key |= ((int8_t)p_fixed_size & 0x01) << 9;
|
||||||
}
|
key |= ((int8_t)p_filter & 0x07) << 10; // Bits 10-13.
|
||||||
if (p_opaque_prepass) {
|
|
||||||
hash |= 1 << 3;
|
|
||||||
}
|
|
||||||
if (p_double_sided) {
|
|
||||||
hash |= 1 << 4;
|
|
||||||
}
|
|
||||||
if (p_billboard) {
|
|
||||||
hash |= 1 << 5;
|
|
||||||
}
|
|
||||||
if (p_billboard_y) {
|
|
||||||
hash |= 1 << 6;
|
|
||||||
}
|
|
||||||
if (p_msdf) {
|
|
||||||
hash |= 1 << 7;
|
|
||||||
}
|
|
||||||
if (p_no_depth) {
|
|
||||||
hash |= 1 << 8;
|
|
||||||
}
|
|
||||||
if (p_fixed_size) {
|
|
||||||
hash |= 1 << 9;
|
|
||||||
}
|
|
||||||
hash = hash_murmur3_one_64(p_filter, hash);
|
|
||||||
|
|
||||||
if (materials_for_2d.has(hash)) {
|
if (materials_for_2d.has(key)) {
|
||||||
if (r_shader_rid) {
|
if (r_shader_rid) {
|
||||||
*r_shader_rid = materials_for_2d[hash]->get_shader_rid();
|
*r_shader_rid = materials_for_2d[key]->get_shader_rid();
|
||||||
}
|
}
|
||||||
return materials_for_2d[hash];
|
return materials_for_2d[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<StandardMaterial3D> material;
|
Ref<StandardMaterial3D> material;
|
||||||
material.instantiate();
|
material.instantiate();
|
||||||
|
|
||||||
material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED);
|
material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED);
|
||||||
material->set_transparency(p_transparent ? (p_opaque_prepass ? TRANSPARENCY_ALPHA_DEPTH_PRE_PASS : (p_cut_alpha ? TRANSPARENCY_ALPHA_SCISSOR : TRANSPARENCY_ALPHA)) : TRANSPARENCY_DISABLED);
|
material->set_transparency(p_transparency);
|
||||||
material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK);
|
material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK);
|
||||||
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
|
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
|
||||||
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
|
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
|
||||||
|
@ -2374,13 +2352,13 @@ Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transpar
|
||||||
material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED);
|
material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
materials_for_2d[hash] = material;
|
materials_for_2d[key] = material;
|
||||||
|
|
||||||
if (r_shader_rid) {
|
if (r_shader_rid) {
|
||||||
*r_shader_rid = materials_for_2d[hash]->get_shader_rid();
|
*r_shader_rid = materials_for_2d[key]->get_shader_rid();
|
||||||
}
|
}
|
||||||
|
|
||||||
return materials_for_2d[hash];
|
return materials_for_2d[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseMaterial3D::set_on_top_of_alpha() {
|
void BaseMaterial3D::set_on_top_of_alpha() {
|
||||||
|
|
|
@ -760,7 +760,7 @@ public:
|
||||||
static void finish_shaders();
|
static void finish_shaders();
|
||||||
static void flush_changes();
|
static void flush_changes();
|
||||||
|
|
||||||
static Ref<Material> get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RID *r_shader_rid = nullptr);
|
static Ref<Material> get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RID *r_shader_rid = nullptr);
|
||||||
|
|
||||||
virtual RID get_shader_rid() const override;
|
virtual RID get_shader_rid() const override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue