今回の主な話題:材質(テクスチャ)間のパフォーマンスへの影響、パーティクルシステムが放出点を継続的に変更することのパフォーマンスの最適なソリューション、低解像度のDepthTextureのレンダリング方法、Unityでのオブジェクトのリアルタイムライティングのパフォーマンスコスト。
制作
Q1:質問があります。私たちのプロジェクトには、放出点を常に変更する必要のあるパーティクルシステムがあります。worldspaceモードで確かに特定の効果を達成できますが、現在、単一フレーム内に複数の位置から同時に粒子を放出する必要があります。複数の同じParticle Systemで確かに目的を達成できますが、少し浪費と感じて、頻繁に作成および廃棄を導く可能性があります。全部キャッシュしますと合計数が非常に大きいので、一つのParticle Systemでこの効果を実現できる方法がありませんか?
このドキュメントを参照できます。
https://docs.unity3d.com/ScriptReference/ParticleSystem.Emit.html
ParticleSystemのEmit方法でパーティクルを発射したら、1つのフレームで異なるEmitParamを使用してEmitを複数回コールできます。そうすれば、パーティクルシステム自体は移動する必要はありませんが、Emitの位置パラメーターは毎回異なります。
アセット管理
Q2:
シーン1:一枚の512×256テクスチャ。
シーン2:二枚の256×256テクスチャ。
上記のどちらのコストが高いと聞きたいです。
更に、同じキャラクターに。
シーン1:一つのシェーダーと一枚の512×256テクスチャ。
シーン2:二つのシェーダーと二枚の256×256テクスチャ。
この場合には、どちらのコストが高いと聞きたいです。判決の根拠と原因は何ですか?
メモリに関しては、設定が同じ場合、2つは同じはずです(長さと幅が等しいことが必要な一部の圧縮形式を除く)。
両者のCPUコストはほとんど同じです。一つの材質に対して、一枚と二枚の差別はサンプル回数にあります。一枚のテクスチャはテクスチャのバインドコストを一回減らします。理論的に、削減された時間のかかるコストはnsレベルであるから、ほとんどの場合、CPU端末の違いは無視できます。材質が二つある場合、影響されたものは多くなります。より多いDraw CallやRenderState切り替えなどを引き起こす可能性がありますから、Atlas Packingを採用して最適化する必要があります。
GPUコストについて、テクスチャのShaderサンプルを一つ追加すると、必ずより多くの計算が必要になります。それてShader InstructionとCyclesも間違いなく多くなります。しかし、それは本当により多くの実際のコストをもたらすでしょうか?絶対ではありません。GPUの圧力は、ShaderのInstructionだけでなく、同時に、このShaderによってレンダリングされるランタイムのピクセル数にも依存します。自体の比率が小さい場合、サンプリングを1つ増やしても少なくても、実に違いはありません。
レンダリング
Q3: 低解像度のDepthTextureをレンダリングしたいのですが、何か便利な方法はありますか?
一つの方法は、低解像度のRenderTextureを自分で作成し、Shader Replacementを使用してDepthTextureをレンダリングすることです(ShaderはUnityのShadowCaster実現を参照できます)。
もう一つは_LastCameraDepthTextureで他の低解像度カメラ(存在する場合)によってレンダリングされたDepthTextureにアクセスします。
レンダリング
Q4: Unityでライトの受け取り、シャドウの生成、シャドウの受け取りのパフォーマンス状況を了解したいです。これを尋ねる理由は、上記の3つのUnityのパフォーマンスコストを分かりたいです。また、携帯端末で上記3つまたは一部の可能性はありませんか?
問題主が言った「ライトの受け取り」はReal timeのライトの受け取りですか?そうなら、パフォーマンスコストは予測できません。なぜなら、これはレンダリングシーンの複雑さ、光を受け取るオブジェクトの数などに大きく関係して、簡単に「オンにすれば時間がかかり、絶対にオンにしません」と理解できません。この文を参照できます:インディーズゲーム「Abi」のシーンCPUコスト分析
「シャドウの生成」と「シャドウの受け取り」は、ただリアルタイムシャドウ機能の2つのオプションであります。UWAパフォーマンスレポートでShadows.RenderShadowMapとShadows.PrepareShadowMapを注意して、プロジェクトの具体的なパフォーマンス時間コストを確認しますとお勧めします。
現在、リアルタイムライティングとリアルタイムシャドウは、多くのモバイルプロジェクトで広く使用されています。
最後に、UWAブログには素敵なリアルタイムシャドウに関する記事がたくさんあります。それらをチェックして、問題主に役に立ちますと思っています。
管理
Q5: 私たちのプロジェクトは設立の初期段階にあり、MonoとIL2CPPの間にためらっています。Unity ILCPPとMonoどちらがより良いですか?本当にIL2CPPのパフォーマンスが大きな変化はありますか?使ったことのある人が教えてください!
①
IL2CPPとMonoどちらかどうかが、現段階では主にAndroidでの選択です。
まず、プロジェクトの初期段階にこの問題を考える必要はなく、今のIL2CPPの成熟度限り、気にせずいつでも利用できます。初期段階では、パッケージをより早くできるために、Monoを使って出させます。公式バージョンまたはパフォーマンスおよび互換性テスト用のバージョンをIL2CPPの方がよりいいです(もちろんそれは.netでdllコードのホットアップデートがない場合)。
下記の内容は自分がプロジェクトからやってみた、まだは得たものです。
まとめ:
Monoの利点:
1)十分にテストされました;
2)パッケージ化速度は早いです;
3)パッケージサイズは小さいです;
4)AndroidでDLL動的ローディングアセンブリのホットアップデートをサポートします(使ったことはありませんが、IL2CPPがまったくサポートしていないことは確認です)。
IL2CPPの利点:
1)Monoメモリが上昇するだけで下降しないという問題はありません。
2)C#側の計算集約型アルゴリズムのパフォーマンスはN倍に急上昇しました(同じマップのパス検索や自動建物位置計画などのアルゴリズムの速度が3倍以上に増加しました)。
3)Luaホットアップデートには問題はなく、リフレクションコールと導出コール両方ども完全にサポートされています(利点ではないかもしれませんが、確かに予想外です)。
そしてIL2CPPの問題は:
1)ビルド時間が非常に長いです。WindowsバージョンのAndroid NDKツールチェーンのパフォーマンスがどのように低下するのでしょうか。AMD 16コアと32スレッドを使って、NDKはコンパイル時に並列化を完全にサポートします。
2)IL2CPPを採用した後、ARMv7バージョンのみがコンパイルされると、一部のシミュレーターはゲームを起動できません。FAT(ARMv7 + x86)を使ったら大丈夫です、シミュレーターでも非常にスムーズに実行されます。もちろん、パッケージのサイズは20 MB大きくなりました(私たちのc#コードが多すぎるかな…)。
Monoモードで64ビットをサポートすることはできなくなりました。将来的には、IL2CPPが唯一のオプションとなります。Unityは現在、よくやっています。
②
補充します。Androidが2019年にGoogle Playにリリースしたい場合、64ビットライブラリを提供する必要があり、IL2CPPのパスしか使用できないことです。
さらに、IL2CPPにはAndroidにまだ一つの問題があります。それは「Failed to extract resources needed by Il2CPP」。これは、現時点での使用を妨げる唯一の問題であるはずです(2017.3にも再現することがありました)。
https://forum.unity.com/threads/failed-to-extract-resources-needed-by-il2cpp-unity-5-4-0f3.419593/
この問題について簡単に説明します。Androidでは、毎回起動する時にUnityはIL2CPPが必要なアセット(assets / bin / Data / Managedにあり、Monoのconfig及び各種のmetaデータ)を解凍します。問題は、この操作が失敗する可能性もあります。実際、Unityはapkから直接読み取れば大丈夫です。Unity公式がこの問題を早く解決することを祈ります。
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。
UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com