Overhaul WebP packer and split compression options
This commit is contained in:
parent
6a9317c9fc
commit
da132f3266
|
@ -21,7 +21,7 @@
|
||||||
<param index="3" name="lossy_quality" type="float" default="0.8" />
|
<param index="3" name="lossy_quality" type="float" default="0.8" />
|
||||||
<description>
|
<description>
|
||||||
Initializes the compressed texture from a base image. The compression mode must be provided.
|
Initializes the compressed texture from a base image. The compression mode must be provided.
|
||||||
If this image will be used as a normal map, the "normal map" flag is recommended, to ensure optimum quality.
|
[param normal_map] is recommended to ensure optimum quality if this image will be used as a normal map.
|
||||||
If lossy compression is requested, the quality setting can optionally be provided. This maps to Lossy WebP compression quality.
|
If lossy compression is requested, the quality setting can optionally be provided. This maps to Lossy WebP compression quality.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
|
|
@ -2215,9 +2215,6 @@
|
||||||
<member name="rendering/textures/lossless_compression/force_png" type="bool" setter="" getter="" default="false">
|
<member name="rendering/textures/lossless_compression/force_png" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], the texture importer will import lossless textures using the PNG format. Otherwise, it will default to using WebP.
|
If [code]true[/code], the texture importer will import lossless textures using the PNG format. Otherwise, it will default to using WebP.
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/textures/lossless_compression/webp_compression_level" type="int" setter="" getter="" default="2">
|
|
||||||
The default compression level for lossless WebP. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. Supported values are 0 to 9. Note that compression levels above 6 are very slow and offer very little savings.
|
|
||||||
</member>
|
|
||||||
<member name="rendering/textures/vram_compression/import_bptc" type="bool" setter="" getter="" default="false">
|
<member name="rendering/textures/vram_compression/import_bptc" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer.
|
If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer.
|
||||||
[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]).
|
[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]).
|
||||||
|
@ -2234,6 +2231,12 @@
|
||||||
If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles.
|
If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles.
|
||||||
[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]).
|
[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]).
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/textures/webp_compression/compression_method" type="int" setter="" getter="" default="2">
|
||||||
|
The default compression method for WebP. Affects both lossy and lossless WebP. A higher value results in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression method. Supported values are 0 to 6. Note that compression methods above 4 are very slow and offer very little savings.
|
||||||
|
</member>
|
||||||
|
<member name="rendering/textures/webp_compression/lossless_compression_factor" type="float" setter="" getter="" default="25">
|
||||||
|
The default compression factor for lossless WebP. Decompression speed is mostly unaffected by the compression factor. Supported values are 0 to 100.
|
||||||
|
</member>
|
||||||
<member name="rendering/transparent_background" type="bool" setter="" getter="" default="false">
|
<member name="rendering/transparent_background" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], enables [member Viewport.transparent_bg] on the root viewport. This allows per-pixel transparency to be effective after also enabling [member display/window/size/transparent] and [member display/window/per_pixel_transparency/allowed].
|
If [code]true[/code], enables [member Viewport.transparent_bg] on the root viewport. This allows per-pixel transparency to be effective after also enabling [member display/window/size/transparent] and [member display/window/per_pixel_transparency/allowed].
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -41,40 +41,21 @@ namespace WebPCommon {
|
||||||
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
|
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
|
||||||
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
|
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
|
||||||
|
|
||||||
Ref<Image> img = p_image->duplicate();
|
return _webp_packer(p_image, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), false);
|
||||||
if (img->detect_alpha()) {
|
|
||||||
img->convert(Image::FORMAT_RGBA8);
|
|
||||||
} else {
|
|
||||||
img->convert(Image::FORMAT_RGB8);
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2 s(img->get_width(), img->get_height());
|
|
||||||
Vector<uint8_t> data = img->get_data();
|
|
||||||
const uint8_t *r = data.ptr();
|
|
||||||
|
|
||||||
uint8_t *dst_buff = nullptr;
|
|
||||||
size_t dst_size = 0;
|
|
||||||
if (img->get_format() == Image::FORMAT_RGB8) {
|
|
||||||
dst_size = WebPEncodeRGB(r, s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff);
|
|
||||||
} else {
|
|
||||||
dst_size = WebPEncodeRGBA(r, s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(dst_size == 0, Vector<uint8_t>());
|
|
||||||
Vector<uint8_t> dst;
|
|
||||||
dst.resize(dst_size);
|
|
||||||
uint8_t *w = dst.ptrw();
|
|
||||||
memcpy(w, dst_buff, dst_size);
|
|
||||||
WebPFree(dst_buff);
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) {
|
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) {
|
||||||
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
|
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
|
||||||
|
|
||||||
int compression_level = GLOBAL_GET("rendering/textures/lossless_compression/webp_compression_level");
|
float compression_factor = GLOBAL_GET("rendering/textures/webp_compression/lossless_compression_factor");
|
||||||
compression_level = CLAMP(compression_level, 0, 9);
|
compression_factor = CLAMP(compression_factor, 0.0f, 100.0f);
|
||||||
|
|
||||||
|
return _webp_packer(p_image, compression_factor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless) {
|
||||||
|
int compression_method = GLOBAL_GET("rendering/textures/webp_compression/compression_method");
|
||||||
|
compression_method = CLAMP(compression_method, 0, 6);
|
||||||
|
|
||||||
Ref<Image> img = p_image->duplicate();
|
Ref<Image> img = p_image->duplicate();
|
||||||
if (img->detect_alpha()) {
|
if (img->detect_alpha()) {
|
||||||
|
@ -87,16 +68,21 @@ Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) {
|
||||||
Vector<uint8_t> data = img->get_data();
|
Vector<uint8_t> data = img->get_data();
|
||||||
const uint8_t *r = data.ptr();
|
const uint8_t *r = data.ptr();
|
||||||
|
|
||||||
// we need to use the more complex API in order to access the 'exact' flag...
|
// we need to use the more complex API in order to access specific flags...
|
||||||
|
|
||||||
WebPConfig config;
|
WebPConfig config;
|
||||||
WebPPicture pic;
|
WebPPicture pic;
|
||||||
if (!WebPConfigInit(&config) || !WebPConfigLosslessPreset(&config, compression_level) || !WebPPictureInit(&pic)) {
|
if (!WebPConfigInit(&config) || !WebPPictureInit(&pic)) {
|
||||||
ERR_FAIL_V(Vector<uint8_t>());
|
ERR_FAIL_V(Vector<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPMemoryWriter wrt;
|
WebPMemoryWriter wrt;
|
||||||
config.exact = 1;
|
if (p_lossless) {
|
||||||
|
config.lossless = 1;
|
||||||
|
config.exact = 1;
|
||||||
|
}
|
||||||
|
config.method = compression_method;
|
||||||
|
config.quality = p_quality;
|
||||||
pic.use_argb = 1;
|
pic.use_argb = 1;
|
||||||
pic.width = s.width;
|
pic.width = s.width;
|
||||||
pic.height = s.height;
|
pic.height = s.height;
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace WebPCommon {
|
||||||
// Given an image, pack this data into a WebP file.
|
// Given an image, pack this data into a WebP file.
|
||||||
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality);
|
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality);
|
||||||
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image);
|
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image);
|
||||||
|
// Helper function for those above.
|
||||||
|
Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless);
|
||||||
// Given a WebP file, unpack it into an image.
|
// Given a WebP file, unpack it into an image.
|
||||||
Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer);
|
Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer);
|
||||||
Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len);
|
Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len);
|
||||||
|
|
|
@ -64,6 +64,7 @@ bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
|
||||||
GDVIRTUAL_CALL(_is_pixel_opaque, p_x, p_y, ret);
|
GDVIRTUAL_CALL(_is_pixel_opaque, p_x, p_y, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture2D::has_alpha() const {
|
bool Texture2D::has_alpha() const {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
GDVIRTUAL_CALL(_has_alpha, ret);
|
GDVIRTUAL_CALL(_has_alpha, ret);
|
||||||
|
|
|
@ -2847,8 +2847,12 @@ void RenderingServer::init() {
|
||||||
GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2", true);
|
GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2", true);
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/textures/lossless_compression/force_png", false);
|
GLOBAL_DEF("rendering/textures/lossless_compression/force_png", false);
|
||||||
GLOBAL_DEF("rendering/textures/lossless_compression/webp_compression_level", 2);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/lossless_compression/webp_compression_level", PropertyInfo(Variant::INT, "rendering/textures/lossless_compression/webp_compression_level", PROPERTY_HINT_RANGE, "0,9,1"));
|
GLOBAL_DEF("rendering/textures/webp_compression/compression_method", 2);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/webp_compression/compression_method", PropertyInfo(Variant::INT, "rendering/textures/webp_compression/compression_method", PROPERTY_HINT_RANGE, "0,6,1"));
|
||||||
|
|
||||||
|
GLOBAL_DEF("rendering/textures/webp_compression/lossless_compression_factor", 25);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/webp_compression/lossless_compression_factor", PropertyInfo(Variant::FLOAT, "rendering/textures/webp_compression/lossless_compression_factor", PROPERTY_HINT_RANGE, "0,100,1"));
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
|
GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
|
||||||
|
|
Loading…
Reference in New Issue