プレイステーションのドゥームで炎がどのように実装されたか







ゲームエンジンブラックブックの章全体:DOOMはDOOMコンソールポートと開発者が直面した課題について説明しています。 3DOでの完全な失敗、アフィンテクスチャマッピングによる土星の問題点、スーパー任天堂向けにランディリンデンが作成した驚くべき「ゼロからのリバースエンジニアリング」について長い間話すことができます。



最初に大惨事[1]につながる方向に移動し、その後、プレイステーション1(PSX)のポートの開発者はコースを変更し、批評家と市場の間で成功したポートを作成することができました。 最終DOOMは、PCバージョンに匹敵する最初の真のポートでした。 アルファブレンディングを使用したカラーセクターでは、視覚的な品質が向上するだけでなく、目的の色のキーを示すことでゲームプレイも向上しました。 また、PSXコンソールのオーディオ処理ユニットのリバーブ効果により、サウンドが改善されました。



開発チームは非常に高品質な作業を行ったため、 イントロおよびゲームプレイでアニメーション化された炎を生成するために使用することにしたいくつかの空きCPUサイクルがまだ残っています。 これは私にa敬の念を抱かせたので、私はその効果がどのように実現されたかを理解することにしました。 最初の検索で答えが得られなかったとき、私は実行可能ファイルをクラックするためにMIPSブックからほこりを吹き飛ばす準備をしていましたが、サミュエル・ビジャレアルは、任天堂64のバージョンをすでにリバース開発したというTwitterに回答しました[2] 。 私はそれを少しきれいにし、単純化し、最適化するだけで十分でした。



この古典的なデモシーン効果を再発見するのは興味深いことでした。 その根底にある考え方は、90年代の多くの開発者の必須のプログラムセットに含まれていた最初の水の波紋に似ています。 火の効果は、慎重に選択されたカラーパレットと簡単なトリックの組み合わせが望ましい結果を達成する唯一の方法であった時代の生き証人になりました。



基本的な考え方






基本的に、火の効果は単純な標高マップを使用します。 画面サイズの配列には、0〜36の範囲の37個の値が入力されます。各値は白から黒の色に関連付けられ、それらの間の道路に沿って黄色、オレンジ、赤をキャプチャします。 アイデアは、上昇して徐々に冷却される炎の粒子の温度をシミュレートすることです。









フレームバッファは完全に黒で初期化され(ゼロで埋められます)、下部の白いピクセルの単一の白い線(36)が炎の「ソース」です。









画面が更新されるたびに、「熱」が上昇します。 フレームバッファの各ピクセルについて、新しい値が計算されます。 各ピクセルは、その直下にある値を考慮して更新されます。 コードでは、左下隅は配列のゼロインデックスであり、右上隅のインデックスはFIRE_HEIGHT * FIRE_WIDTH-1です。



function doFire() { for(x=0 ; x < FIRE_WIDTH; x++) { for (y = 1; y < FIRE_HEIGHT; y++) { spreadFire(y * FIRE_WIDTH + x); } } } function spreadFire(src) { firePixels[src - FIRE_WIDTH] = firePixels[src] - 1; }
      
      





行0は更新されないことに注意してください(yに対する反復は0ではなく1から始まります)。 このゼロで埋められた文字列は、火の「ジェネレータ」です。 線形冷却(-= 1)を使用した単純なバージョンでは、退屈な均一出力が得られます。









spreadFire()関数をわずかに変更し、発熱量の減衰率を変更できます。 ランダム性を追加するのが適切です。



  function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; firePixels[src - FIRE_WIDTH ] = pixel - (rand & 1); }
      
      







これはすでに優れています。 幻想を完璧にするために、上だけでなく左右にもランダムに分布させることができます。



  function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; var dst = src - rand + 1; firePixels[dst - FIRE_WIDTH ] = firePixels[src] - (rand & 1); }
      
      







[注 trans。:YouTubeは動画をひどくつまんでいます。 元の記事の Javascriptでデモを見るか、ネタバレの下でGIFを開く方が良いでしょう。]



GIF Flame Animation(23メガバイト)
画像






出来上がり! 火炎伝播プロセスを変更することにより、風もシミュレートできることに注意してください。 これは、記事を読むことに成功した読者のための演習として残しておきます。



完全なソースコード






Samuelのバージョンは (論理的に)アセンブラーバージョンのように見えました。 ご覧になりたい場合は、クリーンで簡素化されたバージョンがあります。



参照資料






[1]出典: Game Engine Black Book:DOOMに詳述されている詳細



[2]出典: 2018年3月25日のTwitter投稿。



All Articles