世界を動かす技術を、日本語で。

ボクセルスペース (2017)

概要

  • Voxel Spaceエンジン は、1992年に登場した革新的なレンダリング技術
  • Comanche などのゲームで、当時としては非常に高精細な地形表現を実現
  • 高さマップカラーマップ を利用し、シンプルなアルゴリズムで高速描画
  • パフォーマンス向上 のための工夫や回転処理も実装可能
  • MITライセンス で公開されているが、一部データは除外

Voxel Spaceエンジンの歴史と特徴

  • 1992年当時、 CPU性能は現在の1000分の1、GPU加速は一般的でなかった時代背景
  • 3Dゲームは全てCPUで計算され、 単色ポリゴン描画 が主流
  • 1992年、NovaLogicが Comanche をリリースし、圧倒的なグラフィック表現で話題に
  • 山や谷に テクスチャシャドウ を初めて表現し、他のゲームより3年先を行く技術
  • 全体的に ピクセル化 されているが、当時のゲームの標準的表現

Voxel Spaceのレンダリングアルゴリズム

  • Voxel Space は、レイキャスティングに基づく 2.5Dエンジン
  • 通常の3Dエンジンのような自由度はないが、高速かつ美しい地形描写が可能
  • 地形表現は 高さマップ(height map)カラーマップ(color map) で実現
    • 1024×1024バイトの高さマップとカラーマップを使用
    • 各座標ごとに1つの高さのみ表現でき、建物や木などの複雑な形状は不可
    • カラーマップには既に 陰影や影 が含まれており、描画時の照明計算が不要

基本的な描画手法

  • 描画は 後方から前方へ 順に行い、 ペインターズアルゴリズム を採用
  • 視野角や遠近法を考慮し、地図上のラインをスクリーンの列数に合わせてラスタライズ
  • 2Dマップから高さと色を取得し、 縦線(vertical line) として描画
  • コアアルゴリズムは 数行のコード で実装可能(Python例あり)

視点回転の実装

  • 上記アルゴリズムでは北方向のみ描画可能
  • sin/cos を使い、座標を回転させることで任意の角度からの視点を実現
  • 回転後も同様に高さと色を取得し、縦線で描画

パフォーマンス向上の工夫

  • 前方から後方へ 描画することで、不要な描画を省略可能
    • 各列ごとに yバッファ を持ち、既に描画した最も高い位置を記録
    • 新しい線が見えるのは、直前の線より高い場合のみ
  • レベル・オブ・ディテール(LOD) :近景は詳細に、遠景は粗く描画
  • コード例では、描画距離が遠くなるほどステップサイズを大きくし、効率化

データとライセンス

  • ソフトウェア部分は MITライセンス で公開
  • カラーマップ・高さマップは Comanche からリバースエンジニアリングされたもので、ライセンス対象外
  • 一部国では Voxel Space技術 に特許が残っている可能性あり

参考リンク・リソース

  • Webプロジェクトデモページ
  • Voxel terrain engine入門記事
  • パーソナルウェブサイト
  • カラーマップ・高さマップ各種
  • 詳細はリポジトリのライセンスファイルを参照

このように、 Voxel Spaceエンジン はシンプルなアルゴリズムと高度な工夫で、当時の技術水準を大きく超える表現力を実現した歴史的なゲームエンジンです。

Hackerたちの意見

カラーマップに影が「組み込まれてる」みたいで、カラーマップを見るだけで3Dのベベル効果が得られるのが面白いね。

これが最初に投稿されたとき、AGSエンジンにこのアプローチを移植してゲームを作ったんだ。今はAGSがかなり速くなったけど、当時はそうじゃなかったから、レンダリングがうまくいくようにちょっとした工夫が必要だったよ。 https://github.com/ericoporto/i_rented_a_boat

技術的には、これはボクセル(「ボリュメトリックピクセル」って言うやつ)とは関係ないんだ。ボクセルは3D空間を3つの軸で均等に分けるけど、これは単なるハイトマップで、プリズムのセットなんだ。ドゥームマップに似てるかも。すべてのプリズムは規則的な固定サイズの四角いベースを持ってる。1992年当時は、これがすごく衝撃的だったけどね。

え、そうなの?ハイトマップの各ピクセルは指定された高さのボクセルの列に対応してるよ。同じ高さデータを完全なオクツリーで表現しても、全く同じに見えるはず。

ルイ・キャッスルはウェストウッドスタジオの1997年の「ブレードランナー」のために「ボクセルプラス」ソフトウェアレンダラーを開発したんだ。キャラクターアニメーションに「ボクセル」(引用符付き)を使って、地形だけじゃなくてね。 https://en.wikipedia.org/wiki/Blade_Runner_(1997_video_game) https://news.ycombinator.com/item?id=17171287

ブレードランナーは実際にはボクセルを使ってなかった。彼らは「スライスアニメーション」と呼ばれるかなりユニークな技術を使ってた。3Dモデルは下から上に数百のスライスに切り分けられて、水平面と交差させて得られたポリゴンを保存していた。エンジンはモデルを垂直軸の周りだけ回転させることができた。ずっと前にそのレンダラーのハッキーなJavaScriptバージョンを作ったことがあるよ: http://thomas.fach-pedersen.net/bladerunner/mccoy_anim_13_fr...

EDIT: ScummVM用の進行中のブレードランナーエンジンも宣伝しておくね: https://github.com/scummvm/scummvm/tree/master/engines/blade...

digi_owl 2018年5月28日 | prev [–] https://en.wikipedia.org/wiki/Blade_Runner_%281997_video_gam... ゲームを開発した人たちはそれをボクセルベースだと考えているみたいだね。

madmoose 2018年5月28日 | parent | next [–] 君がリンクしたページではルイ・キャッスルがこう言ってるよ:

「私たちが使っているのはボクセルではなく、いわば『ボクセルプラス』です。」だから「ボクセルではない」ってことだね。ルイ・キャッスルはインタビューであまり技術的になりたくなかったから、ボクセルっぽいって呼んだのかもしれない。彼らの技術はプレスでは詳しく説明されていないけど、 http://deadendthrills.com/future-imperfect-the-lost-art-of-w... という記事では「スライスモデル」技術と呼ばれている。ボクセルの専門家ではないけど、ブレードランナーのレンダリングエンジンのほとんどを逆アセンブルして再実装した私の意見では、ボクセルとは言えないと思う。一つには、モデルを垂直以外の軸で回転させることはできないから。

LouisCastle 2018年5月28日 | root | parent | next [–] 楽しいね!私たちはデータをスライスとして保存して、Y軸に回転を制限してたんだ。どちらも最適化で、アニメーションの各フレームは完全なモデルだったから、回転させる必要がなかった。レンダラーはどの角度からでもそれをレンダリングできたから、私はそれをボクセルだと考えてる。ボクセルのライト版みたいな感じかな。スプライトカードもたくさん使って、ライティングのためにクイックなノーマルハックもしてた。あの頃はできるところで手を抜かないといけなかったからね!

madmoose 2018年5月28日 | root | parent | next [–] こんにちは、ルイ!君がどうやってやったのかを理解するのは本当に楽しかったよ。ありがとう、何と呼んでもいいけどね :) 確かに、たくさんの技術を一つのエンジンに詰め込んだね!フルスクリーンの15BPPビデオにフルZバッファー、上に小さなアルファチャンネル付きのビデオをレンダリングして、キャラクターモデルにはライティングもあった。UIですらループするビデオだったよ。ちゃんとしたパスファインディングが動くようになったら、ScummVMエンジンでブレードランナーがもっと遊びやすくなると思う。作業中にゲームのオープニングシーンを千回は見返したかも…君がゲームコードにスクリプト言語を使ってくれてたらよかったのに。DLLにコンパイルする代わりにね。スピードのためにかなり最適化したのは分かるけど、私たちの作業がずっと楽になったと思うよ :)

DonHopkins 2018年5月28日 | root | parent | prev | next [–] だからデッカード対プリスのシーンを入れなかったのか!彼女がX軸の周りを回転するシーンね! ;)

pjtr 2018年5月28日 | root | parent | prev | next [–] 確かに楽しい!アーティストたちが元のモデルをどうやって作成したのか話してくれる?標準のポリゴンモデルからの自動変換だったのか、それとも完全なボクセルモデルからだったのか?それとも、特別なスライス形式で直接描かれたのかな?

madmoose 2018年5月28日 | root | parent | next [–] ルイではないけど、上でリンクした記事によると、彼らは3D Studio Maxを使ってスライスモデル形式に変換したみたいだよ。

この高さマップには垂直要素が含まれてるよ。

2992年にちゃんとしたPCでプレイしたときは衝撃的だった。

それでも、その頃はボクセルレンダリングって呼ばれてたんだよね。技術的には正しくないけど、見た目もかっこよかったし、響きもクールだった!

以前の議論(2017年): https://news.ycombinator.com/item?id=15772065

これって「マジックカーペット」(1994年)で使われたのと同じアルゴリズム?スタイルがすごく馴染みがあって、どうやって実現したのかずっと気になってたんだ。 https://en.wikipedia.org/wiki/Magic_Carpet_(video_game)

このゲームは元々「ボクセル」エンジンを使ってたけど、最終リリースではアファインテクスチャマッピングに切り替えたんだ(高さマップベースの地形はそのまま)。ボクセルスタイルのエンジンは描画距離が長くなる傾向があるんだよね(遠くのテクスチャアクセスを半分にするためのハックが簡単に使えるから、レンダリングが安く済む)。Magic Carpetのレンダリングについて詳しく知りたいなら、[2]のスライド8から始めてみて。 [1]: https://tcrf.net/Prerelease:Magic_Carpet_(DOS)#1993 [2]: https://web.archive.org/web/20180330004301/http://www.glennc...

余談だけど、このゲームの最初の課題は「オイルタンクホリデー」って呼ばれてる:無防備なオイルタンクにヘリを飛ばして、撃って燃えるのを見て、それから帰る。敵はいない。ただ飛ぶことと撃つことを学ぶだけ。これをコードのテストに応用してるんだ。コードを書いたら、クラッシュせずに何かをすることを証明するための絶対的に最小限のテストを考えてみて。これが私の「オイルタンクホリデー」テスト。失敗するのを見るのはいつも謙虚な気持ちになるよ。

聞いたところによると、スモークテストの煙はオイルタンクから出てるらしい!

このゲームのC++版で、元のComancheマップとレンダリングアルゴリズムをそのまま使ってるやつ: https://codeberg.org/Lew_Palm/voxelcopter

懐かしいな。Comancheは出たときすごかったよ、(確か)うちの家族の386SX-16で動いてたし。Visual Basicでその効果を再現しようとしたけど、当時はあまり成功しなかったな。

自分のデモの一つでこのアプローチを使ったよ: https://www.youtube.com/watch?v=xjbDxvboOjo。プロットツイスト: ハイマップは動的に生成されるんだ。