Partager via


Utilisation de la correction gamma

La correction gamma, ou gamma en abrégé, est le nom d’une opération non linéaire que les systèmes utilisent pour coder et décoder des valeurs de pixels dans les images.

Qu’est-ce que gamma et à quoi sert-il ?

À la fin du pipeline graphique, juste là où l’image quitte l’ordinateur pour effectuer son parcours le long du câble du moniteur, il y a un petit matériel qui peut transformer des valeurs de pixels à la volée. Ce matériel utilise généralement une table de choix pour transformer les pixels. Ce matériel utilise les valeurs rouges, vertes et bleues qui proviennent de la surface à afficher pour rechercher les valeurs corrigées par gamma dans la table, puis envoie les valeurs corrigées au moniteur au lieu des valeurs de surface réelles. Par conséquent, cette table de choix est l’occasion de remplacer n’importe quelle couleur par n’importe quelle autre couleur. Bien que la table ait ce niveau de puissance, l’utilisation classique consiste à ajuster subtilement les images pour compenser les différences dans la réponse du moniteur. La réponse du moniteur est la fonction qui relie la valeur numérique des composants rouge, vert et bleu d’un pixel avec la luminosité affichée de ce pixel.

C’est ce à quoi cette table était destinée, mais les développeurs de jeux ont trouvé des utilisations créatives pour elle, comme le clignotement de l’écran entier rouge pour un effet psychologique. Dans les applications de jeu modernes, dans le cadre du post-traitement de chaque image, nous fournissons généralement d’autres façons de procéder. En fait, nous vous recommandons de laisser la table gamma seule, car elle peut être utilisée pour étalonner la réponse du moniteur, et les modifications en gros apportées à la rampe gamma détruiront cet étalonnage minutieux.

La science de la détermination de la correction gamma est complexe, et n’est pas présentée ici, si ce n’est pour éclairer d’où vient le nom « gamma ». La réponse d’un moniteur CRT (c’est-à-dire un verre à l’ancienne) est une fonction complexe, mais la physique de ces moniteurs signifie qu’ils présentent une réponse qui peut être grossièrement représentée par cette fonction de puissance :

brightness( input ) = inputgamma

La valeur gamma est généralement proche d’une valeur de 2,0. Les moniteurs LCD et toutes les autres technologies plus récentes sont spécialement conçus pour présenter une réponse similaire afin que tous nos logiciels et images n’aient pas à être recalibrés pour ces nouvelles technologies. La norme sRGB déclare que cette valeur gamma est exactement 2,2, et cette valeur est devenue une norme largement implémentée.

L’œil humain a également une fonction de réponse qui inverse approximativement la fonction de puissance CRT. Cela signifie que la luminosité perçue d’un pixel monte de façon très linéaire avec les valeurs RVB de ce pixel.

Étant donné qu’une valeur gamma de 2,2 est devenue une norme de facto, nous n’avons généralement pas à nous soucier trop de la courbe gamma encodée dans cette table, et nous pouvons la laisser comme un mappage linéaire un-à-un. Bien sûr, une bonne correspondance des couleurs nécessite un soin exquis avec cette fonction, mais cette discussion dépasse le cadre de cette rubrique. Windows inclut un outil qui permet aux utilisateurs d’étalonner leurs écrans sur gamma 2.2, et cet outil utilise le matériel de la table de choix pour dériver un réglage subtil soigneusement choisi pour leurs ordinateurs. Les utilisateurs peuvent exécuter cet outil en recherchant « étalonner la couleur ». Il existe également des profils de couleurs bien définis pour des moniteurs particuliers qui automatisent ce processus. L’outil « étalonner la couleur » peut détecter ces moniteurs plus récents et informer les utilisateurs que l’étalonnage est déjà en place.

Cette notion d’encodage d’une loi de puissance en valeurs de couleur est également utile ailleurs dans le pipeline graphique, en particulier dans les textures. Pour les textures, vous souhaitez plus de précision sur les couleurs plus foncées en raison de la réponse logarithmique de l’œil humain dont nous venons de parler. Il est important de gérer soigneusement le gamma dans cette partie du pipeline. Pour plus d’informations, consultez Conversion de données pour l’espace colorimétrique.

Le reste de cette rubrique se concentre uniquement sur la correction gamma dans cette dernière partie du pipeline, entre les données de mémoire tampon de trame et le moniteur. Si vous souhaitez écrire un Assistant étalonnage ou créer des effets spéciaux dans une application plein écran où une étape de post-traitement n’est pas pratique, voici les informations dont vous avez besoin.

Arrière-plan de gamma sur Windows

Les ordinateurs Windows ont généralement une table gamma qui est une table de choix qui prend un triplet d’octets et génère un triplet d’octets. Ces triplets représentent 768 (256 x 3) octets de RAM. Cela est correct lorsque votre format d’affichage contient un triplet de valeurs RVB BYTE, mais n’est pas suffisamment expressif pour décrire les transformations que vous pouvez souhaiter lorsque le format d’affichage a une plage supérieure à [0,1], comme les valeurs à virgule flottante. Les API windows qui contrôlent gamma ont suivi une évolution à mesure que les formats d’affichage sont devenus plus complexes.

Les premières API Windows à offrir un contrôle gamma sont SetDeviceGammaRamp et GetDeviceGammaRamp de Windows Graphics Device Interface (GDI). Ces API fonctionnent avec trois tableaux de 256 entrées de WORD, chaque encodage WORD pouvant atteindre un zéro, représenté par les valeurs WORD 0 et 65535. La précision supplémentaire d’un WORD n’est généralement pas disponible dans les tables de choix matérielles réelles, mais ces API étaient conçues pour être flexibles. Ces API, contrairement aux autres décrites plus loin dans cette section, n’autorisent qu’un petit écart par rapport à une fonction d’identité. En fait, toute entrée dans la rampe doit se trouver à 32 768 de la valeur d’identité. Cette restriction signifie qu’aucune application ne peut rendre l’affichage complètement noir ou vers une autre couleur illisible.

L’API suivante est SetGammaRamp de Microsoft Direct3D 9, qui suit le même modèle et le même format de données que SetDeviceGammaRamp. La valeur par défaut de la rampe gamma Direct3D 9 n’est pas particulièrement utile; il s’agit d’une rampe de WORD initialisée à 0-255, et non à 0-65535, même si l’API est définie en termes de 0-65535.

La dernière API est IDXGIOutput::SetGammaControl. Cette API a un schéma plus flexible pour exprimer le contrôle gamma, car elle convient à l’ensemble accru de formats d’affichage de DXGI, y compris dix bits entiers par canal, des formats float 16 bits et le format de plage étendue XR_BIAS.

Toutes ces API fonctionnent sur le même matériel et modifient les mêmes valeurs. Les API Direct3D 9 et DXGI sont « en écriture seule ». Vous ne pouvez pas lire la valeur du matériel, la modifier, puis la définir. Vous pouvez uniquement définir la rampe. En outre, vous ne pouvez définir gamma que lorsque l’application est en plein écran. Cette restriction est une autre façon de garantir que le bureau est toujours lisible. Autrement dit, l’application peut perturber son propre affichage, mais Windows restaure la rampe gamma précédente lorsque l’application perd le plein écran (par exemple, via alt-tab ou ctrl-alt-del).

Évolution du matériel d’affichage

Certains moniteurs plus récents peuvent afficher un large éventail d’intensités. Toutefois, lorsque le format d’affichage ne peut représenter que des valeurs comprises entre zéro et un, l’affichage doit mapper zéro à sa valeur la plus sombre et un à sa valeur la plus brillante. Cette valeur la plus brillante peut être beaucoup trop brillante pour l’affichage confortable des pages Web avec du texte noir sur un arrière-plan blanc, mais est merveilleuse pour les effets spéciaux sur-brillants, tels que l’affichage de la lumière du soleil scintillant d’un lac ou la foudre s’enfoncant dans le ciel. Nous avons donc besoin d’un moyen d’exprimer ces gammes plus larges. DXGI 1.1 et versions ultérieures contient des valeurs de format d’affichage qui permettent à 1.0 de représenter une valeur blanche confortable et réserve des valeurs de format d’affichage plus larges pour les effets spéciaux trop brillants. DXGI 1.1 prend en charge deux formats d’affichage qui peuvent exprimer ces valeurs plus larges : DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM et virgule flottante 16 bits. Pour une présentation complète de ces formats, consultez Détails du format étendu. Ensuite, nous examinons pourquoi l’API gamma IDXGIOutput::SetGammaControl de DXGI a besoin de valeurs de pixels supérieures à 1.0.

Fonctionnalités de contrôle gamma dans DXGI

DXGI permet au pilote d’affichage d’exprimer ses contrôles gamma sous la forme d’une fonction linéaire pas à pas. Cette fonction linéaire au niveau des étapes est définie par les points de contrôle de cette fonction, la plage de valeurs vers laquelle la fonction peut convertir et une opération de mise à l’échelle et de décalage facultative supplémentaire qui peut être appliquée après la conversion. Une application peut appeler la méthode IDXGIOutput::GetGammaControlCapabilities pour récupérer toutes ces fonctionnalités de contrôle dans la structure DXGI_GAMMA_CONTROL_CAPABILITIES .

Ce graphique montre une fonction linéaire avec seulement quatre points de contrôle.

fonction linéaire de correction gamma

DXGI définit les points de contrôle par leur emplacement le long de l’axe des couleurs de surface. Dans le graphique précédent, les emplacements des points de contrôle sont 0, 0,5, 0,75 et 1,0. Ces points de contrôle indiquent que le matériel peut convertir des valeurs comprises entre 0 et 1,0. DXGI répertorie ces points de contrôle dans le membre du tableau ControlPointPositions de DXGI_GAMMA_CONTROL_CAPABILITIES et les déclare toujours dans l’ordre croissant. DXGI remplit uniquement les premiers éléments du tableau ControlPointPositions et indique le nombre d’éléments avec le membre NumGammaControlPoints de DXGI_GAMMA_CONTROL_CAPABILITIES. Si NumGammaControlPoints est inférieur à 1025, DXGI laisse le reste des éléments ControlPointPositions non définis.

Le matériel représenté par ce graphique peut convertir des valeurs en une plage comprise entre 0 et 1,25. Par conséquent, DXGI définit les membres MinConvertedValue et MaxConvertedValue sur 0.0f et 1.25f respectivement.

DXGI définit le membre ScaleAndOffsetSupported de DXGI_GAMMA_CONTROL_CAPABILITIES pour indiquer si le matériel prend en charge la fonctionnalité d’échelle et de décalage. Si le matériel prend en charge la mise à l’échelle et le décalage, il conserve une table de recherche un-à-un simple, puis ajuste la sortie de la table pour étendre la sortie à une plage supérieure à [0,1]. Le matériel met d’abord à l’échelle les valeurs qui sortent de la table de choix, puis les décaler.

Notes

Différents moniteurs connectés au même ordinateur peuvent avoir des fonctionnalités de contrôle gamma différentes. En outre, les fonctionnalités de contrôle gamma peuvent en fait changer en fonction du mode d’affichage de la sortie. Par conséquent, nous vous recommandons de toujours appeler IDXGIOutput::GetGammaControlCapabilities pour interroger les fonctionnalités de contrôle gamma une fois que votre application passe en mode plein écran.

 

Vous pouvez utiliser ces valeurs de capacité de contrôle gamma pour dériver des valeurs de contrôle que vous pouvez ensuite définir à l’aide de l’API IDXGIOutput::SetGammaControl .

Définition du contrôle gamma avec DXGI

Pour définir des contrôles gamma, vous passez un pointeur vers une structure DXGI_GAMMA_CONTROL lorsque vous appelez l’API IDXGIOutput::SetGammaControl .

Vous définissez les membres Scale et Offset de DXGI_GAMMA_CONTROL pour spécifier les valeurs d’échelle et de décalage que vous souhaitez que le matériel applique aux valeurs que vous obtenez de la table de choix. Vous pouvez définir en toute sécurité Scale sur 1 et Offset sur zéro (autrement dit, une mise à l’échelle par un n’a aucun effet et un décalage de zéro n’a aucun effet) si vous ne souhaitez pas utiliser la fonctionnalité d’échelle et de décalage ou si le matériel n’a pas cette fonctionnalité.

Vous définissez le membre du tableau GammaCurve de DXGI_GAMMA_CONTROL sur une liste de structures DXGI_RGB pour les points de la courbe gamma. Chaque élément DXGI_RGB spécifie les valeurs float qui représentent les composants rouge, vert et bleu pour ce point. La courbe gamma n’utilise pas de valeurs alpha. Vous utilisez le nombre que vous avez obtenu à partir de NumGammaControlPoints de DXGI_GAMMA_CONTROL_CAPABILITIES pour remplir ce nombre d’éléments dans le tableau GammaCurve . Chaque élément que vous placez dans le tableau GammaCurve correspond à la hauteur de chaque point de contrôle.

Notez dans le graphique précédent que vous contrôlez désormais la position verticale de chaque point de contrôle et que vous disposez d’un contrôle distinct pour le rouge, le vert et le bleu. Par exemple, vous pouvez définir toutes les valeurs vertes et bleues sur zéro et définir les valeurs rouges sur un escalier ascendant de zéro à un. Dans ce scénario, l’image affichée affiche uniquement ses parties rouges, le bleu et le vert apparaissant comme noir. Vous pouvez également définir un escalier descendant pour toutes les couleurs, ce qui entraîne un affichage inversé. Toute valeur que vous placez dans le tableau GammaCurve doit être incluse dans les valeurs que vous avez obtenues à partir des membres MinConvertedValue et MaxConvertedValue de DXGI_GAMMA_CONTROL_CAPABILITIES.

Aspects pratiques du contrôle gamma

Les contrôles gamma de DXGI s’appliquent uniquement tant que l’application est en plein écran. Windows restaure l’état précédent de l’affichage lorsque l’application quitte ou revient en mode fenêtré. Toutefois, Windows ne restaure pas l’état gamma de votre application si l’application re-passe en mode plein écran. Votre application doit restaurer explicitement son état gamma lorsqu’elle re-passe en mode plein écran.

Tous les adaptateurs ne prennent pas en charge le contrôle gamma. Si un adaptateur ne prend pas en charge le contrôle gamma, il ignore les appels pour définir une rampe gamma.

Les applications qui s’exécutent sous le bureau à distance ne peuvent pas contrôler gamma du tout.

Le curseur de la souris, s’il est implémenté dans le matériel (comme la plupart d’entre elles), ne répond généralement pas au paramètre gamma.

Guide de programmation pour DXGI