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

Color migration guide #1379

Merged
merged 5 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
@@ -1,22 +1,134 @@
Bevy’s color types have changed! Wherever you used a `bevy::render::Color`, a `bevy::color::Color` is used instead.

These are quite similar! Both are enums storing a color in a specific color space (or to be more precise, using a specific color model). However, each of the different color models now has its own type.

TODO…

- `Color::rgba`, `Color::rgb`, `Color::rbga_u8`, `Color::rgb_u8`, `Color::rgb_from_array` are now `Color::srgba`, `Color::srgb`, `Color::srgba_u8`, `Color::srgb_u8` and `Color::srgb_from_array`.
- `Color::set_a` and `Color::a` is now `Color::set_alpha` and `Color::alpha`. These are part of the `Alpha` trait in `bevy_color`.
- `Color::is_fully_transparent` is now part of the `Alpha` trait in `bevy_color`
- `Color::r`, `Color::set_r`, `Color::with_r` and the equivalents for `g`, `b` `h`, `s` and `l` have been removed due to causing silent relatively expensive conversions. Convert your `Color` into the desired color space, perform your operations there, and then convert it back into a polymorphic `Color` enum.
- `Color::hex` is now `Srgba::hex`. Call `.into` or construct a `Color::Srgba` variant manually to convert it.
Copy link

Choose a reason for hiding this comment

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

or .to_srgba()

Copy link
Member Author

Choose a reason for hiding this comment

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

What section are you referring to for this? You commented on removed text that no longer exists, so I'm not sure what you're talking about.

- `WireframeMaterial`, `ExtractedUiNode`, `ExtractedDirectionalLight`, `ExtractedPointLight`, `ExtractedSpotLight` and `ExtractedSprite` now store a `LinearRgba`, rather than a polymorphic `Color`
- `Color::rgb_linear` and `Color::rgba_linear` are now `Color::linear_rgb` and `Color::linear_rgba`
- The various CSS color constants are no longer stored directly on `Color`. Instead, they’re defined in the `Srgba` color space, and accessed via `bevy::color::palettes::css`. Call `.into()` on them to convert them into a `Color` for quick debugging use, and consider using the much prettier `tailwind` palette for prototyping.
- The `LIME_GREEN` color has been renamed to `LIMEGREEN` to comply with the standard naming.
- Vector field arithmetic operations on `Color` (add, subtract, multiply and divide by a f32) have been removed. Instead, convert your colors into `LinearRgba` space, and perform your operations explicitly there. This is particularly relevant when working with emissive or HDR colors, whose color channel values are routinely outside of the ordinary 0 to 1 range.
- `Color::as_linear_rgba_f32` has been removed. Call `LinearRgba::to_f32_array` instead, converting if needed.
- `Color::as_linear_rgba_u32` has been removed. Call `LinearRgba::to_u32` instead, converting if needed.
- Several other color conversion methods to transform LCH or HSL colors into float arrays or `Vec` types have been removed. Please reimplement these externally or open a PR to re-add them if you found them particularly useful.
- Various methods on `Color` such as `rgb` or `hsl` to convert the color into a specific color space have been removed. Convert into `LinearRgba`, then to the color space of your choice.
- Various implicitly-converting color value methods on `Color` such as `r`, `g`, `b` or `h` have been removed. Please convert it into the color space of your choice, then check these properties.
- `Color` no longer implements `AsBindGroup`. Store a `LinearRgba` internally instead to avoid conversion costs.
Bevy's color support has received a major overhaul, and with it the new `bevy::color` module. Buckle up, many things have been changed!

#### Color space representation

Bevy's main `Color` enum is used to represent color in many different color spaces (such as RGB, HSL, and more). Before, these color spaces were all represented inline as variants:

```rust
enum Color {
Rgba {
red: f32,
green: f32,
blue: f32,
alpha: f32,
},
Hsla {
hue: f32,
saturation: f32,
lightness: f32,
alpha: f32,
},
// ...
}
```

This has been changed so now each color space has its own dedicated struct:

```rust
struct Srgba {
red: f32,
green: f32,
blue: f32,
alpha: f32,
}

struct Hsla {
hue: f32,
saturation: f32,
lightness: f32,
alpha: f32,
}

enum Color {
Srgba(Srgba),
Hsla(Hsla),
// ...
}
```

This makes it easier to organize and manage different color spaces, and makes room to add more! To handle this change, you may need to update your match statements:

```rust
// Before
match color {
Color::Rgba { red, green, blue, alpha } => {
// Something cool here!
},
_ => {},
}

// After
match color {
Color::Srgba(Srgba { red, green, blue, alpha }) => {
// Something cool here!
},
_ => {}
}
```

Additionally, you must now use the `From` and `Into` implementations when converting between color spaces, as compared to the old helper methods such as `as_rgba` and `as_hsla`.

```rust
// Before
let color = Color::rgb(1.0, 0.0, 1.0).as_hsla();

// After
let color: Hsla = Srgba::rgb(1.0, 0.0, 1.0).into();
```

#### `Color` methods

Any mention of RGB has been renamed to [sRGB]. This includes the variant `Color::Rgba` turning into `Color::Srgba` as well as methods such as `Color::rgb` and `Color::rgb_u8` turning into `Color::srgb` and `Color::srgb_u8`.

[sRGB]: https://en.wikipedia.org/wiki/SRGB

Methods to access specific channels of `Color` have been removed due to causing silent, relatively expensive conversions. This includes `Color::r`, `Color::set_r`, `Color::with_r`, and all of the equivalents for `g`, `b` `h`, `s` and `l`. Convert your `Color` into the desired color space, perform your operation there, and then convert it back.

```rust
// Before
let mut color = Color::rgb(0.0, 0.0, 0.0);
color.set_b(1.0);

// After
let color = Color::srgb(0.0, 0.0, 0.0);
let srgba = Srgba {
blue: 1.0,
..Srgba::from(color),
};
let color = Color::from(srgba);
```

`Color::hex` has been moved to `Srgba::hex`. Call `.into()` or construct a `Color::Srgba` variant manually to convert it.

`Color::rgb_linear` and `Color::rgba_linear` have been renamed `Color::linear_rgb` and `Color::linear_rgba` to fit the naming scheme of the `LinearRgba` struct.

`Color::as_linear_rgba_f32` and `Color::as_linear_rgba_u32` have been removed. Call `LinearRgba::to_f32_array` and `LinearRgba::to_u32` instead, converting if necessary.

Several other color conversion methods to transform LCH or HSL colors into float arrays or `Vec` types have been removed. Please reimplement these externally or open a PR to re-add them if you found them particularly useful.

Vector field arithmetic operations on `Color` (add, subtract, multiply and divide by a f32) have been removed. Instead, convert your colors into `LinearRgba` space and perform your operations explicitly there. This is particularly relevant when working with emissive or HDR colors, whose color channel values are routinely outside of the ordinary 0 to 1 range.

#### Alpha

Alpha, also known as transparency, used to be referred to by the letter `a`. It is now called by its full name within structs and methods.

- `Color::set_a` and `Color::a` are now `Color::set_alpha` and `Color::alpha`. These are part of the new `Alpha` trait.
- Additionally, `Color::is_fully_transparent` is now part of the `Alpha`.

#### CSS Constants

The various CSS color constants are no longer stored directly on `Color`. Instead, they’re defined in the `Srgba` color space, and accessed via `bevy::color::palettes`. Call `.into()` on them to convert them into a `Color` for quick debugging use. Please note that these palettes are not necessarily 1:1 with the constants defined previously as somes names and colors have been changed. If you need the same color as before, consider copying the constant into your own code.

Check warning on line 120 in release-content/0.14/migration-guides/12163_Migrate_from_LegacyColor_to_bevy_colorColor.md

View workflow job for this annotation

GitHub Actions / typos

"somes" should be "some" or "sums".
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved

```rust
// Before
let color = Color::BLUE;

// After
use bevy::color::palettes::css::BLUE;

let color = BLUE;
```

#### Switch to `LinearRgba`

`WireframeMaterial`, `ExtractedUiNode`, `ExtractedDirectionalLight`, `ExtractedPointLight`, `ExtractedSpotLight`, and `ExtractedSprite` now store a `LinearRgba` rather than a polymorphic `Color`. Furthermore, `Color` no longer implements `AsBindGroup`. You should store a `LinearRgba` instead to avoid conversion costs.
2 changes: 1 addition & 1 deletion release-content/0.14/migration-guides/_guides.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ areas = ["Color"]
file_name = "13209_move_wgsl_color_operations_from_bevy_pbr_to_bevy_render.md"

[[guides]]
title = "Migrate from `LegacyColor` to `bevy_color::Color`"
title = "Overhaul `Color`"
url = "https://github.com/bevyengine/bevy/pull/12163"
areas = ["Color", "Gizmos", "Rendering", "Text", "UI"]
file_name = "12163_Migrate_from_LegacyColor_to_bevy_colorColor.md"
Expand Down
Loading