Uso de la corrección gamma

La corrección gamma, o gamma para short, es el nombre de una operación no lineal que los sistemas usan para codificar y descodificar valores de píxeles en imágenes.

¿Qué es gamma y para qué sirve?

Al final de la canalización de gráficos, justo donde la imagen deja el equipo para realizar su recorrido a lo largo del cable de monitor, hay una pequeña pieza de hardware que puede transformar valores de píxeles sobre la marcha. Este hardware suele usar una tabla de búsqueda para transformar los píxeles. Este hardware usa los valores rojo, verde y azul que proceden de la superficie que se van a mostrar para buscar valores corregidos gamma en la tabla y, a continuación, envía los valores corregidos al monitor en lugar de los valores de superficie reales. Por lo tanto, esta tabla de búsqueda es una oportunidad para reemplazar cualquier color por cualquier otro color. Aunque la tabla tiene ese nivel de potencia, el uso típico consiste en ajustar las imágenes de forma sutil para compensar las diferencias en la respuesta del monitor. La respuesta del monitor es la función que relaciona el valor numérico de los componentes rojo, verde y azul de un píxel con el brillo mostrado de ese píxel.

Eso es lo que esta tabla estaba pensada para, pero los desarrolladores de juegos encontraron usos creativos para ella, como parpadear toda la pantalla roja para el efecto psicológico. En las aplicaciones de juegos modernas, como parte del posprocesamiento de cada fotograma, normalmente proporcionamos otras formas de hacer estas cosas. De hecho, se recomienda dejar la tabla gamma sola porque podría estar en uso para calibrar la respuesta del monitor, y los cambios mayoristas en la rampa gamma destruirán esta calibración cuidadosa.

La ciencia de determinar la corrección gamma es compleja y no se presenta aquí, aparte de iluminar de dónde procede el nombre "gamma". Una CRT (es decir, un vidrio antiguo) la respuesta de un monitor es una función compleja, pero la física de estos monitores significa que presentan una respuesta que puede representarse de forma grosera por esta función de potencia:

brightness( input ) = inputgamma

El valor gamma suele estar cerca de un valor de 2,0. Los monitores LCD y todas las demás tecnologías más recientes están diseñados específicamente para mostrar una respuesta similar, por lo que no es necesario volver a calibrar todo nuestro software e imágenes para esas nuevas tecnologías. El estándar sRGB declara que este valor gamma es exactamente 2,2 y este valor se ha convertido en un estándar ampliamente implementado.

El ojo humano también tiene una función de respuesta que invierte aproximadamente la función de potencia de CRT. Esto significa que el brillo percibido de un píxel sube muy linealmente con los valores RGB de ese píxel.

Dado que un valor gamma de 2.2 se ha convertido en un estándar de facto, normalmente no es necesario preocuparse demasiado por la curva gamma codificada en esta tabla y puede dejarla como una asignación lineal de uno a uno. Por supuesto, la coincidencia de colores adecuada requiere un cuidado exquisito con esta función, pero esa discusión está fuera del ámbito de este tema. Windows incluye una herramienta que permite a los usuarios calibrar sus pantallas en gamma 2.2, y esta herramienta usa el hardware de la tabla de búsqueda para derivar un ajuste sutil cuidadosamente elegido para sus equipos. Los usuarios pueden ejecutar esta herramienta buscando "calibrar el color". También hay perfiles de color bien definidos para monitores concretos que automatizan este proceso. La herramienta "calibrar color" puede detectar estos monitores más recientes e informar a los usuarios de que la calibración ya está en su lugar.

Esta noción de codificación de una ley de potencia en valores de color es útil también en otras partes de la canalización de gráficos, especialmente en texturas. En el caso de las texturas, desea obtener más precisión en colores más oscuros debido a la respuesta ocular humana logarítmica que acabamos de hablar. El control cuidadoso de gamma en esta parte de la canalización es importante. Para obtener más información, consulte Conversión de datos para el espacio de colores.

El resto de este tema se centra solo en la corrección gamma en esta última parte de la canalización, entre los datos del búfer de fotogramas y el monitor. Si desea escribir un asistente de calibración o crear efectos especiales en una aplicación de pantalla completa en la que un paso posterior al procesamiento no es práctico, esta es la información que necesita.

Fondo de gamma en Windows

Windows equipos suelen tener una tabla gamma que es una tabla de búsqueda que toma un triplete de bytes y genera un triplete de bytes. Estos tripletes son 768 (256 x 3) bytes de RAM. Esto es correcto cuando el formato de presentación contiene un triplete de valores BYTE RGB, pero no es lo suficientemente expresivo como para describir las transformaciones que puede querer cuando el formato de presentación tiene un intervalo mayor que [0,1], como los valores de punto flotante. Las API de Windows que controlan gamma han seguido una evolución a medida que los formatos de visualización se han vuelto más complejos.

Las primeras API de Windows que ofrecer el control gamma son Windows interfaz de dispositivo gráfico (GDI) de SetDeviceGammaRamp y GetDeviceGammaRamp. Estas API funcionan con tres matrices de entrada de 256 WORD, con cada codificación de WORD cero hasta una, representada por valores de WORD 0 y 65535. La precisión adicional de word normalmente no está disponible en tablas de búsqueda de hardware reales, pero estas API estaban diseñadas para ser flexibles. Estas API, a diferencia de las demás descritas más adelante en esta sección, solo permiten una pequeña desviación de una función de identidad. De hecho, cualquier entrada de la rampa debe estar dentro de 32768 del valor de identidad. Esta restricción significa que ninguna aplicación puede convertir completamente la pantalla en negro o en algún otro color ilegible.

La siguiente API es SetGammaRamp de Microsoft Direct3D 9, que sigue el mismo patrón y formato de datos que SetDeviceGammaRamp. El valor predeterminado de la rampa gamma direct3D 9 no es especialmente útil; es una rampa de WORD inicializada en 0-255, no 0-65535, aunque la API se define en términos de 0-65535.

La API más reciente es IDXGIOutput::SetGammaControl. Esta API tiene un esquema más flexible para expresar el control gamma, ya que se ajustará el mayor conjunto de formatos de visualización de DXGI, incluidos diez bits enteros por canal, formatos float de 16 bits de 16 bits y el formato de intervalo extendido XR_BIAS.

Todas estas API funcionan en el mismo hardware y cambian los mismos valores. Las API de Direct3D 9 y DXGI son "solo escritura". No se puede leer el valor del hardware, modificarlo y, a continuación, establecerlo. Solo puedes establecer la rampa. Además, solo puedes establecer gamma cuando la aplicación esté en pantalla completa. Esta restricción es otra manera de garantizar que el escritorio siempre es legible. Es decir, la aplicación puede molestar su propia pantalla, pero Windows restaurará la rampa gamma anterior cuando la aplicación pierda la pantalla completa (por ejemplo, a través de alt-tab o ctrl-alt-del).

Evolución del hardware de pantalla

Algunos monitores más recientes pueden mostrar una amplia gama de densidades. Sin embargo, cuando el formato de presentación solo puede representar valores entre cero y uno, la pantalla debe asignar cero a su valor más oscuro y uno a su valor más brillante. Este valor más brillante puede ser demasiado brillante para la visualización cómoda de páginas web con texto negro en un fondo blanco, pero es maravilloso para efectos especiales demasiado brillantes, como ver la luz del sol brillando fuera de un lago o relámpago hacia el cielo. Por lo tanto, necesitamos una manera de expresar estos rangos más amplios. DXGI 1.1 y versiones posteriores contienen valores de formato de visualización que permiten que 1.0 represente un valor blanco cómodo y reserva valores de formato de visualización más amplios para efectos especiales demasiado brillantes. DXGI 1.1 admite dos formatos de visualización que pueden expresar estos valores más amplios: DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM y punto flotante de 16 bits. Para obtener una explicación completa de estos formatos, vea Detalles del formato extendido. A continuación, veremos por qué la API gamma IDXGIOutput::SetGammaControl de DXGI necesita valores de píxeles mayores que 1,0.

Capacidades de control gamma en DXGI

DXGI permite al controlador de pantalla expresar sus controles gamma como una función lineal paso a paso. Esta función lineal paso a paso se define mediante los puntos de control de esta función, el intervalo de valores a los que la función puede convertir y una operación opcional de escala y desplazamiento opcional que se puede aplicar después de la conversión. Una aplicación puede llamar al método IDXGIOutput::GetGammaControlCapabilities para recuperar todas estas funcionalidades de control en la estructura de DXGI_GAMMA_CONTROL_CAPABILITIES .

Este gráfico muestra una función lineal con solo cuatro puntos de control.

gamma correction linear function

DXGI define los puntos de control por su ubicación a lo largo del eje de colores de la superficie. En el gráfico anterior, las ubicaciones de los puntos de control son 0, 0,5, 0,75 y 1,0. Estos puntos de control indican que el hardware puede convertir valores en el intervalo de 0 a 1,0. DXGI enumera estos puntos de control en el miembro de matriz ControlPointPositions de DXGI_GAMMA_CONTROL_CAPABILITIES y siempre los declara en orden creciente. DXGI rellena solo los primeros elementos de la matriz ControlPointPositions e indica el número de elementos con el miembro NumGammaControlPoints de DXGI_GAMMA_CONTROL_CAPABILITIES. Si NumGammaControlPoints es menor que 1025, DXGI deja sin definir el resto de los elementos ControlPointPositions .

El hardware representado por este grafo puede convertir valores en un intervalo de 0 a 1,25. Por lo tanto, DXGI establece los miembros MinConvertedValue y MaxConvertedValue en 0.0f y 1.25f respectivamente.

DXGI establece el miembro ScaleAndOffsetSupported de DXGI_GAMMA_CONTROL_CAPABILITIES para indicar si el hardware admite la funcionalidad de escalado y desplazamiento. Si el hardware admite la escala y el desplazamiento, mantiene una tabla de búsqueda sencilla de uno a uno, pero, a continuación, ajusta la salida de la tabla para ajustar la salida a un intervalo mayor que [0,1]. El hardware escala primero los valores que salen de la tabla de búsqueda y, a continuación, los desplaza.

Nota

Diferentes monitores conectados al mismo equipo pueden tener diferentes capacidades de control gamma. Además, las funcionalidades de control gamma pueden cambiar de hecho en función del modo de visualización de la salida. Por lo tanto, te recomendamos que llames siempre a IDXGIOutput::GetGammaControlCapabilities para consultar las funcionalidades de control gamma después de que la aplicación entre en modo de pantalla completa.

 

Puede usar estos valores de funcionalidad de control gamma para derivar valores de control que puede establecer mediante la API IDXGIOutput::SetGammaControl .

Establecer el control gamma con DXGI

Para establecer controles gamma, pase un puntero a una estructura de DXGI_GAMMA_CONTROL al llamar a IDXGIOutput::SetGammaControl API.

Establezca los miembros Scale y Offset de DXGI_GAMMA_CONTROL para especificar los valores de escala y desplazamiento que desea que el hardware se aplique a los valores que obtiene de la tabla de búsqueda. Puede establecer de forma segura Scale en 1 y Offset en cero (es decir, una escala por uno no tiene ningún efecto y un desplazamiento de cero no tiene ningún efecto) si no desea usar la funcionalidad de escala y desplazamiento o si el hardware no tiene esa funcionalidad.

Establezca el miembro de matriz GammaCurve de DXGI_GAMMA_CONTROL en una lista de estructuras de DXGI_RGB para los puntos de la curva gamma. Cada elemento DXGI_RGB especifica los valores float que representan los componentes rojo, verde y azul para ese punto. La curva gamma no usa valores alfa. Utilice el número que obtuvo de NumGammaControlPoints de DXGI_GAMMA_CONTROL_CAPABILITIES para rellenar ese número de elementos en la matriz GammaCurve . Cada elemento que coloque en la matriz GammaCurve es el alto de cada punto de control.

Observe en el gráfico anterior que ahora tiene control sobre la ubicación vertical de cada punto de control y tiene un control independiente para rojo, verde y azul. Por ejemplo, puede establecer todos los valores verdes y azules en cero y establecer los valores rojos en una escalera ascendente de cero a uno. En este escenario, la imagen mostrada muestra solo sus partes rojas, con el color azul y verde que aparece como negro. También puede establecer una escalera descendente para todos los colores, lo que da como resultado una pantalla invertida. Cualquier valor que coloque en la matriz GammaCurve debe estar incluido dentro de los valores obtenidos de los miembros MinConvertedValue y MaxConvertedValue de DXGI_GAMMA_CONTROL_CAPABILITIES.

Prácticas de control gamma

Los controles gamma de DXGI solo se aplican siempre y cuando la aplicación esté en pantalla completa. Windows restaura el estado anterior de la pantalla cuando la aplicación sale o vuelve al modo de ventana. Pero Windows no restaura el estado gamma de la aplicación si la aplicación vuelve a entrar en modo de pantalla completa. La aplicación debe restaurar explícitamente su estado gamma cuando vuelve a entrar en el modo de pantalla completa.

No todos los adaptadores admiten el control gamma. Si un adaptador no admite el control gamma, omite las llamadas para establecer una rampa gamma.

Las aplicaciones que se ejecutan en escritorio remoto no pueden controlar gamma en absoluto.

El cursor del mouse, si se implementa en hardware (como la mayoría), normalmente no responde a la configuración gamma.

Guía de programación para DXGI