見出し画像

マインクラフトをリアルにしたい


自由度の高いゲームを作りたい

ゲームプログラマーが一度は「作ってみたい!!」
と思うゲームが、"Minecraft" だと思う

そう思ったプログラマーの一人が私だ

ただ、マインクラフトのようにブロック単位でしかクリエイトができなかったら自由度があまりない

リアルに近づけるにはどうすればいいのだろう…
そう悩み、辿り着いた結果は、

そうだ。穴を掘って水が流せたら最高じゃん
と・・・

そう思って、開発を試みた内容をここに記そうと思う

一先ず、マインクラフトを作る

「どういった技術で作っているのだろう」とか、「これがゲームと呼べるなんて…」と、マインクラフトが出た当時は愕然としたことを覚えている。

一先ず、浅い知識で似たもの作って思ったことが、
処理足りなくね?
だ。

ここでは、マインクラフトの処理負荷軽減に重きを置いて、話をしようと思う。
そのため、FPSカメラとかプレイヤー操作の話は端折り、ステージ生成部分について語ります。


※ここからは、Unityを使用した体験記です。

まず初めに試すことは、キューブ上のメッシュがついたゲームオブジェクトを大量に生成することだろう
当たり前だが、それだと簡単に処理負荷が増え、余裕で現代のGPUではグラフィック処理が足りない

では、この解決策はどうするか?
.
.
.

それは、、、キューブ上のMeshをプログラム上で作成するということだ
プログラム上でメッシュを作成するため、無駄な頂点を増やさずメッシュを作成することができる。

ただ、そこでも新たに問題が発生する
動的にメッシュを生成するということは生成時に莫大な量のポリゴンを生成することになるため、1フレームにCPUの処理の負荷が大きくかかってしまう

そう、ゲーム業界用語で "スパイク" という現象が発生してしまう。

スパイクとは、1フレームに高負荷な処理を行う関係で、1フレーム内で描画まで処理が間に合わず、次以降のフレームで遅れて描画される現象をいう

様々なゲームをしたことがある人には馴染みがあるだろう
カクついたとか、重くなった
とかそういうやつだ。

プロのゲーム業界だと、絶対に最適化する部分の一つであるし、
開発の最後までついて回る呪いだ
今回は、それについては深追いせず、どこかでまた話そうと思う。

話を戻すが、
ステージが広くなればなるほど、発生する現象だ

その回避策の1つとして、GPU上で計算を行う手法がある
GPUは単純な足し引きの計算は得意のため、CPUで行う必要のない処理をGPUに逃がしてあげることによって、CPU/GPUどちらも均等に処理の分配が可能だ

Unityだと、"コンピュートシェーダー"というもののことを指す

この対応でスパイクが起きないのであれば、わざわざユーザーのインタラクトタイミングでメッシュを作成するのではなく、毎フレーム、メッシュを生成してしまってもよいだろう。

これらの技術を組み合わせてキューブを設置したり、削除したりしてもスパイクの起きないマインクラフトが出来上がる

動画を見ていただければわかると思うが、
内側のメッシュが無いので、無駄な描画が行われていないし、インタラクトタイミングでスパイクが発生していない

後は、ステージが広くなった場合の話だが、チャンクやら空間分割やらを用意したらなんとかなるだろうと、なんとなく頭の中で構想ができたので、今回は気にしないでおく

リアルにする

ここまではただのマインクラフトだ
ここからはリアルにしていこうと思うが、どうすればいいのか…

そういえば、マイクラに似たゲームで地面を掘れるゲームあったな
.
.
.

"7 Days to Die" "Deep Rock Galactic" "No Man's Sky"

これらのゲームだ。

この3つのゲームは、全て、ブロック単位ではないが地面を掘ることができる
これらの地面を掘る技術を調べていて到達した技術がある

最終的に辿り着いた手法

それが、「マーチングキューブ法」だ。

海外の記事だと参考になりそうな記事がいくらかあるようだが、
日本の記事では、マーチングキューブ法をゲームに落とし込むような記事が少ない。
というより、当時はなかった気がする

この技法を使用することで以下の表現が可能だ。

地面を掘ったり、盛り上げたりすることができた!
次は…
水を流すところだが、頂点に対応した流体の計算が必要そうでややこしそう。
長くなりそうなので、今回はここまでにしようかと思う
(気が向いたら続編の記事を作成します)

マーチングキューブ法についての詳しいゲームへの落とし込みは、以下の動画で説明されています。

※このnoteは文化庁のルールに基づいて記述されています

この記事が気に入ったらサポートをしてみませんか?