Estoy tratando de entender qué es HDR y cómo funciona.
Entiendo los conceptos básicos y tengo una ligera idea de cómo se implementa con D3D / hlsl.
Sin embargo, todavía está bastante nublado.
Digamos que estoy renderizando una esfera con una textura de la tierra y una pequeña lista de puntos de vértices para que actúen como estrellas, ¿cómo podría representar esto en HDR?
Aquí hay algunas cosas sobre las que estoy confundido:
Supongo que no puedo usar cualquier formato de imagen básico para la textura, ya que los valores se limitarían a [0, 255] y se fijarían a [0, 1] en un sombreador. Lo mismo ocurre con el búfer posterior, supongo que el formato debe ser un formato de punto flotante.
¿Cuáles son los otros pasos involucrados? ¿Seguramente tiene que haber algo más que usar formatos de punto flotante para renderizar a un objetivo de renderizado y luego aplicar algo de floración como un proceso posterior? (teniendo en cuenta que la salida será de 8bpp de todos modos)
Básicamente, ¿cuáles son los pasos para HDR? Como funciona ? Parece que no puedo encontrar buenos artículos / artículos que describan el proceso, aparte de este , pero parece pasar un poco por alto lo básico, por lo que es confuso.
Técnicamente, HDR simplemente significa usar un mayor rango de valores posibles para sus gráficos. Por lo general, está restringido a 256 valores discretos para los canales rojo, verde y azul, lo que significa que si tiene 2 elementos, uno dos veces más brillante que el otro, y un tercero que es 10,000 veces más brillante que el primero, no hay de manera que puede representar a los 3 en la misma escena correctamente: puede hacer que el objeto brillante sea solo 256 veces más brillante que el primero, o hacer que los objetos opacos sean completamente negros (perdiendo el contraste entre ellos) y luego el objeto brillante es infinitamente más brillante que los dos.
Esto es fácil de solucionar mediante el uso de valores de coma flotante para los valores rojo / verde / azul, pero ahora tiene el problema de cómo mostrarlo en un dispositivo gráfico que solo maneja un número fijo de valores discretos por canal (por ejemplo, 256) . Entonces, la segunda parte del problema es cómo mapear los valores de coma flotante de vuelta al rango limitado. La solución trivial es escalar todos los valores proporcionalmente en el rango discreto, pero esto significaría que 1 píxel muy brillante podría hacer que el resto de la pantalla se ennegrezca, etc. enlace para ejemplos de cómo puede abordar esto.
Por lo general, no son sus texturas las que deben almacenarse en un nuevo formato: es cuando se les aplica la iluminación que deben ser capaces de acomodar valores más grandes. Obviamente, sin embargo, si tiene fuentes de luz horneadas en una textura, por ejemplo. un fondo estrellado: es posible que desee un formato de mayor resolución allí. O simplemente haga que el sombreador escale los valores de dichos materiales cuando llegue el momento de renderizarlos.
fuente
Las computadoras tradicionalmente representaban cada píxel en la pantalla como solo 24 bits en la memoria: 8 para rojo, 8 para verde y 8 para azul. Esto es casi suficientes bits que un humano no notaría si agrega más, y el byte de 8 bits es muy conveniente para los microprocesadores, así que eso es lo que se atascó.
Mientras que 8 bits es casi suficiente precisión para mostrar una imagen, definitivamente no es suficiente precisión para calcular una imagen. En varios puntos al calcular una imagen, se requieren al menos 32 bits de precisión.
Esta es la razón por la cual los sombreadores de píxeles calculan los colores con una precisión de 32 bits, incluso cuando se procesa en una imagen de precisión de 8 bits. De lo contrario, no podría, por ejemplo, dividir un valor entre 1000 y luego multiplicarlo por 1000, porque dividir cualquier valor de 8 bits entre 1000 da como resultado cero.
Ha habido una tendencia en los gráficos 3D en tiempo real a mantener todos los gráficos en una precisión de> 8 bits hasta el último momento posible, momento en el cual los> 8 bits de rojo se reducen a 8 bits, y así sucesivamente para el verde y el azul.
HDR se refiere al acto de renderizar en imágenes que tienen una precisión superior a 8 bits. En los videojuegos de televisión contemporáneos, la precisión de 16 bits es la norma, y esto puede ser "suficiente" en los videojuegos en los próximos años.
fuente
Un aspecto del cual creo que es clave para HDR es la aplicación correcta del monitor gamma.
El monitor que está mirando produce luz en función de los píxeles de entrada. Es de esperar que un píxel con valor 255 produzca (aproximadamente) 255 veces más luz que un píxel con valor 1. Este no es el caso. Con un monitor estándar gamma de 2.3, es 255 ^ 2.3 veces más brillante, ¡o aproximadamente 340000!
Todo el mundo que produce contenido (fabricantes de cámaras) lo sabe, o (si es diseñador) usted lo compensa implícitamente.
Todo esto está bien si solo renderizas mapas de bits (bueno, la mayoría de las veces), pero si los usas como texturas en una escena 3D es una historia diferente. Si desea modelar la interacción con la luz correctamente, debe usar cálculos lineales de luz en toda la tubería de renderizado. Esto significa
corrigiendo tus texturas para gamma
renderice todo con luz lineal (donde necesita mucha precisión debido al alto rango dinámico de luz),
aplique la transformación gamma inversa del monitor como la última cosa antes de colocar la imagen en la pantalla.
Cuando realice este cambio en una escena existente, con ilustraciones, luces, etc. existentes, probablemente tenga que corregir muchas de sus intensidades y texturas de luz, porque se eligieron para que se vean bien cuando se renderiza con luz no lineal. Por lo tanto, no es una función que pueda "activar" y esperar que todo se vea mejor así.
fuente