Se desvanece en los juegos más antiguos. Necesita ayuda para descubrir cómo se derivó el algoritmo

12

Lo siento, esta pregunta es un poco esotérica, ¡pero no puedo sacarla de mi cabeza!

Estoy mirando el algoritmo de desvanecimiento utilizado en el juego arcade DoDonPachi (así como en muchos otros juegos más antiguos):

ingrese la descripción de la imagen aquí

Escribí un script de Python para seleccionar algunos píxeles y rastrearlos durante la duración del desvanecimiento. Aquí hay una muestra representativa de los resultados. La primera fila de cada grupo es el valor de color inicial, mientras que cada fila posterior es la diferencia entre el valor de color del cuadro actual y el valor de color del cuadro anterior.

Starting Value: (132, 66, 189)
Frame 1:    [9, 9, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 8, 9]
Frame 5:    [9, 9, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 8, 9]
Frame 9:    [9, 0, 8]
Frame 10:   [8, 0, 8]
Frame 11:   [8, 0, 8]
Frame 12:   [8, 0, 9]
Frame 13:   [9, 0, 8]
Frame 14:   [8, 0, 8]
Frame 15:   [8, 0, 8]
Frame 16:   [8, 0, 9]
Frame 17:   [0, 0, 8]
Frame 18:   [0, 0, 8]
Frame 19:   [0, 0, 8]
Frame 20:   [0, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (132, 0, 0)
Frame 1:    [9, 0, 0]
Frame 2:    [8, 0, 0]
Frame 3:    [8, 0, 0]
Frame 4:    [8, 0, 0]
Frame 5:    [9, 0, 0]
Frame 6:    [8, 0, 0]
Frame 7:    [8, 0, 0]
Frame 8:    [8, 0, 0]
Frame 9:    [9, 0, 0]
Frame 10:   [8, 0, 0]
Frame 11:   [8, 0, 0]
Frame 12:   [8, 0, 0]
Frame 13:   [9, 0, 0]
Frame 14:   [8, 0, 0]
Frame 15:   [8, 0, 0]
Frame 16:   [8, 0, 0]
Frame 17:   [0, 0, 0]
Frame 18:   [0, 0, 0]
Frame 19:   [0, 0, 0]
Frame 20:   [0, 0, 0]
Frame 21:   [0, 0, 0]
Frame 22:   [0, 0, 0]
Frame 23:   [0, 0, 0]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (165, 156, 222)
Frame 1:    [9, 8, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 9, 9]
Frame 5:    [9, 8, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 9, 9]
Frame 9:    [9, 8, 8]
Frame 10:   [8, 8, 8]
Frame 11:   [8, 8, 8]
Frame 12:   [8, 9, 9]
Frame 13:   [9, 8, 8]
Frame 14:   [8, 8, 8]
Frame 15:   [8, 8, 8]
Frame 16:   [8, 9, 9]
Frame 17:   [9, 8, 8]
Frame 18:   [8, 8, 8]
Frame 19:   [8, 8, 8]
Frame 20:   [8, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 9]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 8]
Frame 27:   [0, 0, 8]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (156, 90, 206)
Frame 1:    [8, 8, 8]
Frame 2:    [8, 8, 9]
Frame 3:    [8, 8, 8]
Frame 4:    [9, 9, 8]
Frame 5:    [8, 8, 8]
Frame 6:    [8, 8, 9]
Frame 7:    [8, 8, 8]
Frame 8:    [9, 9, 8]
Frame 9:    [8, 8, 8]
Frame 10:   [8, 8, 9]
Frame 11:   [8, 8, 8]
Frame 12:   [9, 0, 8]
Frame 13:   [8, 0, 8]
Frame 14:   [8, 0, 9]
Frame 15:   [8, 0, 8]
Frame 16:   [9, 0, 8]
Frame 17:   [8, 0, 8]
Frame 18:   [8, 0, 9]
Frame 19:   [8, 0, 8]
Frame 20:   [0, 0, 8]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 9]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 8]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Como puede ver, se sustrae un 8 o un 9 de cada componente de color en cada cuadro. Además, un 9 siempre aparece tres cuadros después de un 8, aunque el valor sustraído inicial es diferente para cada componente de color. Tenga en cuenta también que cada componente de color alcanza 0 (es decir, negro) con una diferencia de 8 o 9, no algún resto arbitrario. ¡Esto significa que el ciclo de valor restado de 8,8,8,9 nunca se rompe! (Este algoritmo probablemente se escribió para garantizar que el último fotograma del desvanecimiento fuera tan suave como los demás).

Ahora, esto me desconcierta. Según mis cálculos, si invierte el proceso, es decir, tome el ciclo 8,8,8,9 y lo sume para encontrar todas las combinaciones posibles en 29 cuadros, solo obtendrá 52 números únicos. Pero, como sucede, ¡cada componente de color es miembro de este conjunto! Esto significa que los colores se seleccionaron específicamente para este algoritmo de desvanecimiento (poco probable) o que el algoritmo de desvanecimiento se diseñó en torno a la paleta de colores del juego. Pero, ¿cómo podría alguien haber descubierto que si toma 8,8,8,9, cambia el ciclo apropiadamente y sigue restando los números de cada componente de color en su paleta, eventualmente llegará a 0 para cada color? ! Tiene que haber algún truco matemático que me estoy perdiendo. ¿Qué es?

Archagon
fuente
2
¿Por qué no solo jugar con el alfa? Así es como lo hago para las animaciones de fundido de entrada / salida.
DogDog
No estoy tratando de replicar el algoritmo en mi propio código, solo estoy tratando de descubrir cómo se derivó.
Archagon
Siento que es lo que dijiste, los colores se seleccionaron según la secuencia 8,8,8,9. Dada esa secuencia, pudieron elegir entre 52 * 52 * 52 colores. Una nota interesante, si comienza en 0 y agrega la secuencia 8,8,8,9, llegará a 255. Lo que les permite usar blanco y negro.
Luis Estrada
@Apoc: el estilo de desvanecimiento es visiblemente diferente del desvanecimiento alfa. ¿Ves cómo cada valor de color disminuye en un número fijo (patrón de números) en lugar de un porcentaje de su valor inicial? Esto significa que hay circunstancias en las que puede preferir usarlo en lugar de métodos más comunes. Estilo retro, por ejemplo.
AlbeyAmakiir

Respuestas:

20

En realidad, hay una lógica simple detrás del patrón 8-8-8-9. Surge de forma natural si usa solo 32 niveles de intensidad (5 bits por componente), pero desea representar eso en una pantalla de 8 bits por componente.

Considere si tiene un nivel de intensidad de 5 bits y desea extenderlo a 8 bits. Lo más simple sería simplemente desplazar a la izquierda y dejar los tres bits bajos en cero. El problema es que no llega al blanco puro. El nivel de intensidad más alto que puede alcanzar es 11111000, o 248. Por lo tanto, no está utilizando el rango de intensidad completo de la pantalla de 8 bits.

Realmente, lo que querría hacer es un cálculo intensity8 = round(intensity5 * 255.0 / 31.0), para reescalar el rango [0, 31] a [0, 255]. Sin embargo, hay un buen truco para lograr esto sin ninguna matemática de punto flotante o divisiones: establezca los tres bits bajos iguales a los tres bits altos. Es decir, para convertir la intensidad de 5 bits a 8 bits lo haría

intensity8 = (intensity5 << 3) | (intensity5 >> 2);

Luego, una intensidad de 11111 se asignará a 11111111 (31 a 255), y los resultados intermedios también harán algo sensato, por ejemplo, 10000 -> 10000100 (16 -> 132).

Este conjunto de números es exactamente lo que tienes. Tomando el componente rojo de su primer ejemplo, tiene:

132    10000100
123    01111011
115    01110011
107    01101011
 99    01100011
 90    01011010
 82    01010010
 74    01001010

Observe cómo los tres bits bajos siempre son iguales a los tres bits superiores. La diferencia de 9 ocurre cuando tanto el bit 0 como el bit 3 cambian al mismo tiempo.

No estoy seguro de por qué los niveles de intensidad de 5 bits se habrían utilizado en esta situación; ¿Tal vez ese era el límite del hardware de la máquina arcade? Es notable que un valor RGB de 5 bits sea de 15 bits, lo que encaja perfectamente en una palabra de 16 bits. En cualquier caso, eso explica el patrón impar 8-8-8-9.

Nathan Reed
fuente
1
16 bits por píxel se llamaba 'High Color'. (Eso es todo lo que recuerdo al respecto) en.wikipedia.org/wiki/High_color
tugs
1
Después de un rápido viaje a través de wikipedia, Sega Saturn ( en.wikipedia.org/wiki/Sega_Saturn#Video ) menciona el modo de visualización en color de 15 bits, así como GameBoy Advance ( en.wikipedia.org/wiki/Game_Boy_Advance )
tirones el
1
¡Eso es brillante! Todo tiene sentido ahora. ¡Gracias!
Archagon
El juego debe haber tenido color de 16 bits, y los artistas probablemente querían exprimir más color de su juego a expensas de la transparencia, dando un esquema de color RGBA 5551.
Archagon
0

Debería mirar en el modo 13h o desvanecimiento de paleta de 256 colores. En aquel entonces, tenías tantos colores y lo que hacías era jugar con toda la paleta, ya que no podías calcular nuevos colores que no estaban en ella.

Deleteman
fuente