Dalvik Heapメモリは高すぎ

今回の主な話題：「Dalvik Heapメモリは高すぎ」、「Unity 5とUnity 2017でのフレームレートが低下」、「Animator.Initialize警告をどのように処理する」。

---
###メモリ
Q１：ゲームに入るばかりの時、Dalvik Heapメモリは異常に高いので、PSSも高く導く。バックグラウンドに一度切り替えて、ゲームに戻すとDalvik Heapメモリはかなり減少した。そして、ネットで調べられたAndroidでGCを呼び出す方法を使ってみた。System.GC、 runFinalizationとの結合、Runtime.getRuntime().gc()を使うなど、全て有効に減少することができない。これを一回有効に呼び出す方法があるかどうか？
>原因がわかった。Android層に一つのSplashを書いた。このSplashはpngタイプので、解像度は1920x1080であり。前には
```int splash_bg = getResources().getIdentifier(bgName, "drawable", getPackageName());
m_BgView.setBackgroundResource(splash_bg);```
この画像はHideSplashで遊離されており、JavaのGCが呼び出された後に回収される。しかし、実際の画像が100MBぐらい増えさせるはずはない。SplashとSplashVideoだけのテストプロジェクトを使った、コードは完全に同じのに、メモリはそんなに多く増えられない。解釈できるのは、JVM後のあるメモリ配分アルゴリズムは原因になるかもしれない。元々低い場合には配分が少なく、一定の数に達し、再び配分すると、さらに大きな1つのメモリが配分される(Android基層には苦手)。

>以降では、まずgetResourcesからBITMAPを取得し、ImageViewに伝える。HideSplashの際に、BITMAPを呼び出すような手動解放方法に変更した。

---
###制作
Q２：一つのMeshRendererに二つの材質がある。他のMaterialPropertyBlocksを設定させたいのに、現在にはできる方法はまだありませんとわかった。RendererからMaterialPropertyBlockを手に入れた後に、指定してある材質に応用することはもうできないでしょうか？みなさんには良い解決策があるのか？
>そうです。MaterialPropertyBlocksはMaterial単位ではなくMeshRenderer単位である。Meshを分割し、一つのRendererにMaterialが一つしかないを確保すると問題主に提案する 。

---
###パフォーマンス
Q３：最近プロジェクトをUnity４からUnity５やUnity 2017にアップグレードした後、ローエンドモデルでのフレームレートは10以上低下した。Adreno Profilerで調べた結果はGPU Boundである。

>社内のゲームはフレームレートへの要求は高いので、ゲームをする時には必ずフルフレームで実行する。だからこの問題は明らかに見られる。努力して、最後に分かったのはUnity５以後、デフォルトでBlitが開いた、解像度が高いほどGPUの圧力が大きくなる。特にローエンドモデルで、私たちはAdreno405でテストした、Unity４ではフルフレームできるが、Unity5やUnity 2017では最高45くらいまで、これはひどい。幸運なのは、Unity2017.2に、公式がBlitの禁止設定を開放したが、Unity５はその運がない。公式からの情報による、当分Unity5.６にこの機能を導入する計画はない。

>こちらを参照してください：https://forum.unity.com/threads/big-performance-issue-with-unity5-on-android.338847

---
###メモリ
Q4：この「Triggers RebuildInternalState」は物体を隠す時に必ず引き起こされるか？Profilerの最後列に必ずWarningがあるので、厳重な間違いを感じた。これをどうやって避けるのか？（前にキャッシュしたことがある場合に）Animator.Initializeの時間コストを明らかになさせるか？
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/650ed1c3-b4b5-bf1c-6e87-73f3b2f2c4b5.png)
>これはAnimationの含むGameObjectがDeactiveされたときのエンジンWarning、多くの状況には確かに高いCPU時間コストを導く。それに対して、問題主にGameObjectが要らない時に直接に画面の外に移して、GameObjectをDeactiveするではなく、掛けたComponentをDisableさせると提案する。これでInternalStateの発生をRebuildできる。

---
###Unreal 4 レンダリング
Q5：こんにちは、UWAのグローバルイルミネーションに関する記事を見て、いくつかの質問がある。
１．UnityのLightmapベイクをする時に、なぜNormal mapからNormal情報を得られないの？UnrealのLightmassも二枚の図をベイクする、一枚は方向に一枚は色。その色はNormalMapの影響を受けるの？
２．Unrealの一つシーンには複数枚のLightmapがある。例えば昼から夜にかけて、グラデーションはどのように融合しているか？
>１．LightmapにおけるDirectional情報とは、ベイクライトの方向情報である。Lightmapでは、一枚が光線のIntensity を記録し、もう一枚はDirecitonalを記録することである。このDirecitonalはShadingの方向に関する計算を参加するの為、例えば、ハイライト計算やnormal計算など。ただのDffuseでもNormalmapが要らない、このDirectional情報を削除し、メモリ占有と計算量を減らすことができる。通常、材質に見られるNormalmapとは、メッシュのNormalであり、Lightmapに記録されているDirectionalとは一つではない。
２．UnrealにおけるPrecomputed Lighting Scenariosは複数セットのLightmapやイルミネーション設定を保存している。できるのはイルミネーションと合わせてLightmapを切り替えることだけ、今には融合はまだ不可能だ。

Q6：ベイクする時イルミネーションのIntensityはbeastのようにNormalを考慮する。Lightmassベイクする時にはNormalmapを提供できるの？
>Unityはベイクする時、放射度を使っている。すなわちまずモデルをブロックに分けて、そしてブロック間の反射を計算して、Normalmapは使わない。Normalmapが提供するのは詳細的な情報であり、グローバルイルミネーションに間接光の計算結果は低周波ので、,高周波の情報を入れると必ず良い効果が得られるではない。Unreal ４のLightmassには、Staticタイプの光源がベイクする時にnormalmapを使わせる設定オプションがあり、project settings->engine rendering->lightingに含まれている。

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

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