Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A scattering of color concepts we're investigating for Graphite #4

Open
Keavon opened this issue Nov 4, 2024 · 3 comments
Open

A scattering of color concepts we're investigating for Graphite #4

Keavon opened this issue Nov 4, 2024 · 3 comments

Comments

@Keavon
Copy link

Keavon commented Nov 4, 2024

Just pasting this here so it's something that can be referenced more publicly. These are a number of loosely organized concepts we've been brainstorming for potential future use with Graphite's use of color. @TrueDoctor was specifically interested in investigating how far it might be possible to encode some or all of these using Rust's traits system.

  • Allows None
  • Allows transparency
  • Alpha association
    • Albedo + Translucency (straight)
    • Emission + Occlusion (premult)
  • Gamma curve
  • Color model
  • Color space (primaries incl. white point)
  • SDR or HDR
  • HDR luminance
  • Number of channels
  • Bit depth per channel
  • Luminance calculation method
  • Additive or subtractive (RGB vs CMYK)
  • Transfer function (PQ/HLG)?
  • Chroma subsampling?
  • Spectral?
  • PBR material channels (albedo, emission, roughness, metalness, normal map)?
  • Whether it's a (0 to 1) fraction of reflectance (used for PBR)

Separately, gradients should be considered for how they interpolate and how mapping operations can be applied to them.

@raphlinus
Copy link
Contributor

Thanks, I think this is useful for discussion. Here is a quick response, though a lot of these topics deserve a more detailed discussion.

Some of the things are natural, some are orthogonal, and others are deliberately out of scope. Definitely handling CMYK colors or more than 3 components is out of scope for this crate, though certainly an interesting problem (and plausibly feature gated).

We have missing channels, transparency, types for premultiplied and separated alpha, methods for calculating luminance. Transfer functions are implicit in color spaces. I deliberately didn't include white point because I think it's unneeded complexity; the Bradford linear chromatic adaptation transform should be good enough for almost all uses, and that is what CSS Color 4 specifies.

We have HDR color spaces represented, most especially DisplayP3, which will be the main focus for HDR rendering in Vello. I imagine some methods for gamut mapping as well, but haven't figured out the details of what that would look like.

We do the color math needed for gradients, but don't deal with gradient geometry. That's in scope for peniko, which almost certainly will take on a dep to the new crate for color (replacing the existing limited rgba8 stuff).

We don't deal with bit depth because I consider packing to be an orthogonal issue, and likely to be quite specific to an image format or GPU integration (I think f16 is a desirable target, and that's an expensive dep). I also consider chroma subsampling to be a detail of an image encoding format.

PBR and other appearance correlates feel out of scope. Probably a good layering is for a crate dealing with PBR materials to depend on this color crate for the color-specific stuff.

Other things that I think of as out of scope include ICC color profiles and ACES transforms.

All these decisions are subject to revision, though I would be wary of anything that dramatically increases complexity for the main use cases we care about.

@TrueDoctor
Copy link

TrueDoctor commented Nov 5, 2024

Looking at the design we should be able to basically just implement our color traits for this representation to allow our nodes to work with the types without too many changes. But I'll need to do a deeper dive to check if it would make sense to adapt it further. We could also consider using a fixed repr (e.g. repr(C)) to make the color types abi compatible.
Your

#[derive(Clone, Copy, Debug)]
pub struct AlphaColor<T> {
    pub components: [f32; 4],
    pub cs: PhantomData<T>,
}

Should be equivalent to our Color type so having zero cost conversions would basically allow us to use both types at the same time which would make it easier to transition to a new type.
Btw. this is where our current color implementation lives: https://github.com/GraphiteEditor/Graphite/blob/master/node-graph/gcore/src/raster/color.rs
sorry for the messy code, we should put the traits on top :D
I think it does also make sense for us to have mask data represented as a color type to benefit from the reduced storage overhead of storing only a single channel while still allowing users to use either a special mask type or just an image as input to a node using a mask

@raphlinus
Copy link
Contributor

One immediately actionable item is slapping #[repr(C)] on the concrete colors. I'm inclined to do that, in part because it seems to be important for the FFI story.

I personally feel that representing alpha mask values is out of scope for this crate, but I am open to concrete proposals that would help unify things for clients.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants