古いゲームで衰退します。アルゴリズムがどのように導出されたかを理解するのに助けが必要


12

申し訳ありませんが、この質問は少し難解ですが、頭から出せないだけです!

アーケードゲームDoDonPachi(および他の多くの古いゲーム)で使用されているフェードアルゴリズムを見ています。

ここに画像の説明を入力してください

数個のピクセルを選択し、フェードの持続時間にわたって追跡するためのpythonスクリプトを作成しました。結果の代表的なサンプルを次に示します。各グループの最初の行は開始色値であり、後続の各行は現在のフレームの色値と前のフレームの色値の差です。

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]

ご覧のとおり、各フレームの各色成分から8または9が差し引かれます。さらに、最初の減算値は各色成分ごとに異なりますが、8の3フレーム後には常に9が表示されます。また、各色成分は8(または9)の差で0(つまり黒)に達し、任意の余りではないことに注意してください。これは、8、8、8、9の減算された値サイクルが壊れないことを意味します!(このアルゴリズムはおそらく、フェードの最後のフレームが他のフレームと同じくらい滑らかであることを保証するために書かれています。

今、これは私を困惑させます。私の計算によれば、プロセスを逆にすると、つまり8、8、8、9サイクルを取り、合計して29フレームで可能なすべての組み合わせを見つけると、52個の一意の数字しか得られません。しかし、そうなると、各色成分はこのセットのメンバーになります!これは、このフェードアルゴリズム専用に色が選択された(ほとんどない)か、フェードアルゴリズムがゲームのカラーパレットに基づいて設計されたことを意味します。しかし、一体8、8、8、9を取得し、サイクルを適切にシフトし、パレットの各色成分から数値を減算し続けると、最終的にすべての色が0になることを誰かが理解できたでしょうか? !私が見逃している数学的なトリックがあります。それは何ですか?


2
アルファ版を試してみませんか?これが、フェードイン/フェードアウトアニメーションの方法です。
DogDog

私は自分のコードでアルゴリズムを複製しようとはせず、それがどのように導出されたかを理解しようとしています。
アルカゴン

色は、8、8、8、9のシーケンスに基づいて選択されたものだと思います。そのシーケンスを考えると、52 * 52 * 52色から選択できました。興味深い注意点として、0から始めてシーケンス8,8,8,9を追加すると、255になります。これにより、白黒を使用できるようになります。
ルイスエストラダ

@Apoc:フェードアウトのスタイルは、アルファフェードとは明らかに異なります。各色の値が、初期値の割合ではなく、固定された数字(数字のパターン)によってどのように低下​​するかを確認しますか?これは、より一般的な方法よりも使用したい状況があることを意味します。たとえば、レトロなスタイル。
-AlbeyAmakiir

回答:


20

実際、8-8-8-9パターンの背後には単純なロジックがあります。32の強度レベル(コンポーネントごとに5ビット)のみを使用しているが、コンポーネントごとに8ビットのディスプレイでレンダリングしたい場合に自然に発生します。

5ビットの強度レベルがあり、それを8ビットに拡張するかどうかを検討してください。最も簡単なことは、左にシフトして下位3ビットをゼロのままにすることです。問題は、それが真っ白にならないことです。到達できる最高の強度レベルは11111000または248です。したがって、8ビットディスプレイの強度範囲全体を使用しているわけではありません。

本当にしたいのはintensity8 = round(intensity5 * 255.0 / 31.0)、[0、31]の範囲を[0、255]に再スケーリングするための計算です。ただし、浮動小数点演算や除算を行わずにこれを実現するには、下位3ビットを上位3ビットに等しく設定するという巧妙なトリックがあります。つまり、強度を5ビットから8ビットに変換するには

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

次に、強度11111が11111111にマッピングされ(31が255にマッピング)、中間結果も同様に正常に処理されます(例:10000-> 10000100(16-> 132))。

この数字のセットは、まさにあなたが持っているものです。最初の例の赤いコンポーネントを使用すると、次のことができます。

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

下位3ビットが常に上位3ビットに等しいことに注意してください。ビット0とビット3の両方が同時に反転すると、9の違いが発生します。

この状況で5ビット強度レベルが使用された理由は不明です。おそらくそれがアーケードマシンのハードウェアの限界だったのでしょうか?5ビットRGB値が15ビットであり、16ビットワードにうまく適合することは注目に値します。いずれにせよ、それは奇妙な8-8-8-9パターンを説明しています。


1
16ビット/ピクセルは「ハイカラー」と呼ばれていました。(それは私がそれについて覚えているすべてについてです)en.wikipedia.org/wiki/High_color-
タグ

1
ウィキペディア、セガサターン( en.wikipedia.org/wiki/Sega_Saturn#Videoが)15ビットカラー表示モードと同様に、ゲームボーイアドバンス(言及en.wikipedia.org/wiki/Game_Boy_Advanceを
タグボート

1
そりゃ素晴らしい!今ではすべてが理にかなっています。ありがとうございました!
アルカゴン

ゲームは16ビットカラーである必要があり、アーティストはおそらく、RGBA 5551カラースキームを使用して、透明性を犠牲にしてゲームからより多くのカラーを絞り出したいと考えていました。
アルカゴン

0

モード13h、つまり256色パレットのフェードを確認する必要があります。当時、あなたはそれだけ多くの色を持っていて、あなたがやったことはパレット全体をいじっていました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.