Crate colstodian
source ·Expand description
An opinionated color management library for games and graphics.
Introduction
Color is a really complex and fascinating topic, and I’d love to take you on a little tour
and show you how colstodian
tries to help make it easier to manage. But, if you really just want to get
sh*t done right now, here’s the basics:
Color
is a unified type representing a color in any ColorEncoding
.
The ColorEncoding
defines a bunch of different properties about how the
color values are stored and what those values actually mean. For example,
Color<SrgbU8>
is a color with red, green, and blue values that vary from
0-255
and the meaning of those values is defined by the full sRGB color encoding standard.
The most common and standard color encodings are exposed in the basic_encodings
module.
Many built-in color encodings expose constructor functions on the Color
type. See the docs for that type for a full list. The ones you are likely most interested in
if you don’t know much about color are:
Color::srgb_u8
: If you have three0-255
values, this is what you wantColor::srgb_f32
: If you have three0.0..=1.0
values, this is probably what you wantColor::linear_srgb
: If you have three0.0..=1.0
values that you know are “linear rgb”, this is probably what you want
If you also have alpha (i.e. four values instead of three), then Color::srgba_u8
, Color::srgba_f32
, and Color::linear_srgba
are the equivalents of the above with an alpha component.
If you want to do math to a color (for example, adding two colors together or multiplying one by a coefficient),
you’ll want to do so in a color encoding that is conducive to that. Color encodings which have this property implement
the WorkingEncoding
trait. If a Color
is not encoded in a working encoding,
it will not implement common math traits like addition, multiplication, etc.
The most common WorkingEncoding
is LinearSrgb
. You can convert a color you have created using any of the
constructors above to LinearSrgb
by using the .convert::<E>()
method.
If you want to output a color into an image file, the most common color encoding for most common image formats
(and the one assumed by viewing programs if a color profile is not embedded) is SrgbU8
.
You can convert a color from a working encoding to SrgbU8
for output again with the .convert::<E>()
method.
Example
Here we construct two colors in different ways, convert them both to LinearSrgb
to work with them, and then convert the result
to SrgbU8
which can be passed on to be displayed in an image.
use colstodian::Color;
use colstodian::basic_encodings::{SrgbU8, LinearSrgb};
let color1 = Color::srgb_u8(102, 54, 220);
let color2 = Color::srgb_f32(0.5, 0.8, 0.1);
let color1_working = color1.convert::<LinearSrgb>();
let color2_working = color2.convert::<LinearSrgb>();
let result_working = color1_working * 0.5 + color2_working;
let output = result_working.convert::<SrgbU8>();
assert_eq!(output, Color::srgb_u8(144, 206, 163));
Color Encoding Basics
Much like how a 3d vector like a glam::Vec3
could be used to describe any of:
- The motion vector of an object in meters per second
- The position of an object relative to a reference point in kilometers
- Three “wellness scores” for a character, which each axis representing how happy the character is about some aspect of their life
A bag of components that describes “a color” could actually be interpreted in many different ways, and the end result of what those components mean is very different.
colstodian
gathers all the information that defines how a color is represented in data as well as
what that data actually means into representative types that implement the ColorEncoding
trait.
Modules
- Contains a basic set of
ColorEncoding
s to get most people going. - Contains advanced usage details of the crate.
Macros
- Assert that
$left
and$right
are equal within a margin of$eps
.
Structs
- A strongly typed color, parameterized by a
ColorEncoding
.
Traits
- A type that implements
ColorEncoding
represents a collection of metadata that together defines how a color’s data is stored and what the values of that data actually mean. - Implemented by color encodings which are designed to be perceptually-uniform. In general these encodings will produce more visually pleasing results when blending between colors (for example, creating gradients) in many situations. However they are certainly not, silver bullets, and often don’t fully deliver on the promise of perceptual uniformity.
- Marks a type as representing a color encoding in which it makes sense to be able to perform mathematical operations on the contained color values directly.