Skip to content

Commit f3eda36

Browse files
committed
BasisU: Use KTX2 format and add import options to configure encoder
1 parent 33b3c20 commit f3eda36

14 files changed

+217
-62
lines changed

core/io/image.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void (*Image::_image_decompress_astc)(Image *) = nullptr;
132132
Vector<uint8_t> (*Image::webp_lossy_packer)(const Ref<Image> &, float) = nullptr;
133133
Vector<uint8_t> (*Image::webp_lossless_packer)(const Ref<Image> &) = nullptr;
134134
Vector<uint8_t> (*Image::png_packer)(const Ref<Image> &) = nullptr;
135-
Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = nullptr;
135+
Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &p_image, Image::UsedChannels p_channels, const BasisUniversalPackerParams &p_basisu_params) = nullptr;
136136

137137
Ref<Image> (*Image::webp_unpacker)(const Vector<uint8_t> &) = nullptr;
138138
Ref<Image> (*Image::png_unpacker)(const Vector<uint8_t> &) = nullptr;

core/io/image.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,15 @@ class Image : public Resource {
182182
ALPHA_BLEND
183183
};
184184

185+
struct BasisUniversalPackerParams {
186+
int uastc_pack_level = 0;
187+
bool rdo_enabled = false;
188+
float rdo_quality_loss = 1;
189+
int rdo_dict_size = 1024;
190+
bool zstd_supercompression = true;
191+
int zstd_supercompression_level = 6;
192+
};
193+
185194
// External saver function pointers.
186195

187196
static SavePNGFunc save_png_func;
@@ -231,7 +240,7 @@ class Image : public Resource {
231240
static Vector<uint8_t> (*webp_lossy_packer)(const Ref<Image> &p_image, float p_quality);
232241
static Vector<uint8_t> (*webp_lossless_packer)(const Ref<Image> &p_image);
233242
static Vector<uint8_t> (*png_packer)(const Ref<Image> &p_image);
234-
static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels);
243+
static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, Image::UsedChannels p_channels, const BasisUniversalPackerParams &p_basisu_params);
235244

236245
static Ref<Image> (*webp_unpacker)(const Vector<uint8_t> &p_buffer);
237246
static Ref<Image> (*png_unpacker)(const Vector<uint8_t> &p_buffer);

doc/classes/PortableCompressedTexture2D.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@
4343
Return whether the flag is overridden for all textures of this type.
4444
</description>
4545
</method>
46+
<method name="set_basisu_compressor_params">
47+
<return type="void" />
48+
<param index="0" name="uastc_pack_level" type="int" />
49+
<param index="1" name="rdo_enabled" type="bool" />
50+
<param index="2" name="rdo_quality_loss" type="float" />
51+
<param index="3" name="rdo_dict_size" type="int" />
52+
<param index="4" name="zstd_supercompression" type="bool" />
53+
<param index="5" name="zstd_supercompression_level" type="int" />
54+
<description>
55+
Set compressor params for Basis Universal compression. See also the settings in [ResourceImporterTexture].
56+
Note: This must be set before [method create_from_image] to take effect.
57+
</description>
58+
</method>
4659
<method name="set_keep_all_compressed_buffers" qualifiers="static">
4760
<return type="void" />
4861
<param index="0" name="keep" type="bool" />
@@ -55,6 +68,7 @@
5568
<member name="keep_compressed_buffer" type="bool" setter="set_keep_compressed_buffer" getter="is_keeping_compressed_buffer" default="false">
5669
When running on the editor, this class will keep the source compressed data in memory. Otherwise, the source compressed data is lost after loading and the resource can't be re saved.
5770
This flag allows to keep the compressed data in memory if you intend it to persist after loading.
71+
Note: This must be set before [method create_from_image] to take effect.
5872
</member>
5973
<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
6074
<member name="size_override" type="Vector2" setter="set_size_override" getter="get_size_override" default="Vector2(0, 0)">

doc/classes/ResourceImporterLayeredTexture.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@
1010
<link title="Importing images">$DOCS_URL/tutorials/assets_pipeline/importing_images.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="basis_universal/rdo_dict_size" type="int" setter="" getter="" default="1024">
14+
Specify the RDO dict size, ranges from 64 to 65536. Higher values increase memory consumption and reduce encoding speed, but give more compression.
15+
</member>
16+
<member name="basis_universal/rdo_enabled" type="bool" setter="" getter="" default="false">
17+
If [code]true[/code], enables Rate-Distortion Optimization (RDO) to reduce disk size.
18+
</member>
19+
<member name="basis_universal/rdo_quality_loss" type="float" setter="" getter="" default="1.0">
20+
Specify the RDO quality loss, ranges from 0.001 to 50.0. Higher value result in smaller file size but lower quality. Good range to try is from 0.25 to 10.0.
21+
</member>
22+
<member name="basis_universal/uastc_pack_level" type="int" setter="" getter="" default="0">
23+
Sets the UASTC compressor's level, ranges from 0 to 4. Slower encoding speed improves quality.
24+
</member>
25+
<member name="basis_universal/zstd_supercompression" type="bool" setter="" getter="" default="true">
26+
If [code]true[/code], enables Zstandard supercompression to reduce disk size.
27+
</member>
28+
<member name="basis_universal/zstd_supercompression_level" type="int" setter="" getter="" default="6">
29+
Specify the compression level for Zstandard supercompression.
30+
</member>
1331
<member name="compress/channel_pack" type="int" setter="" getter="" default="0">
1432
Controls how color channels should be used in the imported texture.
1533
[b]sRGB Friendly:[/b], prevents the RG color format from being used, as it does not support sRGB color.

doc/classes/ResourceImporterTexture.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@
1010
<link title="Importing images">$DOCS_URL/tutorials/assets_pipeline/importing_images.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="basis_universal/rdo_dict_size" type="int" setter="" getter="" default="1024">
14+
Specify the RDO dict size, ranges from 64 to 65536. Higher values increase memory consumption and reduce encoding speed, but give more compression.
15+
</member>
16+
<member name="basis_universal/rdo_enabled" type="bool" setter="" getter="" default="false">
17+
If [code]true[/code], enables Rate-Distortion Optimization (RDO) to reduce disk size.
18+
</member>
19+
<member name="basis_universal/rdo_quality_loss" type="float" setter="" getter="" default="1.0">
20+
Specify the RDO quality loss, ranges from 0.001 to 50.0. Higher value result in smaller file size but lower quality. Good range to try is from 0.25 to 10.0.
21+
</member>
22+
<member name="basis_universal/uastc_pack_level" type="int" setter="" getter="" default="0">
23+
Sets the UASTC compressor's level, ranges from 0 to 4. Slower encoding speed improves quality.
24+
</member>
25+
<member name="basis_universal/zstd_supercompression" type="bool" setter="" getter="" default="true">
26+
If [code]true[/code], enables Zstandard supercompression to reduce disk size.
27+
</member>
28+
<member name="basis_universal/zstd_supercompression_level" type="int" setter="" getter="" default="6">
29+
Specify the compression level for Zstandard supercompression.
30+
</member>
1331
<member name="compress/channel_pack" type="int" setter="" getter="" default="0">
1432
Controls how color channels should be used in the imported texture.
1533
[b]sRGB Friendly:[/b] Prevents the RG color format from being used, as it does not support sRGB color.

editor/import/resource_importer_layered_texture.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,16 @@ void ResourceImporterLayeredTexture::get_import_options(const String &p_path, Li
156156
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1));
157157
}
158158
}
159+
160+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "basis_universal/uastc_pack_level", PROPERTY_HINT_ENUM, "Fastest,Faster,Medium,Slower,Slowest"), 0));
161+
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "basis_universal/rdo_enabled"), false));
162+
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "basis_universal/rdo_quality_loss", PROPERTY_HINT_RANGE, "0.001,50,0.001"), 1.0));
163+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "basis_universal/rdo_dict_size", PROPERTY_HINT_RANGE, "64,65536,1"), 1024));
164+
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "basis_universal/zstd_supercompression"), true));
165+
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "basis_universal/zstd_supercompression_level"), 6));
159166
}
160167

161-
void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) {
168+
void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, const Image::BasisUniversalPackerParams &p_basisu_params, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) {
162169
Vector<Ref<Image>> mipmap_images; //for 3D
163170

164171
if (mode == MODE_3D) {
@@ -278,11 +285,11 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons
278285
}
279286

280287
for (int i = 0; i < p_images.size(); i++) {
281-
ResourceImporterTexture::save_to_ctex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy);
288+
ResourceImporterTexture::save_to_ctex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy, p_basisu_params);
282289
}
283290

284291
for (int i = 0; i < mipmap_images.size(); i++) {
285-
ResourceImporterTexture::save_to_ctex_format(f, mipmap_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy);
292+
ResourceImporterTexture::save_to_ctex_format(f, mipmap_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy, p_basisu_params);
286293
}
287294
}
288295

@@ -300,6 +307,15 @@ Error ResourceImporterLayeredTexture::import(ResourceUID::ID p_source_id, const
300307
int layout = (p_options.has("slices/layout")) ? int(p_options["slices/layout"]) : 0;
301308
int amount = (p_options.has("slices/amount")) ? int(p_options["slices/amount"]) : 0;
302309

310+
const Image::BasisUniversalPackerParams basisu_params{
311+
.uastc_pack_level = p_options["basis_universal/uastc_pack_level"],
312+
.rdo_enabled = p_options["basis_universal/rdo_enabled"],
313+
.rdo_quality_loss = p_options["basis_universal/rdo_quality_loss"],
314+
.rdo_dict_size = p_options["basis_universal/rdo_dict_size"],
315+
.zstd_supercompression = p_options["basis_universal/zstd_supercompression"],
316+
.zstd_supercompression_level = p_options["basis_universal/zstd_supercompression_level"],
317+
};
318+
303319
if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) {
304320
switch (arrangement) {
305321
case CUBEMAP_FORMAT_1X6: {
@@ -392,6 +408,8 @@ Error ResourceImporterLayeredTexture::import(ResourceUID::ID p_source_id, const
392408
texture_import->used_channels = used_channels;
393409
texture_import->high_quality = high_quality;
394410

411+
texture_import->basisu_params = basisu_params;
412+
395413
_check_compress_ctex(p_source_file, texture_import);
396414
if (r_metadata) {
397415
Dictionary meta;
@@ -486,7 +504,8 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source
486504
ERR_FAIL_NULL(r_texture_import->csource);
487505
if (r_texture_import->compress_mode != COMPRESS_VRAM_COMPRESSED) {
488506
// Import normally.
489-
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
507+
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params,
508+
Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
490509
return;
491510
}
492511
// Must import in all formats, in order of priority (so platform chooses the best supported one. IE, etc2 over etc).
@@ -541,7 +560,8 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source
541560
}
542561

543562
if (use_uncompressed) {
544-
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, COMPRESS_VRAM_UNCOMPRESSED, r_texture_import->lossy, Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
563+
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, COMPRESS_VRAM_UNCOMPRESSED, r_texture_import->lossy, r_texture_import->basisu_params,
564+
Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
545565
} else {
546566
if (can_s3tc_bptc) {
547567
Image::CompressMode image_compress_mode;
@@ -553,7 +573,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source
553573
image_compress_mode = Image::COMPRESS_S3TC;
554574
image_compress_format = "s3tc";
555575
}
556-
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
576+
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
557577
r_texture_import->platform_variants->push_back(image_compress_format);
558578
}
559579

@@ -567,7 +587,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source
567587
image_compress_mode = Image::COMPRESS_ETC2;
568588
image_compress_format = "etc2";
569589
}
570-
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
590+
_save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, r_texture_import->basisu_params, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
571591
r_texture_import->platform_variants->push_back(image_compress_format);
572592
}
573593
}

editor/import/resource_importer_layered_texture.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class LayeredTextureImport : public RefCounted {
4949
Vector<Ref<Image>> *slices = nullptr;
5050
int compress_mode = 0;
5151
float lossy = 1.0;
52+
53+
Image::BasisUniversalPackerParams basisu_params;
54+
5255
int hdr_compression = 0;
5356
bool mipmaps = true;
5457
bool high_quality = false;
@@ -108,7 +111,7 @@ class ResourceImporterLayeredTexture : public ResourceImporter {
108111
virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
109112
virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override;
110113

111-
void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2);
114+
void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, const Image::BasisUniversalPackerParams &p_basisu_params, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2);
112115

113116
virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
114117

0 commit comments

Comments
 (0)