AssetBundle名前の設定

今回の主な話題：AssetBundle名前の設定、ShaderのTips最適化の疑問、HDRP Shaderで深度値を取得する方法。

---
###アセット管理
Q1：AssetBundle（以下AB）の名前設定に問題があります。
10個のアセットを使用するAプレハブがある場合、それらすべてを同じAB名で設定します。つまり、同じABパッケージで、AのAB名のみを設定し、他のアセットは設定しません。これでABパッケージに他のアセットも含まれ、同時にAプレハブをロードします。どの方案はより効率的ですか？

①
>これらの2つのソリューションを「手動で依存関係を処理する」と「Unity自動的に依存関係を処理する」と呼びましょう。ABのロードを見ると、2つのメソッドにパッケージ化されたABの内容は同じであるため、効率は同じです。しかし、Unity自動的に依存関係を処理する」方法で、依存されたアセットは隠されてABにインポートされます。他のABのアセットもこれらの隠されたアセットを引用したら、これらの隠されたアセットは他のABにインポートさせ、アセットの冗長性が発生し、ABファイルとインストールパッケージが大きくなり、読み込みが遅く、メモリが増加します。Shaderの冗長性により、Shader.Parseが繰り返し実行され、WarmUpに長い時間がかかるか、ジャムを導きます。

>ですから、「手動で依存関係を処理する」方案をお勧めします。このソリューションでは、明示的に指定されたアセットはABにパッケージし、他のABにあるアセットはこれらの明示的アセットを依存すれば、UnityはABの間の依存関係を生成します。AB内のアセットをロードする前に、このABが依存する他のABを開くと大丈夫です。つまり、依存されたABをメモリにロードし、Unityは自動的に依存されたABに依存されたアセットを探してロードします。

>そして、AB Nameを設定することの効率は比較的に低い、Unity Metaファイルとの結合は厳重し、パッケージ化する時にアセットが依存するファイルを自動的に分析できます。詳細については、この軽量パッケージングソリューションである[XAsset](https://github.com/xasset/xasset)を参照してください。ABのパッケージ化とローディングに初めて接触する初心者にお勧めします。

②
>前の人がはっきり説明しました。このプリセットのみをロードして使用すれば、これらのアセットをどうのように処理しても問題はありません。ただし、実際の開発ではこれほど単純にすることは不可能です。
>
AB名の設定は、LZ4圧縮と一緒に使用する必要があるはずです。すべてのアセットを一つのABにパッケージしても、各アセットを単独にABにパッケージしても、良くないと思います。要件次第でアセットの使用状況を計画することは必要はずです。例えば、いくつかの基本的な大きく依存しているアニメーションに対して、Meshやパーティクル特殊効果テクスチャなどを一つの基本アセットパッケージに組み合わせることができます。UIに対して、Prefabとアトラスを組み合わせることができ（UGUIはより特殊ですが、これで行うこともお勧め）、音楽ファイルも一緒に組み合わせることができます。一部のPrefab独特のアセットは、単独のAB Nameを設定して個別にパッケージできます。
>
ローディングに関することは、LZ4圧縮方式であるため、ABをロードする場合、ヘッダーファイルみたいのデータだけをロードしますから、ロード後にUnloadする必要はありません。UnloadするとCPUを浪費するだけではなく、メモリの冗長性も発生します（特に複数のAB Nameを設定した場合）。自分で記録し、どのABがロードした、またはどのAが解凍しました。後で解放する時にも、心当たりがあれば、メモリリークは発生しません。

---
###Shader
Q2: [Unity公式ウェブサイト](https://docs.unity3d.com/Manual/SL-ShaderPerformance.html)でこのようなゲームの説明でたくさんのColor Maskは使用されていることを見ましたから、焦っています。
![1 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/e5af60de-72c4-29a5-b342-24144b76ce90.png)

>2つの点から見ることができます。
>
1、実際の影響はどのくらいですか？
>
原則として、Profilingで決定しますが、時々に面倒な場合もあります。たとえば、直接影響を受けるデータは簡単に分解できず、テスト結果は特定のハードウェアに依存します。理論的な演繹に依存します。
>
2、根本的な原因は何ですか？
>
Tip背景はモバイルプラットフォームGPUであり、TB（D）Rを考えやすいし、Alpha Testに似たものも考えやすいです。不透明なオブジェクトAがBを遮ると仮定します。AにColor Maskがない場合、HSR(Early-z)階段で、遮られたBの部分は全部捨てることができ、後のPS（FS）に行く必要はありません。また、AにColor Maskがある場合、Bは捨てられません。なぜなら、この時にColor Maskは確定できません（PSでのみ確定可能）。遮られたBの部分は、最終的なColorに貢献があるかもしれません。では、Color Mask = より多くのOverdraw。
>
Color Maskの利点は、Colorの一部のコンポーネントがFrameBufferの読み取りと書き込みを行う必要がないことです。IMRでのFrameBufferの読み取りと書き込みは、内部（ディスプレイ）メモリと直接相互作用するため、速度が非常に遅く、帯域幅の消費量が多くなります。このブロックのコストを減らすことは意義があります。しかし、TB(D)Rでは、シェーディングプロセス中のFrameBufferの読み取りと書き込みの操作はすべてオンチップキャッシュで実行され、速いです。この部分のコストを減らしても、増加したOverdrawコストを相殺できない場合があります。

---
###HDRP
Q3: HDRPでSAMPLE_DEPTH_TEXTUREマクロを使用して取得した深度値が間違っています。HDRPでの深度マップの保存方法が変更されました。一つのMipアトラス、ShaderVariables.hlslのSampleCameraDepth方法みたいですが、必要な.hlslファイルを引用してもundeclared identifier ‘SampleCameraDepth’が表示されます。HDRPでこの方法を使用したり、HDRPで深度値を正しく取得したりした人がいる場合、ぜひ教えてください！よろしくお願いします。
>解決しました。４つの方法で深度値を取得できます。
>
1.float depth = LOAD_TEXTURE2D(_CameraDepthTexture, screenPos);
2.float depth = LOAD_TEXTURE2D_LOD(_CameraDepthTexture, screenPos, 0).r
3.float depth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, screenPos, 0).r
4.float depth = LOAD_TEXTURE2D(_DepthPyramidTexture, screenPos).r

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

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