Skip to content

CompressedImageSaver revamp#23567

Merged
alice-i-cecile merged 43 commits intobevyengine:mainfrom
JMS55:compressed-image-saver2
May 4, 2026
Merged

CompressedImageSaver revamp#23567
alice-i-cecile merged 43 commits intobevyengine:mainfrom
JMS55:compressed-image-saver2

Conversation

@JMS55
Copy link
Copy Markdown
Contributor

@JMS55 JMS55 commented Mar 29, 2026

Objective

  • Provide a higher quality texture compressor
  • Automatically generate mipmaps

Closes #14671.

Solution

  • Use the ctt crate

Testing

  • New compressed_image_saver example (for now I have merged the textures into this branch, but before merging we should place them in the bevy asset repo)

Showcase

image

@JMS55 JMS55 added the A-Assets Load files from disk to use for things like images, models, and sounds label Mar 29, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Assets Mar 29, 2026
@alice-i-cecile alice-i-cecile added C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Mar 29, 2026
@beicause
Copy link
Copy Markdown
Member

beicause commented Apr 1, 2026

FYI I'm working on a basisu asset processor in beicause/bevy_basisu_loader#33

Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
return Err(CompressedImageSaverError::UninitializedImage);
};

if image.texture_descriptor.mip_level_count != 1 {
Copy link
Copy Markdown

@cwfitzgerald cwfitzgerald Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note ctt can deal with any source amount of mips

stride: image.width() * bytes_per_pixel,
format: input_format,
color_space,
alpha: ctt::AlphaMode::Straight, // TODO: User-configurable?
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this should be user configurable.

container: ctt::Container::Ktx2,
quality: ctt::Quality::default(),
output_color_space: None,
output_alpha: None,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The correct default here is Some(premultiplied), though should be user configurable

Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
Comment thread crates/bevy_internal/Cargo.toml Outdated
Copy link
Copy Markdown
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. We're just calling another lib!

I haven't tested this locally, but the code looks fine (barring one complaint).

})
}

#[cfg(feature = "compressed_image_saver_universal")]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am really not a fan of this. Saying we just straight up can't compile either case if both features are enabled kinda sucks.

WDYT about just having two CompressedImageSavers? CompressedImageSaverCtt and CompressedImageSaverUniversal? Then just pick one in the plugin? This way if users want to use the old compression, they can. You could also have a wrapper CompressedImageSaver for compatibility (which internally holds one of the backends), so that we keep old meta files working.

I am personally not a fan of mutually exclusive feature flags, since it means I can't just test with --all-features.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally the idea was that you'd always be using CompressedImageSaver (same meta files), and then depending on what platform you want to target, you'd enable different backends.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use feature gate within a custom asset processor instead of asset savers, instead of using LoadTransformAndSave.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to double down on this. I think we should support both. I'd rather users have the capacity to remix these however they want in their own processors, rather than being limited to whatever processors we give them.

Comment thread _release-content/migration-guides/compressed_image_saver.md Outdated
Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
Comment thread crates/bevy_image/src/compressed_image_saver.rs Outdated
@JMS55 JMS55 requested a review from andriyDev May 3, 2026 17:29
Comment thread .gitignore
@@ -20,6 +20,7 @@ Cargo.lock

# Bevy Assets
assets/**/*.meta
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could remove this now that we don't auto generate meta files, but let's not do that in this PR.

@JMS55 JMS55 requested review from DGriffin91, andriyDev and cwfitzgerald and removed request for DGriffin91 May 3, 2026 18:14
@JMS55 JMS55 requested review from alice-i-cecile and removed request for cwfitzgerald May 3, 2026 18:41
Comment thread crates/bevy_image/src/image_texture_conversion.rs
Comment thread crates/bevy_image/Cargo.toml Outdated
Comment thread _release-content/migration-guides/compressed_image_saver.md
fn default() -> Self {
Self {
input_alpha_mode: AlphaMode::Straight,
output_alpha_mode: AlphaMode::Premultiplied,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a surprising default to me. Why are we changing this on users in the default config?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wdym?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I hand an image processor an image. I expect nothing else to be changed during processing. Why do we expect Straight in but return PMA out?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what the correct API design is for bevy, however if any kind of blending is involved, you need premultiplied alpha for the math to work out. iff you are nearest sampling you can do the premultiplication in the shader, but if you're doing any kind of linear sampling you need premultiplied alpha in the texture.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is generally the best default for users.

Comment thread crates/bevy_image/src/compressed_image_saver/mod.rs Outdated
Copy link
Copy Markdown
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to move the assets out into the bevy-assets repo still 🙂

I've also caught a few smaller problems, which should be addressed.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 4, 2026
@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 4, 2026
Merged via the queue into bevyengine:main with commit 3f9bd6b May 4, 2026
44 checks passed
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in Assets May 4, 2026
@beicause
Copy link
Copy Markdown
Member

beicause commented May 4, 2026

for now I have merged the textures into this branch, but before merging we should place them in the bevy asset repo

@alice-i-cecile I think this is merged too quickly. The assets have not moved to bevy asset repo. Even if we delete these files later, the git history is permanently bloated unless you force push to rewrite history.

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

Labels

A-Assets Load files from disk to use for things like images, models, and sounds C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Improve CompressedImageSaver

6 participants