4 ポイント 投稿者 GN⁺ 2025-01-05 | 1件のコメント | WhatsAppで共有
  • Voxel Spaceは、1992年のNovaLogicのComancheで使われた2.5D地形レンダリング手法で、GPUアクセラレーションが存在しないか高価だった時代に、CPUだけで質感のある山や谷を表現した
  • 地形はハイトマップカラーマップで表現され、Comancheでは1024×1024の1バイトハイトマップと1024×1024の1バイトカラーマップを使用した
  • カラーマップにはすでに陰影と影が含まれているため、レンダリング中にライティング計算は不要だが、マップ上の各位置は1つの高さしか持てないため、建物や木のような複雑なジオメトリ構造は表現しにくい
  • 基本レンダリングは、奥から手前へマップの線分をラスタライズし、各画面列ごとに高さと色を読み取って垂直線を描く方式で、視野角90°と透視投影を数行のコードで実装している
  • 性能改善は、手前から奥へ描画しながら列ごとのy-bufferで隠れた部分をスキップし、遠距離では詳細度を下げる方式で可能になる

Voxel Spaceが登場した背景

  • 1992年当時のCPUは現在より1000倍遅く、GPUアクセラレーションは知られていないか導入が難しかった
  • 3DゲームはCPUだけで計算され、レンダリングエンジンは単色で塗りつぶしたポリゴンを描く方式が一般的だった
  • NovaLogicは1992年にComancheを発売し、山や谷のテクスチャ、陰影、影の表現は当時のゲームグラフィックの中で際立っていた
  • READMEではWeb Demo of the Voxel Space Engineを提供している

地形表現: ハイトマップとカラーマップ

  • Voxel Spaceで地形を表現する最も簡単な方法は、height mapcolor mapを使うことだ
  • Comancheは次の2つのマップを使っている
    • 1024×1024の1バイトハイトマップ
    • 1024×1024の1バイトカラーマップ
  • これらのマップは周期的に繰り返される形になっている
  • 各マップ位置は1つの高さしか持てない
    • 建物や木のような複雑なジオメトリ構造は表現できない
    • その代わり、カラーマップにすでに陰影と影が含まれているため、レンダリング過程でライティングを計算しなくてよい

基本レンダリングアルゴリズム

  • Voxel Spaceエンジンは、ハイトマップとカラーマップをラスタライズし、画面に垂直線を描く方式で地形をレンダリングする
  • 基本手順は次の通り
    • 画面をクリアする
    • オクルージョン処理を保証するために奥から手前へ描く
    • 観測者から同じ光学的距離にあるマップ上の線を見つける
    • 視野角と透視投影を考慮する
    • その線を画面列数に合わせて分割する
    • 各線分位置で高さと色を2Dマップから読み取る
    • 高さ座標に透視投影を適用する
    • 投影された高さとカラーマップの色で垂直線を描く
  • 最も単純なPython形式のコアループは、zを遠距離から近距離へ減らしながら、画面列ごとにDrawVerticalLineを呼び出す
  • 呼び出し例では、位置、カメラ高さ、水平線位置、高さスケール、最大距離、画面の幅と高さを渡す

回転の追加

  • 基本アルゴリズムでは北方向しか見られない
  • 別の方向を見るには、座標を回転するためのコードを追加する
  • 回転版ではphiを視野角として受け取り、sin(phi)cos(phi)を事前計算する
  • 左右の視界境界点の計算に回転後の座標を適用し、各画面列に沿ってxyを一緒に増加させる
  • レンダリングの中核構造は同じまま維持される
    • 距離ごとの線分計算
    • 画面列に合わせたラスタライズ
    • ハイトマップとカラーマップの参照
    • 透視投影後に垂直線を描画

性能改善の方法

  • 奥から手前へ描く代わりに手前から奥へ描けば、隠れる領域を減らせる
  • この方式では、各画面列ごとに最も高いy位置を保存するy-bufferが必要になる
    • 初期y-buffer値は画面の高さに設定する
    • 新たに計算したheight_on_screenが既存のy-bufferより上にあるときだけ、見える部分を描く
    • 描画後、y-bufferをより高い位置に更新する
  • 距離zは近い場所から遠い場所へ増加する
  • dzを徐々に大きくすると、遠距離ではより大きな間隔でサンプリングでき、Level of Detail効果が得られる
  • 近距離はより詳細に、遠距離はより粗くレンダリングする方式だ

提供資料とライセンス

  • リポジトリには複数のカラーマップハイトマップの組が含まれている
  • ソフトウェア部分はMITライセンス
  • Voxel Space技術は、一部の国ではまだ特許が残っている可能性がある
  • カラーマップとハイトマップはComancheゲームからリバースエンジニアリングされた資料のため、ライセンス対象外となっている
  • 関連資料として、Voxel terrain engine - an introductionへのリンクが提供されている

1件のコメント

 
GN⁺ 2025-01-05
Hacker Newsの意見
  • すごく素晴らしい。こういう新しくてエレガントなアルゴリズムが魔法のような体験を生み出してくれた時代が懐かしい
    年を取ったからそう感じるのかもしれないけれど、ハードウェア資源が限られていた時代のゲームには、今よりも大きな魔法があった気がする。80年代、90年代、2000年代初頭には、ほぼ毎年、少なくとも世代ごとにゲームがメディアそのものを前へ押し進め、開発者たちは新しい手法と純粋に魔法のような最適化でハードウェア性能を限界まで絞り出していた
    最近はAAAスタジオの反復的な新作よりも、PICO-8のようなファンタジーコンソールのほうがずっと面白いし、実質的にアセットを差し替えただけのゲームが毎年あれほど成功する理由がよく分からない

    • 現代のAAAゲームにも、今なお魔法のような技術はたくさん入っている。実際、ゲーム業界は性能を真剣に気にする数少ない分野で、ときには安全性や正確性より性能を重視することさえある
      ただ、今ははるかに複雑で、目立ちにくいだけ。昔は賢い数学トリックによって、平たい三角形からテクスチャへと進化する様子が見えたとすれば、今は部屋の隅の陰影をより良くするような進歩になっている。テクスチャの改善は誰でもすぐ気づくが、隅の影は業界の人でなければ明確には指摘しにくい。それでもこうした要素が積み重なって全体のグラフィックを良くしているものの、昔ほど印象的ではない
      AAAゲーム業界は大きなビジネスで、ゲーム制作費は莫大であり、投資家は利益を求める。そのため通常は市場を調査し、売れているものを見て、それに近い方向で作る。独創性は下がってもリスクは低くなる
      逆にインディーゲーム業界には何千ものスタジオがあり、コンテンツ量や完成度でAAAに勝てないので、群れから抜け出すために独創的なアイデアのような別の武器が必要になる。ただし今では、技術的制約を克服することが主な原動力ではない場合が多い。制約が昔ほど多くないからだ。むしろコスト的に手が届かないため、AAA作品ほど技術的に攻めないことがよくある
      PICO-8のシーンはよく知らないが、そのうちどれほどが人工的な技術制約を克服することにあり、どれほどがプラットフォームを意図された形で使い、ゲームプレイに集中することにあるのかは気になる
    • これはほとんど、バラ色の1/4インチ溶接ゴーグルを通した回想に近いと思う。現代のAAAゲームにも気が遠くなるほど素晴らしい瞬間はあるし、反復続編病もある一方で独創的な作品もあり、技術が明らかにそれを可能にしている
      昔にも本当に、本当に、本当にひどいゲームがたくさんあったことも覚えている
    • このアルゴリズムで電卓上に3D Mario Kartを作っていた。その電卓は普通の2Dグラフィックもかろうじて処理する程度だったのでかなり面白かったが、結局完成はしなかった
      プロトタイプの一つはこれ: https://youtu.be/9Z8Bm8ZmWKI
    • このアルゴリズムで電卓上に3D Mario Kartを作っていた。その電卓は普通の2Dグラフィックもかろうじて処理する程度だったのでかなり面白かったが、結局完成はしなかった
      プロトタイプの一つはこれ: https://media.discordapp.net/attachments/953383695908216843/...
    • ゲーム技術には今でも素晴らしいイノベーションがたくさんある。Noita、Dreams、Teardownのようなゲームを見ればいいし、さらに最近のゲームならTiny Gladeもある
      Tiny Gladeの最近の技術発表には魔法のような内容が詰まっている: https://youtu.be/jusWW2pPnA0?si=IE-6W0Z1VCBld0AT
      より基礎的なレベルのエンジンやフレームワークでも素晴らしい技術が出てきている。たとえばUE5のNanite/Lumen/MegaLightsがある
  • 関連リンク。ほかにもあるだろうか?
    VoxelSpace – Terrain rendering algorithm in less than 20 lines of code - https://news.ycombinator.com/item?id=38051859 - 2023年10月、コメント2件
    Voxel Space: Comanche's terrain rendering in less than 20 lines of code (2020) - https://news.ycombinator.com/item?id=26631995 - 2021年3月、コメント71件
    Terrain rendering algorithm in less than 20 lines of code - https://news.ycombinator.com/item?id=21944573 - 2020年1月、コメント116件
    Terrain rendering in fewer than 20 lines of code - https://news.ycombinator.com/item?id=15772065 - 2017年11月、コメント93件
    Show HN: Voxel Space – terrain rendering in less than 20 lines of code - https://news.ycombinator.com/item?id=15339016 - 2017年9月、コメント2件

  • mars.comをすぐに思い出した。ドメインではなくプログラムのほう。動画: https://www.youtube.com/watch?v=_zSjpIyMt0k
    追記: Pouetにもある: https://www.pouet.net/prod.php?which=4662

    • このデモのJavaScript実装も見つけた: http://web.archive.org/web/20140107070635/http://ppl-pilot.c...
    • 昔の記憶が一気によみがえった。1998年ごろ自分のところに回ってきたときは、Microsoft Wordファイルの中に入っていて、マウスで操作できた
      当時はかっこいいと思ったけれど、デモシーンやプログラミングをまったく知らない子どもだったので、完全なゲームではないことにがっかりした。振り返ると、メールで出回っていたしょぼいDirectXデモくらいにしか思っていなかったが、実在していたものだとは知らなかった
    • 正確に言うと、mars.comは8MHzの286でも滑らかに動いた
    • つらい。286で動かして圧倒された記憶がある。同時に、同じマシンでWing Commander 3が動かなくてがっかりもした
  • レンダリング方式はきれいだが、これをボクセルと呼べるのかは分からない。任意の体積をレンダリングできないし、データの保存方式も、与えられたx,yに対して位置を1つしか持てない
    単にハイトマップレンダラの見事な実装ではないのか?

    • 間違いなくボクセルエンジンと見なしてよいと思う。ハイトマップはオクトリーのように張り出し部分をサポートしないが、結局のところ高さはボクセルのスタックだ
      張り出しのないオクトリーは、これとまったく同じ形になるはず
    • 自分の理解では、ボクセルはvolume element(体積要素)のような意味だ。ピクセルがpicture elementに由来するのと似ていて、xは見栄えのための文字に近いと思う
      このレンダリング方式では各列が3Dの箱なので、2x2ボクセル行列と呼んでも特に問題ないと思う
    • こういうハイトマップレンダラは当時、確かに「voxel」と呼ばれていた
    • その通りで、このアルゴリズムに付けられた名前は誤解を招く
  • 1990年代に高校で必要な三角法を学びながら、こうした地形ビューアを作っていた記憶は本当に良いものだ。最初はPascalで、その次はCとAssemblyで作った
    当時は動かすために、ありとあらゆる低レベル最適化が必要だった
    参考にできる本やインターネットなしで実装方法を突き止め、最適化したことは、個人的に最もやりがいのあったことの一つだ

  • この手法でゲームを作った: https://eri0o.itch.io/i-rented-a-boat
    Adventure Game Studioで作ったもので、まだ最適化していなかった以前のバージョンのエンジンで制作した。itchページを更新するのが面倒でそのままにしているが、いつかはやるつもりだ
    そこにどう作ったかを書いてあり、AGSフォーラムにはさらに詳しい内容がある

    • AGSでこれが可能だとは印象的だ
  • タイトルに**[2020]**を入れてもよさそうで、下の議論リンクの他のコメントを見ると[2017]でもよさそうだ
    同じリポジトリについての2021年の議論もあった: https://news.ycombinator.com/item?id=26631995
    そのスレッドからも別の議論へリンクが続いている
    まったく同じではないが、プログラミングを学び始めたころ、地形のハイトマップを生成し、似た手法でアイソメトリック風のレンダリングをするプログラムを書いた記憶がある。QBasicで作り、中学校にあった386時代のDOSマシンで動かし、グラフィックメモリを一時作業領域として使っていた
    とてつもなく遅かったが、出力結果に魅了され、プログラミングを続けるきっかけの一つになった

  • 以前どこかでこれを読んだ記憶があるが、今回は失くさないようにコメントを残しておく
    フライトシミュレータのファンとして、Comancheを初めてプレイしたときの衝撃は今でも覚えている。未来か映画から来たもののようで、本当にコンピュータの時代に生きているのだと感じた

    • Novalogicはこの手法を地形レンダリングにかなり長く使っていて、私が一番好きなのはDelta Forceの第一作だ
      Comanche 4とオリジナルのBlack Hawk Downでは、この方式をやめてポリゴンエンジンへ移行したようだ: https://en.wikipedia.org/wiki/Comanche_4#Reception
    • Comancheを覚えている。8ビットAtariでRescue on Fractalus[0]、発売前の名前でBehind Jaggi Linesの手続き生成に感嘆したときのことを思い出した
      [0] https://www.youtube.com/watch?v=FbZ-chrOgGg 地球への着陸シーンは1:00に出てくる
  • 本当にすごい
    現代のゲームの多くでは、変なカメラアングルやクリッピングの問題で、山が中空構造だとたまに見えてしまう
    しかしこの方式では、山はしっかり詰まっている >:)

  • こういうソフトウェアレンダラを趣味で作ってみることを強くおすすめする。レイトレーサはよくあるプロジェクトだが、こうしたレトロ風のリアルタイムレンダリングコードも週末プロジェクトに向いている
    かなり昔に、ほぼ同じアルゴリズムを実装したことがある。正確には、canvas2dを学ぶ練習としてSDLコードを移植した: http://namuol.github.io/earf-html5/
    もちろん、リンク先の実装のほうが私のものよりずっと速く、ずっと単純なので、参考資料を探しているなら、私の古いCoffeeScriptコードはおすすめしない…