Chaque espace colorimétrique est un ensemble de plusieurs décisions de design, choisies ensemble pour supporter un large éventail de couleurs tout en satisfaisant les contraites techniques liées à la précision et aux technologies d'affichage. Lors de la création d'un asset 3D, ou l'assemblage d'assets 3D ensemble dans une scène, il est important de savoir quelles sont ces propriétés, et comment les propriétés d'un espace colorimétrique se rapporte aux autres espaces colorimétriques de la scène.
Considérons deux espaces colorimétriques très communs: [page:SRGBColorSpace] ("sRGB") et [page:LinearSRGBColorSpace] ("sRGB-Linéaire"). Les deux utilisent les mêmes primaires et point blanc, et donc ont la même gamme de couleur. Le deux utilisent le modèle RGB. Leur seule différence sont les fonctions de transfert — Le sRGB-Linéaire est linéaire et respecte l'intensité physique de la lumière. Le sRGB utilise les fonctions de transfert non-linéaire du sRGB, et reproduit de manière plus proche la façon dont l'oeil humain perçoit la lumière et la réactivité des écrans.
Cette différence est imporante. Les calculs de lumières et les autres opérations de rendu doivent généralement se produire dans un espace de lumière linéaire. Cependant, les espaces colorimétriques linéaires sont moins efficaces dans le stockage d'images ou de framebuffer, et semblent incorrects qiuand ils sont vus par un humain. Par conséquent, les textures d'entrée et l'image du rendu final vont généralement utiliser l'espace colorimétrique sRGB non-linéaire.
ℹ️ NOTE: Alors que certains écrans modernes supportent des gammes plus larges comme Display-P3, les APIs graphiques du web reposent largement sur le sRGB. Les applications utilisant three.js aujourd'hui utilisent généralement uniquement le sRGB et les espaces colorimétriques sRGB-linéaires.
Workflows linéaires — requis pour les méthodes de rendu modernes — ils impliquent généralement plus d'un espace de couleur, chacun assigné à un rôle particulier. Les espace colorimétriques linéaires et non-linéaires sont appropriés pour différents usages, expliqués ci-dessous.
Les couleurs fournies à three.js — par les sélecteurs de couleurs, les textures, les modèles 3D, et d'autres sources — ont toutes un espace colorimétrique associé. Celles qui ne sont pas déjà dans l'espace colorimétrique sRGB-Linéaire doivent-être converties, et les textures doivent recevoir les bonnes consignes de texture.colorSpace. Certaines conversions (pour l'héxadecimal et les couleurs CSS en sRGB) peuvent être automatisées si l'héritage de la gestion des couleurs est désactivé avant l'initialisation des couleurs:
THREE.ColorManagement.enabled = true;
⚠️ ATTENTION: Plusieurs formats de modèles 3D ne définissent par correctement ou de manière cohérente les informations des espaces colorimétriques. Malgré le fait que three.js tente de gérer la plupart des situations, les problèmes sont communs avec les formats de fichiers plus anciens. Pour de meilleurs résultats, utilisez glTF 2.0 ([page:GLTFLoader]) et testez vos modèles 3D dans des visualiseurs en ligne relativement tôt pour vérifier que le modèle est correct en tant que tel.
Le rendu, l'interpolation, et plusieurs autres opérations doivent être performées dans un espace colorimétrique au domaine ouvert, dans lequel les composantes RGB sont proportionnelles à l'illumination physique. Dans three.js, l'espace colorimétrique est le sRGB-Linéaire.
La sortie d'un écran, d'une image, ou d'une vidéo peut impliquer la conversion depuis un espace colorimétrique sRGB-Linéaire au domaine ouvert vers un autre espace colorimétrique. Cette conversion peut être effectuée dans le pass principal du moteur de rendu ([page:WebGLRenderer.outputColorSpace]), ou durant le post-processing.
renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
⚠️ ATTENTION: Les cibles de rendu doivent utiliser soit le sRGB soit le sRGB-Linéaire. Le sRGB gère mieux la précision limitée. Dans le domaine fermé, 8 bits suffisent généralement au sRGB tandis que ≥12 bits (demi float) peuvent être requis pour du sRGB-Linéaire. Si les étapes ultérieures du pipeline nécessitent une entrée en sRGB-Linéaire, les conversions additionnelles peuvent avoir un petit impact sur les performances.
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.
Les méthodes de lecture ou de modification des instances de [page:Color] partent du principe que les données sont déjà dans l'espace colorimétrique de three.js, le sRGB-Linéaire. Les composantes RGB et HSL sont des représentations directes de données stockées par l'instance Color, et ne sont jamais converties implicitement. Les données Color peuvent être explicitement converties avec .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
Avec ColorManagement.enabled = true d'activé (recommandé), certaines conversions sont faites automatiquement. Parce que l'héxadécimal et les couleurs CSS sont généralement en sRGB, les méthodes [page:Color] vont automatiquement convertir ces entrées du sRGB au sRGB-Linéaire dans des setters, ou convertir depuis du sRGB-Linéaire au sRGB lors du renvoi de valeurs héxadécimales ou CSS depuis les 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
Quand une couleur ou une texture individuelle est mal configurée, elle apparaîtra plus lumineuse ou plus sombre qu'attendu. Quand l'espace colorimétrique de sortie du moteur de rendu est mal configuré, la scène entière peut sembler plus sombre (e.g. conversion manquante vers le sRGB) ou plus lumineuse (e.g. une double conversion vers le sRGB avec du post-processing). Dans chaque cas le problème peut ne pas être uniforme, et simplement augmenter/diminuer peut ne pas le résoudre.
Un problème plus subtil peut se produire quand à la fois l'espace colorimétrique d'entrée et l'espace colorimétrique de sortie sont incorrects — les niveaux de luminosité globaux peuvent être corrects, mais les couleurs peuvent changer d'une manière inattendue sous différentes lumières, ou des ombres peuvent sembler plus abruptes et moins lisses que prévu. Ces deux erreurs assemblées ne forment pas une réussite, et il est important que l'espace colorimétrique soit linéaire ("scene referred") et que l'espace colorimétrique de sortie soit linéaire ("display referred").