¿La mejor manera de permitir a los jugadores "teñir" imágenes sin perder calidad de color?


41

Estoy creando un juego isométrico 2.5D (imágenes 2D).

Quiero que los jugadores puedan "teñir" su armadura, ropa y otras cosas. Me parece que la escala de grises lleva a perder algunos de los colores más "naturales". Por ejemplo, hacer un dragón con escala de grises rojo / amarillo y luego aplicar un color de superposición, conduce a un dragón puramente rojo con toda la pérdida del color secundario. Mientras tanto, morir ese mismo Dragón Rojo / Amarillo Azul, lo hace Azul / Blanco que se ve muy bien.

Los personajes de mi juego no tienen una gran variedad de equipos. El juego está más cerca de cómo League of Legends maneja personajes y gráficos. Puede haber un solo tipo de personaje (ej. Héroe) pero múltiples atuendos para el personaje como opciones. Quiero que los jugadores puedan tener la mayor personalización posible en la cantidad limitada de "atuendos" y personajes.

Entonces, quiero que los jugadores puedan seleccionar un personaje, elegir una de varias armas, alternar entre un puñado de opciones de vestuario (en capas sobre los personajes) y luego teñir la mayoría de todo (elegir un color metálico específico para las armas, elegir cualquier color en absoluto para la ropa).

Si pudiera usar la escala de grises sin perder parte del color, lo haría.

Aquí hay un ejemplo de lo que estoy hablando:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Ni siquiera es posible "teñir" al Dragón, sin importar lo que use en las opciones de "Superposición de color" de Photoshop. Obviamente, lo estoy haciendo mal si es posible colorearlo mejor usando la escala de grises. Para un color como verde o amarillo o un púrpura más claro, esto funciona bien. Para cualquier otro color, destruye el arte.

Sin embargo, se ve mucho mejor si NO lo hago en escala de grises, y simplemente aplico un color "HUE" a la imagen original (Rojo / Amarillo).

Tonalidad roja ingrese la descripción de la imagen aquí

Tono púrpura ingrese la descripción de la imagen aquí

¡Ahora los jugadores podrían teñir el Dragón CUALQUIER color, y todavía se vería genial! (El amarillo se vuelve blanco, mientras que el rojo cambia a cualquier color del arco iris).

¿Significa esto que BLANCO o NEGRO es el mejor color secundario? Luego, ¿usa algún tipo de método o sombreador para cambiar el color blanco (secundario) a algo diferente?

¿Hay algún artículo sobre este método complejo de tomar una sola imagen y, basándose en el color, teñir diferentes píxeles?

Para el Dragón, ¿funcionaría mejor como un Dragón de alto contraste blanco / negro? ¿Es el rojo / amarillo el mejor conjunto de colores? Resulta mucho mejor para las imágenes que algunos otros colores que probé. ¿Es la escala de grises aún superior?

¿Las "Opciones de fusión" de Photoshop no incluyen el método para "teñir" adecuadamente las imágenes de un videojuego? ¿Existen sombreadores / métodos complejos que me permitan lograr un mayor éxito?

Nota: Si GrayScale me permite reducir el consumo de RAM de mis imágenes o evitar la pérdida de calidad durante la compresión con pérdida, eso sería algo que consideraría seriamente.


55
Esto es legítimamente interesante. Voy a votar esto y espero que reciba más atención. La teoría del color es un gran tema.
Evan

La rotación de tono es una posibilidad, aunque sea en 2D: no sé si funcionaría en 3D.
cenizas999

Gracias Evan También estoy de acuerdo en que esto es extremadamente interesante, y uno de los mejores temas que he investigado en mi propio tiempo. Me imagino que este tipo de trabajo rara vez se realiza porque requeriría un artista, pero no cualquier artista, un artista que se ocupe de la teoría del color, los sombreadores de videojuegos o incluso un codificador de artistas. Solo puedo imaginar que encontrar a alguien que sobresalga tanto en arte como en programación es raro. No hay casi ninguna investigación que se pueda encontrar sobre este tema en google. Especialmente para alguien que no tiene idea de qué términos clave investigar. Ciertamente no soy un artista.
Carter81

Respuestas:


19

El cambio de tono es una posibilidad que le permitiría obtener una gama de colores sin perder los detalles de color. La idea básica es convertir cada píxel del espacio RGB al HSV, luego compensar el tono por una cantidad definida por el usuario, luego volver a convertir a RGB. En realidad, esto se puede hacer de manera más eficiente aplicando una matriz de rotación a los valores RGB: cree una matriz que gire alrededor del eje (1, 1, 1) mediante el ángulo de tono definido por el usuario. Luego, simplemente puede aplicar esta matriz a cada valor RGB en su sombreador de píxeles.

Esto permitirá que el dragón rojo-amarillo se cambie a un dragón amarillo-verde, verde-cian, cian-azul, azul-magenta o magenta-rojo. Esto es un poco restrictivo ya que los dos colores no pueden modificarse independientemente con este enfoque. Mantendrán su tono relativo a medida que se crean en la imagen original. También hay algunos colores a los que no puede acceder, por ejemplo, no puede hacer un dragón blanco y negro de esta manera. Aún así, esto puede ser suficiente para sus propósitos.

Otra posibilidad, si sus modelos tienen dos o tres "colores clave" (rojo y amarillo aquí), podría crear la imagen original usando un canal de color separado para cada color clave. En este caso, crearías el dragón rojo y verde en lugar de rojo y amarillo, y si tuvieras un tercer color, podrías crearlo en azul. Luego, puede dejar que el usuario elija los tres colores clave y usar los valores rojo, verde y azul de la imagen como cantidades de esos colores definidos por el usuario para combinarlos. De esta manera, su sombreador de píxeles se vería algo así

finalColor = image.r * userColor1 + image.g * userColor2 + image.b * userColor3;

Esto permitiría a los usuarios elegir cualquier combinación de colores que quisieran, incluidos elementos como blanco y negro, o púrpura y dorado.


1
+1 por no solo una buena respuesta, sino una respuesta sobre un tema raro (teoría del color). No tengo idea de por qué no pensé en eso antes. RGB Rojo verde azul. DUH! Los mejores colores para usar son probablemente esos tres colores exactos, debido a la capacidad de manipular los canales individuales.
Carter81

1
El cambio de color es un tema muy difícil porque la mayor parte de la información de la imagen se transmite por el brillo, y el simple cambio de tono no conserva el brillo. Los diferentes tonos tienen diferentes valores de brillo inherentes. Necesitas algoritmos más sofisticados para eso.
API-Beast

10

El problema que enfrenta es que no puede simplemente "teñir" toda la imagen, la apariencia que ve es más que solo un color base. Para uno, tiene gradientes finos de un material a otro, pero lo más importante es que también tiene reflejos, reflejos y sombras, que no están influenciados por el color base. (Esos se agregan básicamente encima).

Por lo tanto, debe descomponer la imagen en sus componentes.

Un ejemplo :

Imagen deconstruida Ejemplos teñidos

En este caso tenemos 3 capas:

  • El fondo: contiene los elementos que no deben colorearse.
  • La parte que debe colorearse: se multiplica por el color. (OpenGL se multiplica por defecto si especifica un color que no sea blanco).
  • Los aspectos más destacados: estos son aditivos dibujados sobre toda la imagen. No es blanco sino amarillo, para emular un cambio de tono. Los objetos no son solo un solo color, el tono cambia junto con el brillo.

+1. Pero "no se puede simplemente" teñir "toda la imagen" es un poco engañoso. Todo depende de la elección de OP para su juego. Por ejemplo, Diablo II lo hizo. Así que no sería tan estricto con las partes "no puedes / necesitas". Esta es solo una de las opciones, mejor aspecto pero más consumo de RAM.
Kromster dice que apoya a Mónica

1
@KromStern Point es, se ve horrible si lo haces, siempre.
API-Beast

Gran respuesta. ¿Es esto posible, sin embargo, a través de la automatización? Si uno tiene miles de imágenes animadas para un solo personaje, no es factible seleccionar a mano cada capa o descomponer la imagen de una en una. Aún así, puedo ver algunas soluciones alternativas para ayudar a automatizarlo si se renderiza desde 3D usando el enmascaramiento, pero independientemente de eso, sigue siendo una gran respuesta.
Carter81

Es posible automatizarlo al encontrar los colores dominantes y extraerlos (mediante el uso de un algoritmo inverso de "color a alfa"). Pero no es que haya implementado algo así.
API-Beast

Para extraer los resaltados, puede tomar la máscara que extrajo anteriormente y filtrarla para que solo le queden los componentes más brillantes.
API-Beast

3

Yo personalmente recomendaría usar texturas de máscara para lograr lo que quieres. Esto asegurará que su textura RGB24 principal mantendrá su calidad de color original sin sacrificar ninguna precisión. También te dará mucha libertad artística para combinar tu textura principal con tu máscara de color.

Cada máscara se puede ver como una textura en escala de grises que interpolará linealmente el color de su textura base con su color personalizado. Digamos que está permitiendo que sus usuarios personalicen dos colores, el sombreador de píxeles se verá así:

entradas: MainTexture (RGB), Mask1Texture (A), Mask2Texture (A), Colour1 (float), Colour2 (float)

salida: (Mask1Texture + Mask2Texture) -MainTexture + Colour1 * Mask1Texture + Colour2 * Mask2Texture

Esto sugiere que cuanto más tenga una máscara un valor grande para un píxel, menos afectará su textura principal al color de salida de ese píxel. Por ejemplo, podría convertir la textura de su dragón en una escala de grises y borrar todo menos sus alas para tener un color de ala personalizado sin importar el color del cuerpo.

He usado esta técnica para juegos móviles y no afectará su rendimiento general. Podría costarle un 33% más de RAM por textura, pero la compensación por la calidad probablemente valga la pena.

Ps Si solo está pensando en usar un color personalizado, simplemente puede usar el canal Alpha de su textura principal RGBA32 como máscara.


2

puede usar paletas de colores y dejar que el jugador edite la paleta. Si usa sombreadores, puede usar texturas 1D como paletas y el valor gris original como índice.

Para convertir una imagen en color verdadero en una imagen con 255 colores, puede tomar todos sus valores de color de píxeles y agruparlos en el espacio de color 3D en 255 grupos con el algoritmo k-means. O use herramientas genéricas de conversión de imágenes. Entonces es importante mencionar que la interpolación de la textura del valor gris será una interpolación de índices en sus texturas de color. Esto puede conducir a un resultado en el que tiene varios colores entre dos texels de su imagen original. Esto puede resolverse deshabilitando la interpolación (creo que no desea hacerlo) o clasificando su paleta de colores de manera útil.


Esto es básicamente lo que estaba pensando también. Es posible que desee ampliar la respuesta a algo un poco más completo. Básicamente, usted deja que el usuario elija dos colores (o más o menos, pero por razones de argumento, 2), haga una textura 1D que se desvanezca de los dos colores. Use una textura en escala de grises en la geometría que sirva como referencia en la textura 1D. Todavía es posible para el usuario establecer colores feos, pero al menos tienen la opción de hacer buenas elecciones de colores contrastantes.
wrosecrans

Sí, también puede obtener la paleta de 255 colores completos con menos colores de usuario, pero aquí solo puedo aconsejarle que lo pruebe. Sé que muchos juegos antiguos usaban cambios en la paleta de colores para hacer variaciones en sus monstruos. Creo que Diablo hizo eso.
Arne

1

puede convertir la imagen en una imagen gris pero aún guardarla con canales rgba. almacene un valor de peso en el canal alfa y luego úselo para decidir cuánto tinte aplicar a un píxel. Este peso se puede calcular en función de lo cerca que esté el color del blanco. cuanto más cercano al blanco esté el píxel, menos colorante se aplicará o menor será el peso. esto dejará la mayoría de los reflejos con su ligereza original, pero aplique un poco del tinte. el color de píxel final se puede encontrar calculando cada canal Ro + (Rd * Ao) donde Ro es el rojo original, Rd es el rojo en el color del tinte y Ao es el Alfa del original. por lo que todos los píxeles blancos no tienen color nuevo y todos los píxeles negros asumen el color del tinte.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.