From 283bea38b367c6cfbb7cd46e711fcc0192c79c9b Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Thu, 10 Mar 2022 00:05:08 -0500 Subject: [PATCH] Color management: Documentation revisions. --- .../en/introduction/Color-management.html | 288 ++++++++---------- 1 file changed, 133 insertions(+), 155 deletions(-) diff --git a/docs/manual/en/introduction/Color-management.html b/docs/manual/en/introduction/Color-management.html index 7f299c5c2e8944..8e6cdf8dd48e0d 100644 --- a/docs/manual/en/introduction/Color-management.html +++ b/docs/manual/en/introduction/Color-management.html @@ -10,7 +10,6 @@ blockquote { font-size: 0.8em; line-height: 1.5em; - background: #f0f0f0; margin-left: 0; border-left: 4px solid #cccccc; padding: 1em 2em 1em 2em; @@ -54,9 +53,7 @@

[name]

-

Background

- -

What is a Color Space?

+

What is a Color Space?

Every color space is a collection of several design decisions, chosen together to support a @@ -67,186 +64,141 @@

What is a Color Space?

- An illustration of the sRGB gamut, showing its color primaries and D65 white point. +
- FIGURE: sRGB color gamut located within the visible spectrum. + FIGURE: A 2D projection of the sRGB color gamut within the visible spectrum. Source: Wikipedia
+
-

Consider two very common color spaces: [page:sRGBColorSpace] ("sRGB") and [page:LinearSRGBColorSpace] ("Linear-sRGB"). Both use the same primaries and white point, and therefore have the same color gamut. Both use the RGB color model. They differ only in the transfer function — Linear-sRGB is linear with respect to physical light intensity. sRGB uses the non-linear sRGB transfer function, and more closely resembles the way that the human eye perceives light and the responsiveness of common display devices.

- -

That difference is important in any color space used for rendering, blending, or compositing. Formally, the transfer function divides the common color spaces into two families:

+ Each color space is triplet — color primaries, white point, and transfer functions — with each + parameter chosen for particular goals. Having defined these parameters, a few additional terms + are helpful: +

+ Consider two very common color spaces: [page:SRGBColorSpace] ("sRGB") and + [page:LinearSRGBColorSpace] ("Linear-sRGB"). Both use the same primaries and white point, + and therefore have the same color gamut. Both use the RGB color model. They differ only in + the transfer functions — Linear-sRGB is linear with respect to physical light intensity. + sRGB uses the nonlinear sRGB transfer functions, and more closely resembles the way that + the human eye perceives light and the responsiveness of common display devices. +

+ +

+ That difference is important. Lighting calculations and other rendering operations must + generally occur in a linear color space. However, a linear colors are less efficient to + store in an image or framebuffer, and do not look correct when viewed by a human observer. + As a result, input textures and the final rendered image will generally use the nonlinear + sRGB color space. +

+

- ℹ️ NOTICE: sRGB is the default color space for most Web APIs and image - formats. While some modern displays support wider gamuts like Display-P3, the web - platform's graphics APIs currently do not. Applications using three.js today will - typically use only the sRGB and Linear-sRGB color spaces. + ℹ️ NOTICE: While some modern displays support wider gamuts like Display-P3, + the web platform's graphics APIs largely rely on sRGB. Applications using three.js + today will typically use only the sRGB and Linear-sRGB color spaces.

-

Roles of Color Spaces

+

Roles of Color Spaces

- Modern rendering workflows require more than one color space, each fulfilling one of several - functional roles. Different families of color spaces (as defined in the section above) are - appropriate for different roles. + Linear workflows — required for modern rendering methods — generally involve more than + one color space, each assigned to a particular role. Linear and nonlinear color spaces are + appropriate for different roles, as explained below.

- - -

Choosing Color Spaces

- -

Recommended Workflow

- -
- - -
- FIGURE: Illustration of a typical linear workflow, with sources provided in - various color spaces, lighting calculations in a linear working color space, and - conversion of rendered results to an output color space for display or export. -
-
+

Input Color Space

- Physically-based rendering (PBR) requires a [link:https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear linear workflow], - and many Non-photorealistic rendering (NPR) techniques benefit from the linear workflow as well. - To use a linear workflow without manual conversion of colors in shaders, the following - settings should be configured: + Colors supplied to three.js — from color pickers, textures, 3D models, and other sources — + each have an associated color space. Those not already in the Linear-sRGB working color + space must be converted, and textures be given the correct .encoding assignment. + Certain conversions (for hexadecimal and CSS colors in sRGB) can be made automatically if + the legacy color management mode is disabled before initializing colors:

-THREE.ColorManagement.enabled = true; -renderer.outputEncoding = THREE.sRGBEncoding; // optional with post-processing +THREE.ColorManagement.legacyMode = false; -

- Within this configuration an application's source colors and textures, and its output to a - device display or to textures, have well-defined color spaces as described below. -

- - - Source colors and textures: - +
+

+ ⚠️ WARNING: [page:Scene.fog] and [page:Scene.background] are exceptions to + the rule. Both are unaffected by [page:WebGLRenderer.outputEncoding] and so must + store RGB components in the renderer's output color space. +

+
+

⚠️ WARNING: Many formats for 3D models do not correctly or consistently @@ -256,20 +208,37 @@

Recommended Workflow

- Output to a device display or image: +

Working Color Space

+ +

+ Rendering (and most other operations) must be done using an open domain linear working + color space, in which RGB components are proportional to physical illumination. In + three.js, the working color space is Linear-sRGB. +

+ +

Output Color Space

+ +

+ Output to a display device, image, or video may involve conversion from the open domain + Linear-sRGB working color space to another color space. This conversion may be performed in + the main render pass ([page:WebGLRenderer.outputEncoding]), or during post-processing. +

+ + +renderer.outputEncoding = THREE.sRGBEncoding; // optional with post-processing + @@ -284,41 +253,47 @@

Recommended Workflow

-

Working with THREE.Color Instances

+

Working with THREE.Color Instances

Methods reading or modifying [page:Color] instances assume the color data is already in the - three.js working color space, [page:LinearSRGBColorSpace]. As a result, the RGB components - of a Color object are linear, and may be used for lighting and interpolation. Because - hexadecimal color values taken from color pickers or CSS are generally sRGB, not Linear-sRGB, - [page:Color] getter and setter methods will automatically perform the conversion when reading or writing - hexadecimal, HSL, CSS, or similar color representations: + three.js working color space, Linear-sRGB, as required for most rendering work. RGB and HSL + components are direct representations of data stored by the Color instance, and are never + converted implicitly. Color data may be explicitly converted with .convertLinearToSRGB() + or .convertSRGBToLinear(). +

+ +

+ Because hexadecimal and CSS colors are generally sRGB, not Linear-sRGB, [page:Color] methods + will automatically convert these inputs from sRGB to Linear-sRGB, or convert from Linear-sRGB + to sRGB when returning hexadecimal or CSS output. For these conversions to occur, + ColorManagement.legacyMode must be disabled.

- // RGB components use the (linear) working color space. + // RGB components use the Linear-sRGB working color space. color.r = color.g = color.b = 0.5; console.log( color.r ); // → 0.5 - // Assignment to hexadecimal, CSS, or other color-parsing setters - // will convert from sRGB to the working color space, Linear-sRGB. + // Assignment of hexadecimal or CSS values will convert from sRGB to Linear-sRGB. // Reading from a getter will reverse the conversion. + + // Hexadecimal conversion. color.setHex( 0x808080 ); console.log( color.r ); // → 0.214041140 console.log( color.getHex() ); // → 0x808080 + // CSS conversion. color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' ); console.log( color.r ); // → 0.214041140 // Conversion in getters and setters may be overridden with a 'colorSpace' argument. - color.setHex( 0x808080, LinearSRGBColorSpace ); + color.setHex( 0x808080, LinearSRGBColorSpace ); // Linear-sRGB hex color. console.log( color.r ); // → 0.5 console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 + console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC - Assigning colors in a wide-gamut color space will clamp the color to the smaller gamut of the - Linear-sRGB working color space, and so is not useful or recommended at this time. -

Common Mistakes

@@ -334,7 +309,7 @@

Common Mistakes

spaces are incorrect — the overall brightness levels may be fine, but colors may change unexpectedly under different lighting, or shading may appear more blown-out and less soft than intended. In other words, two wrongs do not make a right, and it's important that the - working color space be linear ("scene referred") and the output color space be non-linear + working color space be linear ("scene referred") and the display color space be nonlinear ("display referred").

@@ -347,6 +322,9 @@

Further Reading

  • What every coder should know about gamma
  • +
  • + The Hitchhiker's Guide to Digital Color +
  • Blender: Color Management