Gerenciamento de cor

O que é um espaço de cor?

Cada espaço de cor é uma coleção de várias decisões de design, escolhidas em conjunto para dar suporte a uma grande variedade de cores, satisfazendo as restrições técnicas relacionadas à precisão e a tecnologia das telas. Ao criar um recurso 3D ou ao montar recursos 3D em uma cena, é importante saber quais são essas propriedades e como as propriedades de um espaço de cores se relacionam com outros espaços de cor na cena.

Cores sRGB e ponto branco (D65) exibidos no diagrama de referência cromaticidade CIE 1931. A região colorida representa uma projeção 2D da gama sRGB, que é um volume 3D. Fonte: Wikipedia
Esses três parâmetros — cores primárias, ponto branco e transfer functions — definem um espaço de cores, cada um escolhido para objetivos particulares. Tendo definido os parâmetros, alguns termos adicionais são úteis:

Considere dois espaços de cores muito comuns: [page:SRGBColorSpace] ("sRGB") e [page:LinearSRGBColorSpace] ("Linear-sRGB"). Ambos usam as mesmas cores primárias e ponto branco, e, portanto, têm a mesma gama de cores. Ambos usam o modelo de cores RGB. Eles diferem apenas nas transfer functions — Linear-sRGB é linear em relação à intensidade da luz física. sRGB usa as transfer functions sRGB não lineares e se assemelha mais à maneira que o olho humano percebe a luz e a capacidade de resposta de dispositivos de exibição comuns.

Essa diferença é importante. Cálculos de iluminação e outras operações de renderização devem geralmente ocorrem em um espaço de cores linear. No entanto, cores lineares são menos eficientes para armazenar em uma imagem ou framebuffer e não parecem corretas quando vistas por um observador humano. Como resultado, as texturas de entrada e a imagem final renderizada geralmente usarão o método não linear do espaço de cores sRGB.

ℹ️ AVISO: Embora alguns monitores modernos sejam compatíveis com gamas mais amplas, como Display-P3, as APIs gráficas da plataforma web dependem em grande parte do sRGB. Aplicativos que usam three.js hoje normalmente usarão apenas os espaços de cores sRGB e Linear-sRGB.

Atribuições dos espaços de cores

Fluxos de trabalho lineares - necessários para métodos modernos de renderização - geralmente envolvem mais de um espaço de cores, cada um atribuído a uma função específica. Espaços de cores lineares e não lineares são apropriados para diferentes funções, como explicado abaixo.

Input do espaço de cores

Cores fornecidas ao three.js — de seletores de cores, texturas, modelos 3D e outras fontes — cada um tem um espaço de cor associado. Aqueles que ainda não estão na cor de trabalho Linear-sRGB, devem ser convertidos e as texturas devem receber a atribuição texture.colorSpace correta. Certas conversões (para cores hexadecimais e CSS em sRGB) podem ser feitas automaticamente se o modo de gerenciamento de cores herdado é desabilitado antes de inicializar as cores:

THREE.ColorManagement.enabled = true;

⚠️ AVISO: Muitos formatos para modelos 3D não funcionam de forma correta ou consistente na definição das informações do espaço de cores. Enquanto o three.js tenta lidar com a maioria dos casos, problemas são comuns com formatos de arquivo mais antigos. Para melhores resultados, use glTF 2.0 ([page:GLTFLoader]) e teste modelos 3D em visualizadores on-line antecipadamente para confirmar que o recurso em si está correto.

Espaço de cores de trabalho

Renderização, interpolação e muitas outras operações devem ser executadas em um domínio aberto do espaço de cores de trabalho linear, no qual os componentes RGB são proporcionais a iluminação física. No three.js, o espaço de cores de trabalho é Linear-sRGB.

Output do espaço de cores

A saída para um dispositivo de exibição, imagem ou vídeo pode envolver a conversão do domínio aberto do espaço de cores de trabalho linear-sRGB para outro espaço de cores. Essa conversão pode ser feita em uma passagem de renderização principal ([page:WebGLRenderer.outputColorSpace]), ou durante o pós-processamento.

renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing

⚠️ AVISO: Os render targets podem usar sRGB ou Linear-sRGB. sRGB faz melhor uso de precisão limitada. No domínio fechado, 8 bits geralmente são suficientes para sRGB enquanto que ≥12 bits (meio flutuante) podem ser necessários para Linear-sRGB. Se mais tarde os estágios pipeline precisarem de entrada Linear-sRGB, as conversões adicionais podem ter um pequeno custo de desempenho.

Custom materials based on [page:ShaderMaterial] and [page:RawShaderMaterial] have to implement their own output color space conversion. For instances of `ShaderMaterial`, adding the `colorspace_fragment` shader chunk to the fragment shader's `main()` function should be sufficient.

Trabalhando com instâncias THREE.Color

Métodos de leitura ou modificação de instâncias [page:Color] assumem que os dados já estão no espaço de cores de trabalho three.js, Linear-sRGB. Os componentes RGB e HSL são representações diretas de dados armazenados pela instância Color e nunca são convertidos implicitamente. Os dados de cores podem ser convertidos explicitamente com .convertLinearToSRGB() ou .convertSRGBToLinear().

// RGB components (no change). color.r = color.g = color.b = 0.5; console.log( color.r ); // → 0.5 // Manual conversion. color.r = 0.5; color.convertSRGBToLinear(); console.log( color.r ); // → 0.214041140

Com ColorManagement.enabled = true definido (recomendado), determinadas conversões são feitas automaticamente. Como as cores hexadecimais e CSS geralmente são sRGB, métodos [page:Color] irão converter automaticamente essas entradas de sRGB para Linear-sRGB em setters, ou converter de Linear-sRGB para sRGB ao retornar hexadecimal ou CSS de getters.

// 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 // Override conversion with 'colorSpace' argument. color.setHex( 0x808080, LinearSRGBColorSpace ); console.log( color.r ); // → 0.5 console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC

Erros comuns

Quando uma cor ou textura individual é configurada incorretamente, ela aparecerá mais escura ou mais clara do que esperado. Quando o espaço de cores de saída do renderizador está mal configurado, a cena inteira pode aparecer mais escura (por exemplo, conversão ausente para sRGB) ou mais clara (por exemplo, uma conversão dupla para sRGB com pós-processamento). Em cada caso, o problema pode não ser uniforme e simplesmente aumentar/diminuir a iluminação não resolve.

Um problema mais sutil aparece quando ambos os espaços de cores de entrada e saída estão incorretos — os níveis gerais de brilho podem ser bons, mas as cores podem mudar inesperadamente sob iluminação diferente, ou o sombreamento pode parecer mais estourado e menos suave do que o pretendido. Esses dois erros não fazem um acerto, e é importante que o trabalho espaço de cores funcional seja linear ("cena referida") e o espaço de cores de saída seja não linear ("exibição referida").

Leitura adicional