Capítulo 807 de 859

Chapter 807: Color Management (Manual)

Core Idea

Three.js renders internally in a linear color space (Linear-sRGB) and converts to/from nonlinear sRGB at the input (textures, colors) and output (renderer) boundaries; getting this wrong makes a scene look uniformly too dark or too light, or subtly wrong under different lighting.

Key Concepts

  • Color space: primaries + white point + transfer function together defining how numbers map to visible color.
  • sRGB vs. Linear-sRGB: same gamut and primaries, different transfer function — sRGB is nonlinear and closer to human/display perception, Linear-sRGB is linear with respect to physical light.
  • Working color space: the space lighting/shading math happens in — Linear-sRGB in three.js.
  • texture.colorSpace: tags a texture's input color space so it converts correctly into the working space.
  • WebGLRenderer.outputColorSpace: controls the conversion from the linear working space to the final display/output space.
  • THREE.ColorManagement: enabled by default; auto-converts hex and CSS colors (assumed sRGB) into the Linear-sRGB working space.

Code Examples

color.setHex(0x808080);
console.log(color.r); // linear value, not 0.5

color.setHex(0x808080, THREE.LinearSRGBColorSpace);
console.log(color.r); // → 0.5, no sRGB conversion applied
  • What it demonstrates: Color setters convert sRGB hex input to the linear working space by default, and accept an explicit color-space override.

Key Takeaways

  1. Lighting and shading calculations must happen in a linear color space; three.js's working space is Linear-sRGB.
  2. Textures and colors coming in, and the final rendered image going out, are usually nonlinear sRGB and need correct color-space tagging at each boundary.
  3. A misconfigured input or output color space shifts the whole scene uniformly darker or lighter; misconfiguring both at once can produce subtler, non-uniform color errors that don't show up as simple brightness problems.
  4. Custom ShaderMaterial/RawShaderMaterial shaders must implement their own output color-space conversion — three.js won't do it for them automatically.

Connects To

  • GLTFLoader: many older/non-glTF model formats don't reliably encode color-space info, which is a common source of color bugs.
  • WebGLRenderer: owns outputColorSpace.
  • ShaderMaterial / RawShaderMaterial: need manual output color-space handling.