Dalvik Heapメモリは高すぎ

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


メモリ

Q1:ゲームに入るばかりの時、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を呼び出すような手動解放方法に変更した。


制作

Q2:一つのMeshRendererに二つの材質がある。他のMaterialPropertyBlocksを設定させたいのに、現在にはできる方法はまだありませんとわかった。RendererからMaterialPropertyBlockを手に入れた後に、指定してある材質に応用することはもうできないでしょうか?みなさんには良い解決策があるのか?

はい、MaterialPropertyBlocksはMaterial単位ではなくMeshRenderer単位である。Meshを分割し、一つのRendererにMaterialが一つしかないを確保すると問題主に提案する 。


パフォーマンス

Q3:最近プロジェクトをUnity4からUnity5やUnity 2017にアップグレードした後、ローエンドモデルでのフレームレートは10以上低下した。Adreno Profilerで調べた結果はGPU Boundである。

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

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


メモリ

Q4:この「Triggers RebuildInternalState」は物体を隠す時に必ず引き起こされるか?Profilerの最後列に必ずWarningがあるので、厳重な間違いを感じた。これをどうやって避けるのか?(前にキャッシュしたことがある場合に)Animator.Initializeの時間コストを明らかになさせるか?

これはAnimationの含むGameObjectがDeactiveされたときのエンジンWarning、多くの状況には確かに高いCPU時間コストを導く。それに対して、問題主にGameObjectが要らない時に直接に画面の外に移して、GameObjectをDeactiveするではなく、掛けたComponentをDisableさせると提案する。これでInternalStateの発生をRebuildできる。


Unreal 4 レンダリング

Q5:こんにちは、UWAのグローバルイルミネーションに関する記事を見て、いくつかの質問がある。

1.UnityのLightmapベイクをする時に、なぜNormal mapからNormal情報を得られないの?UnrealのLightmassも二枚の図をベイクする、一枚は方向に一枚は色。その色はNormalMapの影響を受けるの?

2.Unrealの一つシーンには複数枚のLightmapがある。例えば昼から夜にかけて、グラデーションはどのように融合しているか?

1.LightmapにおけるDirectional情報とは、ベイクライトの方向情報である。Lightmapでは、一枚が光線のIntensity を記録し、もう一枚はDirecitonalを記録することである。このDirecitonalはShadingの方向に関する計算を参加するの為、例えば、ハイライト計算やnormal計算など。ただのDffuseでもNormalmapが要らない、このDirectional情報を削除し、メモリ占有と計算量を減らすことができる。通常、材質に見られるNormalmapとは、メッシュのNormalであり、Lightmapに記録されているDirectionalとは一つではない。

2.UnrealにおけるPrecomputed Lighting Scenariosは複数セットのLightmapやイルミネーション設定を保存している。できるのはイルミネーションと合わせてLightmapを切り替えることだけ、今には融合はまだ不可能だ。

Q6:ベイクする時イルミネーションのIntensityはbeastのようにNormalを考慮する。Lightmassベイクする時にはNormalmapを提供できるの?

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


UWA公式サイト:https://jp.uwa4d.com

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

UWA公式Q&Aコミュニティ:https://answer.uwa4d.com