Skip to content

Commit

Permalink
bevy_color: Added Color Conversion Mermaid Diagram (#12147)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
bushrat011899 authored Feb 27, 2024
1 parent 00b6545 commit bbcdf68
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 5 deletions.
16 changes: 16 additions & 0 deletions crates/bevy_color/docs/conversion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Conversion

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.

```rust
# use bevy_color::{Srgba, LinearRgba};
let color = Srgba::rgb(0.5, 0.5, 0.5);

// Using From explicitly
let linear_color = LinearRgba::from(color);

// Using Into
let linear_color: LinearRgba = color.into();
```

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.
3 changes: 3 additions & 0 deletions crates/bevy_color/docs/diagrams/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Creating Mermaid Diagrams

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.
22 changes: 22 additions & 0 deletions crates/bevy_color/docs/diagrams/model_graph.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
%%{ init: { 'theme': 'dark', 'flowchart': { 'curve': 'stepAfter', 'padding': 30 }, 'themeCSS': '.label foreignObject { overflow: visible; }' } }%%
flowchart LR
lRGB(<a href='https://en.wikipedia.org/wiki/Rgb'>Linear<br/>sRGB</a>)
Oklab(<a href='https://oklch.com/'>Oklab</a>)
Oklch(<a href='https://oklch.com/'>Oklch</a>)
XYZ(<a href='https://en.wikipedia.org/wiki/XYZ_color'>XYZ</a>)
Lab(<a href='https://en.wikipedia.org/wiki/Lab_color'>Lab</a>)
Lch(<a href='https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_model'>Lch</a>)
sRGB(<a href='https://en.wikipedia.org/wiki/Srgb'>sRGB</a>)
HWB(<a href='https://en.wikipedia.org/wiki/HWB_color_model'>HWB</a>)
HSV(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSV</a>)
HSL(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSL</a>)
GPU <--> lRGB
lRGB <--<a href='https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab'>Conversion</a>--> Oklab
Oklab <--<a href='https://bottosson.github.io/posts/oklab/#the-oklab-color-space'>Conversion</a>--> Oklch
lRGB <--<a href='http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html'>Conversion</a>--> XYZ
XYZ <--<a href='http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html'>Conversion</a>--> Lab
Lab <--<a href='http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html'>Conversion</a>--> Lch
lRGB <--<a href='https://en.wikipedia.org/wiki/SRGB#From_sRGB_to_CIE_XYZ'>Conversion</a>--> sRGB
sRGB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HWB
HWB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HSV
HSV <--<a href='https://en.wikipedia.org/wiki/HSL_and_HSV#Interconversion'>Conversion</a>--> HSL
1 change: 1 addition & 0 deletions crates/bevy_color/docs/diagrams/model_graph.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions crates/bevy_color/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use serde::{Deserialize, Serialize};
///
/// This is useful when you need to store a color in a data structure that can't be generic over
/// the color type.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub enum Color {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/hsla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};

/// Color in Hue-Saturation-Lightness (HSL) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Hsla {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/hsva.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};

/// Color in Hue-Saturation-Value (HSV) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Hsva {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/hwba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ use serde::{Deserialize, Serialize};

/// Color in Hue-Whiteness-Blackness (HWB) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HWB_color_model).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Hwba {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/laba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use serde::{Deserialize, Serialize};

/// Color in LAB color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Laba {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/lcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use serde::{Deserialize, Serialize};

/// Color in LCH color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Lcha {
Expand Down
9 changes: 4 additions & 5 deletions crates/bevy_color/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,10 @@
//!
//! See also the [Wikipedia article on color spaces](https://en.wikipedia.org/wiki/Color_space).
//!
//! # Conversions
//!
//! Each color space can be converted to and from the others using the [`From`] trait. Not all
//! possible combinations of conversions are provided, but every color space has a conversion to
//! and from [`Srgba`] and [`LinearRgba`].
#![doc = include_str!("../docs/conversion.md")]
//! <div>
#![doc = include_str!("../docs/diagrams/model_graph.svg")]
//! </div>
//!
//! # Other Utilities
//!
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/linear_rgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use bytemuck::{Pod, Zeroable};
use serde::{Deserialize, Serialize};

/// Linear RGB color with alpha.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[repr(C)]
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/oklaba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use serde::{Deserialize, Serialize};

/// Color in Oklaba color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Oklaba {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/srgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;

/// Non-linear standard RGB with alpha.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
pub struct Srgba {
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_color/src/xyza.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use serde::{Deserialize, Serialize};

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

0 comments on commit bbcdf68

Please sign in to comment.