-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutil-color.h
77 lines (64 loc) · 2.69 KB
/
util-color.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma once
namespace util
{
// Create typedefs of float vectors to represent RGB/RGBA values.
// These are intentionally *not* type-safe, to reduce friction.
typedef float3 rgb;
typedef float4 rgba;
// Typedefs for gamma-encoded color values, using the sRGB curve.
// Note: alpha is still linear.
typedef float3 srgb;
typedef float4 srgba;
// Rec. 709 luma coefficients for linear RGB space
static const float lumaCoefficients[] = { 0.2126f, 0.7152f, 0.0722f };
inline float luminance(rgb c)
{ return dot(c, float3(lumaCoefficients)); }
inline float luminance(rgba c)
{ return dot(c.rgb, float3(lumaCoefficients)); }
// Composition operator for linear RGB space (premultiplied alpha)
inline rgb blendOver(rgba a, rgb b)
{ return a.rgb + (1.0f - a.a) * b; }
inline rgba blendOver(rgba a, rgba b)
{ return rgba(a.rgb + (1.0f - a.a) * b.rgb, a.a + b.a - a.a * b.a); }
// Convert between non-premultiplied and premultipled alpha
inline rgba premultiplyAlpha(rgba a)
{ return rgba(a.rgb * a.a, a.a); }
inline rgba unPremultiplyAlpha(rgba a)
{ return rgba(a.rgb / a.a, a.a); }
// SRGB/linear color space conversions
inline float SRGBtoLinear(float c)
{ return (c <= 0.04045f) ? c / 12.92f : ::pow((c + 0.055f) / 1.055f, 2.4f); }
inline float linearToSRGB(float c)
{ return (c <= 0.0031308f) ? c * 12.92f : 1.055f*::pow(c, 1.0f/2.4f) - 0.055f; }
inline rgb SRGBtoLinear(srgb c)
{ return select(c <= 0.04045f, c / 12.92f, pow((c + 0.055f) / 1.055f, 2.4f)); }
inline srgb linearToSRGB(rgb c)
{ return select(c <= 0.0031308f, c * 12.92f, 1.055f*pow(c, 1.0f/2.4f) - 0.055f); }
inline rgba SRGBtoLinear(srgba c)
{ return rgba(SRGBtoLinear(c.rgb), c.a); }
inline srgba linearToSRGB(rgba c)
{ return rgba(linearToSRGB(c.rgb), c.a); }
// RGB/HSV conversions
float3 RGBtoHSV(rgb c);
rgb HSVtoRGB(float3 c);
inline float4 RGBtoHSV(rgba c)
{ return float4(RGBtoHSV(c.rgb), c.a); }
inline rgba HSVtoRGB(float4 c)
{ return rgba(HSVtoRGB(c.xyz), c.a); }
// RGB/YCoCg conversions
inline float3 RGBtoYCoCg(rgb c)
{ return { 0.25f * (c.r + 2.0f * c.g + c.b), c.r - c.b, c.g - 0.5f * (c.r + c.b) }; }
inline rgb YCoCgtoRGB(float3 c)
{ return { c.x + 0.5f * (c.y - c.z), c.x + 0.5f * c.z, c.x - 0.5f * (c.y + c.z) }; }
inline float4 RGBtoYCoCg(rgba c)
{ return float4(RGBtoYCoCg(c.rgb), c.a); }
inline rgba YCoCgtoRGB(float4 c)
{ return rgba(YCoCgtoRGB(c.xyz), c.a); }
// RGB/CIELAB conversions
float3 RGBtoCIELAB(rgb c);
rgb CIELABtoRGB(float3 c);
inline float4 RGBtoCIELAB(rgba c)
{ return float4(RGBtoCIELAB(c.rgb), c.a); }
inline rgba CIELABtoRGB(float4 c)
{ return rgba(CIELABtoRGB(c.xyz), c.a); }
}