Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support lossless WebP for texture import #2593

Closed
mortarroad opened this issue Apr 12, 2021 · 5 comments · Fixed by godotengine/godot#47835
Closed

Support lossless WebP for texture import #2593

mortarroad opened this issue Apr 12, 2021 · 5 comments · Fixed by godotengine/godot#47835
Milestone

Comments

@mortarroad
Copy link

The purpose of this issue is to discuss the inclusion of Lossless WebP, and how to implement it best.
I am hoping to implement this myself.

Summary

Lossless WebP has faster decompression and smaller file size than PNG. See https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study
Only the default encoding speed seems to be lower. (But by choosing a fast preset, it looks like it is faster and still yields a smaller size.)
WebP is already supported in Godot, but the lossless mode is not made available.

Implementation approach

Since the WebP library is already included, the implementation is mostly about how to enable the user to access it.

Completely replacing PNG with WebP is not possible, since WebP absurdly only supports image sizes up to 16383, therefore the largest power of two supported is 8192.
Larger textures may be a rare use case, but should still stay supported.

Therefore, the most sensible approach seems to be the following:

Rename the existing formats:
DATA_FORMAT_LOSSLESS becomes DATA_FORMAT_PNG,
DATA_FORMAT_LOSSY becomes DATA_FORMAT_WEBP.

Then, in the lossless importer mode, another checkbox (perhaps called "Use WebP") is added.
That means the COMPRESS_LOSSLESS can import both PNG or WebP.

@Calinou
Copy link
Member

Calinou commented Apr 12, 2021

If the decompression speed claims are true on all platforms (including mobile and WebAssembly), this could be a pretty good solution to decrease the file size of 2D games.

Larger textures may be a rare use case, but should still stay supported.

We can use lossless WebP for textures smaller than 8192×8192 and PNG for larger textures. With textures above 8192×8192, you're expected to use VRAM compression anyway due to how much VRAM a single uncompressed > 8192×8192 texture will take up.

Therefore, the most sensible approach seems to be the following:

Rename the existing formats:
DATA_FORMAT_LOSSLESS becomes DATA_FORMAT_PNG,
DATA_FORMAT_LOSSY becomes DATA_FORMAT_WEBP.

Then, in the lossless importer mode, another checkbox (perhaps called "Use WebP") is added.
That means the COMPRESS_LOSSLESS can import both PNG or WebP.

My issue with doing this is that it introduces a fair amount of complexity and choice paralysis for casual users who already have trouble figuring out which import format they should use. I would really prefer an automatic setup for this, with a project setting for those who really want to override the importer in use (like we already do for VRAM compressors).

If we go with the aforementioned automatic detection, we could have a project setting like force_lossless_import_png for those who prefer fast compression speeds to low file sizes.

@mortarroad
Copy link
Author

Even if we keep the user-interface the same, I'd rename the constants, since they are always that specific format.
Anything else is just needless abstraction.

@mortarroad
Copy link
Author

A side note:
When generating mipmaps is checked in the importer, mipmaps are actually stored in the file for the lossless mode!
For VRAM compression this makes sense, because the compression and therefore generating mipmaps is expensive.
But for lossless textures, there is no expensive encoding step, and generating mipmaps on the GPU is faster than precomputing and uploading them.

@Calinou
Copy link
Member

Calinou commented Apr 12, 2021

But for lossless textures, there is no expensive encoding step, and generating mipmaps on the GPU is faster than precomputing and uploading them.

We can use pregenerated mipmaps to get higher quality mipmaps without slowing down loading times. However, this isn't implemented yet since a basic box filter is currently used: #2450

@clayjohn
Copy link
Member

Regarding storing mipmaps, we also want to implement proper texture streaming (loading higher level mips first) which won't work if we don't pre-generate the mipmaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants