Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,12 @@ trace = ["bevy_internal/trace", "dep:tracing"]
# Basis Universal compressed texture support
basis-universal = ["bevy_internal/basis-universal"]

# Enables compressed KTX2 UASTC texture output on the asset processor
# Texture compression asset processor (cross-platform, transcodes to any GPU format at load time)
compressed_image_saver_universal = [
"bevy_internal/compressed_image_saver_universal",
]

# Texture compression asset processor (BCn for desktop, ASTC for mobile via env var)
compressed_image_saver = ["bevy_internal/compressed_image_saver"]

# BMP image format support
Expand Down
20 changes: 20 additions & 0 deletions _release-content/migration-guides/compressed_image_saver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: "`CompressedImageSaver` improvements"
pull_requests: [23567]
---

The `compressed_image_saver` Cargo feature has been reworked. The old behavior (Basis Universal UASTC compression) has been moved to a new feature called `compressed_image_saver_universal`, and the `compressed_image_saver` feature now uses the `ctt` library to compress textures into BCn (desktop) or ASTC (mobile) formats instead.

If you were using the `compressed_image_saver` feature and want to keep the previous Basis Universal behavior, rename the feature in your `Cargo.toml`:

```toml
# Before
bevy = { version = "0.18", features = ["compressed_image_saver"] }

# After (keeps old Basis Universal behavior)
bevy = { version = "0.19", features = ["compressed_image_saver_universal"] }
```

Alternatively, keep using `compressed_image_saver` to get the new BCn/ASTC compression backend. This produces higher-quality output and supports a wider range of input formats, but does not support all platforms in a single file like UASTC does. We recommend sticking to `compressed_image_saver_universal` when targeting the web.

`CompressedImageSaverError` has a new variant `CompressionFailed`. If you were matching exhaustively on this enum, add a branch for it.
21 changes: 21 additions & 0 deletions _release-content/release-notes/compressed_image_saver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: CompressedImageSaver Improvements
authors: ["@JMS55", "@cwfitzgerald"]
pull_requests: [23567]
---

Bevy's `CompressedImageSaver` asset processor has been significantly upgraded with a new compression backend powered by the [`ctt`](https://github.com/cwfitzgerald/ctt) library.

The new `compressed_image_saver` feature compresses textures into BCn formats (for desktop GPUs) or ASTC formats (for mobile GPUs), producing higher-quality output than the previous Basis Universal approach. The compressor automatically selects the best output format based on the input texture's channel count and type — for example, single-channel textures get BC4, HDR textures get BC6H, and standard RGBA textures get BC7.

## Automatic Mipmap Generation

No more manually generating mipmaps! The new backend automatically produces a full mip chain during compression. This means less aliasing when textures are viewed at a distance and better GPU cache utilization — all for free, just by running your textures through the asset processor.

## ASTC for Mobile

To target mobile GPUs, set the `BEVY_COMPRESSED_IMAGE_SAVER_ASTC` environment variable with your desired block size (e.g. `4x4`, `6x6`, `8x8`). Larger blocks give smaller files at the cost of quality. All 14 ASTC block sizes are supported.

## Basis Universal is Still Available

The previous Basis Universal compression behavior has been moved to the `compressed_image_saver_universal` feature. This remains the best choice for cross-platform distribution (including WebGPU), since UASTC can be transcoded at load time to whatever format the target GPU supports.
10 changes: 7 additions & 3 deletions crates/bevy_image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ zstd_rust = ["zstd", "dep:ruzstd"]
# Binding to zstd C implementation (faster)
zstd_c = ["zstd", "dep:zstd"]

# Enables compressed KTX2 UASTC texture output on the asset processor
compressed_image_saver = ["basis-universal"]
# Texture compression asset processor (cross-platform, transcodes to any GPU format at load time)
compressed_image_saver_universal = ["basis-universal"]

# Texture compression asset processor (BCn for desktop, ASTC for mobile via env var)
compressed_image_saver = ["dep:ctt", "ktx2"]

[dependencies]
# bevy
Expand Down Expand Up @@ -79,7 +82,7 @@ futures-lite = "2.0.1"
guillotiere = "0.6.0"
rectangle-pack = "0.4"
ddsfile = { version = "0.5.2", optional = true }
ktx2 = { version = "0.4.0", optional = true }
ktx2 = { git = "https://github.com/BVE-Reborn/ktx2.git", rev = "49e6fed", optional = true }
# For ktx2 supercompression
flate2 = { version = "1.0.22", optional = true }
zstd = { version = "0.13.3", optional = true }
Expand All @@ -88,6 +91,7 @@ ruzstd = { version = "0.8.0", optional = true }
basis-universal = { version = "0.3.0", optional = true }
tracing = { version = "0.1", default-features = false, features = ["std"] }
half = { version = "2.4.1" }
ctt = { git = "https://github.com/cwfitzgerald/ctt", rev = "0ac0748fc25fd0cdee2794a43d1617cc5b776e05", optional = true }

[dev-dependencies]
bevy_ecs = { path = "../bevy_ecs", version = "0.19.0-dev" }
Expand Down
Loading
Loading