Fondu dans les jeux plus anciens. Besoin d'aide pour comprendre comment l'algorithme a été dérivé

12

Désolé, cette question est un peu ésotérique, mais je ne peux pas la sortir de ma tête!

Je regarde l'algorithme de fondu utilisé dans le jeu d'arcade DoDonPachi (ainsi que de nombreux autres jeux plus anciens):

entrez la description de l'image ici

J'ai écrit un script python pour sélectionner quelques pixels et les suivre pendant la durée du fondu. Voici un échantillon représentatif des résultats. La première ligne de chaque groupe est la valeur de couleur de départ, tandis que chaque ligne suivante est la différence entre la valeur de couleur de l'image actuelle et la valeur de couleur de l'image précédente.

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]

Comme vous pouvez le voir, un 8 ou un 9 est soustrait de chaque composante de couleur dans chaque image. En outre, un 9 apparaît toujours trois images après un 8, même si la valeur soustraite de départ est différente pour chaque composante de couleur. Notez également que chaque composante de couleur atteint 0 (c'est-à-dire, le noir) avec une différence de 8 ou 9, pas un reste arbitraire. Cela signifie que le cycle de valeur soustrait de 8,8,8,9 n'est jamais rompu! (Cet algorithme a probablement été écrit pour garantir que la dernière image du fondu était aussi fluide que les autres.)

Maintenant, cela me laisse perplexe. Selon mes calculs, si vous inversez le processus - c'est-à-dire, prenez le cycle 8,8,8,9 et résumez-le pour trouver toutes les combinaisons possibles dans 29 images - vous n'obtenez que 52 nombres uniques. Mais en l'occurrence, chaque composant de couleur fait partie de cet ensemble! Cela signifie que les couleurs ont été choisies spécifiquement pour cet algorithme de fondu (peu probable) ou que l'algorithme de fondu a été conçu autour de la palette de couleurs du jeu. Mais comment diable quelqu'un aurait-il pu comprendre que si vous prenez 8,8,8,9, changez le cycle de manière appropriée et continuez à soustraire les nombres de chaque composante de couleur de votre palette, vous finirez par atteindre 0 pour chaque couleur? ! Il doit y avoir une astuce mathématique qui me manque. Qu'Est-ce que c'est?

Archagon
la source
2
Pourquoi ne pas simplement jouer avec l'alpha? C'est comme ça que je fais pour les animations de fondu d'entrée / sortie.
DogDog
Je n'essaie pas de répliquer l'algorithme dans mon propre code, j'essaie simplement de comprendre comment il a été dérivé.
Archagon
J'ai l'impression que c'est ce que vous avez dit, les couleurs ont été choisies sur la base de la séquence 8,8,8,9. Compte tenu de cette séquence, ils ont pu choisir parmi 52 * 52 * 52 couleurs. Une note intéressante, si vous commencez à 0 et ajoutez la séquence 8,8,8,9 vous obtiendrez à 255. Ce qui leur permet d'utiliser du noir et blanc.
Luis Estrada
@Apoc: Le style du fondu sortant est visiblement différent du fondu alpha. Voyez comment chaque valeur de couleur descend par un nombre fixe (motif numérique) plutôt qu'un pourcentage de sa valeur initiale? Cela signifie qu'il existe des circonstances dans lesquelles vous préférerez peut-être l'utiliser plutôt que des méthodes plus courantes. Un style rétro, par exemple.
AlbeyAmakiir

Réponses:

20

En fait, il y a une logique simple derrière le modèle 8-8-8-9. Cela se produit naturellement si vous n'utilisez que 32 niveaux d'intensité (5 bits par composant), mais que vous souhaitez le rendre sur un affichage à 8 bits par composant.

Considérez si vous avez un niveau d'intensité de 5 bits et que vous souhaitez l'étendre à 8 bits. La chose la plus simple à faire serait de simplement décaler vers la gauche et de laisser les trois bits bas à zéro. Le problème, c'est que ça ne va pas jusqu'au blanc pur. Le niveau d'intensité le plus élevé que vous pouvez atteindre est 11111000, ou 248. Vous n'utilisez donc pas la plage d'intensité complète de l'affichage 8 bits.

Vraiment, ce que vous voudriez faire est un calcul comme intensity8 = round(intensity5 * 255.0 / 31.0), pour redimensionner la plage [0, 31] à [0, 255]. Cependant, il existe une astuce intéressante pour y parvenir sans aucune mathématique à virgule flottante ni division: définissez les trois bits inférieurs égaux aux trois bits supérieurs. Autrement dit, pour convertir l'intensité de 5 bits à 8 bits, vous feriez

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

Ensuite, une intensité de 11111 correspondra à 11111111 (31 correspond à 255), et les résultats intermédiaires feront également quelque chose de sensé, par exemple 10000 -> 10000100 (16 -> 132).

Cet ensemble de chiffres est exactement ce que vous avez. En prenant la composante rouge de votre premier exemple, vous avez:

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

Notez comment les trois bits inférieurs sont toujours égaux aux trois bits supérieurs. La différence de 9 se produit lorsque le bit 0 et le bit 3 basculent en même temps.

Je ne sais pas pourquoi des niveaux d'intensité de 5 bits auraient été utilisés dans cette situation; c'était peut-être la limite du matériel de la machine d'arcade? Il est à noter qu'une valeur RVB 5 bits est de 15 bits, ce qui convient parfaitement à un mot 16 bits. Dans tous les cas, cela explique l'étrange motif 8-8-8-9.

Nathan Reed
la source
1
16 bits par pixel étaient appelés «High Color». (C'est à peu près tout ce dont je me souviens) fr.wikipedia.org/wiki/High_color
remorqueurs
1
Après un rapide voyage sur wikipedia, Sega Saturn ( en.wikipedia.org/wiki/Sega_Saturn#Video ) mentionne le mode d'affichage couleur 15 bits, ainsi que GameBoy Advance ( en.wikipedia.org/wiki/Game_Boy_Advance )
remorqueurs
1
C'est brillant! Tout s'explique maintenant. Je vous remercie!
Archagon
Le jeu devait avoir une couleur 16 bits, et les artistes voulaient probablement extraire plus de couleur de leur jeu au détriment de la transparence, donnant un schéma de couleurs RGBA 5551.
Archagon
0

Vous devriez regarder dans le mode 13h ou la décoloration de la palette de 256 couleurs. À l'époque, vous aviez autant de couleurs et ce que vous faisiez était de jouer avec toute la palette, car vous ne pouviez pas calculer de nouvelles couleurs qui n'y étaient pas.

Deleteman
la source