Compartir a través de


Uso de la corrección gamma

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 es 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 mesa 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, le recomendamos que deje la tabla gamma solo porque podría estar en uso para calibrar la respuesta del monitor, y los cambios al por mayor 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 proviene el nombre "gamma". Una respuesta de un monitor CRT (es decir, un vidrio antiguo) es una función compleja, pero la física de estos monitores significa que muestran una respuesta que puede representarse de forma bruta mediante esta función de poder:

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 presentar una respuesta similar, por lo que no es necesario volver a almacenar en caché 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 de forma muy lineal 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 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 otra parte de la canalización de gráficos, especialmente en texturas. En el caso de las texturas, quieres más precisión en los colores más oscuros debido a la respuesta logarítmica de los ojos humanos que acabamos de hablar. El control cuidadoso de gamma en esta parte de la canalización es importante. Para obtener más información, consulta Convertir datos para el espacio de colores.

El resto de este tema se centra únicamente 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

Normalmente, los equipos Windows tienen 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 rango 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 pantalla se han vuelto más complejos.

Las primeras API de Windows que ofrecen control gamma son la Interfaz de dispositivo gráfico de Windows (GDI) SetDeviceGammaRamp y GetDeviceGammaRamp. Estas API funcionan con tres matrices de entrada de 256 WORD, con cada codificación 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 la pantalla completamente 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 pantalla de DXGI, incluidos diez bits enteros por canal, formatos flotantes 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 puede 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 una 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 solar brillando fuera de un lago o relámpago hacia el cielo. Por lo tanto, necesitamos una manera de expresar estas gamas más amplias. 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 pantalla más amplios para efectos especiales demasiado brillantes. DXGI 1.1 admite dos formatos de pantalla 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 DXGI_GAMMA_CONTROL_CAPABILITIES .

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

función lineal de corrección gamma

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 el resto de los elementos ControlPointPositions sin definir.

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 escala y desplazamiento. Si el hardware admite la escala y el desplazamiento, mantiene una tabla de búsqueda sencilla uno a uno, pero luego 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 capacidades de control gamma pueden cambiar de hecho en función del modo de presentación de la salida. Por lo tanto, te recomendamos que siempre llames 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, se pasa un puntero a una estructura de DXGI_GAMMA_CONTROL cuando se llama a la API IDXGIOutput::SetGammaControl .

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 escalado y desplazamiento o si el hardware no tiene esa funcionalidad.

Establece 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 flotantes que representan los componentes rojo, verde y azul de ese punto. La curva gamma no usa valores alfa. Utilice el número obtenido 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 posició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, donde el azul y el verde aparecen como negros. 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 en 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 vuelva a entrar en 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