Blendet ältere Spiele ein. Brauchen Sie Hilfe, um herauszufinden, wie der Algorithmus abgeleitet wurde

12

Entschuldigung, diese Frage ist ein bisschen esoterisch, aber ich kann es einfach nicht aus meinem Kopf bekommen!

Ich schaue mir den Fade-Algorithmus an, der im Arcade-Spiel DoDonPachi (sowie in vielen anderen älteren Spielen) verwendet wird:

Bildbeschreibung hier eingeben

Ich habe ein Python-Skript geschrieben, um einige Pixel auszuwählen und sie für die Dauer der Überblendung zu verfolgen. Hier ist eine repräsentative Auswahl der Ergebnisse. Die erste Zeile jeder Gruppe ist der Startfarbwert, während jede nachfolgende Zeile die Differenz zwischen dem Farbwert des aktuellen Bilds und dem Farbwert des vorherigen Bilds ist.

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]

Wie Sie sehen können, wird von jeder Farbkomponente in jedem Bild entweder eine 8 oder eine 9 subtrahiert. Außerdem erscheint eine 9 immer drei Frames nach einer 8, obwohl der subtrahierte Startwert für jede Farbkomponente unterschiedlich ist. Beachten Sie auch, dass jede Farbkomponente 0 (dh schwarz) mit einer Differenz von entweder 8 oder 9 erreicht, nicht mit einem willkürlichen Rest. Dies bedeutet, dass der subtrahierte Wertezyklus von 8,8,8,9 niemals unterbrochen wird! (Dieser Algorithmus wurde wahrscheinlich geschrieben, um sicherzustellen, dass der letzte Frame der Überblendung so flüssig wie die anderen war.)

Das verwirrt mich. Nach meinen Berechnungen erhalten Sie nur 52 eindeutige Zahlen, wenn Sie den Vorgang umkehren, dh den Zyklus 8,8,8,9 nehmen und zusammenfassen, um alle möglichen Kombinationen in 29 Bildern zu finden. Aber wie es so ist, ist jede Farbkomponente ein Mitglied dieses Sets! Dies bedeutet, dass entweder die Farben speziell für diesen Überblendungsalgorithmus ausgewählt wurden (unwahrscheinlich) oder dass der Überblendungsalgorithmus entsprechend der Farbpalette des Spiels entworfen wurde. Aber wie um alles in der Welt hätte jemand herausfinden können, dass Sie, wenn Sie 8,8,8,9 nehmen, den Zyklus entsprechend verschieben und die Zahlen von jeder Farbkomponente in Ihrer Palette subtrahieren, schließlich für jede einzelne Farbe 0 erreichen? ! Es muss einen mathematischen Trick geben, den ich vermisse. Was ist es?

Archagon
quelle
2
Warum nicht einfach mit dem Alpha spielen? So kann ich Animationen ein- und ausblenden.
DogDog
Ich versuche nicht, den Algorithmus in meinem eigenen Code zu replizieren, sondern nur herauszufinden, wie er abgeleitet wurde.
Archagon
Ich glaube, es ist das, was du gesagt hast, die Farben wurden basierend auf der Sequenz 8,8,8,9 ausgewählt. In dieser Reihenfolge konnten sie aus 52 * 52 * 52 Farben wählen. Ein interessanter Hinweis: Wenn Sie bei 0 beginnen und die Sequenz 8,8,8,9 hinzufügen, erhalten Sie 255. Dadurch können sie Schwarzweiß verwenden.
Luis Estrada
@Apoc: Der Stil des Ausblendens unterscheidet sich sichtbar vom Alpha-Fade. Sehen Sie, wie jeder Farbwert um eine feste Zahl (Zahlenmuster) und nicht um einen Prozentsatz seines Anfangswerts verringert wird? Dies bedeutet, dass es Umstände gibt, unter denen Sie es möglicherweise vorziehen, es gegenüber allgemeineren Methoden zu verwenden. Zum Beispiel im Retro-Stil.
AlbeyAmakiir

Antworten:

20

Eigentlich steckt hinter dem 8-8-8-9-Muster eine einfache Logik. Dies ist natürlich der Fall, wenn Sie nur 32 Intensitätsstufen (5 Bit pro Komponente) verwenden, diese jedoch auf einer 8-Bit-Anzeige pro Komponente rendern möchten.

Überlegen Sie, ob Sie eine 5-Bit-Intensitätsstufe haben und diese auf 8 Bit erweitern möchten. Am einfachsten wäre es, einfach nach links zu schieben und die niedrigen drei Bits auf Null zu belassen. Das Problem ist, dass es dann nicht bis zu reinem Weiß geht. Die höchste Intensität, die Sie erreichen können, ist 11111000 oder 248. Sie nutzen also nicht den gesamten Intensitätsbereich der 8-Bit-Anzeige.

In Wirklichkeit möchten Sie eine Berechnung durchführen intensity8 = round(intensity5 * 255.0 / 31.0), um den Bereich [0, 31] auf [0, 255] zu skalieren. Es gibt jedoch einen tollen Trick, um dies ohne Gleitkomma-Mathematik oder Dividieren zu erreichen: Setzen Sie die niedrigen drei Bits gleich den hohen drei Bits. Das heißt, Sie konvertieren die Intensität von 5-Bit auf 8-Bit

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

Dann wird eine Intensität von 11111 auf 11111111 (31 auf 255) abgebildet, und Zwischenergebnisse führen ebenfalls zu etwas Vernünftigem, z. B. 10000 -> 10000100 (16 -> 132).

Diese Zahlenreihe ist genau das, was Sie haben. Nehmen Sie die rote Komponente Ihres ersten Beispiels, so haben Sie:

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

Beachten Sie, dass die unteren drei Bits immer den oberen drei Bits entsprechen. Die Differenz von 9 tritt auf, wenn sowohl Bit 0 als auch Bit 3 gleichzeitig kippen.

Ich bin mir nicht sicher, warum in dieser Situation 5-Bit-Intensitätsstufen verwendet worden wären. Vielleicht war das die Grenze der Hardware des Arcade-Automaten? Es ist bemerkenswert, dass ein 5-Bit-RGB-Wert 15 Bit beträgt, was gut in ein 16-Bit-Wort passt. Dies erklärt auf jeden Fall das ungerade 8-8-8-9-Muster.

Nathan Reed
quelle
1
16 Bit pro Pixel wurden als "High Color" bezeichnet. (Das ist alles , was ich über sie erinnern) en.wikipedia.org/wiki/High_color
zerrt
1
Nach einer kurzen Reise durch Wikipedia erwähnt Sega Saturn ( en.wikipedia.org/wiki/Sega_Saturn#Video ) den 15-Bit-Farbanzeigemodus sowie GameBoy Advance ( en.wikipedia.org/wiki/Game_Boy_Advance )
tugs
1
Das ist hervorragend! Es macht jetzt alles Sinn. Vielen Dank!
Archagon
Das Spiel muss 16-Bit-Farben enthalten haben, und die Künstler wollten wahrscheinlich auf Kosten der Transparenz mehr Farbe aus ihrem Spiel herausholen, um ein RGBA 5551-Farbschema zu erhalten.
Archagon
0

Sie sollten sich den Modus 13h oder das Ausblenden der 256-Farben-Palette ansehen. Damals hatten Sie so viele Farben und was Sie getan haben, hat die gesamte Palette durcheinander gebracht, da Sie keine neuen Farben berechnen konnten, die nicht darin enthalten waren.

Deleteman
quelle