Skip to content

Commit bbcdf68

Browse files
bevy_color: Added Color Conversion Mermaid Diagram (#12147)
Shows relationships between color spaces and explains what files should contain which conversions. # Objective - Provide documentation for maintainers and users on how color space conversion is implemented. ## Solution - Created a mermaid diagram documenting the relationships between various color spaces. This diagram also includes links to defining articles, and edges include links to conversion formulae. - Added a `conversion.md` document which is included in the documentation of each of the color spaces. This ensures it is readily visible in all relevant contexts. ## Notes The diagram is in the Mermaid (`.mmd`) format, and must be converted into an SVG file (or other image format) prior to use in Rust documentation. I've included a link to [mermaid.live](https://mermaid.live) as an option for doing such conversion in an appropriate README. Below is a screenshot of the documentation added. ![Capture](https://github.com/bevyengine/bevy/assets/2217286/370a65f2-6dd4-4af7-a99b-3763832d1b8a)
1 parent 00b6545 commit bbcdf68

15 files changed

+86
-5
lines changed

crates/bevy_color/docs/conversion.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Conversion
2+
3+
Conversion between the various color spaces is achieved using Rust's native [From] trait. Because certain color spaces are defined by their transformation to and from another space, these [From] implementations reflect that set of definitions.
4+
5+
```rust
6+
# use bevy_color::{Srgba, LinearRgba};
7+
let color = Srgba::rgb(0.5, 0.5, 0.5);
8+
9+
// Using From explicitly
10+
let linear_color = LinearRgba::from(color);
11+
12+
// Using Into
13+
let linear_color: LinearRgba = color.into();
14+
```
15+
16+
For example, the [sRGB](crate::Srgba) space is defined by its relationship with [Linear RGB](crate::LinearRgba), and [HWB](crate::Hwba) by its with [sRGB](crate::Srgba). As such, it is the responsibility of [sRGB](crate::Srgba) to provide [From] implementations for [Linear RGB](crate::LinearRgba), and [HWB](crate::Hwba) for [sRGB](crate::Srgba). To then provide conversion between [Linear RGB](crate::LinearRgba) and [HWB](crate::Hwba) directly, [HWB](crate::Hwba) is responsible for implementing these conversions, delegating to [sRGB](crate::Srgba) as an intermediatory. This ensures that all conversions take the shortest path between any two spaces, and limit the proliferation of domain specific knowledge for each color space to their respective definitions.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Creating Mermaid Diagrams
2+
3+
Mermaid diagrams (`.mmd` files) can be converted to SVG using various tools. The simplest to work with is [mermaid.live](https://mermaid.live/), which is a HTML web app. When editing `.mmd` files, make sure to regenerate the associated SVGs.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
%%{ init: { 'theme': 'dark', 'flowchart': { 'curve': 'stepAfter', 'padding': 30 }, 'themeCSS': '.label foreignObject { overflow: visible; }' } }%%
2+
flowchart LR
3+
lRGB(<a href='https://en.wikipedia.org/wiki/Rgb'>Linear<br/>sRGB</a>)
4+
Oklab(<a href='https://oklch.com/'>Oklab</a>)
5+
Oklch(<a href='https://oklch.com/'>Oklch</a>)
6+
XYZ(<a href='https://en.wikipedia.org/wiki/XYZ_color'>XYZ</a>)
7+
Lab(<a href='https://en.wikipedia.org/wiki/Lab_color'>Lab</a>)
8+
Lch(<a href='https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_model'>Lch</a>)
9+
sRGB(<a href='https://en.wikipedia.org/wiki/Srgb'>sRGB</a>)
10+
HWB(<a href='https://en.wikipedia.org/wiki/HWB_color_model'>HWB</a>)
11+
HSV(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSV</a>)
12+
HSL(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSL</a>)
13+
GPU <--> lRGB
14+
lRGB <--<a href='https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab'>Conversion</a>--> Oklab
15+
Oklab <--<a href='https://bottosson.github.io/posts/oklab/#the-oklab-color-space'>Conversion</a>--> Oklch
16+
lRGB <--<a href='http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html'>Conversion</a>--> XYZ
17+
XYZ <--<a href='http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html'>Conversion</a>--> Lab
18+
Lab <--<a href='http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html'>Conversion</a>--> Lch
19+
lRGB <--<a href='https://en.wikipedia.org/wiki/SRGB#From_sRGB_to_CIE_XYZ'>Conversion</a>--> sRGB
20+
sRGB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HWB
21+
HWB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HSV
22+
HSV <--<a href='https://en.wikipedia.org/wiki/HSL_and_HSV#Interconversion'>Conversion</a>--> HSL

crates/bevy_color/docs/diagrams/model_graph.svg

Lines changed: 1 addition & 0 deletions
Loading

crates/bevy_color/src/color.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ use serde::{Deserialize, Serialize};
66
///
77
/// This is useful when you need to store a color in a data structure that can't be generic over
88
/// the color type.
9+
#[doc = include_str!("../docs/conversion.md")]
10+
/// <div>
11+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
12+
/// </div>
913
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
1014
#[reflect(PartialEq, Serialize, Deserialize)]
1115
pub enum Color {

crates/bevy_color/src/hsla.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};
44

55
/// Color in Hue-Saturation-Lightness (HSL) color space with alpha.
66
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
7+
#[doc = include_str!("../docs/conversion.md")]
8+
/// <div>
9+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
10+
/// </div>
711
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
812
#[reflect(PartialEq, Serialize, Deserialize)]
913
pub struct Hsla {

crates/bevy_color/src/hsva.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};
44

55
/// Color in Hue-Saturation-Value (HSV) color space with alpha.
66
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
7+
#[doc = include_str!("../docs/conversion.md")]
8+
/// <div>
9+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
10+
/// </div>
711
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
812
#[reflect(PartialEq, Serialize, Deserialize)]
913
pub struct Hsva {

crates/bevy_color/src/hwba.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ use serde::{Deserialize, Serialize};
88

99
/// Color in Hue-Whiteness-Blackness (HWB) color space with alpha.
1010
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HWB_color_model).
11+
#[doc = include_str!("../docs/conversion.md")]
12+
/// <div>
13+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
14+
/// </div>
1115
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
1216
#[reflect(PartialEq, Serialize, Deserialize)]
1317
pub struct Hwba {

crates/bevy_color/src/laba.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
55
use serde::{Deserialize, Serialize};
66

77
/// Color in LAB color space, with alpha
8+
#[doc = include_str!("../docs/conversion.md")]
9+
/// <div>
10+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
11+
/// </div>
812
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
913
#[reflect(PartialEq, Serialize, Deserialize)]
1014
pub struct Laba {

crates/bevy_color/src/lcha.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
33
use serde::{Deserialize, Serialize};
44

55
/// Color in LCH color space, with alpha
6+
#[doc = include_str!("../docs/conversion.md")]
7+
/// <div>
8+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
9+
/// </div>
610
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
711
#[reflect(PartialEq, Serialize, Deserialize)]
812
pub struct Lcha {

crates/bevy_color/src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@
5050
//!
5151
//! See also the [Wikipedia article on color spaces](https://en.wikipedia.org/wiki/Color_space).
5252
//!
53-
//! # Conversions
54-
//!
55-
//! Each color space can be converted to and from the others using the [`From`] trait. Not all
56-
//! possible combinations of conversions are provided, but every color space has a conversion to
57-
//! and from [`Srgba`] and [`LinearRgba`].
53+
#![doc = include_str!("../docs/conversion.md")]
54+
//! <div>
55+
#![doc = include_str!("../docs/diagrams/model_graph.svg")]
56+
//! </div>
5857
//!
5958
//! # Other Utilities
6059
//!

crates/bevy_color/src/linear_rgba.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use bytemuck::{Pod, Zeroable};
55
use serde::{Deserialize, Serialize};
66

77
/// Linear RGB color with alpha.
8+
#[doc = include_str!("../docs/conversion.md")]
9+
/// <div>
10+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
11+
/// </div>
812
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
913
#[reflect(PartialEq, Serialize, Deserialize)]
1014
#[repr(C)]

crates/bevy_color/src/oklaba.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
66
use serde::{Deserialize, Serialize};
77

88
/// Color in Oklaba color space, with alpha
9+
#[doc = include_str!("../docs/conversion.md")]
10+
/// <div>
11+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
12+
/// </div>
913
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
1014
#[reflect(PartialEq, Serialize, Deserialize)]
1115
pub struct Oklaba {

crates/bevy_color/src/srgba.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ use serde::{Deserialize, Serialize};
66
use thiserror::Error;
77

88
/// Non-linear standard RGB with alpha.
9+
#[doc = include_str!("../docs/conversion.md")]
10+
/// <div>
11+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
12+
/// </div>
913
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
1014
#[reflect(PartialEq, Serialize, Deserialize)]
1115
pub struct Srgba {

crates/bevy_color/src/xyza.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
33
use serde::{Deserialize, Serialize};
44

55
/// [CIE 1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space, also known as XYZ, with an alpha channel.
6+
#[doc = include_str!("../docs/conversion.md")]
7+
/// <div>
8+
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
9+
/// </div>
610
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
711
#[reflect(PartialEq, Serialize, Deserialize)]
812
pub struct Xyza {

0 commit comments

Comments
 (0)