Skip to content

Commit

Permalink
Color migration guide (#1379)
Browse files Browse the repository at this point in the history
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
  • Loading branch information
BD103 and alice-i-cecile committed Jun 11, 2024
1 parent 9813b19 commit c57c223
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 23 deletions.
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.
- `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 some names and colors have been changed. If you need the same color as before, consider copying the constant into your own code.

```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

0 comments on commit c57c223

Please sign in to comment.