今回は、前回に引き続き地形の生成についてです。
試行錯誤の末、地形(Terrain)を管理できるツールを作ることにしました。

ことの発端

地形は、いくつかのツールやUnityのアセットを駆使して作成していくことになります。
大部分は現行でいけるのですが、ツールの橋渡しでデータの管理が大変というのと
いくつか表現で避けられない部分が出てきたため、Terrainシステムを作ることにしました。
Shade3Dとしてのブログというのもあり、「あれ、最近Unityのことしか書いてないな」というのもありましたので、
ツール寄りとしての大義名分を設けるという意味もあります。
VRコンテンツとしては納得のいくものを作りたいのもあり、周り(制作環境)も含めて洗い出していこうと思います。
なお、現状で公開できない部分もありますので公開可能な内容だけを書くようにします。
といってもTerrain部の開発は最近始めたばかりですので、お見せできる内容は少ないわけですが、、、。

Terrainの構成

改めてTerrainの構成です。

  • 地面の凸凹
  • 土や草/岩などの、地面の凸凹に割り当てるテクスチャ
  • 木や草の配置
  • 建物の配置

Terrainとして上記の表現を積み上げていくことで、「シーン」を作ることになります。

上の画像はUnityでの編集画面になります。
画像の上は左から、高さなし、山の高さを指定、テクスチャを割り当て。
画像の中央は左から、高さのみ、草の指定、木の指定。
画像の下は、家を配置。

この部分までは既存の処理でいけますが、
次に表現が難しい部分をいくつかピックアップしました。
現状の回避策がある部分については記載するようにしてます。

隆起での凸凹

「地面の凸凹」は高さマップ(Height Map)としてグレイスケールの濃淡をテクスチャとして採用します。
左は都市部の地形用、右は山の地形用の高さマップです。これらをレイヤ的に重ねて扱います。

この高さマップのテクスチャにより、凸凹が表現できます。
この場合、テクスチャの解像度が荒いと滑らかにはならない箇所がでてきます。
テクスチャの解像度が十分な場合でもTerrain自身はグリッドに区切った状態での凸凹表現となるため、
Terrain自身の解像度に依存する部分が出てきます。
下画像のように、斜め方向の隆起に弱いです。

上記はUnityでのTerrainになりますが、高さマップを使用したTerrain生成を行うツールでは同じ表現となるようでした。
自然の地形の場合はそんなに目立たないですが、都市部になって整備された地形になると、この部分が気になってきます。
VRの場合はずっと近づいた目線で地面を見るため、このガタガタな部分は結構目についてしまいます。
解決策はTerrainの解像度を上げるのが簡単ですが、
それだけ地面を構築するメッシュの面数が増えるため、速度低下につながってしまいます。
別の回避策として、元となる高さマップをぼかしてエッジが緩やかになるようにする、という手がありそうです。

ただ、ディテールが失われることになるので難しいところです。
このような場合は、Terrainを使用せずに自前の地面用のメッシュを用意するのが確実なのかもしれません。

急な隆起での側面

高さが急激に変わる崖など、高さマップは平面グリッド状の構成であるため縦方向の間延びができてしまいます。

この側面部分のテクスチャも間延びしてしまいます。
この部分は、高さマップとしては以下のようになってます。

黒と灰色の変化が急ですね。
これを解決するには、急激な変化が起きないように高さマップをぼかす、という手が考えられそうです。

以下のように、少し緩和されて高さ方向も側面部分に面ができました。

ただ、根本解決にはまだ遠そうですね。

テクスチャのタイリングが見える

下画像の左は、引いてみたときの山の地形です。
遠目では問題ないのですが、近づいていくと右のようにテクスチャのタイリングがばれてしまいます。

これについては、地形にカメラを近づけていって異なるテクスチャで重ねていくことで
タイリングを分かりにくくします。

Unityのアセット「TerrainComposer 2」(https://assetstore.unity.com/packages/tools/terrain/terraincomposer-2-65563)を使用することで、
ノイズとしてテクスチャをレイヤのように重ねて管理することもできます。
ただ、このタイリングを見えなくする調整は、地形を目で確認できる位置までカメラをズームして編集をずっと繰り返すことになるため、
手間がかかります。

Terrainにオブジェクトを配置

Terrainの高さの位置にオブジェクトを配置する、という機能があります。
地形の凸凹が変化しても、オブジェクトの位置は自動的に調整されます。
これは、地形上に石のようなランダム性のあるものを配置する場合に向いており、
建物を配置する場合にはあまり向いていません。
以下、「TerrainComposer 2」のアセットを使って石を地形に配置した例です。

特定の位置に石をピンポイントで配置、ということはできません。
一定の範囲内にランダムに配置、となります。
建物を配置する際は、道路に沿って建物を配置したり、配置する場所を1つ1つ指定したい場合も出てきそうです。
Unity上のスクリプトではTerrainの指定位置の高さを求める機能がありますので、
この建物などの接地機能についてはプログラムで実装できそうではあります。
もしかしたら、この機能を満たすアセットがすでにあるかもしれませんが。

Terrainとしての研究開発と手順

上記を改善/管理するというのを目的としてTerrainをシステム化することにしました。
ただ、まだまだ調査/検証段階ですので予定は今後変更されるかもしれません。
ここで、筆者がよくやって泥沼になる「研究」について書いていこうと思います。
Terrainのシステムを作るのは結構工数がかかり、新しく考えないといけないことがたくさんあります。

いつもこんな感じで進めています。
研究の場合はやってみたけど実現できなかったということも多いので、予定は未定で大雑把のほうがいいかなと思ってます。

  1. 表現したいものを定める(目標設定)
  2. すでに誰か実現できているか調査
  3. スケジュール調整
  4. 問題解決の方法論/論文などを探す
  5. 問題解決の方法論を試行錯誤する(アルゴリズムの確定)
  6. 実装(ライブラリ/エンジン化)

表現したいものを定める(目標設定)

いまの対象は、このブログ記事の主題である「昔の日本の風景をVRで作る」になります。
この際に地形と建物を管理したい、というのが研究の目標です。
この目標が定まっていれば、ぶれにくいかなと。
時間があれば、「これあれば便利そうだから実装してみよう」も腕試しになっていいかと思います。
ただ、たいてい飽きてしまいますので、モチベーションを保つ意味でも目標は定めておいたほうがいいかなと思います。

すでに誰か実現できているか調査

誰かが考えついているアイデアは、ツール化されていたり方法論は論文とかで出ていたりしていることが多いかと思われます。
近道できるのであれば、それを利用させていただくのがよさそうです。
あくまでも目標を実現するための研究、としないと自己満足だけになったり、先駆者のほうがすでにいいもの作ってることが多いですので、、、。
もし、「おお、なんか革新的なアイデアが浮かんだぞ」というのがあれば、それは秘めて隠して進めておいたほうがいろいろ戦略は練りやすいかもしれませんね。

スケジュール調整

「実装してみないとわからない」の典型的な研究は、スケジュールの見積もりが難しいです。
時間をすごく消費するので、ある程度期間を設けて無理なら諦める(もしくは後でリベンジ/再稼働させる)、というのもよくしたりします。
Terrainならどれくらい時間がかかるでしょうかね、最低1年はかかるかなと見積もってます。
仕事だと予算割けなそうですね(^_^;
このブログに書いているのは個人プロジェクトなので、、、研究を入れることができるというわりとレアケースなのです。
なので、仕事の場合は極力研究を入れないようにすることが多いのですが、
失敗も含めて研究を繰り返していると勘が養われるのと知識がつくことになりますので、研究肌な方はやっておいて損はないかなと思ってます。

問題解決の方法論/論文などを探す

複数のアルゴリズム(物事を実現するための方法/理論)を組み合わせることになるため、
それぞれがどのようなやり方で実現できそうか調査することになります。
Terrainの場合は技術系ですので論文を探すのも手です。
調査については、「ググる」(ネットで検索)でとりあえず。
技術系は日本語の解説が検索できることは少なく、英語で検索したほうがいいかもしれません。
情報量は英語のほうが段違いに多いです。
なお、「ある問題を解決できる方法が見つかった」場合でも特許で縛られている場合があります。
そのあたりは念入りにチェックするようにしてます。
例えば、今実装しているTerrainシステムでは「マーチングキューブ (Marching Cubes)」というのをもっとも基盤部分で使用しています。
この方法は、過去特許で縛られていて手出しできませんでした。
今はその特許自身が失効してますので利用できます。
あと面白いのが特許で囲まれている論文があった場合、それを超えた理論で誰もが使える形にして飛び越えてしまう、という論文が見つかったりします。
その辺は研究の競争になりますね。

問題解決の方法論を試行錯誤する(アルゴリズムの確定)

実装する機能を実現する場合に既存の方法が見つからないときは、
そのアルゴリズムを頭をひねって考えます。
方法論を自分で確立する、という工程になります。
Terrainの場合は複数の理論を組み合わせることになり、単純に既存技術だけでは難しい部分も出てきます。
たぶんもっとも時間のかかる部分です。
これらのアルゴリズムを組み合わせて、ようやく1つの機能としてライブラリ/エンジン化できる道が出来上がります。
ここまでが「調査/研究」です。

実装(ライブラリ/エンジン化)

アルゴリズムを固めた段階で、それを目標を実現するための機能として
ライブラリ化/エンジン化します。
この部分は「プログラム」になりますね。
これは、目標(ここでは「昔の日本の風景をVRで作る」)が効率的にできるようにシステムとして構築していくことになります。
機能としてプログラムから利用できる実装でもいいですし、ツールにして編集できるようにする、でもよさそうです。

大きく、「調査/研究」「ライブラリ化(プログラム)」「コンテンツからのライブラリ利用」という流れで進めていくことになります。
それぞれがまったくの別分野、ということを十分把握しておく必要があります。
特に仕事の場合、研究が入ると工数が見積もりにくいのと目標達成できなかった、というのになりかねません(経験談です)。
研究が入る可能性がある場合、声を大にして研究の難しさを先方に伝えることをお勧めします。
開発仕事に対して研究要素が絡んでいるのにGoすると、結構泥沼化します。

今回は、自身のプロジェクトでもあるため研究はあえて入れるようにしました。
ここはShade3Dのブログ記事であるため、少しくらい噛ませるほうがいいかなという魂胆もあります。
建物についてはShade3Dでモデリングすることになりますので、
建物の配置もTerrainのシステム内に入れてしまうようにする予定で進めてます。
そんなこんなで、Terrainシステム作ってます。

Terrainシステム進捗

現段階は、あるツールの一部で使う「ライブラリ/エンジン」としてTerrain機能を実装中です。
また、表示の検証でUnityを使ってます。
Unityから見ると「Terrainのアセット(プラグイン)」を使うことになります。

以下のような高さマップを与えます。これは、直線的で斜めのラインが結構あります。

これを立体化したときに、まだ荒い部分は多いですがエッジを滑らかしたり、
急な高さがある場所にも面が貼られるようにしています。


後、以下のような複雑な地形にも対応できるように実装中です。
実際は使いませんが、検証用にノイズで陸地の凸凹を自動生成させてます。

現段階ではまだリアルタイム性は設けていませんが、当然VRですのでリアルタイムに地形を扱えるように理論を立てています。
今は、地形生成に数秒時間がかかってます。

山肌のような凸凹を作って、球で抜いてみました。

まだまだ改善しないといけない点が多いのですが、このような感じでいろんなパターンを検証しつつ、Terrainエンジンとして詰めていくようにしていってます。
まだ「調査/研究」段階になります。

この他、いくつかは現段階では機能を隠しています。
しばらくはこのTerrainシステムを調整していくことになるでしょうか。

ということで、今回はコンテンツ制作からスピンアウトして地形を研究として作る、
というテーマについて書いてみました。
しばらくは理論的な検証が続くと思いますが、一度作ってしまえば応用が利きそうな基盤をまず整えて、
積み重ねるようにVRコンテンツとして昇華できればと考えています。