BlenderとUnityで作ったものをVR(Oculus  Quest/Oculus Link)で動かします

【Unity】Terrainの地面や山を「Terrain To Mesh」でメッシュに変換してみる

 
Unityを使っている時、Terrainで作った山や地面を非表示にしてみると、結構負荷が下がる気がしました。建物や家などのオブジェクトと違って、Terrainの形はシンプルなのに描画負荷が高いのでしょうか?
 
そんな時、アセットストアで「Terrain To Mesh」というTerrainをメッシュに変換するツールを見つけました。
 
どこまで効果があるか分かりませんが、効果があることを期待しつつ試してみました。



(1) Terrain To Meshをインストールする

アセットストアで「Terrain To Mesh」を購入しました。
12/27時点で定価25ドルでした。
 

インストールする

Asset Store」でDownloadした後、「Import」ボタンをクリックします。
 
VacuumShaders」フォルダ以下にインポートされるようですね。
 
無事にインストールできました!
 
Assets/Terrain To Mesh/Doc/ReadMe.pdf」に使い方が書いてあります。
説明書によると、Terrainのオブジェクトを指定して、パラメータ入力して、Generateボタン押せば変換できるようですね。
 

使ってみる

まずは使ってみます。
 
メニューバーで「Window -> VacuumShaders -> Terrain To Mesh」をクリックします。
 
TerrainToMesh」というウィンドウが開くので、そこに「Terrainのオブジェクト」をD&Dします。
 
いまのUnityプロジェクトには4つのTerrainがあります。まずは「Terrain1」というオブジェクトをD&Dしてみました。
今回は一つだけですが、複数のTerrainオブジェクトをD&Dして、変換することもできます。消したい場合は、右クリックして表示されたメニューで「Clear selection」ですね。
 

URP用シェーダーを追加でインストールする

Export Maps」にチェックを入れたところ、何かエラーが表示されました。
 
URP用のシェーダーがインストールされてません。ココをクリックしてアセットストアを開いてください。」とのこと。どうやら、URP用のシェーダーは別売りだったようです。
 
早速、「Terrain To Mesh – Scriptable Render Pipeline」をアセットストアで追加購入しました。
こちらの定価は10ドル。
 
必要条件を確認してみると、URPとHDPの場合は「Unity 2019.3 以上」で「ShaderGraph v7.2.1 以上」でした。いまのプロジェクトでは問題なく使えそうです。
 
インポートしておきましょう。
 
TerrainToMesh」画面を開いてみると、エラーが消えてました。
これで設定できますね。
 

(2) Terrainをメッシュに変換する

設定パラメータを確認しつつ、Terrainをメッシュに変換してみます。
 

1. Sub-folder Name

このツールでTerrainをメッシュに変換すると、「Assets/(Temporary)/」というフォルダ以下にPrefabが作成されます。
ここの設定では、更に「サブフォルダ」を作るか、が指定できます。
 
基本的には「」で良いですね。
 

2. Export Maps

ここにチェックを入れると、Terrainの地面や山の表面をテクスチャ画像として出力してくれます。
 
テクスチャの種類には「Splatmaps、Basemap、Heightmap」などがありますね。とりあえず全部出力してみました。
 

3. Export Trees

Terrainで配置した「」のデータをエクスポートします。
 
説明書に、
Exports tree prefabs used by Unity Terrain asset. Exported trees are original tree prefabs and have no Unity Terrain LOD system like: billboard, distance fade, etc.
と書いてありました。Unityのプロジェクト側に「実体となるアセット」があれば問題ないようです。いまの環境の場合、Standard Assetsの「Broadleaf_Mobile」ですね。
 
木のデータをエクスポートできるのは良いんですが、メリットは何でしょうね。木を再配置しなくても大きさなどを変更できる、とかでしょうか。
 

4. Export Unity Mesh

Terrainをメッシュに変更する際の設定です。
 
・Chunk count horizontal/vertical:水平・垂直に何分割するか?
・Vertex count horizontal/vertical:水平・垂直の頂点数をいくらにするか?
ですね。
 
例えば、Chunk countを両方とも 10 にした場合、縦横10×10で 100個 に分割されます。
そして、Vertex countを 25 にすると「分割された1つの塊(これがChunk)」ごとの頂点数が 25 になります。数値が大きいほど、オブジェクトの輪郭が滑らかになります。
 
この設定のうち、Chunk countは「オクルージョンカリング」機能に関係ありそうですね。
 
オクルージョンカリングは「カメラに見えていないオブジェクトを描画しない」ことで負荷を下げますので、分割単位が小さくなるとその分だけ、描画するオブジェクトを減らすことができます。ですが、細かくし過ぎると逆に「オクルージョンカリングで描画しないオブジェクトを判別する負荷」が高くなりますので、ほどほどが良さそうです。
 

5.その他の設定

・Mesh Compression:メッシュ圧縮するかどうか。良く分からないのでオフで。
・Attach MeshCollider:メッシュコライダーを付けるかどうか。とりあえずオフで。
・Export OBJ Mesh:objファイルを出力するか。モデリングソフトなどで再利用する場合に使います。オフで。
 

メッシュに変換できた!

画面下の「Generate」ボタンをクリックすると変換が始まります。
変換速度は結構速いですね。
 
変換が完了すると、これまで使っていたTerrainが自動的に非表示になり、メッシュに変換されたオブジェクトが「Terrain1 (ID_97960)」のような名前で自動生成されました!
 
試しに1区画を選択してみると、こんな感じになります。
 
更に、オブジェクトを非表示にしてみると、そこだけがちゃんと消えました。
ぱっと見ただけでは気づきませんでしたが、良い感じにメッシュ変換&分割してくれたようですね。
 
池の底部分も大丈夫っぽい。
テクスチャ画像もエクスポートされてるようです。
 
上空から見てみましょう
キレイに100分割されてます。これが自動でできるのはかなり便利かも。
 


(3) 細かいところを確認してみる

変換はできましたが、気になるところがいくつかありました。
 

1. テクスチャの色がおかしい

テクスチャ画像は貼り付けられていますが、色合いがおかしい。
 
分割した区画ごとに色が微妙に違います。
 
試しに、テクスチャ無しでエクスポートしてみました。
白いのは仕方ないとして、やはり色合いがおかしいですね。テクスチャ画像側の問題では無さそうです。
 

[解決] ライトをベイクし直す

そういえば、以前の設定変更で「Lighting」タブの「Auto Generate」設定をオフにしていたのを忘れてました。
 
Generate Lighting」ボタンをクリックしてしばらく待つと、テクスチャの色が直りました。
 

2. 草花が無くなった

なんか地面が寂しいと思ってましたが、草花が無くなったようです。
 
以前はこの位置に草がありましたね。
 

[解決] Terrainの木を使うなら表示できる

どうやら、地面や木はエクスポートしますが、草花は対象外のようですね。やや残念。
 
表示したい場合は、以下を設定するのが良いですね。
・元のTerarinオブジェクトを再表示する。
・「Inspector -> Terrain -> [Terrain Settings]ボタン」をクリックする。
・設定で「Basic Terrain -> Draw」のチェックを外す。これで、Terrainの地面が消えます。
・設定で「Tree & Detail Objects -> Draw」のチェックは入れる。これで、木と草花が表示されます。
・「Export Trees」でエクスポートした木のオブジェクトを非表示にする。
 
木をエクスポートするメリットはあまり無さそうでしたので、これでも良いと思いました。
 

3. 地面の当たり判定がおかしい

この記事で作成した「風魔法」を地面に撃ってみると、地面を貫通してました。
 
風魔法は地面を貫通して、地面の下に設定してる「水面の平面オブジェクト」に当たっているようです。
どうやら、Terrain側のコライダーが無いらしい。
 

[解決] Attach MeshColliderをオンにする

5.その他の設定」では「Attach MeshCollider」をオフにしてましたが、オンにする必要があったようです。
Vertex Density(頂点の密度)」は 1 のままです。
 
この状態で風魔法を撃ってみると、地面に当たるようになりました。
 

4. 地面の凹凸が少ない

池の底面など、凸凹したところを見てみると、微妙に形が違います。
 
まず、元のTerrainの地面です。
 
そして、Terrain To Meshで変換した地面です。
凸凹が少ないので、影も少なくなってますね。
 

[解決] Vertex countの数値を大きくする

Vertex count25 でしたが、これを倍の 50 にして変換し直してみます。
 
元のTerrainの地面に、かなり形が近づきました。
 
元のTerrain」と「変換後のオブジェクト」を同時に表示してみます。
ほとんど同じ形になってるのが分かります。
 

5. 木が風で揺れない

元のTerrainをオフにしていると、Terrainで設定していた「Wind Zone」による風が止まってしまいました。
 

[解決] 元のTerrainで風だけをオンにする

元のTerrainを表示した後、「Basic Terrain」と「Tree & Detail Objects」の「Draw」を両方ともオフにします。
この設定で、地面や木などの描画が非表示になりますが、「Wind Zone」はオンですので風が吹きます。
 

(4) オクルージョンカリングと負荷

オクルージョンカリングが正しく動いているか、確認しておきましょう。
 

全体のすがた

すべてを表示した場合がこちらです。
 
Unityの「Play」ボタンをクリックし、「Occlusion」タブで「Visualization」を選択すると、カメラから見えていて「描画しているオブジェクト」を視覚的に表示することができます。
 
確認してみましょう。
 

カメラの方向を変えて確認する

まずは「」を向いてみます。ここでは、画面左上を「」として記載していますよ。
カメラが向いた方だけオブジェクトが表示されてますね。
 
試しに、元のTerrainでのカリング具合を表示してみました。
ほとんど同じですが、こちらの方が地面が細かく分割されているようですね。Chunk countを 10 → 20にすると同じになりそうですが、いまのままで良いでしょう。
 
東を向いてみます。
 
南です。
 
最後に西。
他の方向でも問題ないようですね。
 

描画負荷はあまり変わらなさそう

Profilerで描画負荷を確認してみます。
 
まずは、元のTerrainです。
 
そして、変換後のオブジェクトの場合です。
これだけを表示した感じでは、描画負荷はあまり変わらない感じでしょうか。
 
アセットストアのレビューを見ていると、モバイル機での描画負荷が下がった的なことが書いてありましたので、状況によっては効果があるのかも知れません。
 


(5) 地面の頂点数が減った?

オブジェクトを表示した時の「頂点数」などを確認しておきましょう。
 
まずは、ほぼ何も無い状態です。
 
画面左下の「Statistics」で頂点数などが確認できます。
・Batches:10、Saved by batching:-3
Tris:14、Verts:40、SetPass calls:9
 

「地面」だけを表示した場合

まずは、地面だけを表示した状態で確認してみます。
 
[元のTerrain]
 
[変換したオブジェクト]
 
一つ目の数値が [元のTerrain]、二つ目が [変換したオブジェクト] です。
・Batches:25 → 28、Saved by batching:-3 → -21
Tris:18.2k → 14、Verts:10.4k → 40、SetPass calls:14 → 14
 
頂点数が18.2kから14に減った!と喜んでましたが、この数値は何も表示してない時」と同じ値ですね。さすがに頂点数が 0 という事は無いと思うのですが。。。
 
とはいえ、Batchesなどの値は変わってるので、別のオブジェクトの値を表示してはいるようです。Statisticsの表示がおかしい?
 

「木」だけを表示した場合

次に、木だけを表示した状態で確認してみます。
 
[元のTerrain]
 
[変換したオブジェクト]
 
・Batches:408 → 398、Saved by batching:898 → 898
Tris:497.8k → 485.1k、Verts:571.4k → 548.9k、SetPass calls:30 → 27
こちらはちゃんと頂点数が表示されているようですね。
 
頂点数がやや減ってますが、草花を表示してないので、その分なのかも知れません。
 

DirectX 12では結果は逆

少し気になったのでネットで調べてみると、DirectXのバージョンで「Statistics」の表示が変わることがある、という記事を見つけました。
ここに書いてある方法で、DirectXのバージョンを 11 から 12 に変更してみます。
 
リスト先頭に「Direct3D12 (Experimental)」が来てるのでOKですね。
 
[何もない状態]
・Batches:10、Saved by batching:-3
Tris:11.2k、Verts:6.2k、SetPass calls:9
 
何もない状態のはずですが、頂点数が11.2kになってますね。なぜだ。。。
とりあえず、これをベースの状態とします。
 
[元のTerrain]
 
[変換したオブジェクト]
DirectX 12の場合の結果です。
・Batches:26 → 28、Saved by batching:-3 → -21
Tris:29.4k → 97.7k、Verts:16.6k → 51.2k、SetPass calls:14 → 14
頂点数が3倍に増えたように見えますね。。。
 
なお、DirectX 11の時は、
・Batches:25 → 28、Saved by batching:-3 → -21
Tris:18.2k → 14、Verts:10.4k → 40、SetPass calls:14 → 14
でした。
 
結果が逆ですね。どちらが正しいんでしょうか。
 

木でも試してみる

念のため、木でも試してみましょう。
 
[元のTerrain]
 
[変換したオブジェクト]
 
DirectX 12の場合の結果です。
・Batches:405 → 396、Saved by batching:899 → 899
Tris:509.6k494.3k、Verts:580.6k552.8k、SetPass calls:28 → 27
 
そして、DirectX 11の時は、
・Batches:408 → 398、Saved by batching:898 → 898
Tris:497.8k → 485.1k、Verts:571.4k → 548.9k、SetPass calls:30 → 27
でした。
 
こちらはほとんど同じ結果ですね。
 

負荷を見てみる

[元のTerrain]
 
[変換したオブジェクト]
 
・FPS:540前後 → 560前後
 
頂点数が増えたのでFPSが下がると思いましたが、逆にほんの少しですがFPSが上がってました
風が止まったり、草花が非表示になった分かも知れませんが、そこまで大きな差異は無かったようですね。
 

まとめ 

Terrainで作った地面や山を「Terrain To Mesh」を使ってUnityのメッシュに変換してみました。
 
頂点が下がったと思ったら、DirectX 12で確認してみると逆に増えていたり、けど負荷はそんなに変わっていなかったりで、いろいろ試してきましたが、効果は良く分からないのが正直なところです。
 
負荷が増えたわけでは無いので、しばらくはこのままで使ってみようかと思います。
 
スポンサーリンク

コメント

  • トラックバックは利用できません。

  • コメント (0)

  1. この記事へのコメントはありません。

ブログの女の子を作る #56 Unity用の「RealToon」トゥーンシェーダーをURP版で使ってみる

ブログの女の子を作る #57 髪の毛を改善する (1) UV展開をやり直す【Blender】

最近のコメント

だーしゅ
IT関係のお仕事してます。
VRは楽しいですね。

[当ブログについて]