ナビメッシュ情報導出

今回の主な話題:「ナビメッシュ情報導出」、「LoadLevelAsyncロード効率」、「IL2CPP使用後のMonoメモリ理解」。


ロード

Q1:携帯でLoadLevelAsyncとLoadLevelのロードスピードをテストします。同じシーンで、LoadLevelAsyncはLoadLevelより40%くらい長く時間をかかります。これは正しいですか。LoadLevelには重い時があるのため、Loadingプログレスバーがスムーズではないが、LoadLevelAsyncを採用したらLoading時間が増えるはずです。

プロジェクトに動的シーンをロードする私のやり方は、オブジェクトをPrefabにします、使ったのはResources.LoadAsyncです。今にも、大きなオブジェクトをロードする場合、Red mi 2のようなローエンドモデルではまだ重っています、200ms以上かかります。ですからこのロードをスムーズするために、何かいい方法ありますか。

一般的にLoadLevelAsyncはLoadLevelより時間かかりますが、40%遅いかどうかは、次々のシーンがロードすべき量で決定します。定数ではありません。

実は、LoadLevelとLoadLevelAsync最も根本的な違いは、前者は必ず次のフレームが終わる前にロードを完成させます。だからシーンが大きい時、後の単フレームコストも大きくなります。後者にはこのような限制はありません。エンジンは現在の使用状況やThreadPriority(この値はLoadLevelAsyncに影響あるかどうかはまだ実験されていませんけど、確かにLoadAsyncに影響があります)により、自分で調整できます。しかし、Asyncを使ったら、絶対にスムーズになることではありません。下記の図に赤枠にのはLoadLevel、緑枠にのはLoadLevelAsync操作です。

本格的な「スムーズ」非同期ロード方式のは、今のUnityエンジンにはありません。複雑なPrefab(大きなテクスチャや複数のAnimationClipなど)にあう時、ロードにまだ重い状況はあります。もしこの問題を解決したいなら、UWAからのアドバイスは:

⑴先に具体的にどちらのPrefabロードのCPU時間コストは高いかを特定します。

⑵このPrefabに時間のかかる動作(大きなテクスチャ、複数のAnimationClipまたはシェーダーなど)が多いかどうかを確認します。

⑶特定された動作を前期プリロードすることを試み、Prefabロード時の一部分の高コストを解決します。


メモリ

Q2:私はIL2CPPを使った後、Monoメモリはもう存在しするか。IL2CPPを用いて,Profilerツールで取得したmanagedObject(int32[]など)はどのようなメモリですか。

簡単に認められるのは、IL2CPPはただMonoの仮想マシンの実現を取り替えました。だからMonoメモリを配分すべき場所は同じように配分します(些細なディテールは違うかもしれません)。Monoメモリ配分にIL2CPPとMono最も違うのはReserved Totalは低下できます、MonoのReserved Totalは上昇のみ低下できません。


レンダリング

Q3:シーンが自動的にベイクしたナビメッシュ情報はNavMesh.assetの中に保存されてあります、開くと下記のようなデータが見られます:

プロジェクトはサーバーでロケーションする必要があり、できる人にこのデータの解析やレセt用のナビメッシュへの還元を手伝っていただきたいです。Unityバージョンは5.5.1です、Unity4.2にこの解析コードはありましたけど、新版には様式は変わりました。

まずはNavMesh.CalculateTriangulationですべての頂点と索引データを取得します、これは完全な、構築したNavMesh、多辺形情報(最大辺数は6の凸多辺形)が含まれてあります。しかしこのデータにのすべての多辺形の辺は共有していません(多辺形の辺は重複のデータ)。ですからまずは重複の辺を合併します、RacastNavigationが提供したコードを利用できます、rcBuildPolyMeshに基づいて一つの修正版を作って(例えばrcBuildPolyMeshBySeparatePolyTriangleと呼ぶ)、目的は既有の多辺形の重複の辺を合併します。これが終わったら、RacastNavigationが残った構築流れを利用できます:

1) NavMeshを作成し,以上のPolyMeshを用いて初期化します(dtCreateNavMeshData, dtNavMesh::Init)。

2)既存のNavMeshによるエンクロースボックスを更新します。

3)既存のNavMeshに従って、一つ一つのTileをファイルに書き込みます(その前にカスタマイズされたヘッダ情報を書き込むことができ、読み取りやすくなります)。

4)サーバーに蓄積されたデータを読み込み,初期化してNavMeshを生成すると、findpathが行えます。(このデータをRacastNavigationのDemoに導入し、可視化状況を見ることもできます)。

以上の1〜4はRacastNavigation例で流れ構築の一部です、重点はrcBuildPolyMeshBySeparatePolyTriangleで多辺形を合併すればいいんです。このような利点は,導出されたNavMeshとUnityに構築されたNavMesh,多辺形は同じです。DetailMeshに支持するのは、まだできませんらしいです。

また,サーバを直接利用するには問題があるかもしれないが,Unityが導出したデータが細長い三角形のものが多い場合,RacastNavigationの結果がUnityと大きく異なり,RacastNavigationのコードを少し修正する必要があります。


レンダリング

Q4:現在、私が使用しているUnityバージョンは2017.1.0f3 for MACであり、iOSプラットフォームでBake Environment Reflectionsを行う際にHDR情報を失いました。操作手順は下記のように:

⑴Standalone Platformを使ったとき、HDR付きSkyBox CubeMapマップ(デフォルト圧縮方式BC6H)を使いました。生成されたReflectionProbe-0.exrは対象に顕著なハイライトを与えます。

⑵iOS Platformに切り替えた後,再び同じSkyBox CubeMapパッチ(圧縮方式はPVRTC, 圧縮しないRGB24 bitも試みた)でReflectionProbe−0.exrをベイクすると,この効果は消えました。

⑶このとき,私が前のStandaloneが生成したReflectionProbe−0.exrを置き換えますと,Standaloneと同様のハイライトが得られます。これをiPhone 7Plusで動作させますと,「ステップ⑴」と同じ効果が得られます。ReflectionProbe-0中のHDR情報は保存されましたと分かりました。しかし、iOS Platformでは、ReflectionProbe−0のデフォルト圧縮方式はPVRTCやRGB 24 bitであり,どちらの方式もHDR情報を保存できません。

⑷2枚のReflectionProbe−0.exrスタンプを比較しますと、ファイルのサイズは違う、Standaloneのスタンプの方がちっと大きいです。これはUnityのBugですか。

こちらに私が例のプロジェクトexr_EnvRef_iOS.zipをアップロードしました。デフォルトはPC Standaloneで、Platformを手動的に切り替え、後に再びGenerate Lightingの必要があります。

問題主のプロジェクトファイルを使ってみました、確かに同じ問題が出てきました、そしてAndroidでも同様です。今から見るとReflection-Probeがベイクされた時2セットの異なる操作が使われているとしか判断できません。

もう一つの手がかりを提供します、renderdoc−>texture viewerで画素値を見ることができます。

Standalone(PC)

Android

上の図から分かれるのは、似たようなエリアに対してStandaloneのベイク結果の値はAndroidより高いです。

Unity5.6で効果は同じと発見しました、結論は問題主と同じです:MobileプラットフォームでベイクされたのはLDRなProbeです。彼は輝度を高めましたが、実にはもっと簡単な方法があります:高mipを見ればいいです。まずはPCでの効果です。

そしてAndroidでの:

輝度上の違いはPCでは輝度>1画素(一般的には太陽など)があり、畳み込み時の値は大きくなりました;Androidでは相対的に低いです。Mip=0の場合には誰も0−1ですから見えません。今の結論はモバイルプラットフォームでベイクされたのはまだLDRなProbeです。これは間違いです。暫定的な解決策はStandalone でベイクしたらコピーします。

問題主からの補充:新しい発見はありました、ほぼbugが確認できます。2枚のreflectionProbe—0.exrスタンプは確かに違います。サイズ以外、iOSプラットフォームに切り替わった後に生成されたexrは、ハイライト部分のHDR情報を失っています。

一見するとこの2枚の画像は同じですが、

exposureを調整し,exposureを−5にする(openexrを用いたが,psを用いて直接曝露度を調整することも可能です)。

上図には2つの 鮮明なスポットが見られますが,このスポットは非常に明るいため,物体に強いライトを生成できます。しかし、iOS Platformでベイクするとき、Unityはこの情報を失ってしまいました。ただし,すべてのexrにこのような問題が生じるわけではありません、局所的に強力な光源を持つHDR画像だけが現れます。


UWA Technologiesは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析最適化ソリューション及びコンサルティングサービスを提供している会社でございます。

UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com