From 599e5e4e764756de2c8bfa8c2fe864d5b62d6716 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Thu, 29 Feb 2024 14:35:12 -0500 Subject: [PATCH] Migrate from `LegacyColor` to `bevy_color::Color` (#12163) # Objective - As part of the migration process we need to a) see the end effect of the migration on user ergonomics b) check for serious perf regressions c) actually migrate the code - To accomplish this, I'm going to attempt to migrate all of the remaining user-facing usages of `LegacyColor` in one PR, being careful to keep a clean commit history. - Fixes #12056. ## Solution I've chosen to use the polymorphic `Color` type as our standard user-facing API. - [x] Migrate `bevy_gizmos`. - [x] Take `impl Into` in all `bevy_gizmos` APIs - [x] Migrate sprites - [x] Migrate UI - [x] Migrate `ColorMaterial` - [x] Migrate `MaterialMesh2D` - [x] Migrate fog - [x] Migrate lights - [x] Migrate StandardMaterial - [x] Migrate wireframes - [x] Migrate clear color - [x] Migrate text - [x] Migrate gltf loader - [x] Register color types for reflection - [x] Remove `LegacyColor` - [x] Make sure CI passes Incidental improvements to ease migration: - added `Color::srgba_u8`, `Color::srgba_from_array` and friends - added `set_alpha`, `is_fully_transparent` and `is_fully_opaque` to the `Alpha` trait - add and immediately deprecate (lol) `Color::rgb` and friends in favor of more explicit and consistent `Color::srgb` - standardized on white and black for most example text colors - added vector field traits to `LinearRgba`: ~~`Add`, `Sub`, `AddAssign`, `SubAssign`,~~ `Mul` and `Div`. Multiplications and divisions do not scale alpha. `Add` and `Sub` have been cut from this PR. - added `LinearRgba` and `Srgba` `RED/GREEN/BLUE` - added `LinearRgba_to_f32_array` and `LinearRgba::to_u32` ## Migration Guide 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. --------- Co-authored-by: Alice Cecile Co-authored-by: Afonso Lage Co-authored-by: Rob Parrett Co-authored-by: Zachary Harrold --- crates/bevy_color/src/color.rs | 103 +- crates/bevy_color/src/color_ops.rs | 13 + crates/bevy_color/src/hsla.rs | 5 + crates/bevy_color/src/hsva.rs | 5 + crates/bevy_color/src/hwba.rs | 5 + crates/bevy_color/src/laba.rs | 5 + crates/bevy_color/src/lcha.rs | 5 + crates/bevy_color/src/linear_rgba.rs | 93 + crates/bevy_color/src/oklaba.rs | 5 + crates/bevy_color/src/oklcha.rs | 5 + crates/bevy_color/src/srgba.rs | 29 + crates/bevy_color/src/xyza.rs | 5 + crates/bevy_gizmos/src/aabb.rs | 10 +- crates/bevy_gizmos/src/arcs.rs | 36 +- crates/bevy_gizmos/src/arrows.rs | 19 +- crates/bevy_gizmos/src/circles.rs | 42 +- crates/bevy_gizmos/src/gizmos.rs | 154 +- crates/bevy_gizmos/src/grid.rs | 18 +- crates/bevy_gizmos/src/lib.rs | 3 +- crates/bevy_gizmos/src/primitives/dim2.rs | 72 +- crates/bevy_gizmos/src/primitives/dim3.rs | 44 +- crates/bevy_gizmos/src/primitives/helpers.rs | 8 +- crates/bevy_gltf/Cargo.toml | 1 + crates/bevy_gltf/src/loader.rs | 20 +- crates/bevy_internal/src/lib.rs | 3 +- crates/bevy_pbr/Cargo.toml | 1 + crates/bevy_pbr/src/fog.rs | 40 +- crates/bevy_pbr/src/lib.rs | 4 +- crates/bevy_pbr/src/light.rs | 18 +- crates/bevy_pbr/src/material.rs | 8 +- crates/bevy_pbr/src/pbr_material.rs | 37 +- crates/bevy_pbr/src/render/fog.rs | 29 +- crates/bevy_pbr/src/render/light.rs | 16 +- crates/bevy_pbr/src/wireframe.rs | 15 +- crates/bevy_render/src/camera/clear_color.rs | 13 +- crates/bevy_render/src/color/mod.rs | 1809 ----------------- crates/bevy_render/src/lib.rs | 15 +- .../src/render_resource/bind_group.rs | 34 +- crates/bevy_sprite/Cargo.toml | 1 + .../bevy_sprite/src/mesh2d/color_material.rs | 17 +- crates/bevy_sprite/src/mesh2d/material.rs | 7 +- crates/bevy_sprite/src/render/mod.rs | 12 +- crates/bevy_sprite/src/sprite.rs | 4 +- .../src/texture_slice/computed_slices.rs | 2 +- crates/bevy_text/Cargo.toml | 1 + crates/bevy_text/src/text.rs | 19 +- crates/bevy_text/src/text2d.rs | 6 +- crates/bevy_ui/Cargo.toml | 1 + crates/bevy_ui/src/node_bundles.rs | 16 +- crates/bevy_ui/src/render/mod.rs | 16 +- crates/bevy_ui/src/texture_slice.rs | 2 +- crates/bevy_ui/src/ui_material.rs | 7 +- crates/bevy_ui/src/ui_node.rs | 42 +- errors/B0004.md | 4 +- examples/2d/2d_shapes.rs | 2 +- examples/2d/2d_viewport_to_world.rs | 4 +- examples/2d/bloom_2d.rs | 8 +- examples/2d/bounding_2d.rs | 24 +- examples/2d/custom_gltf_vertex_attribute.rs | 2 +- examples/2d/mesh2d.rs | 4 +- examples/2d/mesh2d_manual.rs | 8 +- examples/2d/mesh2d_vertex_color_texture.rs | 8 +- examples/2d/pixel_grid_snap.rs | 2 +- examples/2d/sprite_slice.rs | 2 +- examples/2d/text2d.rs | 17 +- examples/2d/texture_atlas.rs | 4 +- examples/2d/transparency_2d.rs | 4 +- examples/3d/3d_scene.rs | 4 +- examples/3d/3d_shapes.rs | 3 +- examples/3d/3d_viewport_to_world.rs | 7 +- examples/3d/animated_material.rs | 5 +- examples/3d/anti_aliasing.rs | 4 +- examples/3d/atmospheric_fog.rs | 20 +- examples/3d/blend_modes.rs | 24 +- examples/3d/bloom_3d.rs | 11 +- examples/3d/deferred_rendering.rs | 14 +- examples/3d/deterministic.rs | 2 +- examples/3d/fog.rs | 38 +- examples/3d/irradiance_volumes.rs | 11 +- examples/3d/lighting.rs | 31 +- examples/3d/lightmaps.rs | 3 +- examples/3d/lines.rs | 6 +- examples/3d/orthographic.rs | 10 +- examples/3d/parallax_mapping.rs | 2 +- examples/3d/parenting.rs | 2 +- examples/3d/pbr.rs | 6 +- examples/3d/reflection_probes.rs | 4 +- examples/3d/render_to_texture.rs | 4 +- examples/3d/shadow_biases.rs | 6 +- examples/3d/shadow_caster_receiver.rs | 11 +- examples/3d/skybox.rs | 2 +- examples/3d/spherical_area_lights.rs | 6 +- examples/3d/split_screen.rs | 9 +- examples/3d/spotlight.rs | 20 +- examples/3d/ssao.rs | 4 +- examples/3d/texture.rs | 4 +- examples/3d/tonemapping.rs | 12 +- examples/3d/transmission.rs | 49 +- examples/3d/transparency_3d.rs | 12 +- examples/3d/two_passes.rs | 4 +- examples/3d/vertex_colors.rs | 4 +- examples/3d/wireframe.rs | 25 +- examples/animation/animated_fox.rs | 4 +- examples/animation/animated_transform.rs | 6 +- examples/animation/cubic_curve.rs | 7 +- examples/animation/custom_skinned_mesh.rs | 2 +- examples/asset/asset_loading.rs | 2 +- examples/async_tasks/async_compute.rs | 2 +- .../external_source_external_thread.rs | 1 - examples/audio/spatial_audio_2d.rs | 7 +- examples/audio/spatial_audio_3d.rs | 11 +- examples/ecs/hierarchy.rs | 5 +- examples/ecs/iter_combinations.rs | 12 +- examples/ecs/removal_detection.rs | 2 +- examples/ecs/state.rs | 17 +- examples/games/alien_cake_addict.rs | 6 +- examples/games/breakout.rs | 14 +- examples/games/contributors.rs | 11 +- examples/games/game_menu.rs | 35 +- examples/games/stepping.rs | 4 +- examples/gizmos/2d_gizmos.rs | 38 +- examples/gizmos/3d_gizmos.rs | 31 +- examples/math/render_primitives.rs | 10 +- examples/mobile/src/lib.rs | 15 +- .../shader/compute_shader_game_of_life.rs | 2 +- examples/shader/custom_vertex_attribute.rs | 4 +- examples/shader/extended_material.rs | 3 +- examples/shader/post_processing.rs | 4 +- examples/shader/shader_defs.rs | 6 +- examples/shader/shader_instancing.rs | 2 +- examples/shader/shader_material.rs | 4 +- examples/shader/shader_material_2d.rs | 4 +- examples/shader/shader_material_glsl.rs | 4 +- .../shader_material_screenspace_texture.rs | 2 +- examples/shader/shader_prepass.rs | 10 +- examples/stress_tests/bevymark.rs | 37 +- examples/stress_tests/many_buttons.rs | 13 +- examples/stress_tests/many_cubes.rs | 4 +- examples/stress_tests/many_foxes.rs | 2 +- examples/stress_tests/many_gizmos.rs | 6 +- examples/stress_tests/many_glyphs.rs | 3 +- examples/stress_tests/many_lights.rs | 7 +- examples/stress_tests/many_sprites.rs | 5 +- examples/stress_tests/text_pipeline.rs | 5 +- examples/time/virtual_time.rs | 6 +- examples/tools/gamepad_viewer.rs | 8 +- examples/transforms/3d_rotation.rs | 2 +- examples/transforms/scale.rs | 2 +- examples/transforms/transform.rs | 6 +- examples/transforms/translation.rs | 2 +- examples/ui/borders.rs | 12 +- examples/ui/button.rs | 18 +- examples/ui/display_and_visibility.rs | 38 +- examples/ui/flex_layout.rs | 14 +- examples/ui/font_atlas_debug.rs | 8 +- examples/ui/grid.rs | 60 +- examples/ui/overflow.rs | 18 +- examples/ui/overflow_debug.rs | 6 +- examples/ui/relative_cursor_position.rs | 8 +- examples/ui/render_ui_to_texture.rs | 5 +- examples/ui/size_constraints.rs | 32 +- examples/ui/text.rs | 16 +- examples/ui/text_debug.rs | 21 +- examples/ui/text_wrap_debug.rs | 6 +- examples/ui/transparency_ui.rs | 10 +- examples/ui/ui.rs | 27 +- examples/ui/ui_material.rs | 6 +- examples/ui/ui_scaling.rs | 10 +- examples/ui/ui_texture_atlas.rs | 4 +- examples/ui/ui_texture_slice.rs | 16 +- examples/ui/viewport_debug.rs | 15 +- examples/ui/window_fallthrough.rs | 2 +- examples/ui/z_index.rs | 19 +- examples/window/clear_color.rs | 6 +- examples/window/low_power.rs | 14 +- examples/window/scale_factor_override.rs | 2 +- examples/window/screenshot.rs | 4 +- examples/window/transparent_window.rs | 2 +- tests/window/minimising.rs | 6 +- tests/window/resizing.rs | 6 +- 180 files changed, 1371 insertions(+), 2807 deletions(-) delete mode 100644 crates/bevy_render/src/color/mod.rs diff --git a/crates/bevy_color/src/color.rs b/crates/bevy_color/src/color.rs index 9af7ce1f8a..bfb5118712 100644 --- a/crates/bevy_color/src/color.rs +++ b/crates/bevy_color/src/color.rs @@ -45,6 +45,12 @@ impl Color { (*self).into() } + #[deprecated = "Use `Color::srgba` instead"] + /// Creates a new [`Color`] object storing a [`Srgba`] color. + pub const fn rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self { + Self::srgba(red, green, blue, alpha) + } + /// Creates a new [`Color`] object storing a [`Srgba`] color. pub const fn srgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self { Self::Srgba(Srgba { @@ -55,6 +61,12 @@ impl Color { }) } + #[deprecated = "Use `Color::srgb` instead"] + /// Creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0. + pub const fn rgb(red: f32, green: f32, blue: f32) -> Self { + Self::srgb(red, green, blue) + } + /// Creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0. pub const fn srgb(red: f32, green: f32, blue: f32) -> Self { Self::Srgba(Srgba { @@ -65,7 +77,69 @@ impl Color { }) } - /// Createsa new [`Color`] object storing a [`LinearRgba`] color. + #[deprecated = "Use `Color::srgb_from_array` instead"] + /// Reads an array of floats to creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0. + pub fn rgb_from_array([r, g, b]: [f32; 3]) -> Self { + Self::Srgba(Srgba::rgb(r, g, b)) + } + + /// Reads an array of floats to creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0. + pub fn srgb_from_array(array: [f32; 3]) -> Self { + Self::Srgba(Srgba { + red: array[0], + green: array[1], + blue: array[2], + alpha: 1.0, + }) + } + + #[deprecated = "Use `Color::srgba_u8` instead"] + /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values. + /// + /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0. + pub fn rgba_u8(red: u8, green: u8, blue: u8, alpha: u8) -> Self { + Self::srgba_u8(red, green, blue, alpha) + } + + /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values. + /// + /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0. + pub fn srgba_u8(red: u8, green: u8, blue: u8, alpha: u8) -> Self { + Self::Srgba(Srgba { + red: red as f32 / 255.0, + green: green as f32 / 255.0, + blue: blue as f32 / 255.0, + alpha: alpha as f32 / 255.0, + }) + } + + #[deprecated = "Use `Color::srgb_u8` instead"] + /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values with an alpha of 1.0. + /// + /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0. + pub fn rgb_u8(red: u8, green: u8, blue: u8) -> Self { + Self::srgb_u8(red, green, blue) + } + + /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values with an alpha of 1.0. + /// + /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0. + pub fn srgb_u8(red: u8, green: u8, blue: u8) -> Self { + Self::Srgba(Srgba { + red: red as f32 / 255.0, + green: green as f32 / 255.0, + blue: blue as f32 / 255.0, + alpha: 1.0, + }) + } + + #[deprecated = "Use Color::linear_rgba instead."] + /// Creates a new [`Color`] object storing a [`LinearRgba`] color. + pub const fn rbga_linear(red: f32, green: f32, blue: f32, alpha: f32) -> Self { + Self::linear_rgba(red, green, blue, alpha) + } + + /// Creates a new [`Color`] object storing a [`LinearRgba`] color. pub const fn linear_rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self { Self::LinearRgba(LinearRgba { red, @@ -75,7 +149,13 @@ impl Color { }) } - /// a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0. + #[deprecated = "Use Color::linear_rgb instead."] + /// Creates a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0. + pub const fn rgb_linear(red: f32, green: f32, blue: f32) -> Self { + Self::linear_rgb(red, green, blue) + } + + /// Creates a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0. pub const fn linear_rgb(red: f32, green: f32, blue: f32) -> Self { Self::LinearRgba(LinearRgba { red, @@ -241,8 +321,8 @@ impl Color { /// A fully black [`Color::LinearRgba`] color with an alpha of 1.0. pub const BLACK: Self = Self::linear_rgb(0., 0., 0.); - /// A fully transparent [`Color::LinearRgba`] color. - pub const TRANSPARENT: Self = Self::linear_rgba(0., 0., 0., 0.); + /// A fully transparent [`Color::LinearRgba`] color with 0 red, green and blue. + pub const NONE: Self = Self::linear_rgba(0., 0., 0., 0.); } impl Default for Color { @@ -286,6 +366,21 @@ impl Alpha for Color { Color::Xyza(x) => x.alpha(), } } + + fn set_alpha(&mut self, alpha: f32) { + match self { + Color::Srgba(x) => x.set_alpha(alpha), + Color::LinearRgba(x) => x.set_alpha(alpha), + Color::Hsla(x) => x.set_alpha(alpha), + Color::Hsva(x) => x.set_alpha(alpha), + Color::Hwba(x) => x.set_alpha(alpha), + Color::Laba(x) => x.set_alpha(alpha), + Color::Lcha(x) => x.set_alpha(alpha), + Color::Oklaba(x) => x.set_alpha(alpha), + Color::Oklcha(x) => x.set_alpha(alpha), + Color::Xyza(x) => x.set_alpha(alpha), + } + } } impl From for Color { diff --git a/crates/bevy_color/src/color_ops.rs b/crates/bevy_color/src/color_ops.rs index 08f4cb14c8..efa3529905 100644 --- a/crates/bevy_color/src/color_ops.rs +++ b/crates/bevy_color/src/color_ops.rs @@ -47,4 +47,17 @@ pub trait Alpha: Sized { /// Return a the alpha component of this color. fn alpha(&self) -> f32; + + /// Sets the alpha component of this color. + fn set_alpha(&mut self, alpha: f32); + + /// Is the alpha component of this color less than or equal to 0.0? + fn is_fully_transparent(&self) -> bool { + self.alpha() <= 0.0 + } + + /// Is the alpha component of this color greater than or equal to 1.0? + fn is_fully_opaque(&self) -> bool { + self.alpha() >= 1.0 + } } diff --git a/crates/bevy_color/src/hsla.rs b/crates/bevy_color/src/hsla.rs index 0559274427..2e31d5f9b1 100644 --- a/crates/bevy_color/src/hsla.rs +++ b/crates/bevy_color/src/hsla.rs @@ -134,6 +134,11 @@ impl Alpha for Hsla { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Hsla { diff --git a/crates/bevy_color/src/hsva.rs b/crates/bevy_color/src/hsva.rs index f671981ddc..bc788c8948 100644 --- a/crates/bevy_color/src/hsva.rs +++ b/crates/bevy_color/src/hsva.rs @@ -84,6 +84,11 @@ impl Alpha for Hsva { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl From for Hwba { diff --git a/crates/bevy_color/src/hwba.rs b/crates/bevy_color/src/hwba.rs index 744acd865b..b3b7b6bf62 100644 --- a/crates/bevy_color/src/hwba.rs +++ b/crates/bevy_color/src/hwba.rs @@ -88,6 +88,11 @@ impl Alpha for Hwba { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl From for Hwba { diff --git a/crates/bevy_color/src/laba.rs b/crates/bevy_color/src/laba.rs index 43b4556359..31e8b643cc 100644 --- a/crates/bevy_color/src/laba.rs +++ b/crates/bevy_color/src/laba.rs @@ -103,6 +103,11 @@ impl Alpha for Laba { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Laba { diff --git a/crates/bevy_color/src/lcha.rs b/crates/bevy_color/src/lcha.rs index 7a14ce854d..d59698bedc 100644 --- a/crates/bevy_color/src/lcha.rs +++ b/crates/bevy_color/src/lcha.rs @@ -130,6 +130,11 @@ impl Alpha for Lcha { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Lcha { diff --git a/crates/bevy_color/src/linear_rgba.rs b/crates/bevy_color/src/linear_rgba.rs index c0aeb88dfc..b07efa951e 100644 --- a/crates/bevy_color/src/linear_rgba.rs +++ b/crates/bevy_color/src/linear_rgba.rs @@ -1,3 +1,5 @@ +use std::ops::{Div, Mul}; + use crate::{color_difference::EuclideanDistance, Alpha, Luminance, Mix, StandardColor}; use bevy_math::Vec4; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; @@ -50,6 +52,30 @@ impl LinearRgba { alpha: 0.0, }; + /// A fully red color with full alpha. + pub const RED: Self = Self { + red: 1.0, + green: 0.0, + blue: 0.0, + alpha: 1.0, + }; + + /// A fully green color with full alpha. + pub const GREEN: Self = Self { + red: 0.0, + green: 1.0, + blue: 0.0, + alpha: 1.0, + }; + + /// A fully blue color with full alpha. + pub const BLUE: Self = Self { + red: 0.0, + green: 0.0, + blue: 1.0, + alpha: 1.0, + }; + /// An invalid color. /// /// This type can be used to represent an invalid color value; @@ -127,6 +153,26 @@ impl LinearRgba { self.mix_assign(Self::new(1.0, 1.0, 1.0, self.alpha), adjustment); } } + + /// Converts the color into a [f32; 4] array in RGBA order. + /// + /// This is useful for passing the color to a shader. + pub fn to_f32_array(&self) -> [f32; 4] { + [self.red, self.green, self.blue, self.alpha] + } + + /// Converts this color to a u32. + /// + /// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian). + /// `A` will be the most significant byte and `R` the least significant. + pub fn as_u32(&self) -> u32 { + u32::from_le_bytes([ + (self.red * 255.0) as u8, + (self.green * 255.0) as u8, + (self.blue * 255.0) as u8, + (self.alpha * 255.0) as u8, + ]) + } } impl Default for LinearRgba { @@ -193,6 +239,11 @@ impl Alpha for LinearRgba { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl EuclideanDistance for LinearRgba { @@ -228,6 +279,48 @@ impl From for wgpu::Color { } } +/// All color channels are scaled directly, +/// but alpha is unchanged. +/// +/// Values are not clamped. +impl Mul for LinearRgba { + type Output = Self; + + fn mul(self, rhs: f32) -> Self { + Self { + red: self.red * rhs, + green: self.green * rhs, + blue: self.blue * rhs, + alpha: self.alpha, + } + } +} + +impl Mul for f32 { + type Output = LinearRgba; + + fn mul(self, rhs: LinearRgba) -> LinearRgba { + rhs * self + } +} + +/// All color channels are scaled directly, +/// but alpha is unchanged. +/// +/// Values are not clamped. +impl Div for LinearRgba { + type Output = Self; + + fn div(self, rhs: f32) -> Self { + Self { + red: self.red / rhs, + green: self.green / rhs, + blue: self.blue / rhs, + alpha: self.alpha, + } + } +} + // [`LinearRgba`] is intended to be used with shaders // So it's the only color type that implements [`ShaderType`] to make it easier to use inside shaders impl encase::ShaderType for LinearRgba { diff --git a/crates/bevy_color/src/oklaba.rs b/crates/bevy_color/src/oklaba.rs index cc6dbe6808..7bfeb8d996 100644 --- a/crates/bevy_color/src/oklaba.rs +++ b/crates/bevy_color/src/oklaba.rs @@ -99,6 +99,11 @@ impl Alpha for Oklaba { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Oklaba { diff --git a/crates/bevy_color/src/oklcha.rs b/crates/bevy_color/src/oklcha.rs index 052b4b9edf..939193a4ec 100644 --- a/crates/bevy_color/src/oklcha.rs +++ b/crates/bevy_color/src/oklcha.rs @@ -129,6 +129,11 @@ impl Alpha for Oklcha { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Oklcha { diff --git a/crates/bevy_color/src/srgba.rs b/crates/bevy_color/src/srgba.rs index b2425bb36c..e23beea218 100644 --- a/crates/bevy_color/src/srgba.rs +++ b/crates/bevy_color/src/srgba.rs @@ -37,6 +37,30 @@ impl Srgba { ///
pub const WHITE: Srgba = Srgba::new(1.0, 1.0, 1.0, 1.0); + /// A fully red color with full alpha. + pub const RED: Self = Self { + red: 1.0, + green: 0.0, + blue: 0.0, + alpha: 1.0, + }; + + /// A fully green color with full alpha. + pub const GREEN: Self = Self { + red: 0.0, + green: 1.0, + blue: 0.0, + alpha: 1.0, + }; + + /// A fully blue color with full alpha. + pub const BLUE: Self = Self { + red: 0.0, + green: 0.0, + blue: 1.0, + alpha: 1.0, + }; + /// Construct a new [`Srgba`] color from components. /// /// # Arguments @@ -264,6 +288,11 @@ impl Alpha for Srgba { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl EuclideanDistance for Srgba { diff --git a/crates/bevy_color/src/xyza.rs b/crates/bevy_color/src/xyza.rs index 0aa8a0f5a9..76bf27cef0 100644 --- a/crates/bevy_color/src/xyza.rs +++ b/crates/bevy_color/src/xyza.rs @@ -86,6 +86,11 @@ impl Alpha for Xyza { fn alpha(&self) -> f32 { self.alpha } + + #[inline] + fn set_alpha(&mut self, alpha: f32) { + self.alpha = alpha; + } } impl Luminance for Xyza { diff --git a/crates/bevy_gizmos/src/aabb.rs b/crates/bevy_gizmos/src/aabb.rs index d264051703..1b62775245 100644 --- a/crates/bevy_gizmos/src/aabb.rs +++ b/crates/bevy_gizmos/src/aabb.rs @@ -3,7 +3,7 @@ use crate as bevy_gizmos; use bevy_app::{Plugin, PostUpdate}; -use bevy_color::Oklcha; +use bevy_color::{Color, Oklcha}; use bevy_ecs::{ component::Component, entity::Entity, @@ -13,7 +13,7 @@ use bevy_ecs::{ system::{Query, Res}, }; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{color::LegacyColor, primitives::Aabb}; +use bevy_render::primitives::Aabb; use bevy_transform::{ components::{GlobalTransform, Transform}, TransformSystem, @@ -58,7 +58,7 @@ pub struct AabbGizmoConfigGroup { /// A random color is chosen per box if `None`. /// /// Defaults to `None`. - pub default_color: Option, + pub default_color: Option, } /// Add this [`Component`] to an entity to draw its [`Aabb`] component. @@ -68,7 +68,7 @@ pub struct ShowAabbGizmo { /// The color of the box. /// /// The default color from the [`AabbGizmoConfigGroup`] config is used if `None`, - pub color: Option, + pub color: Option, } fn draw_aabbs( @@ -97,7 +97,7 @@ fn draw_all_aabbs( } } -fn color_from_entity(entity: Entity) -> LegacyColor { +fn color_from_entity(entity: Entity) -> Color { Oklcha::sequential_dispersed(entity.index()).into() } diff --git a/crates/bevy_gizmos/src/arcs.rs b/crates/bevy_gizmos/src/arcs.rs index 09864b6005..9f9181afe7 100644 --- a/crates/bevy_gizmos/src/arcs.rs +++ b/crates/bevy_gizmos/src/arcs.rs @@ -5,8 +5,8 @@ use crate::circles::DEFAULT_CIRCLE_SEGMENTS; use crate::prelude::{GizmoConfigGroup, Gizmos}; +use bevy_color::Color; use bevy_math::{Quat, Vec2, Vec3}; -use bevy_render::color::LegacyColor; use std::f32::consts::TAU; // === 2D === @@ -29,13 +29,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; /// # use std::f32::consts::PI; + /// # use bevy_color::palettes::basic::{GREEN, RED}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.arc_2d(Vec2::ZERO, 0., PI / 4., 1., LegacyColor::GREEN); + /// gizmos.arc_2d(Vec2::ZERO, 0., PI / 4., 1., GREEN); /// /// // Arcs have 32 line-segments by default. /// // You may want to increase this for larger arcs. /// gizmos - /// .arc_2d(Vec2::ZERO, 0., PI / 4., 5., LegacyColor::RED) + /// .arc_2d(Vec2::ZERO, 0., PI / 4., 5., RED) /// .segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -47,7 +48,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { direction_angle: f32, arc_angle: f32, radius: f32, - color: LegacyColor, + color: impl Into, ) -> Arc2dBuilder<'_, 'w, 's, T> { Arc2dBuilder { gizmos: self, @@ -55,7 +56,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { direction_angle, arc_angle, radius, - color, + color: color.into(), segments: None, } } @@ -68,7 +69,7 @@ pub struct Arc2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { direction_angle: f32, arc_angle: f32, radius: f32, - color: LegacyColor, + color: Color, segments: Option, } @@ -142,6 +143,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; /// # use std::f32::consts::PI; + /// # use bevy_color::palettes::css::ORANGE; /// fn system(mut gizmos: Gizmos) { /// // rotation rotates normal to point in the direction of `Vec3::NEG_ONE` /// let rotation = Quat::from_rotation_arc(Vec3::Y, Vec3::NEG_ONE.normalize()); @@ -152,7 +154,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// 0.25, /// Vec3::ONE, /// rotation, - /// LegacyColor::ORANGE + /// ORANGE /// ) /// .segments(100); /// } @@ -165,7 +167,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { radius: f32, position: Vec3, rotation: Quat, - color: LegacyColor, + color: impl Into, ) -> Arc3dBuilder<'_, 'w, 's, T> { Arc3dBuilder { gizmos: self, @@ -174,7 +176,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { rotation, angle, radius, - color, + color: color.into(), segments: None, } } @@ -197,12 +199,13 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::css::ORANGE; /// fn system(mut gizmos: Gizmos) { /// gizmos.short_arc_3d_between( /// Vec3::ONE, /// Vec3::ONE + Vec3::NEG_ONE, /// Vec3::ZERO, - /// LegacyColor::ORANGE + /// ORANGE /// ) /// .segments(100); /// } @@ -221,7 +224,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { center: Vec3, from: Vec3, to: Vec3, - color: LegacyColor, + color: impl Into, ) -> Arc3dBuilder<'_, 'w, 's, T> { self.arc_from_to(center, from, to, color, |x| x) } @@ -243,12 +246,13 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::css::ORANGE; /// fn system(mut gizmos: Gizmos) { /// gizmos.long_arc_3d_between( /// Vec3::ONE, /// Vec3::ONE + Vec3::NEG_ONE, /// Vec3::ZERO, - /// LegacyColor::ORANGE + /// ORANGE /// ) /// .segments(100); /// } @@ -267,7 +271,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { center: Vec3, from: Vec3, to: Vec3, - color: LegacyColor, + color: impl Into, ) -> Arc3dBuilder<'_, 'w, 's, T> { self.arc_from_to(center, from, to, color, |angle| { if angle > 0.0 { @@ -286,7 +290,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { center: Vec3, from: Vec3, to: Vec3, - color: LegacyColor, + color: impl Into, angle_fn: impl Fn(f32) -> f32, ) -> Arc3dBuilder<'_, 'w, 's, T> { // `from` and `to` can be the same here since in either case nothing gets rendered and the @@ -308,7 +312,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { rotation, angle, radius, - color, + color: color.into(), segments: None, } } @@ -331,7 +335,7 @@ pub struct Arc3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { rotation: Quat, angle: f32, radius: f32, - color: LegacyColor, + color: Color, segments: Option, } diff --git a/crates/bevy_gizmos/src/arrows.rs b/crates/bevy_gizmos/src/arrows.rs index 9dc81b7759..ddac8a8c7c 100644 --- a/crates/bevy_gizmos/src/arrows.rs +++ b/crates/bevy_gizmos/src/arrows.rs @@ -4,15 +4,15 @@ //! and assorted support items. use crate::prelude::{GizmoConfigGroup, Gizmos}; +use bevy_color::Color; use bevy_math::{Quat, Vec2, Vec3}; -use bevy_render::color::LegacyColor; /// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`] pub struct ArrowBuilder<'a, 'w, 's, T: GizmoConfigGroup> { gizmos: &'a mut Gizmos<'w, 's, T>, start: Vec3, end: Vec3, - color: LegacyColor, + color: Color, tip_length: f32, } @@ -25,8 +25,9 @@ impl ArrowBuilder<'_, '_, '_, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.arrow(Vec3::ZERO, Vec3::ONE, LegacyColor::GREEN) + /// gizmos.arrow(Vec3::ZERO, Vec3::ONE, GREEN) /// .with_tip_length(3.); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -76,8 +77,9 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.arrow(Vec3::ZERO, Vec3::ONE, LegacyColor::GREEN); + /// gizmos.arrow(Vec3::ZERO, Vec3::ONE, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` @@ -85,14 +87,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { &mut self, start: Vec3, end: Vec3, - color: LegacyColor, + color: impl Into, ) -> ArrowBuilder<'_, 'w, 's, T> { let length = (end - start).length(); ArrowBuilder { gizmos: self, start, end, - color, + color: color.into(), tip_length: length / 10., } } @@ -106,8 +108,9 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.arrow_2d(Vec2::ZERO, Vec2::X, LegacyColor::GREEN); + /// gizmos.arrow_2d(Vec2::ZERO, Vec2::X, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` @@ -115,7 +118,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { &mut self, start: Vec2, end: Vec2, - color: LegacyColor, + color: impl Into, ) -> ArrowBuilder<'_, 'w, 's, T> { self.arrow(start.extend(0.), end.extend(0.), color) } diff --git a/crates/bevy_gizmos/src/circles.rs b/crates/bevy_gizmos/src/circles.rs index 69cca6061d..af22d09527 100644 --- a/crates/bevy_gizmos/src/circles.rs +++ b/crates/bevy_gizmos/src/circles.rs @@ -4,9 +4,9 @@ //! and assorted support items. use crate::prelude::{GizmoConfigGroup, Gizmos}; +use bevy_color::Color; use bevy_math::Mat2; use bevy_math::{Dir3, Quat, Vec2, Vec3}; -use bevy_render::color::LegacyColor; use std::f32::consts::TAU; pub(crate) const DEFAULT_CIRCLE_SEGMENTS: usize = 32; @@ -29,13 +29,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.ellipse(Vec3::ZERO, Quat::IDENTITY, Vec2::new(1., 2.), LegacyColor::GREEN); + /// gizmos.ellipse(Vec3::ZERO, Quat::IDENTITY, Vec2::new(1., 2.), GREEN); /// /// // Ellipses have 32 line-segments by default. /// // You may want to increase this for larger ellipses. /// gizmos - /// .ellipse(Vec3::ZERO, Quat::IDENTITY, Vec2::new(5., 1.), LegacyColor::RED) + /// .ellipse(Vec3::ZERO, Quat::IDENTITY, Vec2::new(5., 1.), RED) /// .segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -46,14 +47,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { position: Vec3, rotation: Quat, half_size: Vec2, - color: LegacyColor, + color: impl Into, ) -> EllipseBuilder<'_, 'w, 's, T> { EllipseBuilder { gizmos: self, position, rotation, half_size, - color, + color: color.into(), segments: DEFAULT_CIRCLE_SEGMENTS, } } @@ -67,13 +68,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.ellipse_2d(Vec2::ZERO, 180.0_f32.to_radians(), Vec2::new(2., 1.), LegacyColor::GREEN); + /// gizmos.ellipse_2d(Vec2::ZERO, 180.0_f32.to_radians(), Vec2::new(2., 1.), GREEN); /// /// // Ellipses have 32 line-segments by default. /// // You may want to increase this for larger ellipses. /// gizmos - /// .ellipse_2d(Vec2::ZERO, 180.0_f32.to_radians(), Vec2::new(5., 1.), LegacyColor::RED) + /// .ellipse_2d(Vec2::ZERO, 180.0_f32.to_radians(), Vec2::new(5., 1.), RED) /// .segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -84,14 +86,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { position: Vec2, angle: f32, half_size: Vec2, - color: LegacyColor, + color: impl Into, ) -> Ellipse2dBuilder<'_, 'w, 's, T> { Ellipse2dBuilder { gizmos: self, position, rotation: Mat2::from_angle(angle), half_size, - color, + color: color.into(), segments: DEFAULT_CIRCLE_SEGMENTS, } } @@ -105,13 +107,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.circle(Vec3::ZERO, Dir3::Z, 1., LegacyColor::GREEN); + /// gizmos.circle(Vec3::ZERO, Dir3::Z, 1., GREEN); /// /// // Circles have 32 line-segments by default. /// // You may want to increase this for larger circles. /// gizmos - /// .circle(Vec3::ZERO, Dir3::Z, 5., LegacyColor::RED) + /// .circle(Vec3::ZERO, Dir3::Z, 5., RED) /// .segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -122,14 +125,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { position: Vec3, normal: Dir3, radius: f32, - color: LegacyColor, + color: impl Into, ) -> EllipseBuilder<'_, 'w, 's, T> { EllipseBuilder { gizmos: self, position, rotation: Quat::from_rotation_arc(Vec3::Z, *normal), half_size: Vec2::splat(radius), - color, + color: color.into(), segments: DEFAULT_CIRCLE_SEGMENTS, } } @@ -143,13 +146,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.circle_2d(Vec2::ZERO, 1., LegacyColor::GREEN); + /// gizmos.circle_2d(Vec2::ZERO, 1., GREEN); /// /// // Circles have 32 line-segments by default. /// // You may want to increase this for larger circles. /// gizmos - /// .circle_2d(Vec2::ZERO, 5., LegacyColor::RED) + /// .circle_2d(Vec2::ZERO, 5., RED) /// .segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -159,14 +163,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { &mut self, position: Vec2, radius: f32, - color: LegacyColor, + color: impl Into, ) -> Ellipse2dBuilder<'_, 'w, 's, T> { Ellipse2dBuilder { gizmos: self, position, rotation: Mat2::IDENTITY, half_size: Vec2::splat(radius), - color, + color: color.into(), segments: DEFAULT_CIRCLE_SEGMENTS, } } @@ -178,7 +182,7 @@ pub struct EllipseBuilder<'a, 'w, 's, T: GizmoConfigGroup> { position: Vec3, rotation: Quat, half_size: Vec2, - color: LegacyColor, + color: Color, segments: usize, } @@ -209,7 +213,7 @@ pub struct Ellipse2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { position: Vec2, rotation: Mat2, half_size: Vec2, - color: LegacyColor, + color: Color, segments: usize, } diff --git a/crates/bevy_gizmos/src/gizmos.rs b/crates/bevy_gizmos/src/gizmos.rs index 1fc3e85287..eaef65d54e 100644 --- a/crates/bevy_gizmos/src/gizmos.rs +++ b/crates/bevy_gizmos/src/gizmos.rs @@ -3,14 +3,13 @@ use std::{iter, marker::PhantomData}; use crate::circles::DEFAULT_CIRCLE_SEGMENTS; -use bevy_color::LinearRgba; +use bevy_color::{Color, LinearRgba}; use bevy_ecs::{ component::Tick, system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam}, world::{unsafe_world_cell::UnsafeWorldCell, World}, }; use bevy_math::{Dir3, Mat2, Quat, Vec2, Vec3}; -use bevy_render::color::LegacyColor; use bevy_transform::TransformPoint; use crate::{ @@ -130,13 +129,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.line(Vec3::ZERO, Vec3::X, LegacyColor::GREEN); + /// gizmos.line(Vec3::ZERO, Vec3::X, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn line(&mut self, start: Vec3, end: Vec3, color: LegacyColor) { + pub fn line(&mut self, start: Vec3, end: Vec3, color: impl Into) { if !self.enabled { return; } @@ -153,18 +153,19 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.line_gradient(Vec3::ZERO, Vec3::X, LegacyColor::GREEN, LegacyColor::RED); + /// gizmos.line_gradient(Vec3::ZERO, Vec3::X, GREEN, RED); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn line_gradient( + pub fn line_gradient>( &mut self, start: Vec3, end: Vec3, - start_color: LegacyColor, - end_color: LegacyColor, + start_color: C, + end_color: C, ) { if !self.enabled { return; @@ -182,13 +183,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.ray(Vec3::Y, Vec3::X, LegacyColor::GREEN); + /// gizmos.ray(Vec3::Y, Vec3::X, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn ray(&mut self, start: Vec3, vector: Vec3, color: LegacyColor) { + pub fn ray(&mut self, start: Vec3, vector: Vec3, color: impl Into) { if !self.enabled { return; } @@ -204,18 +206,19 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.ray_gradient(Vec3::Y, Vec3::X, LegacyColor::GREEN, LegacyColor::RED); + /// gizmos.ray_gradient(Vec3::Y, Vec3::X, GREEN, RED); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn ray_gradient( + pub fn ray_gradient>( &mut self, start: Vec3, vector: Vec3, - start_color: LegacyColor, - end_color: LegacyColor, + start_color: C, + end_color: C, ) { if !self.enabled { return; @@ -232,19 +235,25 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.linestrip([Vec3::ZERO, Vec3::X, Vec3::Y], LegacyColor::GREEN); + /// gizmos.linestrip([Vec3::ZERO, Vec3::X, Vec3::Y], GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn linestrip(&mut self, positions: impl IntoIterator, color: LegacyColor) { + pub fn linestrip( + &mut self, + positions: impl IntoIterator, + color: impl Into, + ) { if !self.enabled { return; } self.extend_strip_positions(positions); let len = self.buffer.strip_positions.len(); - self.buffer.strip_colors.resize(len - 1, color.into()); + let linear_color = LinearRgba::from(color.into()); + self.buffer.strip_colors.resize(len - 1, linear_color); self.buffer.strip_colors.push(LinearRgba::NAN); } @@ -257,17 +266,21 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{BLUE, GREEN, RED}; /// fn system(mut gizmos: Gizmos) { /// gizmos.linestrip_gradient([ - /// (Vec3::ZERO, LegacyColor::GREEN), - /// (Vec3::X, LegacyColor::RED), - /// (Vec3::Y, LegacyColor::BLUE) + /// (Vec3::ZERO, GREEN), + /// (Vec3::X, RED), + /// (Vec3::Y, BLUE) /// ]); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn linestrip_gradient(&mut self, points: impl IntoIterator) { + pub fn linestrip_gradient>( + &mut self, + points: impl IntoIterator, + ) { if !self.enabled { return; } @@ -285,7 +298,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { for (position, color) in points { strip_positions.push(position.to_array()); - strip_colors.push(color.into()); + strip_colors.push(LinearRgba::from(color.into())); } strip_positions.push([f32::NAN; 3]); @@ -301,13 +314,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::Color; /// fn system(mut gizmos: Gizmos) { - /// gizmos.sphere(Vec3::ZERO, Quat::IDENTITY, 1., LegacyColor::BLACK); + /// gizmos.sphere(Vec3::ZERO, Quat::IDENTITY, 1., Color::BLACK); /// /// // Each circle has 32 line-segments by default. /// // You may want to increase this for larger spheres. /// gizmos - /// .sphere(Vec3::ZERO, Quat::IDENTITY, 5., LegacyColor::BLACK) + /// .sphere(Vec3::ZERO, Quat::IDENTITY, 5., Color::BLACK) /// .circle_segments(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -318,14 +332,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { position: Vec3, rotation: Quat, radius: f32, - color: LegacyColor, + color: impl Into, ) -> SphereBuilder<'_, 'w, 's, T> { SphereBuilder { gizmos: self, position, rotation, radius, - color, + color: color.into(), circle_segments: DEFAULT_CIRCLE_SEGMENTS, } } @@ -339,13 +353,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.rect(Vec3::ZERO, Quat::IDENTITY, Vec2::ONE, LegacyColor::GREEN); + /// gizmos.rect(Vec3::ZERO, Quat::IDENTITY, Vec2::ONE, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn rect(&mut self, position: Vec3, rotation: Quat, size: Vec2, color: LegacyColor) { + pub fn rect(&mut self, position: Vec3, rotation: Quat, size: Vec2, color: impl Into) { if !self.enabled { return; } @@ -362,13 +377,15 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_transform::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.cuboid(Transform::IDENTITY, LegacyColor::GREEN); + /// gizmos.cuboid(Transform::IDENTITY, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn cuboid(&mut self, transform: impl TransformPoint, color: LegacyColor) { + pub fn cuboid(&mut self, transform: impl TransformPoint, color: impl Into) { + let polymorphic_color: Color = color.into(); if !self.enabled { return; } @@ -382,13 +399,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { tlf, trf, brf, blf, tlf, // Front tlb, trb, brb, blb, tlb, // Back ]; - self.linestrip(strip_positions, color); + self.linestrip(strip_positions, polymorphic_color); let list_positions = [ trf, trb, brf, brb, blf, blb, // Front to back ]; self.extend_list_positions(list_positions); - self.add_list_color(color, 6); + + self.add_list_color(polymorphic_color, 6); } /// Draw a line in 2D from `start` to `end`. @@ -400,13 +418,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.line_2d(Vec2::ZERO, Vec2::X, LegacyColor::GREEN); + /// gizmos.line_2d(Vec2::ZERO, Vec2::X, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn line_2d(&mut self, start: Vec2, end: Vec2, color: LegacyColor) { + pub fn line_2d(&mut self, start: Vec2, end: Vec2, color: impl Into) { if !self.enabled { return; } @@ -422,18 +441,19 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.line_gradient_2d(Vec2::ZERO, Vec2::X, LegacyColor::GREEN, LegacyColor::RED); + /// gizmos.line_gradient_2d(Vec2::ZERO, Vec2::X, GREEN, RED); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn line_gradient_2d( + pub fn line_gradient_2d>( &mut self, start: Vec2, end: Vec2, - start_color: LegacyColor, - end_color: LegacyColor, + start_color: C, + end_color: C, ) { if !self.enabled { return; @@ -450,13 +470,18 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.linestrip_2d([Vec2::ZERO, Vec2::X, Vec2::Y], LegacyColor::GREEN); + /// gizmos.linestrip_2d([Vec2::ZERO, Vec2::X, Vec2::Y], GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn linestrip_2d(&mut self, positions: impl IntoIterator, color: LegacyColor) { + pub fn linestrip_2d( + &mut self, + positions: impl IntoIterator, + color: impl Into, + ) { if !self.enabled { return; } @@ -472,19 +497,20 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN, BLUE}; /// fn system(mut gizmos: Gizmos) { /// gizmos.linestrip_gradient_2d([ - /// (Vec2::ZERO, LegacyColor::GREEN), - /// (Vec2::X, LegacyColor::RED), - /// (Vec2::Y, LegacyColor::BLUE) + /// (Vec2::ZERO, GREEN), + /// (Vec2::X, RED), + /// (Vec2::Y, BLUE) /// ]); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn linestrip_gradient_2d( + pub fn linestrip_gradient_2d>( &mut self, - positions: impl IntoIterator, + positions: impl IntoIterator, ) { if !self.enabled { return; @@ -505,13 +531,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.ray_2d(Vec2::Y, Vec2::X, LegacyColor::GREEN); + /// gizmos.ray_2d(Vec2::Y, Vec2::X, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn ray_2d(&mut self, start: Vec2, vector: Vec2, color: LegacyColor) { + pub fn ray_2d(&mut self, start: Vec2, vector: Vec2, color: impl Into) { if !self.enabled { return; } @@ -527,18 +554,19 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::{RED, GREEN}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.line_gradient(Vec3::Y, Vec3::X, LegacyColor::GREEN, LegacyColor::RED); + /// gizmos.line_gradient(Vec3::Y, Vec3::X, GREEN, RED); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn ray_gradient_2d( + pub fn ray_gradient_2d>( &mut self, start: Vec2, vector: Vec2, - start_color: LegacyColor, - end_color: LegacyColor, + start_color: C, + end_color: C, ) { if !self.enabled { return; @@ -555,13 +583,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { - /// gizmos.rect_2d(Vec2::ZERO, 0., Vec2::ONE, LegacyColor::GREEN); + /// gizmos.rect_2d(Vec2::ZERO, 0., Vec2::ONE, GREEN); /// } /// # bevy_ecs::system::assert_is_system(system); /// ``` #[inline] - pub fn rect_2d(&mut self, position: Vec2, rotation: f32, size: Vec2, color: LegacyColor) { + pub fn rect_2d(&mut self, position: Vec2, rotation: f32, size: Vec2, color: impl Into) { if !self.enabled { return; } @@ -578,17 +607,22 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { } #[inline] - fn extend_list_colors(&mut self, colors: impl IntoIterator) { - self.buffer - .list_colors - .extend(colors.into_iter().map(LinearRgba::from)); + fn extend_list_colors(&mut self, colors: impl IntoIterator>) { + self.buffer.list_colors.extend( + colors + .into_iter() + .map(|color| LinearRgba::from(color.into())), + ); } #[inline] - fn add_list_color(&mut self, color: LegacyColor, count: usize) { + fn add_list_color(&mut self, color: impl Into, count: usize) { + let polymorphic_color: Color = color.into(); + let linear_color = LinearRgba::from(polymorphic_color); + self.buffer .list_colors - .extend(iter::repeat(LinearRgba::from(color)).take(count)); + .extend(iter::repeat(linear_color).take(count)); } #[inline] @@ -608,7 +642,7 @@ pub struct SphereBuilder<'a, 'w, 's, T: GizmoConfigGroup> { position: Vec3, rotation: Quat, radius: f32, - color: LegacyColor, + color: Color, circle_segments: usize, } diff --git a/crates/bevy_gizmos/src/grid.rs b/crates/bevy_gizmos/src/grid.rs index 838ce334e8..c7b0077468 100644 --- a/crates/bevy_gizmos/src/grid.rs +++ b/crates/bevy_gizmos/src/grid.rs @@ -4,8 +4,8 @@ //! and assorted support items. use crate::prelude::{GizmoConfigGroup, Gizmos}; +use bevy_color::LinearRgba; use bevy_math::{Quat, UVec2, Vec2, Vec3}; -use bevy_render::color::LegacyColor; /// A builder returned by [`Gizmos::grid`] and [`Gizmos::grid_2d`] pub struct GridBuilder<'a, 'w, 's, T: GizmoConfigGroup> { @@ -16,7 +16,7 @@ pub struct GridBuilder<'a, 'w, 's, T: GizmoConfigGroup> { cell_count: UVec2, skew: Vec2, outer_edges: bool, - color: LegacyColor, + color: LinearRgba, } impl GridBuilder<'_, '_, '_, T> { @@ -126,13 +126,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { /// gizmos.grid( /// Vec3::ZERO, /// Quat::IDENTITY, /// UVec2::new(10, 10), /// Vec2::splat(2.), - /// LegacyColor::GREEN + /// GREEN /// ) /// .skew_x(0.25) /// .outer_edges(true); @@ -145,7 +146,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { rotation: Quat, cell_count: UVec2, spacing: Vec2, - color: LegacyColor, + color: impl Into, ) -> GridBuilder<'_, 'w, 's, T> { GridBuilder { gizmos: self, @@ -155,7 +156,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { cell_count, skew: Vec2::ZERO, outer_edges: false, - color, + color: color.into(), } } @@ -181,13 +182,14 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { /// # use bevy_gizmos::prelude::*; /// # use bevy_render::prelude::*; /// # use bevy_math::prelude::*; + /// # use bevy_color::palettes::basic::GREEN; /// fn system(mut gizmos: Gizmos) { /// gizmos.grid_2d( /// Vec2::ZERO, /// 0.0, /// UVec2::new(10, 10), /// Vec2::splat(1.), - /// LegacyColor::GREEN + /// GREEN /// ) /// .skew_x(0.25) /// .outer_edges(true); @@ -200,7 +202,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { rotation: f32, cell_count: UVec2, spacing: Vec2, - color: LegacyColor, + color: impl Into, ) -> GridBuilder<'_, 'w, 's, T> { GridBuilder { gizmos: self, @@ -210,7 +212,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> { cell_count, skew: Vec2::ZERO, outer_edges: false, - color, + color: color.into(), } } } diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index 188c726efc..dc0db0cbfa 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -5,8 +5,9 @@ //! # use bevy_gizmos::prelude::*; //! # use bevy_render::prelude::*; //! # use bevy_math::prelude::*; +//! # use bevy_color::palettes::basic::GREEN; //! fn system(mut gizmos: Gizmos) { -//! gizmos.line(Vec3::ZERO, Vec3::X, LegacyColor::GREEN); +//! gizmos.line(Vec3::ZERO, Vec3::X, GREEN); //! } //! # bevy_ecs::system::assert_is_system(system); //! ``` diff --git a/crates/bevy_gizmos/src/primitives/dim2.rs b/crates/bevy_gizmos/src/primitives/dim2.rs index a5c242ab56..dfc2813b5e 100644 --- a/crates/bevy_gizmos/src/primitives/dim2.rs +++ b/crates/bevy_gizmos/src/primitives/dim2.rs @@ -4,12 +4,12 @@ use std::f32::consts::PI; use super::helpers::*; +use bevy_color::Color; use bevy_math::primitives::{ BoxedPolygon, BoxedPolyline2d, Capsule2d, Circle, Ellipse, Line2d, Plane2d, Polygon, Polyline2d, Primitive2d, Rectangle, RegularPolygon, Segment2d, Triangle2d, }; use bevy_math::{Dir2, Mat2, Vec2}; -use bevy_render::color::LegacyColor; use crate::prelude::{GizmoConfigGroup, Gizmos}; @@ -32,7 +32,7 @@ pub trait GizmoPrimitive2d { primitive: P, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_>; } @@ -46,7 +46,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T> { primitive: Dir2, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -70,7 +70,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T> primitive: Circle, position: Vec2, _angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -90,7 +90,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T primitive: Ellipse, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -110,8 +110,10 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, primitive: Capsule2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { + let polymorphic_color: Color = color.into(); + if !self.enabled { return; } @@ -136,8 +138,8 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, .map(rotate_then_translate_2d(angle, position)); // draw left and right side of capsule "rectangle" - self.line_2d(bottom_left, top_left, color); - self.line_2d(bottom_right, top_right, color); + self.line_2d(bottom_left, top_left, polymorphic_color); + self.line_2d(bottom_right, top_right, polymorphic_color); // if the capsule is rotated we have to start the arc at a different offset angle, // calculate that here @@ -146,13 +148,19 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, let start_angle_bottom = PI + angle_offset; // draw arcs - self.arc_2d(top_center, start_angle_top, PI, primitive.radius, color); + self.arc_2d( + top_center, + start_angle_top, + PI, + primitive.radius, + polymorphic_color, + ); self.arc_2d( bottom_center, start_angle_bottom, PI, primitive.radius, - color, + polymorphic_color, ); } } @@ -165,9 +173,9 @@ pub struct Line2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { direction: Dir2, // Direction of the line - position: Vec2, // position of the center of the line - rotation: Mat2, // rotation of the line - color: LegacyColor, // color of the line + position: Vec2, // position of the center of the line + rotation: Mat2, // rotation of the line + color: Color, // color of the line draw_arrow: bool, // decides whether to indicate the direction of the line with an arrow } @@ -188,14 +196,14 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T> primitive: Line2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { Line2dBuilder { gizmos: self, direction: primitive.direction, position, rotation: Mat2::from_angle(angle), - color, + color: color.into(), draw_arrow: false, } } @@ -239,8 +247,10 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T primitive: Plane2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { + let polymorphic_color: Color = color.into(); + if !self.enabled { return; } @@ -257,13 +267,13 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T // offset the normal so it starts on the plane line position + HALF_MIN_LINE_LEN * rotation * *normal, angle, - color, + polymorphic_color, ) .draw_arrow(true); // draw the plane line let direction = Dir2::new_unchecked(-normal.perp()); - self.primitive_2d(Line2d { direction }, position, angle, color) + self.primitive_2d(Line2d { direction }, position, angle, polymorphic_color) .draw_arrow(false); // draw an arrow such that the normal is always left side of the plane with respect to the @@ -271,7 +281,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, T self.arrow_2d( position, position + MIN_LINE_LEN * (rotation * *direction), - color, + polymorphic_color, ); } } @@ -285,9 +295,9 @@ pub struct Segment2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { direction: Dir2, // Direction of the line segment half_length: f32, // Half-length of the line segment - position: Vec2, // position of the center of the line segment - rotation: Mat2, // rotation of the line segment - color: LegacyColor, // color of the line segment + position: Vec2, // position of the center of the line segment + rotation: Mat2, // rotation of the line segment + color: Color, // color of the line segment draw_arrow: bool, // decides whether to draw just a line or an arrow } @@ -308,7 +318,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, primitive: Segment2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { Segment2dBuilder { gizmos: self, @@ -317,7 +327,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, position, rotation: Mat2::from_angle(angle), - color, + color: color.into(), draw_arrow: Default::default(), } @@ -354,7 +364,7 @@ impl<'w, 's, const N: usize, T: GizmoConfigGroup> GizmoPrimitive2d primitive: Polyline2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -381,7 +391,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<' primitive: BoxedPolyline2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -408,7 +418,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's primitive: Triangle2d, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -429,7 +439,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, 's, primitive: Rectangle, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -459,7 +469,7 @@ impl<'w, 's, const N: usize, T: GizmoConfigGroup> GizmoPrimitive2d> primitive: Polygon, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -496,7 +506,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w, primitive: BoxedPolygon, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; @@ -531,7 +541,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive2d for Gizmos<'w primitive: RegularPolygon, position: Vec2, angle: f32, - color: LegacyColor, + color: impl Into, ) -> Self::Output<'_> { if !self.enabled { return; diff --git a/crates/bevy_gizmos/src/primitives/dim3.rs b/crates/bevy_gizmos/src/primitives/dim3.rs index f989fd9ac0..6359517a68 100644 --- a/crates/bevy_gizmos/src/primitives/dim3.rs +++ b/crates/bevy_gizmos/src/primitives/dim3.rs @@ -3,12 +3,12 @@ use super::helpers::*; use std::f32::consts::TAU; +use bevy_color::Color; use bevy_math::primitives::{ BoxedPolyline3d, Capsule3d, Cone, ConicalFrustum, Cuboid, Cylinder, Line3d, Plane3d, Polyline3d, Primitive3d, Segment3d, Sphere, Torus, }; use bevy_math::{Dir3, Quat, Vec3}; -use bevy_render::color::LegacyColor; use crate::prelude::{GizmoConfigGroup, Gizmos}; @@ -29,7 +29,7 @@ pub trait GizmoPrimitive3d { primitive: P, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_>; } @@ -43,7 +43,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> { primitive: Dir3, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { self.arrow(position, position + (rotation * *primitive), color); } @@ -63,7 +63,7 @@ pub struct SphereBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // Center position of the sphere in 3D space position: Vec3, // Color of the sphere - color: LegacyColor, + color: Color, // Number of segments used to approximate the sphere geometry segments: usize, @@ -85,7 +85,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> primitive: Sphere, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { SphereBuilder { gizmos: self, @@ -146,7 +146,7 @@ pub struct Plane3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // Center position of the sphere in 3D space position: Vec3, // Color of the sphere - color: LegacyColor, + color: Color, // Number of axis to hint the plane axis_count: usize, @@ -184,7 +184,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T primitive: Plane3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { Plane3dBuilder { gizmos: self, @@ -251,7 +251,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> primitive: Line3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { if !self.enabled { return; @@ -278,7 +278,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, primitive: Segment3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { if !self.enabled { return; @@ -303,7 +303,7 @@ impl<'w, 's, const N: usize, T: GizmoConfigGroup> GizmoPrimitive3d primitive: Polyline3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { if !self.enabled { return; @@ -328,7 +328,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<' primitive: BoxedPolyline3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { if !self.enabled { return; @@ -355,7 +355,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> primitive: Cuboid, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { if !self.enabled { return; @@ -417,7 +417,7 @@ pub struct Cylinder3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // default orientation is: the cylinder is aligned with `Vec3::Y` axis rotation: Quat, // Color of the cylinder - color: LegacyColor, + color: Color, // Number of segments used to approximate the cylinder geometry segments: usize, @@ -439,7 +439,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, primitive: Cylinder, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { Cylinder3dBuilder { gizmos: self, @@ -514,7 +514,7 @@ pub struct Capsule3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // default orientation is: the capsule is aligned with `Vec3::Y` axis rotation: Quat, // Color of the capsule - color: LegacyColor, + color: Color, // Number of segments used to approximate the capsule geometry segments: usize, @@ -536,7 +536,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, primitive: Capsule3d, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { Capsule3dBuilder { gizmos: self, @@ -607,7 +607,7 @@ pub struct Cone3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // default orientation is: cone base normal is aligned with the `Vec3::Y` axis rotation: Quat, // Color of the cone - color: LegacyColor, + color: Color, // Number of segments used to approximate the cone geometry segments: usize, @@ -629,7 +629,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> { primitive: Cone, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { Cone3dBuilder { gizmos: self, @@ -703,7 +703,7 @@ pub struct ConicalFrustum3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // default orientation is: conical frustum base shape normals are aligned with `Vec3::Y` axis rotation: Quat, // Color of the conical frustum - color: LegacyColor, + color: Color, // Number of segments used to approximate the curved surfaces segments: usize, @@ -725,7 +725,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w primitive: ConicalFrustum, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { ConicalFrustum3dBuilder { gizmos: self, @@ -807,7 +807,7 @@ pub struct Torus3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> { // default orientation is: major circle normal is aligned with `Vec3::Y` axis rotation: Quat, // Color of the torus - color: LegacyColor, + color: Color, // Number of segments in the minor (tube) direction minor_segments: usize, @@ -837,7 +837,7 @@ impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d for Gizmos<'w, 's, T> primitive: Torus, position: Vec3, rotation: Quat, - color: LegacyColor, + color: Color, ) -> Self::Output<'_> { Torus3dBuilder { gizmos: self, diff --git a/crates/bevy_gizmos/src/primitives/helpers.rs b/crates/bevy_gizmos/src/primitives/helpers.rs index 54669930c9..3de0502829 100644 --- a/crates/bevy_gizmos/src/primitives/helpers.rs +++ b/crates/bevy_gizmos/src/primitives/helpers.rs @@ -1,7 +1,7 @@ use std::f32::consts::TAU; +use bevy_color::Color; use bevy_math::{Mat2, Quat, Vec2, Vec3}; -use bevy_render::color::LegacyColor; use crate::prelude::{GizmoConfigGroup, Gizmos}; @@ -58,7 +58,7 @@ pub(crate) fn draw_semi_sphere( rotation: Quat, center: Vec3, top: Vec3, - color: LegacyColor, + color: Color, ) { circle_coordinates(radius, segments) .map(|p| Vec3::new(p.x, 0.0, p.y)) @@ -81,7 +81,7 @@ pub(crate) fn draw_circle_3d( segments: usize, rotation: Quat, translation: Vec3, - color: LegacyColor, + color: Color, ) { let positions = (0..=segments) .map(|frac| frac as f32 / segments as f32) @@ -100,7 +100,7 @@ pub(crate) fn draw_cylinder_vertical_lines( half_height: f32, rotation: Quat, center: Vec3, - color: LegacyColor, + color: Color, ) { circle_coordinates(radius, segments) .map(move |point_2d| { diff --git a/crates/bevy_gltf/Cargo.toml b/crates/bevy_gltf/Cargo.toml index a73dfacaf7..2d7817f6f4 100644 --- a/crates/bevy_gltf/Cargo.toml +++ b/crates/bevy_gltf/Cargo.toml @@ -17,6 +17,7 @@ pbr_transmission_textures = [] bevy_animation = { path = "../bevy_animation", version = "0.14.0-dev", optional = true } bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_core = { path = "../bevy_core", version = "0.14.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index c6200a6339..ca6a309684 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -3,6 +3,7 @@ use bevy_animation::{AnimationTarget, AnimationTargetId}; use bevy_asset::{ io::Reader, AssetLoadError, AssetLoader, AsyncReadExt, Handle, LoadContext, ReadAssetBytesError, }; +use bevy_color::{Color, LinearRgba}; use bevy_core::Name; use bevy_core_pipeline::prelude::Camera3dBundle; use bevy_ecs::entity::EntityHashMap; @@ -17,7 +18,6 @@ use bevy_pbr::{ use bevy_render::{ alpha::AlphaMode, camera::{Camera, OrthographicProjection, PerspectiveProjection, Projection, ScalingMode}, - color::LegacyColor, mesh::{ morph::{MeshMorphWeights, MorphAttributes, MorphTargetImage, MorphWeights}, skinning::{SkinnedMesh, SkinnedMeshInverseBindposes}, @@ -913,8 +913,13 @@ fn load_material( let ior = material.ior().unwrap_or(1.5); + // We need to operate in the Linear color space and be willing to exceed 1.0 in our channels + let base_emissive = LinearRgba::rgb(emissive[0], emissive[1], emissive[2]); + let scaled_emissive = base_emissive * material.emissive_strength().unwrap_or(1.0); + let emissive = Color::from(scaled_emissive); + StandardMaterial { - base_color: LegacyColor::rgba_linear(color[0], color[1], color[2], color[3]), + base_color: Color::linear_rgba(color[0], color[1], color[2], color[3]), base_color_texture, perceptual_roughness: pbr.roughness_factor(), metallic: pbr.metallic_factor(), @@ -929,8 +934,7 @@ fn load_material( Some(Face::Back) }, occlusion_texture, - emissive: LegacyColor::rgb_linear(emissive[0], emissive[1], emissive[2]) - * material.emissive_strength().unwrap_or(1.0), + emissive, emissive_texture, specular_transmission, #[cfg(feature = "pbr_transmission_textures")] @@ -940,7 +944,7 @@ fn load_material( thickness_texture, ior, attenuation_distance, - attenuation_color: LegacyColor::rgb_linear( + attenuation_color: Color::linear_rgb( attenuation_color[0], attenuation_color[1], attenuation_color[2], @@ -1169,7 +1173,7 @@ fn load_node( gltf::khr_lights_punctual::Kind::Directional => { let mut entity = parent.spawn(DirectionalLightBundle { directional_light: DirectionalLight { - color: LegacyColor::rgb_from_array(light.color()), + color: Color::srgb_from_array(light.color()), // NOTE: KHR_punctual_lights defines the intensity units for directional // lights in lux (lm/m^2) which is what we need. illuminance: light.intensity(), @@ -1189,7 +1193,7 @@ fn load_node( gltf::khr_lights_punctual::Kind::Point => { let mut entity = parent.spawn(PointLightBundle { point_light: PointLight { - color: LegacyColor::rgb_from_array(light.color()), + color: Color::srgb_from_array(light.color()), // NOTE: KHR_punctual_lights defines the intensity units for point lights in // candela (lm/sr) which is luminous intensity and we need luminous power. // For a point light, luminous power = 4 * pi * luminous intensity @@ -1215,7 +1219,7 @@ fn load_node( } => { let mut entity = parent.spawn(SpotLightBundle { spot_light: SpotLight { - color: LegacyColor::rgb_from_array(light.color()), + color: Color::srgb_from_array(light.color()), // NOTE: KHR_punctual_lights defines the intensity units for spot lights in // candela (lm/sr) which is luminous intensity and we need luminous power. // For a spot light, we map luminous power = 4 * pi * luminous intensity diff --git a/crates/bevy_internal/src/lib.rs b/crates/bevy_internal/src/lib.rs index 02a3440d1a..25a2584c7d 100644 --- a/crates/bevy_internal/src/lib.rs +++ b/crates/bevy_internal/src/lib.rs @@ -183,8 +183,9 @@ pub mod gizmos { //! # use bevy_gizmos::prelude::*; //! # use bevy_render::prelude::*; //! # use bevy_math::prelude::*; + //! # use bevy_color::palettes::basic::GREEN; //! fn system(mut gizmos: Gizmos) { - //! gizmos.line(Vec3::ZERO, Vec3::X, LegacyColor::GREEN); + //! gizmos.line(Vec3::ZERO, Vec3::X, GREEN); //! } //! # bevy_ecs::system::assert_is_system(system); //! ``` diff --git a/crates/bevy_pbr/Cargo.toml b/crates/bevy_pbr/Cargo.toml index e6b2c4637a..1e05323c85 100644 --- a/crates/bevy_pbr/Cargo.toml +++ b/crates/bevy_pbr/Cargo.toml @@ -20,6 +20,7 @@ ios_simulator = ["bevy_render/ios_simulator"] # bevy bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_math = { path = "../bevy_math", version = "0.14.0-dev" } diff --git a/crates/bevy_pbr/src/fog.rs b/crates/bevy_pbr/src/fog.rs index 4a8af5a603..8ed7533a6c 100644 --- a/crates/bevy_pbr/src/fog.rs +++ b/crates/bevy_pbr/src/fog.rs @@ -1,7 +1,8 @@ +use bevy_color::{Color, LinearRgba}; use bevy_ecs::prelude::*; use bevy_math::Vec3; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{color::LegacyColor, extract_component::ExtractComponent, prelude::Camera}; +use bevy_render::{extract_component::ExtractComponent, prelude::Camera}; /// Configures the “classic” computer graphics [distance fog](https://en.wikipedia.org/wiki/Distance_fog) effect, /// in which objects appear progressively more covered in atmospheric haze the further away they are from the camera. @@ -24,6 +25,7 @@ use bevy_render::{color::LegacyColor, extract_component::ExtractComponent, prelu /// # use bevy_render::prelude::*; /// # use bevy_core_pipeline::prelude::*; /// # use bevy_pbr::prelude::*; +/// # use bevy_color::Color; /// # fn system(mut commands: Commands) { /// commands.spawn(( /// // Setup your camera as usual @@ -33,7 +35,7 @@ use bevy_render::{color::LegacyColor, extract_component::ExtractComponent, prelu /// }, /// // Add fog to the same entity /// FogSettings { -/// color: LegacyColor::WHITE, +/// color: Color::WHITE, /// falloff: FogFalloff::Exponential { density: 1e-3 }, /// ..Default::default() /// }, @@ -54,14 +56,14 @@ pub struct FogSettings { /// /// **Tip:** The alpha channel of the color can be used to “modulate” the fog effect without /// changing the fog falloff mode or parameters. - pub color: LegacyColor, + pub color: Color, /// Color used to modulate the influence of directional light colors on the /// fog, where the view direction aligns with each directional light direction, /// producing a “glow” or light dispersion effect. (e.g. around the sun) /// - /// Use [`LegacyColor::NONE`] to disable the effect. - pub directional_light_color: LegacyColor, + /// Use [`Color::NONE`] to disable the effect. + pub directional_light_color: Color, /// The exponent applied to the directional light alignment calculation. /// A higher value means a more concentrated “glow”. @@ -345,7 +347,7 @@ impl FogFalloff { /// [`FogFalloff::REVISED_KOSCHMIEDER_CONTRAST_THRESHOLD`]. pub fn from_visibility_color( visibility: f32, - extinction_inscattering_color: LegacyColor, + extinction_inscattering_color: Color, ) -> FogFalloff { FogFalloff::from_visibility_contrast_colors( visibility, @@ -361,12 +363,12 @@ impl FogFalloff { /// /// ## Tips /// - Alpha values of the provided colors can modulate the `extinction` and `inscattering` effects; - /// - Using an `extinction_color` of [`LegacyColor::WHITE`] or [`LegacyColor::NONE`] disables the extinction effect; - /// - Using an `inscattering_color` of [`LegacyColor::BLACK`] or [`LegacyColor::NONE`] disables the inscattering effect. + /// - Using an `extinction_color` of [`Color::WHITE`] or [`Color::NONE`] disables the extinction effect; + /// - Using an `inscattering_color` of [`Color::BLACK`] or [`Color::NONE`] disables the inscattering effect. pub fn from_visibility_colors( visibility: f32, - extinction_color: LegacyColor, - inscattering_color: LegacyColor, + extinction_color: Color, + inscattering_color: Color, ) -> FogFalloff { FogFalloff::from_visibility_contrast_colors( visibility, @@ -381,7 +383,7 @@ impl FogFalloff { pub fn from_visibility_contrast_color( visibility: f32, contrast_threshold: f32, - extinction_inscattering_color: LegacyColor, + extinction_inscattering_color: Color, ) -> FogFalloff { FogFalloff::from_visibility_contrast_colors( visibility, @@ -396,18 +398,18 @@ impl FogFalloff { /// /// ## Tips /// - Alpha values of the provided colors can modulate the `extinction` and `inscattering` effects; - /// - Using an `extinction_color` of [`LegacyColor::WHITE`] or [`LegacyColor::NONE`] disables the extinction effect; - /// - Using an `inscattering_color` of [`LegacyColor::BLACK`] or [`LegacyColor::NONE`] disables the inscattering effect. + /// - Using an `extinction_color` of [`Color::WHITE`] or [`Color::NONE`] disables the extinction effect; + /// - Using an `inscattering_color` of [`Color::BLACK`] or [`Color::NONE`] disables the inscattering effect. pub fn from_visibility_contrast_colors( visibility: f32, contrast_threshold: f32, - extinction_color: LegacyColor, - inscattering_color: LegacyColor, + extinction_color: Color, + inscattering_color: Color, ) -> FogFalloff { use std::f32::consts::E; - let [r_e, g_e, b_e, a_e] = extinction_color.as_linear_rgba_f32(); - let [r_i, g_i, b_i, a_i] = inscattering_color.as_linear_rgba_f32(); + let [r_e, g_e, b_e, a_e] = LinearRgba::from(extinction_color).to_f32_array(); + let [r_i, g_i, b_i, a_i] = LinearRgba::from(inscattering_color).to_f32_array(); FogFalloff::Atmospheric { extinction: Vec3::new( @@ -464,12 +466,12 @@ impl FogFalloff { impl Default for FogSettings { fn default() -> Self { FogSettings { - color: LegacyColor::rgba(1.0, 1.0, 1.0, 1.0), + color: Color::WHITE, falloff: FogFalloff::Linear { start: 0.0, end: 100.0, }, - directional_light_color: LegacyColor::NONE, + directional_light_color: Color::NONE, directional_light_exponent: 8.0, } } diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index e13b2e9521..bc06f4d34d 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -17,6 +17,7 @@ mod prepass; mod render; mod ssao; +use bevy_color::{Color, LinearRgba}; pub use bundle::*; pub use extended_material::*; pub use fog::*; @@ -73,7 +74,6 @@ use bevy_render::{ camera::{CameraUpdateSystem, Projection}, extract_component::ExtractComponentPlugin, extract_resource::ExtractResourcePlugin, - prelude::LegacyColor, render_asset::prepare_assets, render_graph::RenderGraph, render_phase::sort_phase_system, @@ -336,7 +336,7 @@ impl Plugin for PbrPlugin { app.world.resource_mut::>().insert( Handle::::default(), StandardMaterial { - base_color: LegacyColor::rgb(1.0, 0.0, 0.5), + base_color: Color::srgb(1.0, 0.0, 0.5), unlit: true, ..Default::default() }, diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 69a5958817..ac94689bc3 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -97,7 +97,7 @@ pub mod light_consts { #[derive(Component, Debug, Clone, Copy, Reflect)] #[reflect(Component, Default)] pub struct PointLight { - pub color: LegacyColor, + pub color: Color, /// Luminous power in lumens, representing the amount of light emitted by this source in all directions. pub intensity: f32, pub range: f32, @@ -113,7 +113,7 @@ pub struct PointLight { impl Default for PointLight { fn default() -> Self { PointLight { - color: LegacyColor::rgb(1.0, 1.0, 1.0), + color: Color::WHITE, // 1,000,000 lumens is a very large "cinema light" capable of registering brightly at Bevy's // default "very overcast day" exposure level. For "indoor lighting" with a lower exposure, // this would be way too bright. @@ -151,7 +151,7 @@ impl Default for PointLightShadowMap { #[derive(Component, Debug, Clone, Copy, Reflect)] #[reflect(Component, Default)] pub struct SpotLight { - pub color: LegacyColor, + pub color: Color, /// Luminous power in lumens, representing the amount of light emitted by this source in all directions. pub intensity: f32, pub range: f32, @@ -184,7 +184,7 @@ impl Default for SpotLight { fn default() -> Self { // a quarter arc attenuating from the center Self { - color: LegacyColor::rgb(1.0, 1.0, 1.0), + color: Color::WHITE, // 1,000,000 lumens is a very large "cinema light" capable of registering brightly at Bevy's // default "very overcast day" exposure level. For "indoor lighting" with a lower exposure, // this would be way too bright. @@ -250,7 +250,7 @@ impl Default for SpotLight { #[derive(Component, Debug, Clone, Reflect)] #[reflect(Component, Default)] pub struct DirectionalLight { - pub color: LegacyColor, + pub color: Color, /// Illuminance in lux (lumens per square meter), representing the amount of /// light projected onto surfaces by this light source. Lux is used here /// instead of lumens because a directional light illuminates all surfaces @@ -268,7 +268,7 @@ pub struct DirectionalLight { impl Default for DirectionalLight { fn default() -> Self { DirectionalLight { - color: LegacyColor::rgb(1.0, 1.0, 1.0), + color: Color::WHITE, illuminance: light_consts::lux::AMBIENT_DAYLIGHT, shadows_enabled: false, shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS, @@ -635,7 +635,7 @@ fn calculate_cascade( #[derive(Resource, Clone, Debug, ExtractResource, Reflect)] #[reflect(Resource)] pub struct AmbientLight { - pub color: LegacyColor, + pub color: Color, /// A direct scale factor multiplied with `color` before being passed to the shader. pub brightness: f32, } @@ -643,14 +643,14 @@ pub struct AmbientLight { impl Default for AmbientLight { fn default() -> Self { Self { - color: LegacyColor::WHITE, + color: Color::WHITE, brightness: 80.0, } } } impl AmbientLight { pub const NONE: AmbientLight = AmbientLight { - color: LegacyColor::WHITE, + color: Color::WHITE, brightness: 0.0, }; } diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 9fe9abd1a8..aab0ea7a1e 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -49,7 +49,9 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight}; /// # use bevy_pbr::{Material, MaterialMeshBundle}; /// # use bevy_ecs::prelude::*; /// # use bevy_reflect::TypePath; -/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image, color::LegacyColor}; +/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image}; +/// # use bevy_color::LinearRgba; +/// # use bevy_color::palettes::basic::RED; /// # use bevy_asset::{Handle, AssetServer, Assets, Asset}; /// /// #[derive(AsBindGroup, Debug, Clone, Asset, TypePath)] @@ -57,7 +59,7 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight}; /// // Uniform bindings must implement `ShaderType`, which will be used to convert the value to /// // its shader-compatible equivalent. Most core math types already implement `ShaderType`. /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// // Images can be bound as textures in shaders. If the Image's sampler is also needed, just /// // add the sampler attribute with a different binding index. /// #[texture(1)] @@ -77,7 +79,7 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight}; /// fn setup(mut commands: Commands, mut materials: ResMut>, asset_server: Res) { /// commands.spawn(MaterialMeshBundle { /// material: materials.add(CustomMaterial { -/// color: LegacyColor::RED, +/// color: RED.into(), /// color_texture: asset_server.load("some_image.png"), /// }), /// ..Default::default() diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 5ad7080231..135e720ce1 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -1,4 +1,5 @@ use bevy_asset::Asset; +use bevy_color::Alpha; use bevy_math::{Affine2, Mat3, Vec4}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{mesh::MeshVertexBufferLayout, render_asset::RenderAssets, render_resource::*}; @@ -10,7 +11,7 @@ use crate::*; /// Standard property values with pictures here /// . /// -/// May be created directly from a [`LegacyColor`] or an [`Image`]. +/// May be created directly from a [`Color`] or an [`Image`]. #[derive(Asset, AsBindGroup, Reflect, Debug, Clone)] #[bind_group_data(StandardMaterialKey)] #[uniform(0, StandardMaterialUniform)] @@ -22,15 +23,15 @@ pub struct StandardMaterial { /// in between. If used together with a `base_color_texture`, this is factored into the final /// base color as `base_color * base_color_texture_value` /// - /// Defaults to [`LegacyColor::WHITE`]. - pub base_color: LegacyColor, + /// Defaults to [`Color::WHITE`]. + pub base_color: Color, /// The texture component of the material's color before lighting. /// The actual pre-lighting color is `base_color * this_texture`. /// /// See [`base_color`] for details. /// - /// You should set `base_color` to [`LegacyColor::WHITE`] (the default) + /// You should set `base_color` to [`Color::WHITE`] (the default) /// if you want the texture to show as-is. /// /// Setting `base_color` to something else than white will tint @@ -54,17 +55,17 @@ pub struct StandardMaterial { /// This means that for a light emissive value, in darkness, /// you will mostly see the emissive component. /// - /// The default emissive color is black, which doesn't add anything to the material color. + /// The default emissive color is [`Color::BLACK`], which doesn't add anything to the material color. /// /// Note that **an emissive material won't light up surrounding areas like a light source**, /// it just adds a value to the color seen on screen. - pub emissive: LegacyColor, + pub emissive: Color, /// The emissive map, multiplies pixels with [`emissive`] /// to get the final "emitting" color of a surface. /// /// This color is multiplied by [`emissive`] to get the final emitted color. - /// Meaning that you should set [`emissive`] to [`LegacyColor::WHITE`] + /// Meaning that you should set [`emissive`] to [`Color::WHITE`] /// if you want to use the full range of color of the emissive texture. /// /// [`emissive`]: StandardMaterial::emissive @@ -271,7 +272,7 @@ pub struct StandardMaterial { /// The resulting (non-absorbed) color after white light travels through the attenuation distance. /// - /// Defaults to [`LegacyColor::WHITE`], i.e. no change. + /// Defaults to [`Color::WHITE`], i.e. no change. /// /// **Note:** To have any effect, must be used in conjunction with: /// - [`StandardMaterial::attenuation_distance`]; @@ -279,7 +280,7 @@ pub struct StandardMaterial { /// - [`StandardMaterial::diffuse_transmission`] or [`StandardMaterial::specular_transmission`]. #[doc(alias = "absorption_color")] #[doc(alias = "extinction_color")] - pub attenuation_color: LegacyColor, + pub attenuation_color: Color, /// Used to fake the lighting of bumps and dents on a material. /// @@ -479,9 +480,9 @@ impl Default for StandardMaterial { StandardMaterial { // White because it gets multiplied with texture values if someone uses // a texture. - base_color: LegacyColor::rgb(1.0, 1.0, 1.0), + base_color: Color::WHITE, base_color_texture: None, - emissive: LegacyColor::BLACK, + emissive: Color::BLACK, emissive_texture: None, // Matches Blender's default roughness. perceptual_roughness: 0.5, @@ -502,7 +503,7 @@ impl Default for StandardMaterial { #[cfg(feature = "pbr_transmission_textures")] thickness_texture: None, ior: 1.5, - attenuation_color: LegacyColor::WHITE, + attenuation_color: Color::WHITE, attenuation_distance: f32::INFINITY, occlusion_texture: None, normal_map_texture: None, @@ -525,11 +526,11 @@ impl Default for StandardMaterial { } } -impl From for StandardMaterial { - fn from(color: LegacyColor) -> Self { +impl From for StandardMaterial { + fn from(color: Color) -> Self { StandardMaterial { base_color: color, - alpha_mode: if color.a() < 1.0 { + alpha_mode: if color.alpha() < 1.0 { AlphaMode::Blend } else { AlphaMode::Opaque @@ -714,8 +715,8 @@ impl AsBindGroupShaderType for StandardMaterial { } StandardMaterialUniform { - base_color: self.base_color.as_linear_rgba_f32().into(), - emissive: self.emissive.as_linear_rgba_f32().into(), + base_color: LinearRgba::from(self.base_color).to_f32_array().into(), + emissive: LinearRgba::from(self.base_color).to_f32_array().into(), roughness: self.perceptual_roughness, metallic: self.metallic, reflectance: self.reflectance, @@ -724,7 +725,7 @@ impl AsBindGroupShaderType for StandardMaterial { thickness: self.thickness, ior: self.ior, attenuation_distance: self.attenuation_distance, - attenuation_color: self.attenuation_color.as_linear_rgba_f32().into(), + attenuation_color: LinearRgba::from(self.base_color).to_f32_array().into(), flags: flags.bits(), alpha_cutoff, parallax_depth_scale: self.parallax_depth_scale, diff --git a/crates/bevy_pbr/src/render/fog.rs b/crates/bevy_pbr/src/render/fog.rs index 1738b261b5..27dce7eb4a 100644 --- a/crates/bevy_pbr/src/render/fog.rs +++ b/crates/bevy_pbr/src/render/fog.rs @@ -1,5 +1,6 @@ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; +use bevy_color::LinearRgba; use bevy_ecs::prelude::*; use bevy_math::{Vec3, Vec4}; use bevy_render::{ @@ -65,33 +66,24 @@ pub fn prepare_fog( match &fog.falloff { FogFalloff::Linear { start, end } => GpuFog { mode: GPU_FOG_MODE_LINEAR, - base_color: fog.color.as_linear_rgba_f32().into(), - directional_light_color: fog - .directional_light_color - .as_linear_rgba_f32() - .into(), + base_color: LinearRgba::from(fog.color).into(), + directional_light_color: LinearRgba::from(fog.directional_light_color).into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*start, *end, 0.0), ..Default::default() }, FogFalloff::Exponential { density } => GpuFog { mode: GPU_FOG_MODE_EXPONENTIAL, - base_color: fog.color.as_linear_rgba_f32().into(), - directional_light_color: fog - .directional_light_color - .as_linear_rgba_f32() - .into(), + base_color: LinearRgba::from(fog.color).into(), + directional_light_color: LinearRgba::from(fog.directional_light_color).into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*density, 0.0, 0.0), ..Default::default() }, FogFalloff::ExponentialSquared { density } => GpuFog { mode: GPU_FOG_MODE_EXPONENTIAL_SQUARED, - base_color: fog.color.as_linear_rgba_f32().into(), - directional_light_color: fog - .directional_light_color - .as_linear_rgba_f32() - .into(), + base_color: LinearRgba::from(fog.color).into(), + directional_light_color: LinearRgba::from(fog.directional_light_color).into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*density, 0.0, 0.0), ..Default::default() @@ -101,11 +93,8 @@ pub fn prepare_fog( inscattering, } => GpuFog { mode: GPU_FOG_MODE_ATMOSPHERIC, - base_color: fog.color.as_linear_rgba_f32().into(), - directional_light_color: fog - .directional_light_color - .as_linear_rgba_f32() - .into(), + base_color: LinearRgba::from(fog.color).into(), + directional_light_color: LinearRgba::from(fog.directional_light_color).into(), directional_light_exponent: fog.directional_light_exponent, be: *extinction, bi: *inscattering, diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 1259665d58..54eec94111 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -28,7 +28,7 @@ use crate::*; #[derive(Component)] pub struct ExtractedPointLight { - pub color: LegacyColor, + pub color: LinearRgba, /// luminous intensity in lumens per steradian pub intensity: f32, pub range: f32, @@ -42,7 +42,7 @@ pub struct ExtractedPointLight { #[derive(Component, Debug)] pub struct ExtractedDirectionalLight { - pub color: LegacyColor, + pub color: LinearRgba, pub illuminance: f32, pub transform: GlobalTransform, pub shadows_enabled: bool, @@ -384,7 +384,7 @@ pub fn extract_lights( // However, since exclusive access to the main world in extract is ill-advised, we just clone here. let render_cubemap_visible_entities = cubemap_visible_entities.clone(); let extracted_point_light = ExtractedPointLight { - color: point_light.color, + color: point_light.color.into(), // NOTE: Map from luminous power in lumens to luminous intensity in lumens per steradian // for a point light. See https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower // for details. @@ -430,7 +430,7 @@ pub fn extract_lights( entity, ( ExtractedPointLight { - color: spot_light.color, + color: spot_light.color.into(), // NOTE: Map from luminous power in lumens to luminous intensity in lumens per steradian // for a point light. See https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower // for details. @@ -478,7 +478,7 @@ pub fn extract_lights( let render_visible_entities = visible_entities.clone(); commands.get_or_spawn(entity).insert(( ExtractedDirectionalLight { - color: directional_light.color, + color: directional_light.color.into(), illuminance: directional_light.illuminance, transform: *transform, shadows_enabled: directional_light.shadows_enabled, @@ -871,7 +871,7 @@ pub fn prepare_lights( light_custom_data, // premultiply color by intensity // we don't use the alpha at all, so no reason to multiply only [0..3] - color_inverse_square_range: (Vec4::from_slice(&light.color.as_linear_rgba_f32()) + color_inverse_square_range: (Vec4::from_slice(&light.color.to_f32_array()) * light.intensity) .xyz() .extend(1.0 / (light.range * light.range)), @@ -908,7 +908,7 @@ pub fn prepare_lights( cascades: [GpuDirectionalCascade::default(); MAX_CASCADES_PER_LIGHT], // premultiply color by illuminance // we don't use the alpha at all, so no reason to multiply only [0..3] - color: Vec4::from_slice(&light.color.as_linear_rgba_f32()) * light.illuminance, + color: Vec4::from_slice(&light.color.to_f32_array()) * light.illuminance, // direction is negated to be ready for N.L dir_to_light: light.transform.back(), flags: flags.bits(), @@ -982,7 +982,7 @@ pub fn prepare_lights( let n_clusters = clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z; let mut gpu_lights = GpuLights { directional_lights: gpu_directional_lights, - ambient_color: Vec4::from_slice(&ambient_light.color.as_linear_rgba_f32()) + ambient_color: Vec4::from_slice(&LinearRgba::from(ambient_light.color).to_f32_array()) * ambient_light.brightness, cluster_factors: Vec4::new( clusters.dimensions.x as f32 / extracted_view.viewport.z as f32, diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 5f025ee429..10bf057100 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,6 +1,7 @@ use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin}; use bevy_app::{Plugin, Startup, Update}; use bevy_asset::{load_internal_asset, Asset, Assets, Handle}; +use bevy_color::{Color, LinearRgba}; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath}; use bevy_render::{ @@ -65,7 +66,7 @@ pub struct Wireframe; #[derive(Component, Debug, Clone, Default, Reflect)] #[reflect(Component, Default)] pub struct WireframeColor { - pub color: LegacyColor, + pub color: Color, } /// Disables wireframe rendering for any entity it is attached to. @@ -85,7 +86,7 @@ pub struct WireframeConfig { /// If [`Self::global`] is set, any [`Entity`] that does not have a [`Wireframe`] component attached to it will have /// wireframes using this color. Otherwise, this will be the fallback color for any entity that has a [`Wireframe`], /// but no [`WireframeColor`]. - pub default_color: LegacyColor, + pub default_color: Color, } #[derive(Resource)] @@ -102,7 +103,7 @@ fn setup_global_wireframe_material( // Create the handle used for the global material commands.insert_resource(GlobalWireframeMaterial { handle: materials.add(WireframeMaterial { - color: config.default_color, + color: config.default_color.into(), }), }); } @@ -114,7 +115,7 @@ fn global_color_changed( global_material: Res, ) { if let Some(global_material) = materials.get_mut(&global_material.handle) { - global_material.color = config.default_color; + global_material.color = config.default_color.into(); } } @@ -129,7 +130,7 @@ fn wireframe_color_changed( ) { for (mut handle, wireframe_color) in &mut colors_changed { *handle = materials.add(WireframeMaterial { - color: wireframe_color.color, + color: wireframe_color.color.into(), }); } } @@ -157,7 +158,7 @@ fn apply_wireframe_material( for (e, wireframe_color) in &wireframes { let material = if let Some(wireframe_color) = wireframe_color { materials.add(WireframeMaterial { - color: wireframe_color.color, + color: wireframe_color.color.into(), }) } else { // If there's no color specified we can use the global material since it's already set to use the default_color @@ -196,7 +197,7 @@ fn apply_global_wireframe_material( #[derive(Default, AsBindGroup, TypePath, Debug, Clone, Asset)] pub struct WireframeMaterial { #[uniform(0)] - pub color: LegacyColor, + pub color: LinearRgba, } impl Material for WireframeMaterial { diff --git a/crates/bevy_render/src/camera/clear_color.rs b/crates/bevy_render/src/camera/clear_color.rs index 9a549fe3c4..02b74ce46c 100644 --- a/crates/bevy_render/src/camera/clear_color.rs +++ b/crates/bevy_render/src/camera/clear_color.rs @@ -1,4 +1,5 @@ -use crate::{color::LegacyColor, extract_resource::ExtractResource}; +use crate::extract_resource::ExtractResource; +use bevy_color::Color; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::prelude::*; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; @@ -12,15 +13,15 @@ pub enum ClearColorConfig { #[default] Default, /// The given clear color is used, overriding the [`ClearColor`] resource defined in the world. - Custom(LegacyColor), + Custom(Color), /// No clear color is used: the camera will simply draw on top of anything already in the viewport. /// /// This can be useful when multiple cameras are rendering to the same viewport. None, } -impl From for ClearColorConfig { - fn from(color: LegacyColor) -> Self { +impl From for ClearColorConfig { + fn from(color: Color) -> Self { Self::Custom(color) } } @@ -31,11 +32,11 @@ impl From for ClearColorConfig { /// when there are portions of the screen with nothing rendered. #[derive(Resource, Clone, Debug, Deref, DerefMut, ExtractResource, Reflect)] #[reflect(Resource)] -pub struct ClearColor(pub LegacyColor); +pub struct ClearColor(pub Color); /// Match the dark gray bevy website code block color by default. impl Default for ClearColor { fn default() -> Self { - Self(LegacyColor::rgb_u8(43, 44, 47)) + Self(Color::srgb_u8(43, 44, 47)) } } diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs deleted file mode 100644 index c1f38f8e2e..0000000000 --- a/crates/bevy_render/src/color/mod.rs +++ /dev/null @@ -1,1809 +0,0 @@ -use bevy_color::{ - Color, HexColorError, Hsla, Hsva, Hwba, Laba, Lcha, LinearRgba, Oklaba, Oklcha, Srgba, Xyza, -}; - -use bevy_math::{Vec3, Vec4}; -use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; -use serde::{Deserialize, Serialize}; -use std::ops::{Add, Mul, MulAssign}; - -#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)] -#[reflect(PartialEq, Serialize, Deserialize)] -pub enum LegacyColor { - /// sRGBA color - Rgba { - /// Red channel. [0.0, 1.0] - red: f32, - /// Green channel. [0.0, 1.0] - green: f32, - /// Blue channel. [0.0, 1.0] - blue: f32, - /// Alpha channel. [0.0, 1.0] - alpha: f32, - }, - /// RGBA color in the Linear sRGB colorspace (often colloquially referred to as "linear", "RGB", or "linear RGB"). - RgbaLinear { - /// Red channel. [0.0, 1.0] - red: f32, - /// Green channel. [0.0, 1.0] - green: f32, - /// Blue channel. [0.0, 1.0] - blue: f32, - /// Alpha channel. [0.0, 1.0] - alpha: f32, - }, - /// HSL (hue, saturation, lightness) color with an alpha channel - Hsla { - /// Hue channel. [0.0, 360.0] - hue: f32, - /// Saturation channel. [0.0, 1.0] - saturation: f32, - /// Lightness channel. [0.0, 1.0] - lightness: f32, - /// Alpha channel. [0.0, 1.0] - alpha: f32, - }, - /// LCH(ab) (lightness, chroma, hue) color with an alpha channel - Lcha { - /// Lightness channel. [0.0, 1.5] - lightness: f32, - /// Chroma channel. [0.0, 1.5] - chroma: f32, - /// Hue channel. [0.0, 360.0] - hue: f32, - /// Alpha channel. [0.0, 1.0] - alpha: f32, - }, -} - -impl LegacyColor { - ///
- pub const ALICE_BLUE: LegacyColor = LegacyColor::rgb(0.94, 0.97, 1.0); - ///
- pub const ANTIQUE_WHITE: LegacyColor = LegacyColor::rgb(0.98, 0.92, 0.84); - ///
- pub const AQUAMARINE: LegacyColor = LegacyColor::rgb(0.49, 1.0, 0.83); - ///
- pub const AZURE: LegacyColor = LegacyColor::rgb(0.94, 1.0, 1.0); - ///
- pub const BEIGE: LegacyColor = LegacyColor::rgb(0.96, 0.96, 0.86); - ///
- pub const BISQUE: LegacyColor = LegacyColor::rgb(1.0, 0.89, 0.77); - ///
- pub const BLACK: LegacyColor = LegacyColor::rgb(0.0, 0.0, 0.0); - ///
- pub const BLUE: LegacyColor = LegacyColor::rgb(0.0, 0.0, 1.0); - ///
- pub const CRIMSON: LegacyColor = LegacyColor::rgb(0.86, 0.08, 0.24); - ///
- pub const CYAN: LegacyColor = LegacyColor::rgb(0.0, 1.0, 1.0); - ///
- pub const DARK_GRAY: LegacyColor = LegacyColor::rgb(0.25, 0.25, 0.25); - ///
- pub const DARK_GREEN: LegacyColor = LegacyColor::rgb(0.0, 0.5, 0.0); - ///
- pub const FUCHSIA: LegacyColor = LegacyColor::rgb(1.0, 0.0, 1.0); - ///
- pub const GOLD: LegacyColor = LegacyColor::rgb(1.0, 0.84, 0.0); - ///
- pub const GRAY: LegacyColor = LegacyColor::rgb(0.5, 0.5, 0.5); - ///
- pub const GREEN: LegacyColor = LegacyColor::rgb(0.0, 1.0, 0.0); - ///
- pub const INDIGO: LegacyColor = LegacyColor::rgb(0.29, 0.0, 0.51); - ///
- pub const LIME_GREEN: LegacyColor = LegacyColor::rgb(0.2, 0.8, 0.2); - ///
- pub const MAROON: LegacyColor = LegacyColor::rgb(0.5, 0.0, 0.0); - ///
- pub const MIDNIGHT_BLUE: LegacyColor = LegacyColor::rgb(0.1, 0.1, 0.44); - ///
- pub const NAVY: LegacyColor = LegacyColor::rgb(0.0, 0.0, 0.5); - ///
- #[doc(alias = "transparent")] - pub const NONE: LegacyColor = LegacyColor::rgba(0.0, 0.0, 0.0, 0.0); - ///
- pub const OLIVE: LegacyColor = LegacyColor::rgb(0.5, 0.5, 0.0); - ///
- pub const ORANGE: LegacyColor = LegacyColor::rgb(1.0, 0.65, 0.0); - ///
- pub const ORANGE_RED: LegacyColor = LegacyColor::rgb(1.0, 0.27, 0.0); - ///
- pub const PINK: LegacyColor = LegacyColor::rgb(1.0, 0.08, 0.58); - ///
- pub const PURPLE: LegacyColor = LegacyColor::rgb(0.5, 0.0, 0.5); - ///
- pub const RED: LegacyColor = LegacyColor::rgb(1.0, 0.0, 0.0); - ///
- pub const SALMON: LegacyColor = LegacyColor::rgb(0.98, 0.5, 0.45); - ///
- pub const SEA_GREEN: LegacyColor = LegacyColor::rgb(0.18, 0.55, 0.34); - ///
- pub const SILVER: LegacyColor = LegacyColor::rgb(0.75, 0.75, 0.75); - ///
- pub const TEAL: LegacyColor = LegacyColor::rgb(0.0, 0.5, 0.5); - ///
- pub const TOMATO: LegacyColor = LegacyColor::rgb(1.0, 0.39, 0.28); - ///
- pub const TURQUOISE: LegacyColor = LegacyColor::rgb(0.25, 0.88, 0.82); - ///
- pub const VIOLET: LegacyColor = LegacyColor::rgb(0.93, 0.51, 0.93); - ///
- pub const WHITE: LegacyColor = LegacyColor::rgb(1.0, 1.0, 1.0); - ///
- pub const YELLOW: LegacyColor = LegacyColor::rgb(1.0, 1.0, 0.0); - ///
- pub const YELLOW_GREEN: LegacyColor = LegacyColor::rgb(0.6, 0.8, 0.2); - - /// New `Color` from sRGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0.0, 1.0] - /// * `g` - Green channel. [0.0, 1.0] - /// * `b` - Blue channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::rgba`], [`LegacyColor::rgb_u8`], [`LegacyColor::hex`]. - /// - pub const fn rgb(r: f32, g: f32, b: f32) -> LegacyColor { - LegacyColor::Rgba { - red: r, - green: g, - blue: b, - alpha: 1.0, - } - } - - /// New `Color` from sRGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0.0, 1.0] - /// * `g` - Green channel. [0.0, 1.0] - /// * `b` - Blue channel. [0.0, 1.0] - /// * `a` - Alpha channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::rgb`], [`LegacyColor::rgba_u8`], [`LegacyColor::hex`]. - /// - pub const fn rgba(r: f32, g: f32, b: f32, a: f32) -> LegacyColor { - LegacyColor::Rgba { - red: r, - green: g, - blue: b, - alpha: a, - } - } - - /// New `Color` from linear RGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0.0, 1.0] - /// * `g` - Green channel. [0.0, 1.0] - /// * `b` - Blue channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::rgb`], [`LegacyColor::rgba_linear`]. - /// - pub const fn rgb_linear(r: f32, g: f32, b: f32) -> LegacyColor { - LegacyColor::RgbaLinear { - red: r, - green: g, - blue: b, - alpha: 1.0, - } - } - - /// New `Color` from linear RGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0.0, 1.0] - /// * `g` - Green channel. [0.0, 1.0] - /// * `b` - Blue channel. [0.0, 1.0] - /// * `a` - Alpha channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::rgba`], [`LegacyColor::rgb_linear`]. - /// - pub const fn rgba_linear(r: f32, g: f32, b: f32, a: f32) -> LegacyColor { - LegacyColor::RgbaLinear { - red: r, - green: g, - blue: b, - alpha: a, - } - } - - /// New `Color` with HSL representation in sRGB colorspace. - /// - /// # Arguments - /// - /// * `hue` - Hue channel. [0.0, 360.0] - /// * `saturation` - Saturation channel. [0.0, 1.0] - /// * `lightness` - Lightness channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::hsla`]. - /// - pub const fn hsl(hue: f32, saturation: f32, lightness: f32) -> LegacyColor { - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha: 1.0, - } - } - - /// New `Color` with HSL representation in sRGB colorspace. - /// - /// # Arguments - /// - /// * `hue` - Hue channel. [0.0, 360.0] - /// * `saturation` - Saturation channel. [0.0, 1.0] - /// * `lightness` - Lightness channel. [0.0, 1.0] - /// * `alpha` - Alpha channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::hsl`]. - /// - pub const fn hsla(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> LegacyColor { - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } - } - - /// New `Color` with LCH representation in sRGB colorspace. - /// - /// # Arguments - /// - /// * `lightness` - Lightness channel. [0.0, 1.5] - /// * `chroma` - Chroma channel. [0.0, 1.5] - /// * `hue` - Hue channel. [0.0, 360.0] - /// - /// See also [`LegacyColor::lcha`]. - pub const fn lch(lightness: f32, chroma: f32, hue: f32) -> LegacyColor { - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha: 1.0, - } - } - - /// New `Color` with LCH representation in sRGB colorspace. - /// - /// # Arguments - /// - /// * `lightness` - Lightness channel. [0.0, 1.5] - /// * `chroma` - Chroma channel. [0.0, 1.5] - /// * `hue` - Hue channel. [0.0, 360.0] - /// * `alpha` - Alpha channel. [0.0, 1.0] - /// - /// See also [`LegacyColor::lch`]. - pub const fn lcha(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> LegacyColor { - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } - } - - /// New `Color` from sRGB colorspace. - /// - /// # Examples - /// - /// ``` - /// # use bevy_render::color::LegacyColor; - /// let color = LegacyColor::hex("FF00FF").unwrap(); // fuchsia - /// let color = LegacyColor::hex("FF00FF7F").unwrap(); // partially transparent fuchsia - /// - /// // A standard hex color notation is also available - /// assert_eq!(LegacyColor::hex("#FFFFFF").unwrap(), LegacyColor::rgb(1.0, 1.0, 1.0)); - /// ``` - /// - pub fn hex>(hex: T) -> Result { - Srgba::hex(hex).map(|color| color.into()) - } - - /// New `Color` from sRGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0, 255] - /// * `g` - Green channel. [0, 255] - /// * `b` - Blue channel. [0, 255] - /// - /// See also [`LegacyColor::rgb`], [`LegacyColor::rgba_u8`], [`LegacyColor::hex`]. - /// - pub fn rgb_u8(r: u8, g: u8, b: u8) -> LegacyColor { - LegacyColor::rgba_u8(r, g, b, u8::MAX) - } - - // Float operations in const fn are not stable yet - // see https://github.com/rust-lang/rust/issues/57241 - /// New `Color` from sRGB colorspace. - /// - /// # Arguments - /// - /// * `r` - Red channel. [0, 255] - /// * `g` - Green channel. [0, 255] - /// * `b` - Blue channel. [0, 255] - /// * `a` - Alpha channel. [0, 255] - /// - /// See also [`LegacyColor::rgba`], [`LegacyColor::rgb_u8`], [`LegacyColor::hex`]. - /// - pub fn rgba_u8(r: u8, g: u8, b: u8, a: u8) -> LegacyColor { - LegacyColor::rgba( - r as f32 / u8::MAX as f32, - g as f32 / u8::MAX as f32, - b as f32 / u8::MAX as f32, - a as f32 / u8::MAX as f32, - ) - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return red in sRGB colorspace - pub fn r(&self) -> f32 { - match self.as_rgba() { - LegacyColor::Rgba { red, .. } => red, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return green in sRGB colorspace - pub fn g(&self) -> f32 { - match self.as_rgba() { - LegacyColor::Rgba { green, .. } => green, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return blue in sRGB colorspace - pub fn b(&self) -> f32 { - match self.as_rgba() { - LegacyColor::Rgba { blue, .. } => blue, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and set red - pub fn set_r(&mut self, r: f32) -> &mut Self { - *self = self.as_rgba(); - match self { - LegacyColor::Rgba { red, .. } => *red = r, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return this color with red set to a new value - #[must_use] - pub fn with_r(mut self, r: f32) -> Self { - self.set_r(r); - self - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and set green - pub fn set_g(&mut self, g: f32) -> &mut Self { - *self = self.as_rgba(); - match self { - LegacyColor::Rgba { green, .. } => *green = g, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return this color with green set to a new value - #[must_use] - pub fn with_g(mut self, g: f32) -> Self { - self.set_g(g); - self - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and set blue - pub fn set_b(&mut self, b: f32) -> &mut Self { - *self = self.as_rgba(); - match self { - LegacyColor::Rgba { blue, .. } => *blue = b, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Rgba`] and return this color with blue set to a new value - #[must_use] - pub fn with_b(mut self, b: f32) -> Self { - self.set_b(b); - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return hue - pub fn h(&self) -> f32 { - match self.as_hsla() { - LegacyColor::Hsla { hue, .. } => hue, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return saturation - pub fn s(&self) -> f32 { - match self.as_hsla() { - LegacyColor::Hsla { saturation, .. } => saturation, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return lightness - pub fn l(&self) -> f32 { - match self.as_hsla() { - LegacyColor::Hsla { lightness, .. } => lightness, - _ => unreachable!(), - } - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and set hue - pub fn set_h(&mut self, h: f32) -> &mut Self { - *self = self.as_hsla(); - match self { - LegacyColor::Hsla { hue, .. } => *hue = h, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return this color with hue set to a new value - #[must_use] - pub fn with_h(mut self, h: f32) -> Self { - self.set_h(h); - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and set saturation - pub fn set_s(&mut self, s: f32) -> &mut Self { - *self = self.as_hsla(); - match self { - LegacyColor::Hsla { saturation, .. } => *saturation = s, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return this color with saturation set to a new value - #[must_use] - pub fn with_s(mut self, s: f32) -> Self { - self.set_s(s); - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and set lightness - pub fn set_l(&mut self, l: f32) -> &mut Self { - *self = self.as_hsla(); - match self { - LegacyColor::Hsla { lightness, .. } => *lightness = l, - _ => unreachable!(), - } - self - } - - /// Converts a Color to variant [`LegacyColor::Hsla`] and return this color with lightness set to a new value - #[must_use] - pub fn with_l(mut self, l: f32) -> Self { - self.set_l(l); - self - } - - /// Get alpha. - #[inline(always)] - pub fn a(&self) -> f32 { - match self { - LegacyColor::Rgba { alpha, .. } - | LegacyColor::RgbaLinear { alpha, .. } - | LegacyColor::Hsla { alpha, .. } - | LegacyColor::Lcha { alpha, .. } => *alpha, - } - } - - /// Set alpha. - pub fn set_a(&mut self, a: f32) -> &mut Self { - match self { - LegacyColor::Rgba { alpha, .. } - | LegacyColor::RgbaLinear { alpha, .. } - | LegacyColor::Hsla { alpha, .. } - | LegacyColor::Lcha { alpha, .. } => { - *alpha = a; - } - } - self - } - - /// Returns this color with a new alpha value. - #[must_use] - pub fn with_a(mut self, a: f32) -> Self { - self.set_a(a); - self - } - - /// Determine if the color is fully transparent, i.e. if the alpha is 0. - /// - /// # Examples - /// - /// ``` - /// # use bevy_render::color::LegacyColor; - /// // Fully transparent colors - /// assert!(LegacyColor::NONE.is_fully_transparent()); - /// assert!(LegacyColor::rgba(1.0, 0.5, 0.5, 0.0).is_fully_transparent()); - /// - /// // (Partially) opaque colors - /// assert!(!LegacyColor::BLACK.is_fully_transparent()); - /// assert!(!LegacyColor::rgba(1.0, 0.5, 0.5, 0.2).is_fully_transparent()); - /// ``` - #[inline(always)] - pub fn is_fully_transparent(&self) -> bool { - self.a() == 0.0 - } - - /// Converts a `Color` to variant `LegacyColor::Rgba` - pub fn as_rgba(self: &LegacyColor) -> LegacyColor { - Srgba::from(*self).into() - } - - /// Converts a `Color` to variant `LegacyColor::RgbaLinear` - pub fn as_rgba_linear(self: &LegacyColor) -> LegacyColor { - LinearRgba::from(*self).into() - } - - /// Converts a `Color` to variant `LegacyColor::Hsla` - pub fn as_hsla(self: &LegacyColor) -> LegacyColor { - Hsla::from(*self).into() - } - - /// Converts a `Color` to variant `LegacyColor::Lcha` - pub fn as_lcha(self: &LegacyColor) -> LegacyColor { - Lcha::from(*self).into() - } - - /// Converts a `Color` to a `[u8; 4]` from sRGB colorspace - pub fn as_rgba_u8(&self) -> [u8; 4] { - let [r, g, b, a] = self.as_rgba_f32(); - [ - (r * u8::MAX as f32) as u8, - (g * u8::MAX as f32) as u8, - (b * u8::MAX as f32) as u8, - (a * u8::MAX as f32) as u8, - ] - } - - /// Converts a `Color` to a `[f32; 4]` from sRGB colorspace - pub fn as_rgba_f32(self: LegacyColor) -> [f32; 4] { - let Srgba { - red, - green, - blue, - alpha, - } = Srgba::from(self); - [red, green, blue, alpha] - } - - /// Converts a `Color` to a `[f32; 4]` from linear RGB colorspace - #[inline] - pub fn as_linear_rgba_f32(self: LegacyColor) -> [f32; 4] { - let LinearRgba { - red, - green, - blue, - alpha, - } = LinearRgba::from(self); - [red, green, blue, alpha] - } - - /// Converts a `Color` to a `[f32; 4]` from HSL colorspace - pub fn as_hsla_f32(self: LegacyColor) -> [f32; 4] { - let Hsla { - hue, - saturation, - lightness, - alpha, - } = Hsla::from(self); - [hue, saturation, lightness, alpha] - } - - /// Converts a `Color` to a `[f32; 4]` from LCH colorspace - pub fn as_lcha_f32(self: LegacyColor) -> [f32; 4] { - let Lcha { - lightness, - chroma, - hue, - alpha, - } = Lcha::from(self); - [lightness, chroma, hue, alpha] - } - - /// Converts `Color` to a `u32` from sRGB colorspace. - /// - /// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian). - /// `A` will be the most significant byte and `R` the least significant. - pub fn as_rgba_u32(self: LegacyColor) -> u32 { - u32::from_le_bytes(self.as_rgba_u8()) - } - - /// Converts Color to a u32 from linear RGB colorspace. - /// - /// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian). - /// `A` will be the most significant byte and `R` the least significant. - pub fn as_linear_rgba_u32(self: LegacyColor) -> u32 { - let LinearRgba { - red, - green, - blue, - alpha, - } = self.into(); - u32::from_le_bytes([ - (red * 255.0) as u8, - (green * 255.0) as u8, - (blue * 255.0) as u8, - (alpha * 255.0) as u8, - ]) - } - - /// New `Color` from `[f32; 4]` (or a type that can be converted into them) with RGB representation in sRGB colorspace. - #[inline] - pub fn rgba_from_array(arr: impl Into<[f32; 4]>) -> Self { - let [r, g, b, a]: [f32; 4] = arr.into(); - LegacyColor::rgba(r, g, b, a) - } - - /// New `Color` from `[f32; 3]` (or a type that can be converted into them) with RGB representation in sRGB colorspace. - #[inline] - pub fn rgb_from_array(arr: impl Into<[f32; 3]>) -> Self { - let [r, g, b]: [f32; 3] = arr.into(); - LegacyColor::rgb(r, g, b) - } - - /// New `Color` from `[f32; 4]` (or a type that can be converted into them) with RGB representation in linear RGB colorspace. - #[inline] - pub fn rgba_linear_from_array(arr: impl Into<[f32; 4]>) -> Self { - let [r, g, b, a]: [f32; 4] = arr.into(); - LegacyColor::rgba_linear(r, g, b, a) - } - - /// New `Color` from `[f32; 3]` (or a type that can be converted into them) with RGB representation in linear RGB colorspace. - #[inline] - pub fn rgb_linear_from_array(arr: impl Into<[f32; 3]>) -> Self { - let [r, g, b]: [f32; 3] = arr.into(); - LegacyColor::rgb_linear(r, g, b) - } - - /// New `Color` from `[f32; 4]` (or a type that can be converted into them) with HSL representation in sRGB colorspace. - #[inline] - pub fn hsla_from_array(arr: impl Into<[f32; 4]>) -> Self { - let [h, s, l, a]: [f32; 4] = arr.into(); - LegacyColor::hsla(h, s, l, a) - } - - /// New `Color` from `[f32; 3]` (or a type that can be converted into them) with HSL representation in sRGB colorspace. - #[inline] - pub fn hsl_from_array(arr: impl Into<[f32; 3]>) -> Self { - let [h, s, l]: [f32; 3] = arr.into(); - LegacyColor::hsl(h, s, l) - } - - /// New `Color` from `[f32; 4]` (or a type that can be converted into them) with LCH representation in sRGB colorspace. - #[inline] - pub fn lcha_from_array(arr: impl Into<[f32; 4]>) -> Self { - let [l, c, h, a]: [f32; 4] = arr.into(); - LegacyColor::lcha(l, c, h, a) - } - - /// New `Color` from `[f32; 3]` (or a type that can be converted into them) with LCH representation in sRGB colorspace. - #[inline] - pub fn lch_from_array(arr: impl Into<[f32; 3]>) -> Self { - let [l, c, h]: [f32; 3] = arr.into(); - LegacyColor::lch(l, c, h) - } - - /// Convert `Color` to RGBA and return as `Vec4`. - #[inline] - pub fn rgba_to_vec4(&self) -> Vec4 { - let color = self.as_rgba(); - match color { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => Vec4::new(red, green, blue, alpha), - _ => unreachable!(), - } - } - - /// Convert `Color` to RGBA and return as `Vec3`. - #[inline] - pub fn rgb_to_vec3(&self) -> Vec3 { - let color = self.as_rgba(); - match color { - LegacyColor::Rgba { - red, green, blue, .. - } => Vec3::new(red, green, blue), - _ => unreachable!(), - } - } - - /// Convert `Color` to linear RGBA and return as `Vec4`. - #[inline] - pub fn rgba_linear_to_vec4(&self) -> Vec4 { - let color = self.as_rgba_linear(); - match color { - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => Vec4::new(red, green, blue, alpha), - _ => unreachable!(), - } - } - - /// Convert `Color` to linear RGBA and return as `Vec3`. - #[inline] - pub fn rgb_linear_to_vec3(&self) -> Vec3 { - let color = self.as_rgba_linear(); - match color { - LegacyColor::RgbaLinear { - red, green, blue, .. - } => Vec3::new(red, green, blue), - _ => unreachable!(), - } - } - - /// Convert `Color` to HSLA and return as `Vec4`. - #[inline] - pub fn hsla_to_vec4(&self) -> Vec4 { - let color = self.as_hsla(); - match color { - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => Vec4::new(hue, saturation, lightness, alpha), - _ => unreachable!(), - } - } - - /// Convert `Color` to HSLA and return as `Vec3`. - #[inline] - pub fn hsl_to_vec3(&self) -> Vec3 { - let color = self.as_hsla(); - match color { - LegacyColor::Hsla { - hue, - saturation, - lightness, - .. - } => Vec3::new(hue, saturation, lightness), - _ => unreachable!(), - } - } - - /// Convert `Color` to LCHA and return as `Vec4`. - #[inline] - pub fn lcha_to_vec4(&self) -> Vec4 { - let color = self.as_lcha(); - match color { - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => Vec4::new(lightness, chroma, hue, alpha), - _ => unreachable!(), - } - } - - /// Convert `Color` to LCHA and return as `Vec3`. - #[inline] - pub fn lch_to_vec3(&self) -> Vec3 { - let color = self.as_lcha(); - match color { - LegacyColor::Lcha { - lightness, - chroma, - hue, - .. - } => Vec3::new(lightness, chroma, hue), - _ => unreachable!(), - } - } -} - -impl Default for LegacyColor { - fn default() -> Self { - LegacyColor::WHITE - } -} - -impl Add for LegacyColor { - type Output = LegacyColor; - - fn add(self, rhs: LegacyColor) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => { - let rhs = rhs.as_rgba_f32(); - LegacyColor::Rgba { - red: red + rhs[0], - green: green + rhs[1], - blue: blue + rhs[2], - alpha: alpha + rhs[3], - } - } - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => { - let rhs = rhs.as_linear_rgba_f32(); - LegacyColor::RgbaLinear { - red: red + rhs[0], - green: green + rhs[1], - blue: blue + rhs[2], - alpha: alpha + rhs[3], - } - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => { - let rhs = rhs.as_hsla_f32(); - LegacyColor::Hsla { - hue: hue + rhs[0], - saturation: saturation + rhs[1], - lightness: lightness + rhs[2], - alpha: alpha + rhs[3], - } - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => { - let rhs = rhs.as_lcha_f32(); - LegacyColor::Lcha { - lightness: lightness + rhs[0], - chroma: chroma + rhs[1], - hue: hue + rhs[2], - alpha: alpha + rhs[3], - } - } - } - } -} - -impl From for Color { - fn from(value: LegacyColor) -> Self { - match value { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => Srgba::new(red, green, blue, alpha).into(), - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LinearRgba::new(red, green, blue, alpha).into(), - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => Hsla::new(hue, saturation, lightness, alpha).into(), - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => Lcha::new(lightness, chroma, hue, alpha).into(), - } - } -} - -impl From for LegacyColor { - fn from(value: Color) -> Self { - match value { - Color::Srgba(x) => x.into(), - Color::LinearRgba(x) => x.into(), - Color::Hsla(x) => x.into(), - Color::Hsva(x) => x.into(), - Color::Hwba(x) => x.into(), - Color::Laba(x) => x.into(), - Color::Lcha(x) => x.into(), - Color::Oklaba(x) => x.into(), - Color::Oklcha(x) => x.into(), - Color::Xyza(x) => x.into(), - } - } -} - -impl From for LegacyColor { - fn from( - LinearRgba { - red, - green, - blue, - alpha, - }: LinearRgba, - ) -> Self { - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } - } -} - -impl From for Xyza { - fn from(value: LegacyColor) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Xyza) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for LinearRgba { - fn from(value: LegacyColor) -> Self { - Color::from(value).into() - } -} - -impl From for LegacyColor { - fn from( - Srgba { - red, - green, - blue, - alpha, - }: Srgba, - ) -> Self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } - } -} - -impl From for Srgba { - fn from(value: LegacyColor) -> Self { - Color::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Hsla) -> Self { - LegacyColor::Hsla { - hue: value.hue, - saturation: value.saturation, - lightness: value.lightness, - alpha: value.alpha, - } - } -} - -impl From for Hsla { - fn from(value: LegacyColor) -> Self { - Color::from(value).into() - } -} - -impl From for Hsva { - fn from(value: LegacyColor) -> Self { - Hsla::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Hsva) -> Self { - Hsla::from(value).into() - } -} - -impl From for Hwba { - fn from(value: LegacyColor) -> Self { - Hsla::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Hwba) -> Self { - Hsla::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Laba) -> Self { - Lcha::from(value).into() - } -} - -impl From for LegacyColor { - fn from( - Lcha { - lightness, - chroma, - hue, - alpha, - }: Lcha, - ) -> Self { - LegacyColor::Lcha { - hue, - chroma, - lightness, - alpha, - } - } -} - -impl From for Lcha { - fn from(value: LegacyColor) -> Self { - Color::from(value).into() - } -} - -impl From for Laba { - fn from(value: LegacyColor) -> Self { - Color::from(value).into() - } -} - -impl From for Oklaba { - fn from(value: LegacyColor) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Oklaba) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for Oklcha { - fn from(value: LegacyColor) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for LegacyColor { - fn from(value: Oklcha) -> Self { - LinearRgba::from(value).into() - } -} - -impl From for wgpu::Color { - fn from(color: LegacyColor) -> Self { - if let LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } = color.as_rgba_linear() - { - wgpu::Color { - r: red as f64, - g: green as f64, - b: blue as f64, - a: alpha as f64, - } - } else { - unreachable!() - } - } -} - -impl Mul for LegacyColor { - type Output = LegacyColor; - - fn mul(self, rhs: f32) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => LegacyColor::Rgba { - red: red * rhs, - green: green * rhs, - blue: blue * rhs, - alpha, - }, - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LegacyColor::RgbaLinear { - red: red * rhs, - green: green * rhs, - blue: blue * rhs, - alpha, - }, - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => LegacyColor::Hsla { - hue: hue * rhs, - saturation: saturation * rhs, - lightness: lightness * rhs, - alpha, - }, - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => LegacyColor::Lcha { - lightness: lightness * rhs, - chroma: chroma * rhs, - hue: hue * rhs, - alpha, - }, - } - } -} - -impl MulAssign for LegacyColor { - fn mul_assign(&mut self, rhs: f32) { - match self { - LegacyColor::Rgba { - red, green, blue, .. - } - | LegacyColor::RgbaLinear { - red, green, blue, .. - } => { - *red *= rhs; - *green *= rhs; - *blue *= rhs; - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - .. - } => { - *hue *= rhs; - *saturation *= rhs; - *lightness *= rhs; - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - .. - } => { - *lightness *= rhs; - *chroma *= rhs; - *hue *= rhs; - } - } - } -} - -impl Mul for LegacyColor { - type Output = LegacyColor; - - fn mul(self, rhs: Vec4) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => LegacyColor::Rgba { - red: red * rhs.x, - green: green * rhs.y, - blue: blue * rhs.z, - alpha: alpha * rhs.w, - }, - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LegacyColor::RgbaLinear { - red: red * rhs.x, - green: green * rhs.y, - blue: blue * rhs.z, - alpha: alpha * rhs.w, - }, - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => LegacyColor::Hsla { - hue: hue * rhs.x, - saturation: saturation * rhs.y, - lightness: lightness * rhs.z, - alpha: alpha * rhs.w, - }, - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => LegacyColor::Lcha { - lightness: lightness * rhs.x, - chroma: chroma * rhs.y, - hue: hue * rhs.z, - alpha: alpha * rhs.w, - }, - } - } -} - -impl MulAssign for LegacyColor { - fn mul_assign(&mut self, rhs: Vec4) { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } - | LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => { - *red *= rhs.x; - *green *= rhs.y; - *blue *= rhs.z; - *alpha *= rhs.w; - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => { - *hue *= rhs.x; - *saturation *= rhs.y; - *lightness *= rhs.z; - *alpha *= rhs.w; - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => { - *lightness *= rhs.x; - *chroma *= rhs.y; - *hue *= rhs.z; - *alpha *= rhs.w; - } - } - } -} - -impl Mul for LegacyColor { - type Output = LegacyColor; - - fn mul(self, rhs: Vec3) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => LegacyColor::Rgba { - red: red * rhs.x, - green: green * rhs.y, - blue: blue * rhs.z, - alpha, - }, - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LegacyColor::RgbaLinear { - red: red * rhs.x, - green: green * rhs.y, - blue: blue * rhs.z, - alpha, - }, - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => LegacyColor::Hsla { - hue: hue * rhs.x, - saturation: saturation * rhs.y, - lightness: lightness * rhs.z, - alpha, - }, - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => LegacyColor::Lcha { - lightness: lightness * rhs.x, - chroma: chroma * rhs.y, - hue: hue * rhs.z, - alpha, - }, - } - } -} - -impl MulAssign for LegacyColor { - fn mul_assign(&mut self, rhs: Vec3) { - match self { - LegacyColor::Rgba { - red, green, blue, .. - } - | LegacyColor::RgbaLinear { - red, green, blue, .. - } => { - *red *= rhs.x; - *green *= rhs.y; - *blue *= rhs.z; - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - .. - } => { - *hue *= rhs.x; - *saturation *= rhs.y; - *lightness *= rhs.z; - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - .. - } => { - *lightness *= rhs.x; - *chroma *= rhs.y; - *hue *= rhs.z; - } - } - } -} - -impl Mul<[f32; 4]> for LegacyColor { - type Output = LegacyColor; - - fn mul(self, rhs: [f32; 4]) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => LegacyColor::Rgba { - red: red * rhs[0], - green: green * rhs[1], - blue: blue * rhs[2], - alpha: alpha * rhs[3], - }, - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LegacyColor::RgbaLinear { - red: red * rhs[0], - green: green * rhs[1], - blue: blue * rhs[2], - alpha: alpha * rhs[3], - }, - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => LegacyColor::Hsla { - hue: hue * rhs[0], - saturation: saturation * rhs[1], - lightness: lightness * rhs[2], - alpha: alpha * rhs[3], - }, - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => LegacyColor::Lcha { - lightness: lightness * rhs[0], - chroma: chroma * rhs[1], - hue: hue * rhs[2], - alpha: alpha * rhs[3], - }, - } - } -} - -impl MulAssign<[f32; 4]> for LegacyColor { - fn mul_assign(&mut self, rhs: [f32; 4]) { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } - | LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => { - *red *= rhs[0]; - *green *= rhs[1]; - *blue *= rhs[2]; - *alpha *= rhs[3]; - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => { - *hue *= rhs[0]; - *saturation *= rhs[1]; - *lightness *= rhs[2]; - *alpha *= rhs[3]; - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => { - *lightness *= rhs[0]; - *chroma *= rhs[1]; - *hue *= rhs[2]; - *alpha *= rhs[3]; - } - } - } -} - -impl Mul<[f32; 3]> for LegacyColor { - type Output = LegacyColor; - - fn mul(self, rhs: [f32; 3]) -> Self::Output { - match self { - LegacyColor::Rgba { - red, - green, - blue, - alpha, - } => LegacyColor::Rgba { - red: red * rhs[0], - green: green * rhs[1], - blue: blue * rhs[2], - alpha, - }, - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } => LegacyColor::RgbaLinear { - red: red * rhs[0], - green: green * rhs[1], - blue: blue * rhs[2], - alpha, - }, - LegacyColor::Hsla { - hue, - saturation, - lightness, - alpha, - } => LegacyColor::Hsla { - hue: hue * rhs[0], - saturation: saturation * rhs[1], - lightness: lightness * rhs[2], - alpha, - }, - LegacyColor::Lcha { - lightness, - chroma, - hue, - alpha, - } => LegacyColor::Lcha { - lightness: lightness * rhs[0], - chroma: chroma * rhs[1], - hue: hue * rhs[2], - alpha, - }, - } - } -} - -impl MulAssign<[f32; 3]> for LegacyColor { - fn mul_assign(&mut self, rhs: [f32; 3]) { - match self { - LegacyColor::Rgba { - red, green, blue, .. - } - | LegacyColor::RgbaLinear { - red, green, blue, .. - } => { - *red *= rhs[0]; - *green *= rhs[1]; - *blue *= rhs[2]; - } - LegacyColor::Hsla { - hue, - saturation, - lightness, - .. - } => { - *hue *= rhs[0]; - *saturation *= rhs[1]; - *lightness *= rhs[2]; - } - LegacyColor::Lcha { - lightness, - chroma, - hue, - .. - } => { - *lightness *= rhs[0]; - *chroma *= rhs[1]; - *hue *= rhs[2]; - } - } - } -} - -impl encase::ShaderType for LegacyColor { - type ExtraMetadata = (); - - const METADATA: encase::private::Metadata = { - let size = - encase::private::SizeValue::from(::SHADER_SIZE) - .mul(4); - let alignment = encase::private::AlignmentValue::from_next_power_of_two_size(size); - - encase::private::Metadata { - alignment, - has_uniform_min_alignment: false, - min_size: size, - extra: (), - } - }; - - const UNIFORM_COMPAT_ASSERT: fn() = || {}; -} - -impl encase::private::WriteInto for LegacyColor { - fn write_into(&self, writer: &mut encase::private::Writer) { - let linear = self.as_linear_rgba_f32(); - for el in &linear { - encase::private::WriteInto::write_into(el, writer); - } - } -} - -impl encase::private::ReadFrom for LegacyColor { - fn read_from( - &mut self, - reader: &mut encase::private::Reader, - ) { - let mut buffer = [0.0f32; 4]; - for el in &mut buffer { - encase::private::ReadFrom::read_from(el, reader); - } - - *self = LegacyColor::RgbaLinear { - red: buffer[0], - green: buffer[1], - blue: buffer[2], - alpha: buffer[3], - } - } -} - -impl encase::private::CreateFrom for LegacyColor { - fn create_from(reader: &mut encase::private::Reader) -> Self - where - B: encase::private::BufferRef, - { - // These are intentionally not inlined in the constructor to make this - // resilient to internal Color refactors / implicit type changes. - let red: f32 = encase::private::CreateFrom::create_from(reader); - let green: f32 = encase::private::CreateFrom::create_from(reader); - let blue: f32 = encase::private::CreateFrom::create_from(reader); - let alpha: f32 = encase::private::CreateFrom::create_from(reader); - LegacyColor::RgbaLinear { - red, - green, - blue, - alpha, - } - } -} - -impl encase::ShaderSize for LegacyColor {} - -#[cfg(test)] -mod tests { - use std::num::ParseIntError; - - use super::*; - - #[test] - fn hex_color() { - assert_eq!(LegacyColor::hex("FFF"), Ok(LegacyColor::WHITE)); - assert_eq!(LegacyColor::hex("FFFF"), Ok(LegacyColor::WHITE)); - assert_eq!(LegacyColor::hex("FFFFFF"), Ok(LegacyColor::WHITE)); - assert_eq!(LegacyColor::hex("FFFFFFFF"), Ok(LegacyColor::WHITE)); - assert_eq!(LegacyColor::hex("000"), Ok(LegacyColor::BLACK)); - assert_eq!(LegacyColor::hex("000F"), Ok(LegacyColor::BLACK)); - assert_eq!(LegacyColor::hex("000000"), Ok(LegacyColor::BLACK)); - assert_eq!(LegacyColor::hex("000000FF"), Ok(LegacyColor::BLACK)); - assert_eq!( - LegacyColor::hex("03a9f4"), - Ok(LegacyColor::rgb_u8(3, 169, 244)) - ); - assert_eq!(LegacyColor::hex("yy"), Err(HexColorError::Length)); - let Err(HexColorError::Parse(ParseIntError { .. })) = LegacyColor::hex("yyy") else { - panic!("Expected Parse Int Error") - }; - assert_eq!( - LegacyColor::hex("#f2a"), - Ok(LegacyColor::rgb_u8(255, 34, 170)) - ); - assert_eq!( - LegacyColor::hex("#e23030"), - Ok(LegacyColor::rgb_u8(226, 48, 48)) - ); - assert_eq!(LegacyColor::hex("#ff"), Err(HexColorError::Length)); - let Err(HexColorError::Parse(ParseIntError { .. })) = LegacyColor::hex("##fff") else { - panic!("Expected Parse Int Error") - }; - } - - #[test] - fn conversions_vec4() { - let starting_vec4 = Vec4::new(0.4, 0.5, 0.6, 1.0); - let starting_color = LegacyColor::rgba_from_array(starting_vec4); - - assert_eq!(starting_vec4, starting_color.rgba_to_vec4()); - - let transformation = Vec4::new(0.5, 0.5, 0.5, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba_from_array(starting_vec4 * transformation) - ); - } - - #[test] - fn mul_and_mulassign_f32() { - let transformation = 0.5; - let starting_color = LegacyColor::rgba(0.4, 0.5, 0.6, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba(0.4 * 0.5, 0.5 * 0.5, 0.6 * 0.5, 1.0), - ); - - let mut mutated_color = starting_color; - mutated_color *= transformation; - - assert_eq!(starting_color * transformation, mutated_color); - } - - #[test] - fn mul_and_mulassign_f32by3() { - let transformation = [0.4, 0.5, 0.6]; - let starting_color = LegacyColor::rgba(0.4, 0.5, 0.6, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba(0.4 * 0.4, 0.5 * 0.5, 0.6 * 0.6, 1.0), - ); - - let mut mutated_color = starting_color; - mutated_color *= transformation; - - assert_eq!(starting_color * transformation, mutated_color); - } - - #[test] - fn mul_and_mulassign_f32by4() { - let transformation = [0.4, 0.5, 0.6, 0.9]; - let starting_color = LegacyColor::rgba(0.4, 0.5, 0.6, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba(0.4 * 0.4, 0.5 * 0.5, 0.6 * 0.6, 1.0 * 0.9), - ); - - let mut mutated_color = starting_color; - mutated_color *= transformation; - - assert_eq!(starting_color * transformation, mutated_color); - } - - #[test] - fn mul_and_mulassign_vec3() { - let transformation = Vec3::new(0.2, 0.3, 0.4); - let starting_color = LegacyColor::rgba(0.4, 0.5, 0.6, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba(0.4 * 0.2, 0.5 * 0.3, 0.6 * 0.4, 1.0), - ); - - let mut mutated_color = starting_color; - mutated_color *= transformation; - - assert_eq!(starting_color * transformation, mutated_color); - } - - #[test] - fn mul_and_mulassign_vec4() { - let transformation = Vec4::new(0.2, 0.3, 0.4, 0.5); - let starting_color = LegacyColor::rgba(0.4, 0.5, 0.6, 1.0); - - assert_eq!( - starting_color * transformation, - LegacyColor::rgba(0.4 * 0.2, 0.5 * 0.3, 0.6 * 0.4, 1.0 * 0.5), - ); - - let mut mutated_color = starting_color; - mutated_color *= transformation; - - assert_eq!(starting_color * transformation, mutated_color); - } - - // regression test for https://github.com/bevyengine/bevy/pull/8040 - #[test] - fn convert_to_rgba_linear() { - let rgba = LegacyColor::rgba(0., 0., 0., 0.); - let rgba_l = LegacyColor::rgba_linear(0., 0., 0., 0.); - let hsla = LegacyColor::hsla(0., 0., 0., 0.); - let lcha = LegacyColor::lcha(0., 0., 0., 0.); - assert_eq!(rgba_l, rgba_l.as_rgba_linear()); - let LegacyColor::RgbaLinear { .. } = rgba.as_rgba_linear() else { - panic!("from Rgba") - }; - let LegacyColor::RgbaLinear { .. } = hsla.as_rgba_linear() else { - panic!("from Hsla") - }; - let LegacyColor::RgbaLinear { .. } = lcha.as_rgba_linear() else { - panic!("from Lcha") - }; - } -} diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index c9d99f661c..d972356b02 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -9,7 +9,6 @@ extern crate core; pub mod alpha; pub mod batching; pub mod camera; -pub mod color; pub mod deterministic; pub mod extract_component; pub mod extract_instances; @@ -38,7 +37,6 @@ pub mod prelude { Camera, ClearColor, ClearColorConfig, OrthographicProjection, PerspectiveProjection, Projection, }, - color::LegacyColor, mesh::{morph::MorphWeights, primitives::Meshable, Mesh}, render_resource::Shader, spatial_bundle::SpatialBundle, @@ -330,7 +328,18 @@ impl Plugin for RenderPlugin { )); app.register_type::() - .register_type::() + // These types cannot be registered in bevy_color, as it does not depend on the rest of Bevy + // BLOCKED: once https://github.com/bevyengine/bevy/pull/5781 lands, we can remove all but the Color registration + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() .register_type::() .register_type::() .register_type::() diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index fc7661b175..4e6898b7cb 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -74,12 +74,13 @@ impl Deref for BindGroup { /// what their binding type is, and what index they should be bound at: /// /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::*, texture::Image}; +/// # use bevy_render::{render_resource::*, texture::Image}; +/// # use bevy_color::LinearRgba; /// # use bevy_asset::Handle; /// #[derive(AsBindGroup)] /// struct CoolMaterial { /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// #[texture(1)] /// #[sampler(2)] /// color_texture: Handle, @@ -109,7 +110,7 @@ impl Deref for BindGroup { /// * `uniform(BINDING_INDEX)` /// * The field will be converted to a shader-compatible type using the [`ShaderType`] trait, written to a [`Buffer`], and bound as a uniform. /// [`ShaderType`] is implemented for most math types already, such as [`f32`], [`Vec4`](bevy_math::Vec4), and -/// [`LegacyColor`](crate::color::LegacyColor). It can also be derived for custom structs. +/// [`LinearRgba`](bevy_color::LinearRgba). It can also be derived for custom structs. /// /// * `texture(BINDING_INDEX, arguments)` /// * This field's [`Handle`](bevy_asset::Handle) will be used to look up the matching [`Texture`](crate::render_resource::Texture) @@ -162,24 +163,26 @@ impl Deref for BindGroup { /// /// Note that fields without field-level binding attributes will be ignored. /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::AsBindGroup}; +/// # use bevy_render::{render_resource::AsBindGroup}; +/// # use bevy_color::LinearRgba; /// # use bevy_asset::Handle; /// #[derive(AsBindGroup)] /// struct CoolMaterial { /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// this_field_is_ignored: String, /// } /// ``` /// /// As mentioned above, [`Option>`] is also supported: /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::AsBindGroup, texture::Image}; +/// # use bevy_render::{render_resource::AsBindGroup, texture::Image}; +/// # use bevy_color::LinearRgba; /// # use bevy_asset::Handle; /// #[derive(AsBindGroup)] /// struct CoolMaterial { /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// #[texture(1)] /// #[sampler(2)] /// color_texture: Option>, @@ -190,11 +193,12 @@ impl Deref for BindGroup { /// /// Field uniforms with the same index will be combined into a single binding: /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::AsBindGroup}; +/// # use bevy_render::{render_resource::AsBindGroup}; +/// # use bevy_color::LinearRgba; /// #[derive(AsBindGroup)] /// struct CoolMaterial { /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// #[uniform(0)] /// roughness: f32, /// } @@ -227,17 +231,18 @@ impl Deref for BindGroup { /// The previous `CoolMaterial` example illustrating "combining multiple field-level uniform attributes with the same binding index" can /// also be equivalently represented with a single struct-level uniform attribute: /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::{AsBindGroup, ShaderType}}; +/// # use bevy_render::{render_resource::{AsBindGroup, ShaderType}}; +/// # use bevy_color::LinearRgba; /// #[derive(AsBindGroup)] /// #[uniform(0, CoolMaterialUniform)] /// struct CoolMaterial { -/// color: LegacyColor, +/// color: LinearRgba, /// roughness: f32, /// } /// /// #[derive(ShaderType)] /// struct CoolMaterialUniform { -/// color: LegacyColor, +/// color: LinearRgba, /// roughness: f32, /// } /// @@ -253,12 +258,13 @@ impl Deref for BindGroup { /// /// Setting `bind_group_data` looks like this: /// ``` -/// # use bevy_render::{color::LegacyColor, render_resource::AsBindGroup}; +/// # use bevy_render::{render_resource::AsBindGroup}; +/// # use bevy_color::LinearRgba; /// #[derive(AsBindGroup)] /// #[bind_group_data(CoolMaterialKey)] /// struct CoolMaterial { /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// is_shaded: bool, /// } /// diff --git a/crates/bevy_sprite/Cargo.toml b/crates/bevy_sprite/Cargo.toml index 471236f726..ce8c402de2 100644 --- a/crates/bevy_sprite/Cargo.toml +++ b/crates/bevy_sprite/Cargo.toml @@ -16,6 +16,7 @@ webgpu = [] # bevy bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_log = { path = "../bevy_log", version = "0.14.0-dev" } diff --git a/crates/bevy_sprite/src/mesh2d/color_material.rs b/crates/bevy_sprite/src/mesh2d/color_material.rs index 2dcc378134..59d489361b 100644 --- a/crates/bevy_sprite/src/mesh2d/color_material.rs +++ b/crates/bevy_sprite/src/mesh2d/color_material.rs @@ -1,11 +1,10 @@ use crate::{Material2d, Material2dPlugin, MaterialMesh2dBundle}; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Asset, AssetApp, Assets, Handle}; +use bevy_color::{Color, LinearRgba}; use bevy_math::Vec4; use bevy_reflect::prelude::*; -use bevy_render::{ - color::LegacyColor, render_asset::RenderAssets, render_resource::*, texture::Image, -}; +use bevy_render::{render_asset::RenderAssets, render_resource::*, texture::Image}; pub const COLOR_MATERIAL_SHADER_HANDLE: Handle = Handle::weak_from_u128(3253086872234592509); @@ -28,7 +27,7 @@ impl Plugin for ColorMaterialPlugin { app.world.resource_mut::>().insert( Handle::::default(), ColorMaterial { - color: LegacyColor::rgb(1.0, 0.0, 1.0), + color: Color::srgb(1.0, 0.0, 1.0), ..Default::default() }, ); @@ -40,7 +39,7 @@ impl Plugin for ColorMaterialPlugin { #[reflect(Default, Debug)] #[uniform(0, ColorMaterialUniform)] pub struct ColorMaterial { - pub color: LegacyColor, + pub color: Color, #[texture(1)] #[sampler(2)] pub texture: Option>, @@ -49,14 +48,14 @@ pub struct ColorMaterial { impl Default for ColorMaterial { fn default() -> Self { ColorMaterial { - color: LegacyColor::WHITE, + color: Color::WHITE, texture: None, } } } -impl From for ColorMaterial { - fn from(color: LegacyColor) -> Self { +impl From for ColorMaterial { + fn from(color: Color) -> Self { ColorMaterial { color, ..Default::default() @@ -98,7 +97,7 @@ impl AsBindGroupShaderType for ColorMaterial { } ColorMaterialUniform { - color: self.color.as_linear_rgba_f32().into(), + color: LinearRgba::from(self.color).to_f32_array().into(), flags: flags.bits(), } } diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 9858204a34..8e0dc38d42 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -54,7 +54,8 @@ use crate::{ /// # use bevy_sprite::{Material2d, MaterialMesh2dBundle}; /// # use bevy_ecs::prelude::*; /// # use bevy_reflect::TypePath; -/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image, color::LegacyColor}; +/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image}; +/// # use bevy_color::LinearRgba; /// # use bevy_asset::{Handle, AssetServer, Assets, Asset}; /// /// #[derive(AsBindGroup, Debug, Clone, Asset, TypePath)] @@ -62,7 +63,7 @@ use crate::{ /// // Uniform bindings must implement `ShaderType`, which will be used to convert the value to /// // its shader-compatible equivalent. Most core math types already implement `ShaderType`. /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// // Images can be bound as textures in shaders. If the Image's sampler is also needed, just /// // add the sampler attribute with a different binding index. /// #[texture(1)] @@ -82,7 +83,7 @@ use crate::{ /// fn setup(mut commands: Commands, mut materials: ResMut>, asset_server: Res) { /// commands.spawn(MaterialMesh2dBundle { /// material: materials.add(CustomMaterial { -/// color: LegacyColor::RED, +/// color: LinearRgba::RED, /// color_texture: asset_server.load("some_image.png"), /// }), /// ..Default::default() diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index a8da994adb..00cb03feba 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -5,6 +5,7 @@ use crate::{ ComputedTextureSlices, Sprite, SPRITE_SHADER_HANDLE, }; use bevy_asset::{AssetEvent, AssetId, Assets, Handle}; +use bevy_color::LinearRgba; use bevy_core_pipeline::{ core_2d::Transparent2d, tonemapping::{DebandDither, Tonemapping}, @@ -16,7 +17,6 @@ use bevy_ecs::{ }; use bevy_math::{Affine3A, Quat, Rect, Vec2, Vec4}; use bevy_render::{ - color::LegacyColor, render_asset::RenderAssets, render_phase::{ DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline, @@ -295,7 +295,7 @@ impl SpecializedRenderPipeline for SpritePipeline { pub struct ExtractedSprite { pub transform: GlobalTransform, - pub color: LegacyColor, + pub color: LinearRgba, /// Select an area of the texture pub rect: Option, /// Change the on-screen size of the sprite @@ -379,7 +379,7 @@ pub fn extract_sprites( extracted_sprites.sprites.insert( entity, ExtractedSprite { - color: sprite.color, + color: sprite.color.into(), transform: *transform, rect, // Pass the custom size @@ -406,7 +406,7 @@ struct SpriteInstance { impl SpriteInstance { #[inline] - fn from(transform: &Affine3A, color: &LegacyColor, uv_offset_scale: &Vec4) -> Self { + fn from(transform: &Affine3A, color: &LinearRgba, uv_offset_scale: &Vec4) -> Self { let transpose_model_3x3 = transform.matrix3.transpose(); Self { i_model_transpose: [ @@ -414,7 +414,7 @@ impl SpriteInstance { transpose_model_3x3.y_axis.extend(transform.translation.y), transpose_model_3x3.z_axis.extend(transform.translation.z), ], - i_color: color.as_linear_rgba_f32(), + i_color: color.to_f32_array(), i_uv_offset_scale: uv_offset_scale.to_array(), } } @@ -524,7 +524,7 @@ pub fn queue_sprites( let sort_key = FloatOrd(extracted_sprite.transform.translation().z); // Add the item to the render phase - if extracted_sprite.color != LegacyColor::WHITE { + if extracted_sprite.color != LinearRgba::WHITE { transparent_phase.add(Transparent2d { draw_function: draw_sprite_function, pipeline: colored_pipeline, diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index 6224960651..40d0dd5f3c 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -1,7 +1,7 @@ +use bevy_color::Color; use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Rect, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::color::LegacyColor; use crate::TextureSlicer; @@ -13,7 +13,7 @@ use crate::TextureSlicer; #[repr(C)] pub struct Sprite { /// The sprite's color tint - pub color: LegacyColor, + pub color: Color, /// Flip the sprite along the `X` axis pub flip_x: bool, /// Flip the sprite along the `Y` axis diff --git a/crates/bevy_sprite/src/texture_slice/computed_slices.rs b/crates/bevy_sprite/src/texture_slice/computed_slices.rs index cc5954c3cc..cbc5a370b4 100644 --- a/crates/bevy_sprite/src/texture_slice/computed_slices.rs +++ b/crates/bevy_sprite/src/texture_slice/computed_slices.rs @@ -46,7 +46,7 @@ impl ComputedTextureSlices { let transform = transform.mul_transform(Transform::from_translation(offset)); ExtractedSprite { original_entity: Some(original_entity), - color: sprite.color, + color: sprite.color.into(), transform, rect: Some(slice.texture_rect), custom_size: Some(slice.draw_size), diff --git a/crates/bevy_text/Cargo.toml b/crates/bevy_text/Cargo.toml index 2714b03926..c4b8f23a23 100644 --- a/crates/bevy_text/Cargo.toml +++ b/crates/bevy_text/Cargo.toml @@ -16,6 +16,7 @@ default_font = [] # bevy bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_math = { path = "../bevy_math", version = "0.14.0-dev" } bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", features = [ diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 5114115cf3..b0a3dc7604 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -1,7 +1,7 @@ use bevy_asset::Handle; +use bevy_color::Color; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_reflect::prelude::*; -use bevy_render::color::LegacyColor; use bevy_utils::default; use serde::{Deserialize, Serialize}; @@ -33,7 +33,7 @@ impl Text { /// /// ``` /// # use bevy_asset::Handle; - /// # use bevy_render::color::LegacyColor; + /// # use bevy_color::Color; /// # use bevy_text::{Font, Text, TextStyle, JustifyText}; /// # /// # let font_handle: Handle = Default::default(); @@ -45,7 +45,7 @@ impl Text { /// TextStyle { /// font: font_handle.clone(), /// font_size: 60.0, - /// color: LegacyColor::WHITE, + /// color: Color::WHITE, /// }, /// ); /// @@ -54,7 +54,7 @@ impl Text { /// TextStyle { /// font: font_handle, /// font_size: 60.0, - /// color: LegacyColor::WHITE, + /// color: Color::WHITE, /// }, /// ) // You can still add text justifaction. /// .with_justify(JustifyText::Center); @@ -70,7 +70,8 @@ impl Text { /// /// ``` /// # use bevy_asset::Handle; - /// # use bevy_render::color::LegacyColor; + /// # use bevy_color::Color; + /// # use bevy_color::palettes::basic::{RED, BLUE}; /// # use bevy_text::{Font, Text, TextStyle, TextSection}; /// # /// # let font_handle: Handle = Default::default(); @@ -81,7 +82,7 @@ impl Text { /// TextStyle { /// font: font_handle.clone(), /// font_size: 60.0, - /// color: LegacyColor::BLUE, + /// color: BLUE.into(), /// }, /// ), /// TextSection::new( @@ -89,7 +90,7 @@ impl Text { /// TextStyle { /// font: font_handle, /// font_size: 60.0, - /// color: LegacyColor::RED, + /// color: RED.into(), /// }, /// ), /// ]); @@ -204,7 +205,7 @@ pub struct TextStyle { /// A new font atlas is generated for every combination of font handle and scaled font size /// which can have a strong performance impact. pub font_size: f32, - pub color: LegacyColor, + pub color: Color, } impl Default for TextStyle { @@ -212,7 +213,7 @@ impl Default for TextStyle { Self { font: Default::default(), font_size: 12.0, - color: LegacyColor::WHITE, + color: Color::WHITE, } } } diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 07d8f811f8..b653e25984 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -3,6 +3,7 @@ use crate::{ TextPipeline, TextSettings, YAxisOrientation, }; use bevy_asset::Assets; +use bevy_color::LinearRgba; use bevy_ecs::{ bundle::Bundle, change_detection::{DetectChanges, Ref}, @@ -17,7 +18,6 @@ use bevy_ecs::{ use bevy_math::Vec2; use bevy_reflect::Reflect; use bevy_render::{ - prelude::LegacyColor, primitives::Aabb, texture::Image, view::{InheritedVisibility, NoFrustumCulling, ViewVisibility, Visibility}, @@ -117,7 +117,7 @@ pub fn extract_text2d_sprite( let transform = *global_transform * GlobalTransform::from_translation(alignment_translation.extend(0.)) * scaling; - let mut color = LegacyColor::WHITE; + let mut color = LinearRgba::WHITE; let mut current_section = usize::MAX; for PositionedGlyph { position, @@ -127,7 +127,7 @@ pub fn extract_text2d_sprite( } in &text_layout_info.glyphs { if *section_index != current_section { - color = text.sections[*section_index].style.color.as_rgba_linear(); + color = LinearRgba::from(text.sections[*section_index].style.color); current_section = *section_index; } let atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); diff --git a/crates/bevy_ui/Cargo.toml b/crates/bevy_ui/Cargo.toml index bd66776a3a..3f26492577 100644 --- a/crates/bevy_ui/Cargo.toml +++ b/crates/bevy_ui/Cargo.toml @@ -13,6 +13,7 @@ keywords = ["bevy"] bevy_a11y = { path = "../bevy_a11y", version = "0.14.0-dev" } bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.14.0-dev" } bevy_derive = { path = "../bevy_derive", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } diff --git a/crates/bevy_ui/src/node_bundles.rs b/crates/bevy_ui/src/node_bundles.rs index 19845002e3..0a2a81e3d4 100644 --- a/crates/bevy_ui/src/node_bundles.rs +++ b/crates/bevy_ui/src/node_bundles.rs @@ -8,11 +8,9 @@ use crate::{ UiMaterial, ZIndex, }; use bevy_asset::Handle; +use bevy_color::Color; use bevy_ecs::bundle::Bundle; -use bevy_render::{ - prelude::LegacyColor, - view::{InheritedVisibility, ViewVisibility, Visibility}, -}; +use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}; use bevy_sprite::TextureAtlas; #[cfg(feature = "bevy_text")] use bevy_text::{BreakLineOn, JustifyText, Text, TextLayoutInfo, TextSection, TextStyle}; @@ -60,8 +58,8 @@ impl Default for NodeBundle { fn default() -> Self { NodeBundle { // Transparent background - background_color: LegacyColor::NONE.into(), - border_color: LegacyColor::NONE.into(), + background_color: Color::NONE.into(), + border_color: Color::NONE.into(), node: Default::default(), style: Default::default(), focus_policy: Default::default(), @@ -227,7 +225,7 @@ impl Default for TextBundle { view_visibility: Default::default(), z_index: Default::default(), // Transparent background - background_color: BackgroundColor(LegacyColor::NONE), + background_color: BackgroundColor(Color::NONE), } } } @@ -267,7 +265,7 @@ impl TextBundle { } /// Returns this [`TextBundle`] with a new [`BackgroundColor`]. - pub const fn with_background_color(mut self, color: LegacyColor) -> Self { + pub const fn with_background_color(mut self, color: Color) -> Self { self.background_color = BackgroundColor(color); self } @@ -343,7 +341,7 @@ impl Default for ButtonBundle { node: Default::default(), button: Default::default(), style: Default::default(), - border_color: BorderColor(LegacyColor::NONE), + border_color: BorderColor(Color::NONE), interaction: Default::default(), background_color: Default::default(), image: Default::default(), diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 934fa90813..7c00c854cd 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -2,6 +2,7 @@ mod pipeline; mod render_pass; mod ui_material_pipeline; +use bevy_color::{Alpha, LinearRgba}; use bevy_core_pipeline::core_2d::graph::{Core2d, Node2d}; use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d}; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; @@ -25,7 +26,6 @@ use bevy_ecs::prelude::*; use bevy_math::{Mat4, Rect, URect, UVec4, Vec2, Vec3, Vec4Swizzles}; use bevy_render::{ camera::Camera, - color::LegacyColor, render_asset::RenderAssets, render_graph::{RenderGraph, RunGraphOnViewNode}, render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions, RenderPhase}, @@ -130,7 +130,7 @@ fn get_ui_graph(render_app: &mut App) -> RenderGraph { pub struct ExtractedUiNode { pub stack_index: u32, pub transform: Mat4, - pub color: LegacyColor, + pub color: LinearRgba, pub rect: Rect, pub image: AssetId, pub atlas_size: Option, @@ -264,7 +264,7 @@ pub fn extract_uinode_borders( stack_index: node.stack_index, // This translates the uinode's transform to the center of the current border rectangle transform: transform * Mat4::from_translation(edge.center().extend(0.)), - color: border_color.0, + color: border_color.0.into(), rect: Rect { max: edge.size(), ..Default::default() @@ -355,7 +355,7 @@ pub fn extract_uinode_outlines( stack_index: node.stack_index, // This translates the uinode's transform to the center of the current border rectangle transform: transform * Mat4::from_translation(edge.center().extend(0.)), - color: outline.color, + color: outline.color.into(), rect: Rect { max: edge.size(), ..Default::default() @@ -458,7 +458,7 @@ pub fn extract_uinodes( ExtractedUiNode { stack_index: uinode.stack_index, transform: transform.compute_matrix(), - color: color.0, + color: color.0.into(), rect, clip: clip.map(|clip| clip.clip), image, @@ -598,7 +598,7 @@ pub fn extract_text_uinodes( let transform = Mat4::from(global_transform.affine()) * Mat4::from_translation(logical_top_left_nearest_pixel.extend(0.)); - let mut color = LegacyColor::WHITE; + let mut color = LinearRgba::WHITE; let mut current_section = usize::MAX; for PositionedGlyph { position, @@ -608,7 +608,7 @@ pub fn extract_text_uinodes( } in &text_layout_info.glyphs { if *section_index != current_section { - color = text.sections[*section_index].style.color.as_rgba_linear(); + color = LinearRgba::from(text.sections[*section_index].style.color); current_section = *section_index; } let atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); @@ -935,7 +935,7 @@ pub fn prepare_uinodes( .map(|pos| pos / atlas_extent) }; - let color = extracted_uinode.color.as_linear_rgba_f32(); + let color = extracted_uinode.color.to_f32_array(); for i in QUAD_INDICES { ui_meta.vertices.push(UiVertex { position: positions_clipped[i].into(), diff --git a/crates/bevy_ui/src/texture_slice.rs b/crates/bevy_ui/src/texture_slice.rs index 24e77691e9..52a9112d8b 100644 --- a/crates/bevy_ui/src/texture_slice.rs +++ b/crates/bevy_ui/src/texture_slice.rs @@ -60,7 +60,7 @@ impl ComputedTextureSlices { let atlas_size = Some(self.image_size * scale); ExtractedUiNode { stack_index: node.stack_index, - color: background_color.0, + color: background_color.0.into(), transform: transform.compute_matrix(), rect, flip_x, diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index 7f2ce03962..fee66480c7 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -24,7 +24,8 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader /// # use bevy_ui::prelude::*; /// # use bevy_ecs::prelude::*; /// # use bevy_reflect::TypePath; -/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image, color::LegacyColor}; +/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image}; +/// # use bevy_color::LinearRgba; /// # use bevy_asset::{Handle, AssetServer, Assets, Asset}; /// /// #[derive(AsBindGroup, Asset, TypePath, Debug, Clone)] @@ -32,7 +33,7 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader /// // Uniform bindings must implement `ShaderType`, which will be used to convert the value to /// // its shader-compatible equivalent. Most core math types already implement `ShaderType`. /// #[uniform(0)] -/// color: LegacyColor, +/// color: LinearRgba, /// // Images can be bound as textures in shaders. If the Image's sampler is also needed, just /// // add the sampler attribute with a different binding index. /// #[texture(1)] @@ -56,7 +57,7 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader /// ..Default::default() /// }, /// material: materials.add(CustomMaterial { -/// color: LegacyColor::RED, +/// color: LinearRgba::RED, /// color_texture: asset_server.load("some_image.png"), /// }), /// ..Default::default() diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index aef4e724a0..3be256fe1e 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -1,11 +1,11 @@ use crate::{UiRect, Val}; use bevy_asset::Handle; +use bevy_color::Color; use bevy_ecs::{prelude::*, system::SystemParam}; use bevy_math::{Rect, Vec2}; use bevy_reflect::prelude::*; use bevy_render::{ camera::{Camera, RenderTarget}, - color::LegacyColor, texture::Image, }; use bevy_transform::prelude::GlobalTransform; @@ -1597,10 +1597,10 @@ pub enum GridPlacementError { derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -pub struct BackgroundColor(pub LegacyColor); +pub struct BackgroundColor(pub Color); impl BackgroundColor { - pub const DEFAULT: Self = Self(LegacyColor::WHITE); + pub const DEFAULT: Self = Self(Color::WHITE); } impl Default for BackgroundColor { @@ -1609,9 +1609,9 @@ impl Default for BackgroundColor { } } -impl From for BackgroundColor { - fn from(color: LegacyColor) -> Self { - Self(color) +impl> From for BackgroundColor { + fn from(color: T) -> Self { + Self(color.into()) } } @@ -1623,16 +1623,16 @@ impl From for BackgroundColor { derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -pub struct BorderColor(pub LegacyColor); +pub struct BorderColor(pub Color); -impl From for BorderColor { - fn from(color: LegacyColor) -> Self { - Self(color) +impl> From for BorderColor { + fn from(color: T) -> Self { + Self(color.into()) } } impl BorderColor { - pub const DEFAULT: Self = BorderColor(LegacyColor::WHITE); + pub const DEFAULT: Self = BorderColor(Color::WHITE); } impl Default for BorderColor { @@ -1655,7 +1655,7 @@ impl Default for BorderColor { /// ``` /// # use bevy_ecs::prelude::*; /// # use bevy_ui::prelude::*; -/// # use bevy_render::prelude::LegacyColor; +/// # use bevy_color::palettes::basic::{RED, BLUE}; /// fn setup_ui(mut commands: Commands) { /// commands.spawn(( /// NodeBundle { @@ -1664,10 +1664,10 @@ impl Default for BorderColor { /// height: Val::Px(100.), /// ..Default::default() /// }, -/// background_color: LegacyColor::BLUE.into(), +/// background_color: BLUE.into(), /// ..Default::default() /// }, -/// Outline::new(Val::Px(10.), Val::ZERO, LegacyColor::RED) +/// Outline::new(Val::Px(10.), Val::ZERO, RED.into()) /// )); /// } /// ``` @@ -1676,7 +1676,7 @@ impl Default for BorderColor { /// ``` /// # use bevy_ecs::prelude::*; /// # use bevy_ui::prelude::*; -/// # use bevy_render::prelude::LegacyColor; +/// # use bevy_color::Color; /// fn outline_hovered_button_system( /// mut commands: Commands, /// mut node_query: Query<(Entity, &Interaction, Option<&mut Outline>), Changed>, @@ -1684,9 +1684,9 @@ impl Default for BorderColor { /// for (entity, interaction, mut maybe_outline) in node_query.iter_mut() { /// let outline_color = /// if matches!(*interaction, Interaction::Hovered) { -/// LegacyColor::WHITE +/// Color::WHITE /// } else { -/// LegacyColor::NONE +/// Color::NONE /// }; /// if let Some(mut outline) = maybe_outline { /// outline.color = outline_color; @@ -1697,7 +1697,7 @@ impl Default for BorderColor { /// } /// ``` /// Inserting and removing an [`Outline`] component repeatedly will result in table moves, so it is generally preferable to -/// set `Outline::color` to `LegacyColor::NONE` to hide an outline. +/// set `Outline::color` to [`Color::NONE`] to hide an outline. pub struct Outline { /// The width of the outline. /// @@ -1709,14 +1709,14 @@ pub struct Outline { pub offset: Val, /// The color of the outline. /// - /// If you are frequently toggling outlines for a UI node on and off it is recommended to set `LegacyColor::NONE` to hide the outline. + /// If you are frequently toggling outlines for a UI node on and off it is recommended to set [`Color::NONE`] to hide the outline. /// This avoids the table moves that would occur from the repeated insertion and removal of the `Outline` component. - pub color: LegacyColor, + pub color: Color, } impl Outline { /// Create a new outline - pub const fn new(width: Val, offset: Val, color: LegacyColor) -> Self { + pub const fn new(width: Val, offset: Val, color: Color) -> Self { Self { width, offset, diff --git a/errors/B0004.md b/errors/B0004.md index e05d4ef7b8..5cf94109bf 100644 --- a/errors/B0004.md +++ b/errors/B0004.md @@ -34,7 +34,7 @@ fn setup_cube( // cube parent.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::rgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); @@ -81,7 +81,7 @@ fn setup_cube( // cube parent.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::rgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); diff --git a/examples/2d/2d_shapes.rs b/examples/2d/2d_shapes.rs index 9d9c463ef8..be5e70529a 100644 --- a/examples/2d/2d_shapes.rs +++ b/examples/2d/2d_shapes.rs @@ -37,7 +37,7 @@ fn setup( for (i, shape) in shapes.into_iter().enumerate() { // Distribute colors evenly across the rainbow. - let color = LegacyColor::hsl(360. * i as f32 / num_shapes as f32, 0.95, 0.7); + let color = Color::hsl(360. * i as f32 / num_shapes as f32, 0.95, 0.7); commands.spawn(MaterialMesh2dBundle { mesh: shape, diff --git a/examples/2d/2d_viewport_to_world.rs b/examples/2d/2d_viewport_to_world.rs index 59717973ab..788649f979 100644 --- a/examples/2d/2d_viewport_to_world.rs +++ b/examples/2d/2d_viewport_to_world.rs @@ -1,6 +1,6 @@ //! This example demonstrates how to use the `Camera::viewport_to_world_2d` method. -use bevy::prelude::*; +use bevy::{color::palettes::basic::WHITE, prelude::*}; fn main() { App::new() @@ -26,7 +26,7 @@ fn draw_cursor( return; }; - gizmos.circle_2d(point, 10., LegacyColor::WHITE); + gizmos.circle_2d(point, 10., WHITE); } fn setup(mut commands: Commands) { diff --git a/examples/2d/bloom_2d.rs b/examples/2d/bloom_2d.rs index 83e90e8d1f..b1004954ff 100644 --- a/examples/2d/bloom_2d.rs +++ b/examples/2d/bloom_2d.rs @@ -39,7 +39,7 @@ fn setup( commands.spawn(SpriteBundle { texture: asset_server.load("branding/bevy_bird_dark.png"), sprite: Sprite { - color: LegacyColor::rgb(5.0, 5.0, 5.0), // 4. Put something bright in a dark environment to see the effect + color: Color::srgb(5.0, 5.0, 5.0), // 4. Put something bright in a dark environment to see the effect custom_size: Some(Vec2::splat(160.0)), ..default() }, @@ -50,7 +50,7 @@ fn setup( commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(Circle::new(100.)).into(), // 4. Put something bright in a dark environment to see the effect - material: materials.add(LegacyColor::rgb(7.5, 0.0, 7.5)), + material: materials.add(Color::srgb(7.5, 0.0, 7.5)), transform: Transform::from_translation(Vec3::new(-200., 0., 0.)), ..default() }); @@ -59,7 +59,7 @@ fn setup( commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(RegularPolygon::new(100., 6)).into(), // 4. Put something bright in a dark environment to see the effect - material: materials.add(LegacyColor::rgb(6.25, 9.4, 9.1)), + material: materials.add(Color::srgb(6.25, 9.4, 9.1)), transform: Transform::from_translation(Vec3::new(200., 0., 0.)), ..default() }); @@ -70,7 +70,7 @@ fn setup( "", TextStyle { font_size: 18.0, - color: LegacyColor::WHITE, + color: Color::WHITE, ..default() }, ) diff --git a/examples/2d/bounding_2d.rs b/examples/2d/bounding_2d.rs index e6516b9650..acac69bac6 100644 --- a/examples/2d/bounding_2d.rs +++ b/examples/2d/bounding_2d.rs @@ -1,6 +1,6 @@ //! This example demonstrates bounding volume intersections. -use bevy::{math::bounding::*, prelude::*}; +use bevy::{color::palettes::css::*, math::bounding::*, prelude::*}; fn main() { App::new() @@ -97,7 +97,7 @@ enum Shape { } fn render_shapes(mut gizmos: Gizmos, query: Query<(&Shape, &Transform)>) { - let color = LegacyColor::GRAY; + let color = GRAY; for (shape, transform) in query.iter() { let translation = transform.translation.xy(); let rotation = transform.rotation.to_euler(EulerRot::YXZ).2; @@ -177,11 +177,7 @@ fn update_volumes( fn render_volumes(mut gizmos: Gizmos, query: Query<(&CurrentVolume, &Intersects)>) { for (volume, intersects) in query.iter() { - let color = if **intersects { - LegacyColor::CYAN - } else { - LegacyColor::ORANGE_RED - }; + let color = if **intersects { CYAN } else { ORANGE_RED }; match volume { CurrentVolume::Aabb(a) => { gizmos.rect_2d(a.center(), 0., a.half_size() * 2., color); @@ -292,10 +288,10 @@ fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) { gizmos.line_2d( ray.ray.origin, ray.ray.origin + *ray.ray.direction * ray.max, - LegacyColor::WHITE, + WHITE, ); for r in [1., 2., 3.] { - gizmos.circle_2d(ray.ray.origin, r, LegacyColor::FUCHSIA); + gizmos.circle_2d(ray.ray.origin, r, FUCHSIA); } } @@ -331,7 +327,7 @@ fn ray_cast_system( gizmos.circle_2d( ray_cast.ray.origin + *ray_cast.ray.direction * toi, r, - LegacyColor::GREEN, + GREEN, ); } } @@ -363,7 +359,7 @@ fn aabb_cast_system( + aabb_cast.aabb.center(), 0., aabb_cast.aabb.half_size() * 2., - LegacyColor::GREEN, + GREEN, ); } } @@ -393,7 +389,7 @@ fn bounding_circle_cast_system( + *circle_cast.ray.ray.direction * toi + circle_cast.circle.center(), circle_cast.circle.radius(), - LegacyColor::GREEN, + GREEN, ); } } @@ -412,7 +408,7 @@ fn aabb_intersection_system( ) { let center = get_intersection_position(&time); let aabb = Aabb2d::new(center, Vec2::splat(50.)); - gizmos.rect_2d(center, 0., aabb.half_size() * 2., LegacyColor::YELLOW); + gizmos.rect_2d(center, 0., aabb.half_size() * 2., YELLOW); for (volume, mut intersects) in volumes.iter_mut() { let hit = match volume { @@ -431,7 +427,7 @@ fn circle_intersection_system( ) { let center = get_intersection_position(&time); let circle = BoundingCircle::new(center, 50.); - gizmos.circle_2d(center, circle.radius(), LegacyColor::YELLOW); + gizmos.circle_2d(center, circle.radius(), YELLOW); for (volume, mut intersects) in volumes.iter_mut() { let hit = match volume { diff --git a/examples/2d/custom_gltf_vertex_attribute.rs b/examples/2d/custom_gltf_vertex_attribute.rs index 1354838297..2f84665c31 100644 --- a/examples/2d/custom_gltf_vertex_attribute.rs +++ b/examples/2d/custom_gltf_vertex_attribute.rs @@ -21,7 +21,7 @@ const ATTRIBUTE_BARYCENTRIC: MeshVertexAttribute = fn main() { App::new() .insert_resource(AmbientLight { - color: LegacyColor::WHITE, + color: Color::WHITE, brightness: 1.0 / 5.0f32, }) .add_plugins(( diff --git a/examples/2d/mesh2d.rs b/examples/2d/mesh2d.rs index c6a6ec9ef5..e21350fcf0 100644 --- a/examples/2d/mesh2d.rs +++ b/examples/2d/mesh2d.rs @@ -2,7 +2,7 @@ //! //! [`Quad`]: shape::Quad -use bevy::{prelude::*, sprite::MaterialMesh2dBundle}; +use bevy::{color::palettes::basic::PURPLE, prelude::*, sprite::MaterialMesh2dBundle}; fn main() { App::new() @@ -20,7 +20,7 @@ fn setup( commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(Rectangle::default()).into(), transform: Transform::default().with_scale(Vec3::splat(128.)), - material: materials.add(LegacyColor::PURPLE), + material: materials.add(Color::from(PURPLE)), ..default() }); } diff --git a/examples/2d/mesh2d_manual.rs b/examples/2d/mesh2d_manual.rs index 1c89212113..acb0d3b6dc 100644 --- a/examples/2d/mesh2d_manual.rs +++ b/examples/2d/mesh2d_manual.rs @@ -6,12 +6,12 @@ //! [`Material2d`]: bevy::sprite::Material2d use bevy::{ + color::palettes::basic::YELLOW, core_pipeline::core_2d::Transparent2d, prelude::*, render::{ mesh::{Indices, MeshVertexAttribute}, - render_asset::RenderAssetUsages, - render_asset::RenderAssets, + render_asset::{RenderAssetUsages, RenderAssets}, render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline}, render_resource::{ BlendState, ColorTargetState, ColorWrites, Face, FragmentState, FrontFace, @@ -80,8 +80,8 @@ fn star( // Set the position attribute star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos); // And a RGB color attribute as well - let mut v_color: Vec = vec![LegacyColor::BLACK.as_linear_rgba_u32()]; - v_color.extend_from_slice(&[LegacyColor::YELLOW.as_linear_rgba_u32(); 10]); + let mut v_color: Vec = vec![LinearRgba::BLACK.as_u32()]; + v_color.extend_from_slice(&[LinearRgba::from(YELLOW).as_u32(); 10]); star.insert_attribute( MeshVertexAttribute::new("Vertex_Color", 1, VertexFormat::Uint32), v_color, diff --git a/examples/2d/mesh2d_vertex_color_texture.rs b/examples/2d/mesh2d_vertex_color_texture.rs index 5e966044f4..f0a41c60c9 100644 --- a/examples/2d/mesh2d_vertex_color_texture.rs +++ b/examples/2d/mesh2d_vertex_color_texture.rs @@ -27,10 +27,10 @@ fn setup( let mut mesh = Mesh::from(Rectangle::default()); // Build vertex colors for the quad. One entry per vertex (the corners of the quad) let vertex_colors: Vec<[f32; 4]> = vec![ - LegacyColor::RED.as_rgba_f32(), - LegacyColor::GREEN.as_rgba_f32(), - LegacyColor::BLUE.as_rgba_f32(), - LegacyColor::WHITE.as_rgba_f32(), + LinearRgba::RED.to_f32_array(), + LinearRgba::GREEN.to_f32_array(), + LinearRgba::BLUE.to_f32_array(), + LinearRgba::WHITE.to_f32_array(), ]; // Insert the vertex colors as an attribute mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors); diff --git a/examples/2d/pixel_grid_snap.rs b/examples/2d/pixel_grid_snap.rs index ea76869e12..075dc06818 100644 --- a/examples/2d/pixel_grid_snap.rs +++ b/examples/2d/pixel_grid_snap.rs @@ -85,7 +85,7 @@ fn setup_mesh( MaterialMesh2dBundle { mesh: meshes.add(Capsule2d::default()).into(), transform: Transform::from_xyz(40., 0., 2.).with_scale(Vec3::splat(32.)), - material: materials.add(LegacyColor::BLACK), + material: materials.add(Color::BLACK), ..default() }, Rotate, diff --git a/examples/2d/sprite_slice.rs b/examples/2d/sprite_slice.rs index 3170b68119..c2cf40130b 100644 --- a/examples/2d/sprite_slice.rs +++ b/examples/2d/sprite_slice.rs @@ -114,7 +114,7 @@ fn setup(mut commands: Commands, asset_server: Res) { let style = TextStyle { font: font.clone(), font_size: 16.0, - color: LegacyColor::WHITE, + color: Color::WHITE, }; // Load textures diff --git a/examples/2d/text2d.rs b/examples/2d/text2d.rs index d384bcf0ec..a0229545bd 100644 --- a/examples/2d/text2d.rs +++ b/examples/2d/text2d.rs @@ -6,6 +6,7 @@ //! viewport, you may want to look at `games/contributors.rs` or `ui/text.rs`. use bevy::{ + color::palettes::css::*, prelude::*, sprite::Anchor, text::{BreakLineOn, Text2dBounds}, @@ -36,7 +37,7 @@ fn setup(mut commands: Commands, asset_server: Res) { let text_style = TextStyle { font: font.clone(), font_size: 60.0, - color: LegacyColor::WHITE, + ..default() }; let text_justification = JustifyText::Center; // 2d camera @@ -72,14 +73,14 @@ fn setup(mut commands: Commands, asset_server: Res) { let slightly_smaller_text_style = TextStyle { font, font_size: 42.0, - color: LegacyColor::WHITE, + ..default() }; let box_size = Vec2::new(300.0, 200.0); let box_position = Vec2::new(0.0, -250.0); commands .spawn(SpriteBundle { sprite: Sprite { - color: LegacyColor::rgb(0.25, 0.25, 0.75), + color: Color::srgb(0.25, 0.25, 0.75), custom_size: Some(Vec2::new(box_size.x, box_size.y)), ..default() }, @@ -111,7 +112,7 @@ fn setup(mut commands: Commands, asset_server: Res) { commands .spawn(SpriteBundle { sprite: Sprite { - color: LegacyColor::rgb(0.20, 0.3, 0.70), + color: Color::srgb(0.20, 0.3, 0.70), custom_size: Some(Vec2::new(other_box_size.x, other_box_size.y)), ..default() }, @@ -139,10 +140,10 @@ fn setup(mut commands: Commands, asset_server: Res) { }); for (text_anchor, color) in [ - (Anchor::TopLeft, LegacyColor::RED), - (Anchor::TopRight, LegacyColor::GREEN), - (Anchor::BottomRight, LegacyColor::BLUE), - (Anchor::BottomLeft, LegacyColor::YELLOW), + (Anchor::TopLeft, Color::Srgba(RED)), + (Anchor::TopRight, Color::Srgba(GREEN)), + (Anchor::BottomRight, Color::Srgba(BLUE)), + (Anchor::BottomLeft, Color::Srgba(YELLOW)), ] { commands.spawn(Text2dBundle { text: Text { diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 130494aa64..6b5e4eab57 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -124,7 +124,7 @@ fn setup( let text_style: TextStyle = TextStyle { font: font.clone(), font_size: 50.0, - color: LegacyColor::WHITE, + color: Color::WHITE, }; // labels to indicate padding @@ -173,7 +173,7 @@ fn setup( let sampling_label_style = TextStyle { font, font_size: 30.0, - color: LegacyColor::WHITE, + color: Color::WHITE, }; let base_y = 170.0; // y position of the sprites diff --git a/examples/2d/transparency_2d.rs b/examples/2d/transparency_2d.rs index 4071a4fd08..069b73098e 100644 --- a/examples/2d/transparency_2d.rs +++ b/examples/2d/transparency_2d.rs @@ -22,7 +22,7 @@ fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(SpriteBundle { sprite: Sprite { // Alpha channel of the color controls transparency. - color: LegacyColor::rgba(0.0, 0.0, 1.0, 0.7), + color: Color::srgba(0.0, 0.0, 1.0, 0.7), ..default() }, texture: sprite_handle.clone(), @@ -31,7 +31,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }); commands.spawn(SpriteBundle { sprite: Sprite { - color: LegacyColor::rgba(0.0, 1.0, 0.0, 0.3), + color: Color::srgba(0.0, 1.0, 0.0, 0.3), ..default() }, texture: sprite_handle, diff --git a/examples/3d/3d_scene.rs b/examples/3d/3d_scene.rs index 2737dd249b..9b57373ec7 100644 --- a/examples/3d/3d_scene.rs +++ b/examples/3d/3d_scene.rs @@ -18,14 +18,14 @@ fn setup( // circular base commands.spawn(PbrBundle { mesh: meshes.add(Circle::new(4.0)), - material: materials.add(LegacyColor::WHITE), + material: materials.add(Color::WHITE), transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)), ..default() }); // cube commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)), - material: materials.add(LegacyColor::rgb_u8(124, 144, 255)), + material: materials.add(Color::srgb_u8(124, 144, 255)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); diff --git a/examples/3d/3d_shapes.rs b/examples/3d/3d_shapes.rs index db9b3d5bcc..f0aaa9265b 100644 --- a/examples/3d/3d_shapes.rs +++ b/examples/3d/3d_shapes.rs @@ -4,6 +4,7 @@ use std::f32::consts::PI; use bevy::{ + color::palettes::basic::SILVER, prelude::*, render::{ render_asset::RenderAssetUsages, @@ -78,7 +79,7 @@ fn setup( // ground plane commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)), - material: materials.add(LegacyColor::SILVER), + material: materials.add(Color::from(SILVER)), ..default() }); diff --git a/examples/3d/3d_viewport_to_world.rs b/examples/3d/3d_viewport_to_world.rs index f8b5e3c1c0..dafcd9765d 100644 --- a/examples/3d/3d_viewport_to_world.rs +++ b/examples/3d/3d_viewport_to_world.rs @@ -1,7 +1,6 @@ //! This example demonstrates how to use the `Camera::viewport_to_world` method. -use bevy::math::Dir3; -use bevy::prelude::*; +use bevy::{math::Dir3, prelude::*}; fn main() { App::new() @@ -41,7 +40,7 @@ fn draw_cursor( point + ground.up() * 0.01, Dir3::new_unchecked(ground.up()), // Up vector is already normalized. 0.2, - LegacyColor::WHITE, + Color::WHITE, ); } @@ -57,7 +56,7 @@ fn setup( commands.spawn(( PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(20., 20.)), - material: materials.add(LegacyColor::rgb(0.3, 0.5, 0.3)), + material: materials.add(Color::srgb(0.3, 0.5, 0.3)), ..default() }, Ground, diff --git a/examples/3d/animated_material.rs b/examples/3d/animated_material.rs index 0b6883be26..f588295ec3 100644 --- a/examples/3d/animated_material.rs +++ b/examples/3d/animated_material.rs @@ -34,7 +34,7 @@ fn setup( for z in -1..2 { commands.spawn(PbrBundle { mesh: cube.clone(), - material: materials.add(LegacyColor::WHITE), + material: materials.add(Color::WHITE), transform: Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)), ..default() }); @@ -49,12 +49,11 @@ fn animate_materials( ) { for (i, material_handle) in material_handles.iter().enumerate() { if let Some(material) = materials.get_mut(material_handle) { - let color = LegacyColor::hsl( + material.base_color = Color::hsl( ((i as f32 * 2.345 + time.elapsed_seconds_wrapped()) * 100.0) % 360.0, 1.0, 0.5, ); - material.base_color = color; } } } diff --git a/examples/3d/anti_aliasing.rs b/examples/3d/anti_aliasing.rs index 4ee365dce5..fc698733e3 100644 --- a/examples/3d/anti_aliasing.rs +++ b/examples/3d/anti_aliasing.rs @@ -261,7 +261,7 @@ fn setup( // Plane commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)), - material: materials.add(LegacyColor::rgb(0.1, 0.2, 0.1)), + material: materials.add(Color::srgb(0.1, 0.2, 0.1)), ..default() }); @@ -329,7 +329,7 @@ fn setup( intensity: 150.0, }, FogSettings { - color: LegacyColor::rgba_u8(43, 44, 47, 255), + color: Color::srgba_u8(43, 44, 47, 255), falloff: FogFalloff::Linear { start: 1.0, end: 4.0, diff --git a/examples/3d/atmospheric_fog.rs b/examples/3d/atmospheric_fog.rs index dfba2b4f17..b687682abf 100644 --- a/examples/3d/atmospheric_fog.rs +++ b/examples/3d/atmospheric_fog.rs @@ -31,13 +31,13 @@ fn setup_camera_fog(mut commands: Commands) { ..default() }, FogSettings { - color: LegacyColor::rgba(0.35, 0.48, 0.66, 1.0), - directional_light_color: LegacyColor::rgba(1.0, 0.95, 0.85, 0.5), + color: Color::srgba(0.35, 0.48, 0.66, 1.0), + directional_light_color: Color::srgba(1.0, 0.95, 0.85, 0.5), directional_light_exponent: 30.0, falloff: FogFalloff::from_visibility_colors( 15.0, // distance in world units up to which objects retain visibility (>= 5% contrast) - LegacyColor::rgb(0.35, 0.5, 0.66), // atmospheric extinction color (after light is lost due to absorption by atmospheric particles) - LegacyColor::rgb(0.8, 0.844, 1.0), // atmospheric inscattering color (light gained due to scattering from the sun) + Color::srgb(0.35, 0.5, 0.66), // atmospheric extinction color (after light is lost due to absorption by atmospheric particles) + Color::srgb(0.8, 0.844, 1.0), // atmospheric inscattering color (light gained due to scattering from the sun) ), }, )); @@ -60,7 +60,7 @@ fn setup_terrain_scene( // Sun commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { - color: LegacyColor::rgb(0.98, 0.95, 0.82), + color: Color::srgb(0.98, 0.95, 0.82), shadows_enabled: true, ..default() }, @@ -81,7 +81,7 @@ fn setup_terrain_scene( PbrBundle { mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("888888").unwrap(), + base_color: Srgba::hex("888888").unwrap().into(), unlit: true, cull_mode: None, ..default() @@ -115,12 +115,12 @@ fn toggle_system(keycode: Res>, mut fog: Query<&mut FogSett let mut fog_settings = fog.single_mut(); if keycode.just_pressed(KeyCode::Space) { - let a = fog_settings.color.a(); - fog_settings.color.set_a(1.0 - a); + let a = fog_settings.color.alpha(); + fog_settings.color.set_alpha(1.0 - a); } if keycode.just_pressed(KeyCode::KeyS) { - let a = fog_settings.directional_light_color.a(); - fog_settings.directional_light_color.set_a(0.5 - a); + let a = fog_settings.directional_light_color.alpha(); + fog_settings.directional_light_color.set_alpha(0.5 - a); } } diff --git a/examples/3d/blend_modes.rs b/examples/3d/blend_modes.rs index 8cd05f17d8..8930443bb3 100644 --- a/examples/3d/blend_modes.rs +++ b/examples/3d/blend_modes.rs @@ -10,7 +10,7 @@ //! | `Spacebar` | Toggle Unlit | //! | `C` | Randomize Colors | -use bevy::prelude::*; +use bevy::{color::palettes::css::ORANGE, prelude::*}; use rand::random; fn main() { @@ -36,7 +36,7 @@ fn setup( mut materials: ResMut>, asset_server: Res, ) { - let base_color = LegacyColor::rgba(0.9, 0.2, 0.3, 1.0); + let base_color = Color::srgb(0.9, 0.2, 0.3); let icosphere_mesh = meshes.add(Sphere::new(0.9).mesh().ico(7).unwrap()); // Opaque @@ -140,8 +140,8 @@ fn setup( .id(); // Chessboard Plane - let black_material = materials.add(LegacyColor::BLACK); - let white_material = materials.add(LegacyColor::WHITE); + let black_material = materials.add(Color::BLACK); + let white_material = materials.add(Color::WHITE); let plane_mesh = meshes.add(Plane3d::default().mesh().size(2.0, 2.0)); @@ -188,7 +188,7 @@ fn setup( let label_text_style = TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: 25.0, - color: LegacyColor::ORANGE, + color: ORANGE.into(), }; commands.spawn( @@ -300,13 +300,19 @@ fn example_control_system( for (material_handle, controls) in &controllable { let material = materials.get_mut(material_handle).unwrap(); - material.base_color.set_a(state.alpha); if controls.color && randomize_colors { - material.base_color.set_r(random()); - material.base_color.set_g(random()); - material.base_color.set_b(random()); + material.base_color = Srgba { + red: random(), + green: random(), + blue: random(), + alpha: state.alpha, + } + .into(); + } else { + material.base_color.set_alpha(state.alpha); } + if controls.unlit { material.unlit = state.unlit; } diff --git a/examples/3d/bloom_3d.rs b/examples/3d/bloom_3d.rs index dc7f3d187e..34101d35ff 100644 --- a/examples/3d/bloom_3d.rs +++ b/examples/3d/bloom_3d.rs @@ -1,6 +1,7 @@ //! Illustrates bloom post-processing using HDR and emissive materials. use bevy::{ + color::palettes::basic::GRAY, core_pipeline::{ bloom::{BloomCompositeMode, BloomSettings}, tonemapping::Tonemapping, @@ -39,19 +40,19 @@ fn setup_scene( )); let material_emissive1 = materials.add(StandardMaterial { - emissive: LegacyColor::rgb_linear(2300.0, 900.0, 300.0), // 4. Put something bright in a dark environment to see the effect + emissive: Color::linear_rgb(2300.0, 900.0, 300.0), // 4. Put something bright in a dark environment to see the effect ..default() }); let material_emissive2 = materials.add(StandardMaterial { - emissive: LegacyColor::rgb_linear(300.0, 2300.0, 900.0), + emissive: Color::linear_rgb(300.0, 2300.0, 900.0), ..default() }); let material_emissive3 = materials.add(StandardMaterial { - emissive: LegacyColor::rgb_linear(900.0, 300.0, 2300.0), + emissive: Color::linear_rgb(900.0, 300.0, 2300.0), ..default() }); let material_non_emissive = materials.add(StandardMaterial { - base_color: LegacyColor::GRAY, + base_color: GRAY.into(), ..default() }); @@ -89,7 +90,7 @@ fn setup_scene( "", TextStyle { font_size: 20.0, - color: LegacyColor::BLACK, + color: Color::BLACK, ..default() }, ) diff --git a/examples/3d/deferred_rendering.rs b/examples/3d/deferred_rendering.rs index f6d9e18082..165d1de909 100644 --- a/examples/3d/deferred_rendering.rs +++ b/examples/3d/deferred_rendering.rs @@ -48,7 +48,7 @@ fn setup( ..default() }, FogSettings { - color: LegacyColor::rgba_u8(43, 44, 47, 255), + color: Color::srgb_u8(43, 44, 47), falloff: FogFalloff::Linear { start: 1.0, end: 8.0, @@ -95,7 +95,7 @@ fn setup( ..default() }); - let mut forward_mat: StandardMaterial = LegacyColor::rgb(0.1, 0.2, 0.1).into(); + let mut forward_mat: StandardMaterial = Color::srgb(0.1, 0.2, 0.1).into(); forward_mat.opaque_render_method = OpaqueRendererMethod::Forward; let forward_mat_h = materials.add(forward_mat); @@ -123,7 +123,7 @@ fn setup( ..default() }); - let sphere_color = LegacyColor::rgb(10.0, 4.0, 1.0); + let sphere_color = Color::srgb(10.0, 4.0, 1.0); let sphere_pos = Transform::from_xyz(0.4, 0.5, -0.8); // Emissive sphere let mut unlit_mat: StandardMaterial = sphere_color.into(); @@ -156,21 +156,21 @@ fn setup( let s_val = if i < 3 { 0.0 } else { 0.2 }; let material = if j == 0 { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(s_val, s_val, 1.0), + base_color: Color::srgb(s_val, s_val, 1.0), perceptual_roughness: 0.089, metallic: 0.0, ..default() }) } else if j == 1 { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(s_val, 1.0, s_val), + base_color: Color::srgb(s_val, 1.0, s_val), perceptual_roughness: 0.089, metallic: 0.0, ..default() }) } else { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(1.0, s_val, s_val), + base_color: Color::srgb(1.0, s_val, s_val), perceptual_roughness: 0.089, metallic: 0.0, ..default() @@ -193,7 +193,7 @@ fn setup( PbrBundle { mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("888888").unwrap(), + base_color: Srgba::hex("888888").unwrap().into(), unlit: true, cull_mode: None, ..default() diff --git a/examples/3d/deterministic.rs b/examples/3d/deterministic.rs index fae88cbdaf..94149be6b7 100644 --- a/examples/3d/deterministic.rs +++ b/examples/3d/deterministic.rs @@ -40,7 +40,7 @@ fn setup( let mesh = meshes.add(Plane3d::default().mesh().size(2.0, 2.0)); let nb_plane = 10; for i in 0..nb_plane { - let color = LegacyColor::hsl(i as f32 * 360.0 / nb_plane as f32, 1.0, 0.5); + let color = Color::hsl(i as f32 * 360.0 / nb_plane as f32, 1.0, 0.5); commands.spawn(PbrBundle { mesh: mesh.clone(), material: materials.add(StandardMaterial { diff --git a/examples/3d/fog.rs b/examples/3d/fog.rs index 45705aa1be..9fbfd9778d 100644 --- a/examples/3d/fog.rs +++ b/examples/3d/fog.rs @@ -35,7 +35,7 @@ fn setup_camera_fog(mut commands: Commands) { commands.spawn(( Camera3dBundle::default(), FogSettings { - color: LegacyColor::rgba(0.25, 0.25, 0.25, 1.0), + color: Color::srgb(0.25, 0.25, 0.25), falloff: FogFalloff::Linear { start: 5.0, end: 20.0, @@ -51,7 +51,7 @@ fn setup_pyramid_scene( mut materials: ResMut>, ) { let stone = materials.add(StandardMaterial { - base_color: LegacyColor::hex("28221B").unwrap(), + base_color: Srgba::hex("28221B").unwrap().into(), perceptual_roughness: 1.0, ..default() }); @@ -71,7 +71,7 @@ fn setup_pyramid_scene( PbrBundle { mesh: meshes.add(Sphere::default()), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("126212CC").unwrap(), + base_color: Srgba::hex("126212CC").unwrap().into(), reflectance: 1.0, perceptual_roughness: 0.0, metallic: 0.5, @@ -102,7 +102,7 @@ fn setup_pyramid_scene( commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("888888").unwrap(), + base_color: Srgba::hex("888888").unwrap().into(), unlit: true, cull_mode: None, ..default() @@ -259,43 +259,41 @@ fn update_system( .value .push_str("\n\n- / = - Red\n[ / ] - Green\n; / ' - Blue\n. / ? - Alpha"); + // We're performing various operations in the sRGB color space, + // so we convert the fog color to sRGB here, then modify it, + // and finally when we're done we can convert it back and set it. + let mut fog_color = Srgba::from(fog.color); if keycode.pressed(KeyCode::Minus) { - let r = (fog.color.r() - 0.1 * delta).max(0.0); - fog.color.set_r(r); + fog_color.red = (fog_color.red - 0.1 * delta).max(0.0); } if keycode.any_pressed([KeyCode::Equal, KeyCode::NumpadEqual]) { - let r = (fog.color.r() + 0.1 * delta).min(1.0); - fog.color.set_r(r); + fog_color.red = (fog_color.red + 0.1 * delta).min(1.0); } if keycode.pressed(KeyCode::BracketLeft) { - let g = (fog.color.g() - 0.1 * delta).max(0.0); - fog.color.set_g(g); + fog_color.green = (fog_color.green - 0.1 * delta).max(0.0); } if keycode.pressed(KeyCode::BracketRight) { - let g = (fog.color.g() + 0.1 * delta).min(1.0); - fog.color.set_g(g); + fog_color.green = (fog_color.green + 0.1 * delta).min(1.0); } if keycode.pressed(KeyCode::Semicolon) { - let b = (fog.color.b() - 0.1 * delta).max(0.0); - fog.color.set_b(b); + fog_color.blue = (fog_color.blue - 0.1 * delta).max(0.0); } if keycode.pressed(KeyCode::Quote) { - let b = (fog.color.b() + 0.1 * delta).min(1.0); - fog.color.set_b(b); + fog_color.blue = (fog_color.blue + 0.1 * delta).min(1.0); } if keycode.pressed(KeyCode::Period) { - let a = (fog.color.a() - 0.1 * delta).max(0.0); - fog.color.set_a(a); + fog_color.alpha = (fog_color.alpha - 0.1 * delta).max(0.0); } if keycode.pressed(KeyCode::Slash) { - let a = (fog.color.a() + 0.1 * delta).min(1.0); - fog.color.set_a(a); + fog_color.alpha = (fog_color.alpha + 0.1 * delta).min(1.0); } + + fog.color = Color::from(fog_color); } diff --git a/examples/3d/irradiance_volumes.rs b/examples/3d/irradiance_volumes.rs index 34f0608fce..b3d1936581 100644 --- a/examples/3d/irradiance_volumes.rs +++ b/examples/3d/irradiance_volumes.rs @@ -13,6 +13,7 @@ //! //! * Clicking anywhere moves the object. +use bevy::color::palettes::css::*; use bevy::core_pipeline::Skybox; use bevy::math::{uvec3, vec3}; use bevy::pbr::irradiance_volume::IrradianceVolume; @@ -47,7 +48,7 @@ static SWITCH_TO_SPHERE_HELP_TEXT: &str = "Tab: Switch to a plain sphere mesh"; static CLICK_TO_MOVE_HELP_TEXT: &str = "Left click: Move the object"; -static GIZMO_COLOR: LegacyColor = LegacyColor::YELLOW; +static GIZMO_COLOR: Color = Color::Srgba(YELLOW); static VOXEL_TRANSFORM: Mat4 = Mat4::from_cols_array_2d(&[ [-42.317566, 0.0, 0.0, 0.0], @@ -148,7 +149,7 @@ fn main() { .init_resource::() .init_resource::() .insert_resource(AmbientLight { - color: LegacyColor::WHITE, + color: Color::WHITE, brightness: 0.0, }) .add_systems(Startup, setup) @@ -362,7 +363,7 @@ impl AppStatus { TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: 24.0, - color: LegacyColor::ANTIQUE_WHITE, + ..default() }, ) } @@ -515,7 +516,7 @@ impl FromWorld for ExampleAssets { ExampleAssets { main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)), fox: world.load_asset("models/animated/Fox.glb#Scene0"), - main_sphere_material: world.add_asset(LegacyColor::SILVER), + main_sphere_material: world.add_asset(Color::from(SILVER)), main_scene: world .load_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb#Scene0"), irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"), @@ -563,7 +564,7 @@ fn create_cubes( let resolution = image.texture_descriptor.size; let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial { - base: StandardMaterial::from(LegacyColor::RED), + base: StandardMaterial::from(Color::from(RED)), extension: VoxelVisualizationExtension { irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo { transform: VOXEL_TRANSFORM.inverse(), diff --git a/examples/3d/lighting.rs b/examples/3d/lighting.rs index 84ce0db711..31e736ca87 100644 --- a/examples/3d/lighting.rs +++ b/examples/3d/lighting.rs @@ -4,6 +4,7 @@ use std::f32::consts::PI; use bevy::{ + color::palettes::css::*, pbr::{light_consts, CascadeShadowConfigBuilder}, prelude::*, render::camera::{Exposure, PhysicalCameraParameters}, @@ -40,7 +41,7 @@ fn setup( commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(10.0, 10.0)), material: materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, perceptual_roughness: 1.0, ..default() }), @@ -54,7 +55,7 @@ fn setup( mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)), transform, material: materials.add(StandardMaterial { - base_color: LegacyColor::INDIGO, + base_color: INDIGO.into(), perceptual_roughness: 1.0, ..default() }), @@ -67,7 +68,7 @@ fn setup( mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)), transform, material: materials.add(StandardMaterial { - base_color: LegacyColor::INDIGO, + base_color: INDIGO.into(), perceptual_roughness: 1.0, ..default() }), @@ -98,7 +99,7 @@ fn setup( PbrBundle { mesh: meshes.add(Cuboid::default()), material: materials.add(StandardMaterial { - base_color: LegacyColor::PINK, + base_color: PINK.into(), ..default() }), transform: Transform::from_xyz(0.0, 0.5, 0.0), @@ -111,7 +112,7 @@ fn setup( PbrBundle { mesh: meshes.add(Sphere::new(0.5).mesh().uv(32, 18)), material: materials.add(StandardMaterial { - base_color: LegacyColor::LIME_GREEN, + base_color: LIMEGREEN.into(), ..default() }), transform: Transform::from_xyz(1.5, 1.0, 1.5), @@ -122,7 +123,7 @@ fn setup( // ambient light commands.insert_resource(AmbientLight { - color: LegacyColor::ORANGE_RED, + color: ORANGE_RED.into(), brightness: 0.02, }); @@ -133,7 +134,7 @@ fn setup( transform: Transform::from_xyz(1.0, 2.0, 0.0), point_light: PointLight { intensity: 100_000.0, - color: LegacyColor::RED, + color: RED.into(), shadows_enabled: true, ..default() }, @@ -143,8 +144,8 @@ fn setup( builder.spawn(PbrBundle { mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)), material: materials.add(StandardMaterial { - base_color: LegacyColor::RED, - emissive: LegacyColor::rgba_linear(7.13, 0.0, 0.0, 0.0), + base_color: RED.into(), + emissive: Color::linear_rgba(7.13, 0.0, 0.0, 0.0), ..default() }), ..default() @@ -158,7 +159,7 @@ fn setup( .looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z), spot_light: SpotLight { intensity: 100_000.0, - color: LegacyColor::GREEN, + color: GREEN.into(), shadows_enabled: true, inner_angle: 0.6, outer_angle: 0.8, @@ -171,8 +172,8 @@ fn setup( transform: Transform::from_rotation(Quat::from_rotation_x(PI / 2.0)), mesh: meshes.add(Capsule3d::new(0.1, 0.125)), material: materials.add(StandardMaterial { - base_color: LegacyColor::GREEN, - emissive: LegacyColor::rgba_linear(0.0, 7.13, 0.0, 0.0), + base_color: GREEN.into(), + emissive: Color::linear_rgba(0.0, 7.13, 0.0, 0.0), ..default() }), ..default() @@ -186,7 +187,7 @@ fn setup( transform: Transform::from_xyz(0.0, 4.0, 0.0), point_light: PointLight { intensity: 100_000.0, - color: LegacyColor::BLUE, + color: BLUE.into(), shadows_enabled: true, ..default() }, @@ -196,8 +197,8 @@ fn setup( builder.spawn(PbrBundle { mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)), material: materials.add(StandardMaterial { - base_color: LegacyColor::BLUE, - emissive: LegacyColor::rgba_linear(0.0, 0.0, 7.13, 0.0), + base_color: BLUE.into(), + emissive: Color::linear_rgba(0.0, 0.0, 7.13, 0.0), ..default() }), ..default() diff --git a/examples/3d/lightmaps.rs b/examples/3d/lightmaps.rs index 2e8f9cdef4..cd08712436 100644 --- a/examples/3d/lightmaps.rs +++ b/examples/3d/lightmaps.rs @@ -36,7 +36,8 @@ fn add_lightmaps_to_meshes( let exposure = 250.0; for (entity, name, material) in meshes.iter() { if &**name == "Light" { - materials.get_mut(material).unwrap().emissive = LegacyColor::WHITE * exposure; + materials.get_mut(material).unwrap().emissive = + Color::LinearRgba(LinearRgba::WHITE * exposure); continue; } diff --git a/examples/3d/lines.rs b/examples/3d/lines.rs index 424117e76e..8342f13491 100644 --- a/examples/3d/lines.rs +++ b/examples/3d/lines.rs @@ -36,7 +36,7 @@ fn setup( }), transform: Transform::from_xyz(-1.5, 0.0, 0.0), material: materials.add(LineMaterial { - color: LegacyColor::GREEN, + color: LinearRgba::GREEN, }), ..default() }); @@ -52,7 +52,7 @@ fn setup( }), transform: Transform::from_xyz(0.5, 0.0, 0.0), material: materials.add(LineMaterial { - color: LegacyColor::BLUE, + color: LinearRgba::BLUE, }), ..default() }); @@ -67,7 +67,7 @@ fn setup( #[derive(Asset, TypePath, Default, AsBindGroup, Debug, Clone)] struct LineMaterial { #[uniform(0)] - color: LegacyColor, + color: LinearRgba, } impl Material for LineMaterial { diff --git a/examples/3d/orthographic.rs b/examples/3d/orthographic.rs index 20ee4cd260..a56e4f972f 100644 --- a/examples/3d/orthographic.rs +++ b/examples/3d/orthographic.rs @@ -30,31 +30,31 @@ fn setup( // plane commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)), - material: materials.add(LegacyColor::rgb(0.3, 0.5, 0.3)), + material: materials.add(Color::srgb(0.3, 0.5, 0.3)), ..default() }); // cubes commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::srgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(1.5, 0.5, 1.5), ..default() }); commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::srgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(1.5, 0.5, -1.5), ..default() }); commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::srgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(-1.5, 0.5, 1.5), ..default() }); commands.spawn(PbrBundle { mesh: meshes.add(Cuboid::default()), - material: materials.add(LegacyColor::rgb(0.8, 0.7, 0.6)), + material: materials.add(Color::srgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(-1.5, 0.5, -1.5), ..default() }); diff --git a/examples/3d/parallax_mapping.rs b/examples/3d/parallax_mapping.rs index 32fc04226c..0eca862406 100644 --- a/examples/3d/parallax_mapping.rs +++ b/examples/3d/parallax_mapping.rs @@ -243,7 +243,7 @@ fn setup( // with roughness and reflectance set. perceptual_roughness: 0.45, reflectance: 0.18, - ..LegacyColor::rgb_u8(0, 80, 0).into() + ..Color::srgb_u8(0, 80, 0).into() }), transform: Transform::from_xyz(0.0, -1.0, 0.0), ..default() diff --git a/examples/3d/parenting.rs b/examples/3d/parenting.rs index c59b3009f5..9a42ffb59f 100644 --- a/examples/3d/parenting.rs +++ b/examples/3d/parenting.rs @@ -30,7 +30,7 @@ fn setup( ) { let cube_handle = meshes.add(Cuboid::new(2.0, 2.0, 2.0)); let cube_material_handle = materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.8, 0.7, 0.6), + base_color: Color::srgb(0.8, 0.7, 0.6), ..default() }); diff --git a/examples/3d/pbr.rs b/examples/3d/pbr.rs index 19a72e32bc..d1a29c8fc5 100644 --- a/examples/3d/pbr.rs +++ b/examples/3d/pbr.rs @@ -27,7 +27,7 @@ fn setup( commands.spawn(PbrBundle { mesh: sphere_mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("#ffd891").unwrap(), + base_color: Srgba::hex("#ffd891").unwrap().into(), // vary key PBR parameters on a grid of spheres to show the effect metallic: y01, perceptual_roughness: x01, @@ -42,7 +42,7 @@ fn setup( commands.spawn(PbrBundle { mesh: sphere_mesh, material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("#ffd891").unwrap(), + base_color: Srgba::hex("#ffd891").unwrap().into(), // vary key PBR parameters on a grid of spheres to show the effect unlit: true, ..default() @@ -103,7 +103,7 @@ fn setup( "Loading Environment Map...", TextStyle { font_size: 36.0, - color: LegacyColor::RED, + color: Color::WHITE, ..default() }, ) diff --git a/examples/3d/reflection_probes.rs b/examples/3d/reflection_probes.rs index 92c5207278..52239b628f 100644 --- a/examples/3d/reflection_probes.rs +++ b/examples/3d/reflection_probes.rs @@ -128,7 +128,7 @@ fn spawn_sphere( commands.spawn(PbrBundle { mesh: sphere_mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::hex("#ffd891").unwrap(), + base_color: Srgba::hex("#ffd891").unwrap().into(), metallic: 1.0, perceptual_roughness: 0.0, ..StandardMaterial::default() @@ -293,7 +293,7 @@ impl AppStatus { TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: 24.0, - color: LegacyColor::ANTIQUE_WHITE, + ..default() }, ) } diff --git a/examples/3d/render_to_texture.rs b/examples/3d/render_to_texture.rs index 1e71871d3b..b468347831 100644 --- a/examples/3d/render_to_texture.rs +++ b/examples/3d/render_to_texture.rs @@ -64,7 +64,7 @@ fn setup( let cube_handle = meshes.add(Cuboid::new(4.0, 4.0, 4.0)); let cube_material_handle = materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.8, 0.7, 0.6), + base_color: Color::srgb(0.8, 0.7, 0.6), reflectance: 0.02, unlit: false, ..default() @@ -103,7 +103,7 @@ fn setup( // render before the "main pass" camera order: -1, target: image_handle.clone().into(), - clear_color: LegacyColor::WHITE.into(), + clear_color: Color::WHITE.into(), ..default() }, transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) diff --git a/examples/3d/shadow_biases.rs b/examples/3d/shadow_biases.rs index 7079f1717d..7c1c9ad61e 100644 --- a/examples/3d/shadow_biases.rs +++ b/examples/3d/shadow_biases.rs @@ -38,7 +38,7 @@ fn setup( let sphere_radius = 0.25; let white_handle = materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, perceptual_roughness: 1.0, ..default() }); @@ -58,7 +58,7 @@ fn setup( point_light: PointLight { intensity: 0.0, range: spawn_plane_depth, - color: LegacyColor::WHITE, + color: Color::WHITE, shadow_depth_bias: 0.0, shadow_normal_bias: 0.0, shadows_enabled: true, @@ -125,7 +125,7 @@ fn setup( ..default() }, z_index: ZIndex::Global(i32::MAX), - background_color: LegacyColor::BLACK.with_a(0.75).into(), + background_color: Color::BLACK.with_alpha(0.75).into(), ..default() }) .with_children(|c| { diff --git a/examples/3d/shadow_caster_receiver.rs b/examples/3d/shadow_caster_receiver.rs index 95ae0c549d..56296301b2 100644 --- a/examples/3d/shadow_caster_receiver.rs +++ b/examples/3d/shadow_caster_receiver.rs @@ -3,6 +3,7 @@ use std::f32::consts::PI; use bevy::{ + color::palettes::basic::{BLUE, GREEN, RED}, pbr::{light_consts, CascadeShadowConfigBuilder, NotShadowCaster, NotShadowReceiver}, prelude::*, }; @@ -32,7 +33,7 @@ fn setup( let sphere_radius = 0.25; let white_handle = materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, perceptual_roughness: 1.0, ..default() }); @@ -41,7 +42,7 @@ fn setup( // sphere - initially a caster commands.spawn(PbrBundle { mesh: sphere_handle.clone(), - material: materials.add(LegacyColor::RED), + material: materials.add(Color::from(RED)), transform: Transform::from_xyz(-1.0, spawn_height, 0.0), ..default() }); @@ -50,7 +51,7 @@ fn setup( commands.spawn(( PbrBundle { mesh: sphere_handle, - material: materials.add(LegacyColor::BLUE), + material: materials.add(Color::from(BLUE)), transform: Transform::from_xyz(1.0, spawn_height, 0.0), ..default() }, @@ -61,7 +62,7 @@ fn setup( commands.spawn(( PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(20.0, 20.0)), - material: materials.add(LegacyColor::GREEN), + material: materials.add(Color::from(GREEN)), transform: Transform::from_xyz(0.0, 1.0, -10.0), ..default() }, @@ -83,7 +84,7 @@ fn setup( point_light: PointLight { intensity: 0.0, range: spawn_plane_depth, - color: LegacyColor::WHITE, + color: Color::WHITE, shadows_enabled: true, ..default() }, diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 0a5f715b57..beaf5b268f 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -88,7 +88,7 @@ fn setup(mut commands: Commands, asset_server: Res) { // NOTE: The ambient light is used to scale how bright the environment map is so with a bright // environment map, use an appropriate color and brightness to match commands.insert_resource(AmbientLight { - color: LegacyColor::rgb_u8(210, 220, 240), + color: Color::srgb_u8(210, 220, 240), brightness: 1.0, }); diff --git a/examples/3d/spherical_area_lights.rs b/examples/3d/spherical_area_lights.rs index aa9b8ae406..e8e5725fec 100644 --- a/examples/3d/spherical_area_lights.rs +++ b/examples/3d/spherical_area_lights.rs @@ -28,7 +28,7 @@ fn setup( commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)), material: materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.2, 0.2, 0.2), + base_color: Color::srgb(0.2, 0.2, 0.2), perceptual_roughness: 0.08, ..default() }), @@ -51,7 +51,7 @@ fn setup( .spawn(PbrBundle { mesh: mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.5, 0.5, 1.0), + base_color: Color::srgb(0.5, 0.5, 1.0), unlit: true, ..default() }), @@ -63,7 +63,7 @@ fn setup( children.spawn(PointLightBundle { point_light: PointLight { radius, - color: LegacyColor::rgb(0.2, 0.2, 1.0), + color: Color::srgb(0.2, 0.2, 1.0), ..default() }, ..default() diff --git a/examples/3d/split_screen.rs b/examples/3d/split_screen.rs index 290ae66a3e..35b88ae424 100644 --- a/examples/3d/split_screen.rs +++ b/examples/3d/split_screen.rs @@ -3,7 +3,8 @@ use std::f32::consts::PI; use bevy::{ - pbr::CascadeShadowConfigBuilder, prelude::*, render::camera::Viewport, window::WindowResized, + color::palettes::css::DARK_GRAY, pbr::CascadeShadowConfigBuilder, prelude::*, + render::camera::Viewport, window::WindowResized, }; fn main() { @@ -24,7 +25,7 @@ fn setup( // plane commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)), - material: materials.add(LegacyColor::rgb(0.3, 0.5, 0.3)), + material: materials.add(Color::srgb(0.3, 0.5, 0.3)), ..default() }); @@ -145,8 +146,8 @@ fn setup( align_items: AlignItems::Center, ..default() }, - border_color: LegacyColor::WHITE.into(), - background_color: LegacyColor::DARK_GRAY.into(), + border_color: Color::WHITE.into(), + background_color: DARK_GRAY.into(), ..default() }, )) diff --git a/examples/3d/spotlight.rs b/examples/3d/spotlight.rs index 9f72f5f0cf..8ef6dfb521 100644 --- a/examples/3d/spotlight.rs +++ b/examples/3d/spotlight.rs @@ -2,7 +2,11 @@ use std::f32::consts::*; -use bevy::{pbr::NotShadowCaster, prelude::*}; +use bevy::{ + color::palettes::basic::{MAROON, RED}, + pbr::NotShadowCaster, + prelude::*, +}; use rand::{rngs::StdRng, Rng, SeedableRng}; const INSTRUCTIONS: &str = "\ @@ -37,7 +41,7 @@ fn setup( commands.spawn(( PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)), - material: materials.add(LegacyColor::WHITE), + material: materials.add(Color::WHITE), ..default() }, Movable, @@ -46,7 +50,7 @@ fn setup( // cubes let mut rng = StdRng::seed_from_u64(19878367467713); let cube_mesh = meshes.add(Cuboid::new(0.5, 0.5, 0.5)); - let blue = materials.add(LegacyColor::rgb_u8(124, 144, 255)); + let blue = materials.add(Color::srgb_u8(124, 144, 255)); commands.spawn_batch( std::iter::repeat_with(move || { @@ -70,13 +74,13 @@ fn setup( let sphere_mesh = meshes.add(Sphere::new(0.05).mesh().uv(32, 18)); let sphere_mesh_direction = meshes.add(Sphere::new(0.1).mesh().uv(32, 18)); let red_emissive = materials.add(StandardMaterial { - base_color: LegacyColor::RED, - emissive: LegacyColor::rgba_linear(100.0, 0.0, 0.0, 0.0), + base_color: RED.into(), + emissive: Color::linear_rgba(100.0, 0.0, 0.0, 0.0), ..default() }); let maroon_emissive = materials.add(StandardMaterial { - base_color: LegacyColor::MAROON, - emissive: LegacyColor::rgba_linear(50.0, 0.0, 0.0, 0.0), + base_color: MAROON.into(), + emissive: Color::linear_rgba(50.0, 0.0, 0.0, 0.0), ..default() }); @@ -91,7 +95,7 @@ fn setup( .looking_at(Vec3::new(1.0 + x, 0.0, z), Vec3::X), spot_light: SpotLight { intensity: 40_000.0, // lumens - color: LegacyColor::WHITE, + color: Color::WHITE, shadows_enabled: true, inner_angle: PI / 4.0 * 0.85, outer_angle: PI / 4.0, diff --git a/examples/3d/ssao.rs b/examples/3d/ssao.rs index a7399245e6..7a09550fa8 100644 --- a/examples/3d/ssao.rs +++ b/examples/3d/ssao.rs @@ -42,7 +42,7 @@ fn setup( .insert(TemporalAntiAliasBundle::default()); let material = materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.5, 0.5, 0.5), + base_color: Color::srgb(0.5, 0.5, 0.5), perceptual_roughness: 1.0, reflectance: 0.0, ..default() @@ -69,7 +69,7 @@ fn setup( PbrBundle { mesh: meshes.add(Sphere::new(0.4).mesh().uv(72, 36)), material: materials.add(StandardMaterial { - base_color: LegacyColor::rgb(0.4, 0.4, 0.4), + base_color: Color::srgb(0.4, 0.4, 0.4), perceptual_roughness: 1.0, reflectance: 0.0, ..default() diff --git a/examples/3d/texture.rs b/examples/3d/texture.rs index 8d3898bce1..b2bec2db74 100644 --- a/examples/3d/texture.rs +++ b/examples/3d/texture.rs @@ -36,7 +36,7 @@ fn setup( // this material modulates the texture to make it red (and slightly transparent) let red_material_handle = materials.add(StandardMaterial { - base_color: LegacyColor::rgba(1.0, 0.0, 0.0, 0.5), + base_color: Color::srgba(1.0, 0.0, 0.0, 0.5), base_color_texture: Some(texture_handle.clone()), alpha_mode: AlphaMode::Blend, unlit: true, @@ -45,7 +45,7 @@ fn setup( // and lets make this one blue! (and also slightly transparent) let blue_material_handle = materials.add(StandardMaterial { - base_color: LegacyColor::rgba(0.0, 0.0, 1.0, 0.5), + base_color: Color::srgba(0.0, 0.0, 1.0, 0.5), base_color_texture: Some(texture_handle), alpha_mode: AlphaMode::Blend, unlit: true, diff --git a/examples/3d/tonemapping.rs b/examples/3d/tonemapping.rs index 6bfec01dc3..1f34b1fb81 100644 --- a/examples/3d/tonemapping.rs +++ b/examples/3d/tonemapping.rs @@ -66,7 +66,7 @@ fn setup( ..default() }, FogSettings { - color: LegacyColor::rgba_u8(43, 44, 47, 255), + color: Color::srgb_u8(43, 44, 47), falloff: FogFalloff::Linear { start: 1.0, end: 8.0, @@ -109,7 +109,7 @@ fn setup_basic_scene( commands.spawn(( PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)), - material: materials.add(LegacyColor::rgb(0.1, 0.2, 0.1)), + material: materials.add(Color::srgb(0.1, 0.2, 0.1)), ..default() }, SceneNumber(1), @@ -141,21 +141,21 @@ fn setup_basic_scene( let s_val = if i < 3 { 0.0 } else { 0.2 }; let material = if j == 0 { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(s_val, s_val, 1.0), + base_color: Color::srgb(s_val, s_val, 1.0), perceptual_roughness: 0.089, metallic: 0.0, ..default() }) } else if j == 1 { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(s_val, 1.0, s_val), + base_color: Color::srgb(s_val, 1.0, s_val), perceptual_roughness: 0.089, metallic: 0.0, ..default() }) } else { materials.add(StandardMaterial { - base_color: LegacyColor::rgb(1.0, s_val, s_val), + base_color: Color::srgb(1.0, s_val, s_val), perceptual_roughness: 0.089, metallic: 0.0, ..default() @@ -266,7 +266,7 @@ fn setup_image_viewer_scene( "Drag and drop an HDR or EXR file", TextStyle { font_size: 36.0, - color: LegacyColor::BLACK, + color: Color::BLACK, ..default() }, ) diff --git a/examples/3d/transmission.rs b/examples/3d/transmission.rs index cc423c6961..8aa1e76688 100644 --- a/examples/3d/transmission.rs +++ b/examples/3d/transmission.rs @@ -21,14 +21,17 @@ use std::f32::consts::PI; use bevy::{ + color::palettes::css::*, core_pipeline::{ bloom::BloomSettings, core_3d::ScreenSpaceTransmissionQuality, prepass::DepthPrepass, tonemapping::Tonemapping, }, pbr::{NotShadowCaster, PointLightShadowMap, TransmittedShadowReceiver}, prelude::*, - render::camera::{Exposure, TemporalJitter}, - render::view::ColorGrading, + render::{ + camera::{Exposure, TemporalJitter}, + view::ColorGrading, + }, }; #[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))] @@ -41,7 +44,7 @@ fn main() { let mut app = App::new(); app.add_plugins(DefaultPlugins) - .insert_resource(ClearColor(LegacyColor::BLACK)) + .insert_resource(ClearColor(Color::BLACK)) .insert_resource(PointLightShadowMap { size: 2048 }) .insert_resource(AmbientLight { brightness: 0.0, @@ -117,7 +120,7 @@ fn setup( PbrBundle { mesh: cylinder_mesh, material: materials.add(StandardMaterial { - base_color: LegacyColor::rgba(0.9, 0.2, 0.3, 1.0), + base_color: Color::srgb(0.9, 0.2, 0.3), diffuse_transmission: 0.7, perceptual_roughness: 0.32, thickness: 0.2, @@ -134,11 +137,21 @@ fn setup( )); // Candle Flame + let scaled_white = LinearRgba::from(ANTIQUE_WHITE) * 80.; + let scaled_orange = LinearRgba::from(ORANGE_RED) * 16.; + let emissive = LinearRgba { + red: scaled_white.red + scaled_orange.red, + green: scaled_white.green + scaled_orange.green, + blue: scaled_white.blue + scaled_orange.blue, + alpha: 1.0, + } + .into(); + commands.spawn(( PbrBundle { mesh: icosphere_mesh.clone(), material: materials.add(StandardMaterial { - emissive: LegacyColor::ANTIQUE_WHITE * 80.0 + LegacyColor::ORANGE_RED * 16.0, + emissive, diffuse_transmission: 1.0, ..default() }), @@ -154,7 +167,7 @@ fn setup( PbrBundle { mesh: icosphere_mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, specular_transmission: 0.9, diffuse_transmission: 1.0, thickness: 1.8, @@ -177,7 +190,7 @@ fn setup( PbrBundle { mesh: icosphere_mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::RED, + base_color: RED.into(), specular_transmission: 0.9, diffuse_transmission: 1.0, thickness: 1.8, @@ -200,7 +213,7 @@ fn setup( PbrBundle { mesh: icosphere_mesh.clone(), material: materials.add(StandardMaterial { - base_color: LegacyColor::GREEN, + base_color: GREEN.into(), specular_transmission: 0.9, diffuse_transmission: 1.0, thickness: 1.8, @@ -223,7 +236,7 @@ fn setup( PbrBundle { mesh: icosphere_mesh, material: materials.add(StandardMaterial { - base_color: LegacyColor::BLUE, + base_color: BLUE.into(), specular_transmission: 0.9, diffuse_transmission: 1.0, thickness: 1.8, @@ -243,14 +256,14 @@ fn setup( // Chessboard Plane let black_material = materials.add(StandardMaterial { - base_color: LegacyColor::BLACK, + base_color: Color::BLACK, reflectance: 0.3, perceptual_roughness: 0.8, ..default() }); let white_material = materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, reflectance: 0.3, perceptual_roughness: 0.8, ..default() @@ -283,7 +296,7 @@ fn setup( PbrBundle { mesh: plane_mesh, material: materials.add(StandardMaterial { - base_color: LegacyColor::WHITE, + base_color: Color::WHITE, diffuse_transmission: 0.6, perceptual_roughness: 0.8, reflectance: 1.0, @@ -309,7 +322,9 @@ fn setup( PointLightBundle { transform: Transform::from_xyz(-1.0, 1.7, 0.0), point_light: PointLight { - color: LegacyColor::ANTIQUE_WHITE * 0.8 + LegacyColor::ORANGE_RED * 0.2, + color: Color::from( + LinearRgba::from(ANTIQUE_WHITE).mix(&LinearRgba::from(ORANGE_RED), 0.2), + ), intensity: 4_000.0, radius: 0.2, range: 5.0, @@ -350,8 +365,7 @@ fn setup( // Controls Text let text_style = TextStyle { font_size: 18.0, - color: LegacyColor::WHITE, - ..Default::default() + ..default() }; commands.spawn(( @@ -476,9 +490,8 @@ fn example_control_system( } if controls.color && randomize_colors { - material.base_color.set_r(random()); - material.base_color.set_g(random()); - material.base_color.set_b(random()); + material.base_color = + Color::srgba(random(), random(), random(), material.base_color.alpha()); } } diff --git a/examples/3d/transparency_3d.rs b/examples/3d/transparency_3d.rs index 8395db0854..7383ebabd1 100644 --- a/examples/3d/transparency_3d.rs +++ b/examples/3d/transparency_3d.rs @@ -21,7 +21,7 @@ fn setup( // Opaque plane, uses `alpha_mode: Opaque` by default commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(6.0, 6.0)), - material: materials.add(LegacyColor::rgb(0.3, 0.5, 0.3)), + material: materials.add(Color::srgb(0.3, 0.5, 0.3)), ..default() }); @@ -33,7 +33,7 @@ fn setup( // We set it to 0.0 here, because it will be changed over time in the // `fade_transparency` function. // Note that the transparency has no effect on the objects shadow. - base_color: LegacyColor::rgba(0.2, 0.7, 0.1, 0.0), + base_color: Color::srgba(0.2, 0.7, 0.1, 0.0), // Mask sets a cutoff for transparency. Alpha values below are fully transparent, // alpha values above are fully opaque. alpha_mode: AlphaMode::Mask(0.5), @@ -47,7 +47,7 @@ fn setup( commands.spawn(PbrBundle { mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()), material: materials.add(StandardMaterial { - base_color: LegacyColor::rgba(0.2, 0.7, 0.1, 0.0), + base_color: Color::srgba(0.2, 0.7, 0.1, 0.0), alpha_mode: AlphaMode::Mask(0.5), unlit: true, ..default() @@ -62,7 +62,7 @@ fn setup( // Notice how there is no need to set the `alpha_mode` explicitly here. // When converting a color to a material using `into()`, the alpha mode is // automatically set to `Blend` if the alpha channel is anything lower than 1.0. - material: materials.add(LegacyColor::rgba(0.5, 0.5, 1.0, 0.0)), + material: materials.add(Color::srgba(0.5, 0.5, 1.0, 0.0)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); @@ -70,7 +70,7 @@ fn setup( // Opaque sphere commands.spawn(PbrBundle { mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()), - material: materials.add(LegacyColor::rgb(0.7, 0.2, 0.1)), + material: materials.add(Color::srgb(0.7, 0.2, 0.1)), transform: Transform::from_xyz(0.0, 0.5, -1.5), ..default() }); @@ -101,6 +101,6 @@ fn setup( pub fn fade_transparency(time: Res