Skip to content

Commit 93140c0

Browse files
committed
Merge pull request godotengine#99676 from BlueCube3310/tex-import-vram-specified
Add Channel Remap settings to ResourceImporterTexture
2 parents 7d9c75d + 1b51017 commit 93140c0

File tree

3 files changed

+184
-1
lines changed

3 files changed

+184
-1
lines changed

doc/classes/ResourceImporterTexture.xml

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,62 @@
7373
<member name="mipmaps/limit" type="int" setter="" getter="" default="-1">
7474
Unimplemented. This currently has no effect when changed.
7575
</member>
76+
<member name="process/channel_remap/alpha" type="int" setter="" getter="" default="3">
77+
Specifies the data source of the output image's alpha channel.
78+
[b]Red:[/b] Use the values from the source image's red channel.
79+
[b]Green:[/b] Use the values from the source image's green channel.
80+
[b]Blue:[/b] Use the values from the source image's blue channel.
81+
[b]Alpha:[/b] Use the values from the source image's alpha channel.
82+
[b]Red Inverted:[/b] Use inverted values from the source image's red channel ([code]1.0 - R[/code]).
83+
[b]Green Inverted:[/b] Use inverted values from the source image's green channel ([code]1.0 - G[/code]).
84+
[b]Blue Inverted:[/b] Use inverted values from the source image's blue channel ([code]1.0 - B[/code]).
85+
[b]Alpha Inverted:[/b] Use inverted values from the source image's alpha channel ([code]1.0 - A[/code]).
86+
[b]Unused:[/b] Set the color channel's value to the default ([code]1.0[/code] for alpha, [code]0.0[/code] for red, green or blue).
87+
[b]Zero:[/b] Set the color channel's value to [code]0.0[/code].
88+
[b]One:[/b] Set the color channel's value to [code]1.0[/code].
89+
</member>
90+
<member name="process/channel_remap/blue" type="int" setter="" getter="" default="2">
91+
Specifies the data source of the output image's blue channel.
92+
[b]Red:[/b] Use the values from the source image's red channel.
93+
[b]Green:[/b] Use the values from the source image's green channel.
94+
[b]Blue:[/b] Use the values from the source image's blue channel.
95+
[b]Alpha:[/b] Use the values from the source image's alpha channel.
96+
[b]Red Inverted:[/b] Use inverted values from the source image's red channel ([code]1.0 - R[/code]).
97+
[b]Green Inverted:[/b] Use inverted values from the source image's green channel ([code]1.0 - G[/code]).
98+
[b]Blue Inverted:[/b] Use inverted values from the source image's blue channel ([code]1.0 - B[/code]).
99+
[b]Alpha Inverted:[/b] Use inverted values from the source image's alpha channel ([code]1.0 - A[/code]).
100+
[b]Unused:[/b] Set the color channel's value to the default ([code]1.0[/code] for alpha, [code]0.0[/code] for red, green or blue).
101+
[b]Zero:[/b] Set the color channel's value to [code]0.0[/code].
102+
[b]One:[/b] Set the color channel's value to [code]1.0[/code].
103+
</member>
104+
<member name="process/channel_remap/green" type="int" setter="" getter="" default="1">
105+
Specifies the data source of the output image's green channel.
106+
[b]Red:[/b] Use the values from the source image's red channel.
107+
[b]Green:[/b] Use the values from the source image's green channel.
108+
[b]Blue:[/b] Use the values from the source image's blue channel.
109+
[b]Alpha:[/b] Use the values from the source image's alpha channel.
110+
[b]Red Inverted:[/b] Use inverted values from the source image's red channel ([code]1.0 - R[/code]).
111+
[b]Green Inverted:[/b] Use inverted values from the source image's green channel ([code]1.0 - G[/code]).
112+
[b]Blue Inverted:[/b] Use inverted values from the source image's blue channel ([code]1.0 - B[/code]).
113+
[b]Alpha Inverted:[/b] Use inverted values from the source image's alpha channel ([code]1.0 - A[/code]).
114+
[b]Unused:[/b] Set the color channel's value to the default ([code]1.0[/code] for alpha, [code]0.0[/code] for red, green or blue).
115+
[b]Zero:[/b] Set the color channel's value to [code]0.0[/code].
116+
[b]One:[/b] Set the color channel's value to [code]1.0[/code].
117+
</member>
118+
<member name="process/channel_remap/red" type="int" setter="" getter="" default="0">
119+
Specifies the data source of the output image's red channel.
120+
[b]Red:[/b] Use the values from the source image's red channel.
121+
[b]Green:[/b] Use the values from the source image's green channel.
122+
[b]Blue:[/b] Use the values from the source image's blue channel.
123+
[b]Alpha:[/b] Use the values from the source image's alpha channel.
124+
[b]Red Inverted:[/b] Use inverted values from the source image's red channel ([code]1.0 - R[/code]).
125+
[b]Green Inverted:[/b] Use inverted values from the source image's green channel ([code]1.0 - G[/code]).
126+
[b]Blue Inverted:[/b] Use inverted values from the source image's blue channel ([code]1.0 - B[/code]).
127+
[b]Alpha Inverted:[/b] Use inverted values from the source image's alpha channel ([code]1.0 - A[/code]).
128+
[b]Unused:[/b] Set the color channel's value to the default ([code]1.0[/code] for alpha, [code]0.0[/code] for red, green or blue).
129+
[b]Zero:[/b] Set the color channel's value to [code]0.0[/code].
130+
[b]One:[/b] Set the color channel's value to [code]1.0[/code].
131+
</member>
76132
<member name="process/fix_alpha_border" type="bool" setter="" getter="" default="true">
77133
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.
78134
It's recommended to leave this enabled (as it is by default), unless this causes issues for a particular image.
@@ -86,7 +142,7 @@
86142
Some HDR panorama images you can find online may contain extremely bright pixels, due to being taken from real life sources without any clipping.
87143
While these HDR panorama images are accurate to real life, this can cause the radiance map generated by Godot to contain sparkles when used as a background sky. This can be seen in material reflections (even on rough materials in extreme cases). Enabling [member process/hdr_clamp_exposure] can resolve this.
88144
</member>
89-
<member name="process/normal_map_invert_y" type="bool" setter="" getter="" default="false">
145+
<member name="process/normal_map_invert_y" type="bool" setter="" getter="" default="false" deprecated="The same result can be achieved by setting [member process/channel_remap/green] to [code]Green Inverted[/code].">
90146
If [code]true[/code], convert the normal map from Y- (DirectX-style) to Y+ (OpenGL-style) by inverting its green color channel. This is the normal map convention expected by Godot.
91147
More information about normal maps (including a coordinate order table for popular engines) can be found [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details]here[/url].
92148
</member>

editor/import/resource_importer_texture.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo
245245
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
246246
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "roughness/mode", PROPERTY_HINT_ENUM, "Detect,Disabled,Red,Green,Blue,Alpha,Gray"), 0));
247247
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.tga,*.webp"), ""));
248+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/channel_remap/red", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Inverted Red,Inverted Green,Inverted Blue,Inverted Alpha,Unused,Zero,One"), 0));
249+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/channel_remap/green", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Inverted Red,Inverted Green,Inverted Blue,Inverted Alpha,Unused,Zero,One"), 1));
250+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/channel_remap/blue", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Inverted Red,Inverted Green,Inverted Blue,Inverted Alpha,Unused,Zero,One"), 2));
251+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/channel_remap/alpha", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Inverted Red,Inverted Green,Inverted Blue,Inverted Alpha,Unused,Zero,One"), 3));
248252
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D));
249253
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
250254
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false));
@@ -443,6 +447,99 @@ Dictionary ResourceImporterTexture::_load_editor_meta(const String &p_path) cons
443447
return f->get_var();
444448
}
445449

450+
void ResourceImporterTexture::_remap_channels(Ref<Image> &r_image, ChannelRemap p_options[4]) {
451+
bool attempted_hdr_inverted = false;
452+
453+
if (r_image->get_format() >= Image::FORMAT_RF && r_image->get_format() <= Image::FORMAT_RGBE9995) {
454+
// Formats which can hold HDR data cannot be inverted the same way as unsigned normalized ones (1.0 - channel).
455+
for (int i = 0; i < 4; i++) {
456+
switch (p_options[i]) {
457+
case REMAP_INV_R:
458+
attempted_hdr_inverted = true;
459+
p_options[i] = REMAP_R;
460+
break;
461+
case REMAP_INV_G:
462+
attempted_hdr_inverted = true;
463+
p_options[i] = REMAP_G;
464+
break;
465+
case REMAP_INV_B:
466+
attempted_hdr_inverted = true;
467+
p_options[i] = REMAP_B;
468+
break;
469+
case REMAP_INV_A:
470+
attempted_hdr_inverted = true;
471+
p_options[i] = REMAP_A;
472+
break;
473+
default:
474+
break;
475+
}
476+
}
477+
}
478+
479+
if (attempted_hdr_inverted) {
480+
WARN_PRINT("Attempted to use an inverted channel remap on an HDR image. The remap has been changed to its uninverted equivalent.");
481+
}
482+
483+
if (p_options[0] == REMAP_R && p_options[1] == REMAP_G && p_options[2] == REMAP_B && p_options[3] == REMAP_A) {
484+
// Default color map, do nothing.
485+
return;
486+
}
487+
488+
for (int x = 0; x < r_image->get_width(); x++) {
489+
for (int y = 0; y < r_image->get_height(); y++) {
490+
Color src = r_image->get_pixel(x, y);
491+
Color dst;
492+
493+
for (int i = 0; i < 4; i++) {
494+
switch (p_options[i]) {
495+
case REMAP_R:
496+
dst[i] = src.r;
497+
break;
498+
case REMAP_G:
499+
dst[i] = src.g;
500+
break;
501+
case REMAP_B:
502+
dst[i] = src.b;
503+
break;
504+
case REMAP_A:
505+
dst[i] = src.a;
506+
break;
507+
508+
case REMAP_INV_R:
509+
dst[i] = 1.0f - src.r;
510+
break;
511+
case REMAP_INV_G:
512+
dst[i] = 1.0f - src.g;
513+
break;
514+
case REMAP_INV_B:
515+
dst[i] = 1.0f - src.b;
516+
break;
517+
case REMAP_INV_A:
518+
dst[i] = 1.0f - src.a;
519+
break;
520+
521+
case REMAP_UNUSED:
522+
// For Alpha the unused value is 1, for other channels it's 0.
523+
dst[i] = (i == 3) ? 1.0f : 0.0f;
524+
break;
525+
526+
case REMAP_0:
527+
dst[i] = 0.0f;
528+
break;
529+
case REMAP_1:
530+
dst[i] = 1.0f;
531+
break;
532+
533+
default:
534+
break;
535+
}
536+
}
537+
538+
r_image->set_pixel(x, y, dst);
539+
}
540+
}
541+
}
542+
446543
void ResourceImporterTexture::_invert_y_channel(Ref<Image> &r_image) {
447544
// Inverting the green channel can be used to flip a normal map's direction.
448545
// There's no standard when it comes to normal map Y direction, so this is
@@ -508,6 +605,10 @@ Error ResourceImporterTexture::import(ResourceUID::ID p_source_id, const String
508605
const String normal_map = p_options["roughness/src_normal"];
509606

510607
// Processing.
608+
const int remap_r = p_options["process/channel_remap/red"];
609+
const int remap_g = p_options["process/channel_remap/green"];
610+
const int remap_b = p_options["process/channel_remap/blue"];
611+
const int remap_a = p_options["process/channel_remap/alpha"];
511612
const bool fix_alpha_border = p_options["process/fix_alpha_border"];
512613
const bool premult_alpha = p_options["process/premult_alpha"];
513614
const bool normal_map_invert_y = p_options["process/normal_map_invert_y"];
@@ -628,6 +729,17 @@ Error ResourceImporterTexture::import(ResourceUID::ID p_source_id, const String
628729
}
629730
}
630731

732+
{
733+
ChannelRemap remaps[4] = {
734+
(ChannelRemap)remap_r,
735+
(ChannelRemap)remap_g,
736+
(ChannelRemap)remap_b,
737+
(ChannelRemap)remap_a,
738+
};
739+
740+
_remap_channels(target_image, remaps);
741+
}
742+
631743
// Fix alpha border.
632744
if (fix_alpha_border) {
633745
target_image->fix_alpha_edges();

editor/import/resource_importer_texture.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ class ResourceImporterTexture : public ResourceImporter {
4949
COMPRESS_BASIS_UNIVERSAL
5050
};
5151

52+
enum ChannelRemap {
53+
REMAP_R,
54+
REMAP_G,
55+
REMAP_B,
56+
REMAP_A,
57+
REMAP_INV_R,
58+
REMAP_INV_G,
59+
REMAP_INV_B,
60+
REMAP_INV_A,
61+
REMAP_UNUSED,
62+
REMAP_0,
63+
REMAP_1,
64+
};
65+
5266
protected:
5367
enum {
5468
MAKE_3D_FLAG = 1,
@@ -76,6 +90,7 @@ class ResourceImporterTexture : public ResourceImporter {
7690
void _save_editor_meta(const Dictionary &p_metadata, const String &p_to_path);
7791
Dictionary _load_editor_meta(const String &p_to_path) const;
7892

93+
static inline void _remap_channels(Ref<Image> &r_image, ChannelRemap p_options[4]);
7994
static inline void _clamp_hdr_exposure(Ref<Image> &r_image);
8095
static inline void _invert_y_channel(Ref<Image> &r_image);
8196

0 commit comments

Comments
 (0)