Merge pull request #117088 from bruvzg/svg_alp

Add `fix_alpha_border` and `premult_alpha` to the `DPITexture` importer.
This commit is contained in:
Thaddeus Crews 2026-03-11 15:42:00 -05:00
commit 2073a2bbd6
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
6 changed files with 71 additions and 1 deletions

View file

@ -53,6 +53,14 @@
<member name="color_map" type="Dictionary" setter="set_color_map" getter="get_color_map" default="{}">
If set, remaps texture colors according to [Color]-[Color] map.
</member>
<member name="fix_alpha_border" type="bool" setter="set_fix_alpha_border" getter="get_fix_alpha_border" default="false">
If [code]true[/code], puts pixels of the same surrounding color in transition from transparent to opaque areas. For textures displayed with bilinear filtering, this helps to reduce the outline effect when exporting images from an image editor.
</member>
<member name="premult_alpha" type="bool" setter="set_premult_alpha" getter="get_premult_alpha" default="false">
An alternative to fixing darkened borders with [member fix_alpha_border] is to use premultiplied alpha. By enabling this option, the texture will be converted to this format. A premultiplied alpha texture requires specific materials to be displayed correctly:
- In 2D, a [CanvasItemMaterial] will need to be created and configured to use the [constant CanvasItemMaterial.BLEND_MODE_PREMULT_ALPHA] blend mode on [CanvasItem]s that use this texture. In custom [code]canvas_item[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
- In 3D, a [BaseMaterial3D] will need to be created and configured to use the [constant BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA] blend mode on materials that use this texture. In custom [code]spatial[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
</member>
<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
<member name="saturation" type="float" setter="set_saturation" getter="get_saturation" default="1.0">
Overrides texture saturation.

View file

@ -18,6 +18,14 @@
<member name="compress" type="bool" setter="" getter="" default="true">
If [code]true[/code], uses lossless compression for the SVG source.
</member>
<member name="fix_alpha_border" type="bool" setter="" getter="" default="false">
If [code]true[/code], puts pixels of the same surrounding color in transition from transparent to opaque areas. For textures displayed with bilinear filtering, this helps to reduce the outline effect when exporting images from an image editor.
</member>
<member name="premult_alpha" type="bool" setter="" getter="" default="false">
An alternative to fixing darkened borders with [member fix_alpha_border] is to use premultiplied alpha. By enabling this option, the texture will be converted to this format. A premultiplied alpha texture requires specific materials to be displayed correctly:
- In 2D, a [CanvasItemMaterial] will need to be created and configured to use the [constant CanvasItemMaterial.BLEND_MODE_PREMULT_ALPHA] blend mode on [CanvasItem]s that use this texture. In custom [code]canvas_item[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
- In 3D, a [BaseMaterial3D] will need to be created and configured to use the [constant BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA] blend mode on materials that use this texture. In custom [code]spatial[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
</member>
<member name="saturation" type="float" setter="" getter="" default="1.0">
Overrides texture saturation.
</member>

View file

@ -148,7 +148,7 @@
</member>
<member name="process/premult_alpha" type="bool" setter="" getter="" default="false">
An alternative to fixing darkened borders with [member process/fix_alpha_border] is to use premultiplied alpha. By enabling this option, the texture will be converted to this format. A premultiplied alpha texture requires specific materials to be displayed correctly:
- In 2D, a [CanvasItemMaterial] will need to be created and configured to use the [constant CanvasItemMaterial.BLEND_MODE_PREMULT_ALPHA] blend mode on [CanvasItem]s that use this texture. In custom [code]@canvas_item[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
- In 2D, a [CanvasItemMaterial] will need to be created and configured to use the [constant CanvasItemMaterial.BLEND_MODE_PREMULT_ALPHA] blend mode on [CanvasItem]s that use this texture. In custom [code]canvas_item[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
- In 3D, a [BaseMaterial3D] will need to be created and configured to use the [constant BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA] blend mode on materials that use this texture. In custom [code]spatial[/code] shaders, [code]render_mode blend_premul_alpha;[/code] should be used.
</member>
<member name="process/size_limit" type="int" setter="" getter="" default="0">

View file

@ -69,6 +69,8 @@ void ResourceImporterSVG::get_import_options(const String &p_path, List<ImportOp
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "base_scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "saturation", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), 1.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "color_map"), Dictionary()));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "fix_alpha_border"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "premult_alpha"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
}
@ -81,12 +83,16 @@ Error ResourceImporterSVG::import(ResourceUID::ID p_source_id, const String &p_s
double base_scale = p_options["base_scale"];
double saturation = p_options["saturation"];
bool fix_alpha_border = p_options["fix_alpha_border"];
bool premult_alpha = p_options["premult_alpha"];
Dictionary color_map = p_options["color_map"];
dpi_tex->set_base_scale(base_scale);
dpi_tex->set_saturation(saturation);
dpi_tex->set_color_map(color_map);
dpi_tex->set_source(source);
dpi_tex->set_fix_alpha_border(fix_alpha_border);
dpi_tex->set_premult_alpha(premult_alpha);
ERR_FAIL_COND_V_MSG(dpi_tex->get_rid().is_null(), ERR_CANT_OPEN, vformat("Failed loading SVG, unsupported or invalid SVG data in \"%s\".", p_source_file));

View file

@ -103,6 +103,30 @@ String DPITexture::get_source() const {
return source;
}
void DPITexture::set_fix_alpha_border(bool p_enabled) {
if (fix_alpha_border == p_enabled) {
return;
}
fix_alpha_border = p_enabled;
_update_texture();
}
bool DPITexture::get_fix_alpha_border() const {
return fix_alpha_border;
}
void DPITexture::set_premult_alpha(bool p_enabled) {
if (premult_alpha == p_enabled) {
return;
}
premult_alpha = p_enabled;
_update_texture();
}
bool DPITexture::get_premult_alpha() const {
return premult_alpha;
}
void DPITexture::set_base_scale(float p_scale) {
if (base_scale == p_scale) {
return;
@ -202,6 +226,16 @@ RID DPITexture::_load_at_scale(double p_scale, bool p_set_size) const {
img->adjust_bcs(1.0, 1.0, saturation);
}
// Fix alpha border.
if (fix_alpha_border) {
img->fix_alpha_edges();
}
// Premultiply the alpha.
if (premult_alpha) {
img->premultiply_alpha();
}
Size2 current_size = size;
if (p_set_size || size.is_zero_approx()) {
size.x = img->get_width() / p_scale;
@ -353,6 +387,10 @@ void DPITexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_source", "source"), &DPITexture::set_source);
ClassDB::bind_method(D_METHOD("get_source"), &DPITexture::get_source);
ClassDB::bind_method(D_METHOD("set_fix_alpha_border", "fix_alpha_border"), &DPITexture::set_fix_alpha_border);
ClassDB::bind_method(D_METHOD("get_fix_alpha_border"), &DPITexture::get_fix_alpha_border);
ClassDB::bind_method(D_METHOD("set_premult_alpha", "premult_alpha"), &DPITexture::set_premult_alpha);
ClassDB::bind_method(D_METHOD("get_premult_alpha"), &DPITexture::get_premult_alpha);
ClassDB::bind_method(D_METHOD("set_base_scale", "base_scale"), &DPITexture::set_base_scale);
ClassDB::bind_method(D_METHOD("get_base_scale"), &DPITexture::get_base_scale);
ClassDB::bind_method(D_METHOD("set_saturation", "saturation"), &DPITexture::set_saturation);
@ -363,6 +401,8 @@ void DPITexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scaled_rid"), &DPITexture::get_scaled_rid);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "_source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_STORAGE), "set_source", "get_source");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fix_alpha_border", PROPERTY_HINT_NONE, ""), "set_fix_alpha_border", "get_fix_alpha_border");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "premult_alpha", PROPERTY_HINT_NONE, ""), "set_premult_alpha", "get_premult_alpha");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "base_scale", PROPERTY_HINT_RANGE, "0.01,10.0,0.01"), "set_base_scale", "get_base_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "saturation", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_saturation", "get_saturation");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "color_map", PROPERTY_HINT_DICTIONARY_TYPE, "Color;Color"), "set_color_map", "get_color_map");

View file

@ -43,6 +43,8 @@ class DPITexture : public Texture2D {
float saturation = 1.0;
Dictionary color_map;
Size2 size_override;
bool fix_alpha_border = false;
bool premult_alpha = false;
struct ScalingLevel {
HashSet<DPITexture *> textures;
@ -73,6 +75,12 @@ public:
void set_source(const String &p_source);
String get_source() const;
void set_fix_alpha_border(bool p_enabled);
bool get_fix_alpha_border() const;
void set_premult_alpha(bool p_enabled);
bool get_premult_alpha() const;
void set_base_scale(float p_scale);
float get_base_scale() const;