半透明レンダリングがパフォーマンスへの影響


今回の主な話題:半透明レンダリングがパフォーマンスへの影響、PSSメモリが一部のモデルでの急上昇、Action関数のパフォーマンス、ShaderVariantCollection生成設定。


レンダリング

Q1: UWAパフォーマンスレポートには、半透明レンダリングのパフォーマンスコストについて特に説明があります。「一般的に、 UI、シーン、粒子などの原因が高いパフォーマンスコストを導きます。」という文が書いてあります。わかりたいのは、UI(ほとんどのUIは半透明部分があります)が半透明度にどの程度影響を与えますか?UIを作成する際の注意事項はありますか?

ほとんどのモバイルプロジェクトに対して、この影響は大きいです。 半透明レンダリングのCPU側には、注意すべき2つの主なポイントがあります。

(1)UI Draw Call;(2)UI再構築。

UI Draw Callが高いほど、レンダリングの時間コストも高くなります。だから、UWAパフォーマンスレポートのCPUパフォーマンス詳細分析ページに、UI Draw Callの使用状況を確認することをお勧めします。一般的に、モバイルゲームに対して、ピーク値を40以下にコントロールすることをお勧めします。UI Draw Callを減らすため、主には図集をAtlasにパッケージすることやインターリーブを回避することなどです。具体的には自分でグーグルできます。

また、UI再構築も可能な原因であり、主にメインスレッドのselfウェイトコストに現れます。UIが再構築のメッシュが大きい場合、この状況はよく見られます。だから、できる限りに必要のないUIメッシュ再構築を避けってください。これもR&DチームがUI作成時に特に注意すべきところであります。


メモリ

Q2: 最近、Meizu Pro5でゲームを実行するとPSSメモリが急上昇することがわかりました。UWA GOTでテストしましたが、アセットメモリは増加していません。そしてこの問題はMeizu Pro5でのみ発生し、他のモデルではこの問題はありません。どうすれば解決できますか?

一つ簡単なプロジェクトを探しました、下記の図に、NPCの名前と影は同時に顕示出来ません、そうしないとPSSは急上昇します。

下図のように、GfxDriverメモリは増加し続き、1秒あたり約2MBであり、増加しているだけで減らすことはありません。長時間実行すると、Meizu Pro5がクラッシュします。

GfxDriverとPSSが一緒に上昇する場合、GPUにバグがある可能性が高いです。 以下のみを提案できます:
(1)特定のマシンに「UIシャドウ」を追加しないようにし、製作から避けます;
(2)Unityの上位バージョンでデモを実行して、メモリ問題が修正されるかどうかを確認します。

その後、問題主がUnityのバージョンを5.4.5から5.5.6にアップグレードしてから、auto graphics apiを選択した後、メモリ増加の問題が解決されました。


その他

Q3:new Action(Function)と直接にFunction関数を導入することとの違いは何ですか?たとえば、下記の2つの関数の違いは何ですか?

void Method(Action action)
{
}

void MethodCallBack()
{
}

void Start()
{
//Method(new Action(MethodCallBack))  Method(MethodCallBack) の違いは何ですか?どちらのパフォーマンスはより高いですか?
}

理論的には同じです。Method(MethodCallBack)がコンパイルされる時に、コンパイラーは自動的にnew Actionをパッケージしますから、コンパイルの結果から見ると同じです。
この2つの書き方はプロジェクトに時々コールされる場合は問題ありませんが、頻繁にコールされる場合は、外部でActionを定義し、そのActionをMethodに渡して再利用することをお勧めします。すなわち、

Action act = New ActionMethodCallBack);
void Start()
{
Method(act);
}

アニメーション

Q4: 古いアニメーションシステムを使用しており、アニメーションは個別にパッケージされて、実行時にアニメーションはAddClipを介してモデルに追加されますが、AddClipはRebuildInternalStateをトリガーしてピークを発生させます。このピークはどうやって解決できますか?そしてこの問題は古いシステムだけに起こしますか?

RebuildInteralStateはMecanimにもありますが、名前は違いて、「Animator.Initialize」になりました。両者の機能とトリガータイミングはほぼ同じです。
AddClipは確かに時間をかかります。これは以前からそうであったので、特別な要件がない場合は、できるだけシーンがカットするときにAddClipを置き換えることをお勧めします。Runtime(特に戦闘中)にはAddClipを頻繁にコールすることは推薦しません。


アセット管理

Q5:UWAでShaderVariantCollectionに関するすべての資料を確認した後、一つのShaderを事前にロードするShaderVariantCollectionを作りたいです。Shaderのバリアントが多いのため、そしてメンテナンスが便利のために、すべてのShader.keywardsの組み合わせを見つけるツールを作成したいです。ShaderVariantを生成するとき、 1つのパラメーターはPassTypeです。Material.GetTag( "LightMode"、true)で検索する場合、2つの問題があります。
1)一つのShaderに複数のSubShaderまたはPassが異なるLightModeを使用していますが、GetTag(“LightMode”, true)で最初の一つのみ見つかります。
2)一部のShaderにはTags{“LightMode”=XXX}を設定することはありませんが(主にサードパーティのプラグイン)、どうすればいいですか?

私はこちらにツールスクリプトを探します:https://paste.ubuntu.com/26462717

反射をやってみられます。KeywordとPasstypeを同時に見つけることができます。

static MethodInfo GetShaderVariantEntries = null;
public static List<string> GetShaderKeywords(this Shader target)
{
if (GetShaderVariantEntries == null)
GetShaderVariantEntries = typeof(ShaderUtil).GetMethod(GetShaderVariantEntries, BindingFlags.NonPublic | BindingFlags.Static);
        int[] types = null;
        string[] keywords = null;
        object[] args = new object[] { target, new ShaderVariantCollection(), types, keywords };
        GetShaderVariantEntries.Invoke(null, args);
        keywords = args[3] as string[];
        List<string> result = new List<string>();
        foreach (string keyword in keywords)
        {
            foreach (string t in keyword.Split(' '))
            {
                if (!result.Contains(t))
                    result.Add(t);
            }
        }
        return result;
    }

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

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