Dentro de la mente del romhacker: Teoría del color

  • access_time13-08-2019
  • Megaflan

El tratamiento de ficheros binarios es algo que, aunque parezca mentira, no está limitado a alienígenas, con unas nociones básicas el mundo que te rodea, sencillamente, cambia por completo.

En este articulo vamos a comentar, de una forma simplificada, cómo funciona el renderizado de imágenes, sobre todo vamos a centrarnos en el concepto de "color".

¿Y qué es el color?

Bueno, lo idóneo es empezar por aquí: el color es un fenómeno que se produce en la naturaleza. El color no es un objeto. Una pelota, por ejemplo, no es de color rojo porque el objeto sea rojo sino porque la vemos e interpretamos de color rojo, es decir, somos nosotros mismos quienes decidimos que un objeto es de un color u otro y es aquí donde os va a explotar la cabeza.

Tu retina se encarga de estimular tu nervio óptico en base a lo que la retina recibe, la información que recibe tu retina son ondas electromagnéticas, al recibir esas ondas, se interpreta esa información en función a las frecuencias que recibe y dependiendo de las mismas el nervio óptico envía información al cerebro de un color u otro.

¿Y cómo lo hace?

Podemos decir que tu ojo es como una pantalla y dentro de tus células fotorreceptoras se encuentran conos y bastones, dichos conos y bastones actúan como receptores de luz y actúan de forma muy parecida al estándar RGB.

De forma muy simplificada, así funciona la recepción del color en un humano.

El caso viene en que, cuando un renderizador gráfico (la parte de un ordenador que se encarga de interpretar los gráficos) se encarga de interpretar el color funciona exactamente igual, el renderizador no sabe exactamente de que color es una imagen, tienes que darle esa información.

Por lo normal, una imagen se puede componer de dos formas ya sea por la técnica de “luz + color(luminancia y crominancia) o por la técnica “texel(texture element, contienen información de color, luminosidad, saturación, etc...) que vamos a explicar a continuación.

La técnica de “luz + color” se basa en formar una imagen mediante bytes que varían de valor dependiendo de su luminosidad, es decir, cuanto menor sea el valor de ese byte, menor luminosidad, cuanto mayor sea el valor, mayor luminosidad.

(Insertar imagen de Disgaea)

Posteriormente, tenemos una paleta que se encarga de darle a esa luminosidad unos valores, dependiendo del formato de la imagen esto cambia por lo que hay que tener mucho ojo, igualmente, usaremos el formato de color RGBA32 para ello.

Sabiendo esto, el renderizador va a tratar de dibujar los bytes en función a la luminosidad y superponer los valores RGBA para darle color.

(Insertar foto del renderizador)

Y después tenemos la técnica “texel”, los texeles incluyen esa luminosidad, por lo que simplemente dibujamos como si pintásemos con temperas en un lienzo, es decir, aplicamos valores RGBA sobre un lienzo y pintamos, cada objeto “texel” es un pixel en pantalla con un determinado color y luminosidad.

(Insertar imagen que explique RGBA32)

Por lo tanto, en definitiva, los colores realmente no están escritos en el programa, si no que el programa determina que debe elegir un tipo de renderizado u otro, esto significa que podríamos, por ejemplo, simular daltonismo e incluso la perdida de la visión de los colores en el renderizado, podríamos simplemente renderizar en blanco y negro modificando el patrón de bits en el texel, y esto se debe a que la luminosidad es simplemente el resultado de una simplisima ecuación.

L = (R + G + B) / 3

Basicamente, si conseguimos aislar cada uno de los colores dentro del componente RGB y dividimos entre 3 el resultado de la suma de los mismos obtenemos un byte cuyo valor irá entre 0 y 255, ese byte es el equivalente directo a la luminosidad de la imagen, o lo que es lo mismo, el valor en la escala de grises.

Así podemos pasar una imagen de color a blanco y negro, basicamente.

Si os ha gustado este pequeño articulo o tenéis cualquier duda, decidlo en los comentarios, ya que si tenemos un feedback positivo explicaremos más y más cosas sobre el trabajo que efectuamos los tecnicos de Tradusquare.

Comentarios

#593
14-08-2019
Keph

¡Muy interesante!
#594
14-08-2019
Fernando

Mi cabeza explotó en este momento, oye cómo indicaste en todo esto, o cómo puedo iniciar.
#597
14-08-2019
Spoiler

Buen artículo, auqnue habiendo programado engines gráficos (alguno en el mercado), sí que hay un par de cosas que me chirrían:

- El concepto de texel es la unidad atómica de los datos de una textura usada en el pipeline de renderización. Esto es totalmente independiente del espacio de color, o de la "técnica". De hecho, un texel no tiene por qué ser siquiera gráfico. En los pipelines modernos, las gráficas permiten datos de cualquier naturaleza en sus texturas. Por ejemplo, en varias versiones de CUDA, la memoria de textura usa caching mediante entrelazado (swizzling) para aumentar el rendimiento. Así, si por ejemplo subes una nube de puntos como textura, un texel será un punto, o un cluster de puntos (según la configuración del buffer).
En efecto, la diferencia entre una "textura" y cualquier otro buffer en la VRAM lo dictan la API (OpenGL, OpenCL, DirectX, CUDA, Vulkan, etc...), y los drivers del adaptador.

- Lo de L = (R + G + B) / 3... Lo siento pero no es así: En estándares tales como YUV, o HSL, existen matrices para convertir componentes entre diferentes espacios de color. Por ejemplo RGB (1.0, 0.0, 0.0):
-> Corresponde al color puramente rojo.
-> Tiene un valor de 0.5 de luminosidad (HSL)
-> Tiene un valor de 0.299 de luminancia (YUV)
-> El valor de 0.333 correspondería en todo caso a su intensidad (HSI)

Luminosidad, luminancia e intensidad son conceptos distintos. Por ejemplo, la luminancia de RGB (1.0, 0.0, 0.0), siendo 0.299, es diferente a la luminancia de RGB (0.0, 1.0, 0.0), la cual es 0.587. Esto es debido a que son colores situados en diferentes porciones del espectro, y por tanto tienen diferente longitud de onda y energía. En cuanto a la luminosidad e intensidad, sí que serían las mismas (0.5 y 0.333). Comúnmente se entiende por "escala de grises" a un mapa de luminancias, no de intensidades. Y no, estos espacios de color no son tan "niche", de hecho, el formato JPEG lo que almacena es YUV comprimido en huffman.

Otra cosa que yo mencionaría dentro del ámbito de ingeniería inversa, y auditoría binaria de ficheros de imagen, es la diferencia entre formatos de color directo vs color indexado. De hecho la primera imagen parece ser indexada, ya que de lo contrario deberia verse considerablemente "estirada".
Y quizás también, para evitar confusiones al comparar los formatos de imagen y espacios de color con la vista humana, mencionaría la diferencia entre espacios aditivos y sustractivos.
#598
14-08-2019
MegaflanEditor

Permíteme decir que me ha sorprendido una respuesta tan interesante a este artículo, sin duda un ejemplo a seguir.

Igualmente, hay cosas que no se si me he expresado mal durante el articulo o simplemente no han quedado claras debido a intentar explicarlo de la forma más simple posible.

Vamos a empezar con el tema del texel, he leído documentación sobre el tema y me he dado cuenta de que mucha gente atribuye el término a varias cosas distintas, por lo general, ni la Wikipedia te ofrece un artículo completo, solo un "stub", esto se debe al problema de que el texel no es una unidad atómica, eso es el pixel, el texel es solo una matriz de bytes, y dependiendo del formato puede ser una cosa u otra, pero el texel siempre va a ser un objeto que determine la textura, eso incluye el ejemplo que he dado.

Aunque es cierto que quizás es un término muy confuso de usar y que realmente casi nadie usa en este campo por lo abstracto que es, todo sea de paso, aquí no hablamos ni de CUDA, ni de motores gráficos modernos como Unreal porque, de hecho, estos mismos motores modernos no utilizan este espacio de colores, en vez de RGB usan el formato DXT, y de esto podría dedicar un artículo entero a explicar toda la historia que tiene detrás.

Quizás ese ha sido el malentendido, no hablo en ningún momento de motores modernos al intentar simplificar el tema lo más posible, no hablo de compresiones, no hablo de otros espacios de colores diferentes al RGB (por ejemplo, como bien has dicho, el YUV o el HSL) al intentar simplificar el artículo.

Es por ello que cuando hablo de luminosidad y de la formula "L = (R + G + B) / 3, dejo en todo momento que hablo del espacio de colores RGBA32, este fenómeno solo ocurre aquí debido a que, por ejemplo, el YUV contiene directamente la luminosidad junto a la crominancia (YCbCr).

La intención principal del artículo es la divulgación para que los lectores investiguen más sobre el tema con una base y, si los lectores nos leen, se darán cuenta de que este campo es muy extenso y que lo que digo en el artículo son solo unas nociones básicas (como bien digo nada más empezar)

Para terminar, sí, cuando terminé el articulo me di cuenta de que no explicaba el tema del color directo vs color indexado, pero eso es precisamente porque tampoco quería usar terminología muy técnica, como bien dices, la primera imagen parece ser la indexada y, de hecho, estás en lo correcto, a lo que yo llamo "luz + color" es precisamente a la imagen indexada, y a lo que llamo "texel" es la imagen con color directo.

Repito que me ha encantado una respuesta tan interesante como la que has ofrecido y, opino, que tienes un potencial y unos conocimientos muy notables para trabajar con nosotros o en este campo, si quieres hablar con nosotros puedes encontrarnos en Discord, donde estaremos más que encantados de responderte a cualquier otra duda que tengas.
Necesitas registrarte para poder enviar comentarios.
Todos los proyectos alojados en esta página son realizados por fans para fans sin ánimo de lucro.
En esta página únicamente aparecerá contenido sin Copyright y parches para aplicar a copias de juego originales.
TraduSquare 2017-2018