Romain Guy
July 28, 2016
560

This talk explains the importance of processing colors in linear space instead of gamma space.

July 28, 2016

## Transcript

COLORS

2. Color Spaces
Gamma & Linear

3. Gamma & Linear

4. 0, 0, 0 255, 255, 255

5. 0, 0, 0 255, 255, 255
127, 127, 127 ?

6. 0, 0, 0 255, 255, 255
127, 127, 127 ?
128, 128, 128 ?

7. 0, 0, 0 255, 255, 255
127, 127, 127 ?
128, 128, 128 ?
186, 186, 186 ?

8. You are doing it wrong

9. You are doing it wrong
—— —

— —
—— —

10. A CRT uses an electron gun
fired at a phosphorescent
screen

11. A CRT uses an electron gun
fired at a phosphorescent
screen

12. Gamma 2.2

13. Gamma 2.2

14. Gamma 2.2
Gamma
Correction

LCD?
>>>>>>>>>>>>>
<<<<<<<<<<<<<

16. The eye’s response is non-linear

17. Our visual system follows Steven’s power law
The eye’s response is non-linear

18. Our visual system follows Steven’s power law
The eye’s response is non-linear

19. Our visual system follows Steven’s power law
The eye’s response is non-linear
Magnitude of stimulus

20. Our visual system follows Steven’s power law
The eye’s response is non-linear
Subjective magnitude
of sensation
Magnitude of stimulus

21. Our visual system follows Steven’s power law
The eye’s response is non-linear
Gamma!
Subjective magnitude
of sensation
Magnitude of stimulus

22. The response curve of an
LCD is not a gamma curve

23. The response curve of an
LCD is not a gamma curve
It is made to look like a gamma curve
with hardware processing

24. We gamma-encode to optimize
bandwidth and storage
It is a compression scheme

25. Linear
Gamma
Input quantized over 5 bits for visualization
50% of the precision allocated to the darkest 50% intensities
70% of the precision allocated to the darkest 50% intensities
11~12 bits needed
8 bits are sufﬁcient

26. Gamma encoding is not necessary
with high precision, linear formats
Examples: OpenEXR, PNG 16 bit,
Photoshop 16 & 32 bit, RAW ﬁles

27. findViewById(R.id.root).setBackground(0xfff32272);
Gamma encoded

28. a=0

29. a=0
b=1

30. a=0
b=1
c=0.5

31. c=0.5

32. c=0.21
c=0.5

33. This issue affects everything

34. Blurs & resizes → darker image
This issue affects everything

35. Blurs & resizes → darker image
Animations → brightness shifts
This issue affects everything

36. Blurs & resizes → darker image
Animations → brightness shifts
3D lighting → hue shifts
This issue affects everything

37. >>>>>>>>>>>>>>linear space<<<<<<<<<<<<<<
Do all the math in

38. // Gamma encoded colors
int color1 = getColor1();
int color2 = getColor2();

// Extract red and convert to linear
float r1 = ((color2 >> 16) & 0xff) / 255.0f;
r1 = (float) Math.pow(r1, 2.2);
float r2 = // …

// Do the math and gamma-encode
float r = r1 * 0.5f + r2 * 0.5f;
r = (float) Math.pow(r, 1.0 / 2.2);

39. // Do not gamma-decode alpha
// Alpha is *linear*!

40. // OpenGL has extensions and APIs
// for sRGB encoding/decoding and
// correct, linear blending
// Use them, it’s free

41. Color Spaces
It’s more
complicated

42. What is a color?

43. What is a color?
For users, it’s a visual perception that
can be described by hue, brightness
and colorfulness

44. What is a color?
For users, it’s a visual perception that
can be described by hue, brightness
and colorfulness

45. What is a color?
For users, it’s a visual perception that
can be described by hue, brightness
and colorfulness
For developers, it’s a tuple of numbers,
in a color model associated with a
color space

46. What is a color?
For users, it’s a visual perception that
can be described by hue, brightness
and colorfulness
For developers, it’s a tuple of numbers,
in a color model associated with a
color space
RGB(0.92,0.91,0.86)
CMYK(0.5,0.3,0.6,0)

47. Visible
Spectrum
CIE 1931 Chromaticity Diagram

48. sRGB
ProPhotoRGB
Common RGB color spaces

49. What is a color space?

50. It has 3 primaries
What is a color space?

51. It has 3 primaries
It has a white point
What is a color space?

52. It has 3 primaries
It has a white point
It has conversion functions
What is a color space?

53. sRGB
ProPhotoRGB
Common RGB color spaces

54. Conversion functions

55. Equivalent of the gamma functions
Conversion functions

56. Equivalent of the gamma functions
Opto-electronic conversion function (OECF)
Conversion functions

57. Equivalent of the gamma functions
Opto-electronic conversion function (OECF)
Electro-optical conversion function (EOCF)
Conversion functions

58. Which color space?

59. Which color space?
Unless you know otherwise,
always assume sRGB

60. sRGB

61. sRGB

62. float OECF_sRGB(float linear) {
float low = linear * 12.92f;
float high = (pow(linear, 1.0f / 2.4f) * 1.055f) - 0.055f;
return linear <= 0.0031308f ? low : high;
}

63. Easy to optimize

64. Easy to optimize
Use lookup tables, 8 bits for encoding, 16 bits for decoding

65. Easy to optimize
Use lookup tables, 8 bits for encoding, 16 bits for decoding

66. Easy to optimize
Use lookup tables, 8 bits for encoding, 16 bits for decoding

67. OECF

68. Android TV

69. HDTV, Rec.709
Android TV

70. HDTV, Rec.709
→Same primaries & white point as sRGB
Android TV

71. HDTV, Rec.709
→Same primaries & white point as sRGB
→Different OECF/EOCF, ≈gamma 2.4
Android TV

72. HDTV, Rec.709
→Same primaries & white point as sRGB
→Different OECF/EOCF, ≈gamma 2.4
UHDTV, Rec.2020
Android TV

73. HDTV, Rec.709
→Same primaries & white point as sRGB
→Different OECF/EOCF, ≈gamma 2.4
UHDTV, Rec.2020
→Similar OECF/EOCF to Rec.709
Android TV

74. You are doing it wrong

75. You are doing it wrong
—— —

— —
—— —

76. Android is doing it wrong

Animations (ﬁxed in N)
Bitmap resize
Blending
Anti-aliasing
Etc…

78. Let’s recap
Color pipeline

79. Let’s recap
sRGB input
Color pipeline

80. Let’s recap
sRGB input EOCF
Color pipeline

81. Let’s recap
sRGB input EOCF Linear input
Color pipeline

82. Let’s recap
sRGB input EOCF Linear input Processing
Color pipeline

83. Let’s recap
sRGB input EOCF Linear input Processing OECF
Color pipeline

84. Let’s recap
sRGB input EOCF Linear input Processing OECF

Display
Color pipeline

85. Queﬆions