MRが楽しい

MRやVRについて学習したことを書き残す

ホロ恋子ローポリモデルの負荷試験を行う その2(SetPass calls の発生検証)

本日はホロ恋子ローポリモデルの負荷試験です。
ホロ恋子ローポリモデルの表示数を増やしてレンダリング統計ウィンドウで確認してみます。
前回記事の続きです。
bluebirdofoz.hatenablog.com

表示モデルを増やす

早速、シーンにモデルを25体追加してみました。
f:id:bluebirdofoz:20190515093056j:plain

この状態でシーンを再生し、まずはレンダリング統計ウィンドウで確認してみます。
すると以下の通り、Batches が 26、SetPass calls が 2 となりました。
f:id:bluebirdofoz:20190515093108j:plain

Batches の増加は順当ですが、SetPass calls が増えていません。
これはレンダリング統計ウィンドウの調査で記事にした通り、「同じマテリアルの SetPass Call は統合」されるためです。

マテリアルの動的更新によるSetPass callsの発生

単純にアプリとして利用する限りは最適化されるのは良いことですが、モデルの負荷試験としては適切とは言えません。
SetPass calls がモデル毎に呼ばれるようにしてみます。

Unity の設定による変更方法が不明だったので、スクリプトを追加して個別に SetPass calls を発生させることにしました。
以下のような起動時にマテリアルへテクスチャを再設定するスクリプトを作成しました。
・SetTexture.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetTexture : MonoBehaviour {
    /// <summary>
    /// マテリアルに設定するテクスチャ
    /// </summary>
    public Texture setTexture;
    /// <summary>
    /// 参照マテリアル
    /// </summary>
    private Material p_Material = null;

    /// <summary>
    /// 起動時処理
    /// </summary>
    void Start () {
        // コンポーネントがアタッチされたオブジェクトのマテリアルを取得する
        Renderer renderer = GetComponent<Renderer>();
        p_Material = renderer.material;
        // メインテクスチャを設定する
        p_Material.SetTexture("Texture", setTexture);
    }
}

起動時にマテリアルが動的に更新されるため、SetPass calls が統合されなくなるはずです。
試しに1体のモデルにスクリプトをアタッチしてみます。
f:id:bluebirdofoz:20190515093126j:plain

この状態でシーンを再生してみると……。
SetPass calls が 3 になりました。マテリアルを動的に変更されたモデルの SetPass calls が分割されています。
f:id:bluebirdofoz:20190515093137j:plain

モデルを Prefab 化して全てのモデルに SetTexture スクリプトを反映してみました。
この状態でシーンを再生すると……。
f:id:bluebirdofoz:20190515093148j:plain
SetPass calls も 26 になりました。マテリアルの動的更新によって SetPass calls が個別に発生したことが分かります。

なお、逆にマテリアルを共有したまま更新したい場合は Renderer.sharedMaterial でマテリアルを参照するとよいそうです。
docs.unity3d.com

プレハブの動的追加によるSetPass callsの発生の検証

マテリアルの動的更新で SetPass calls は個別に発生することが分かりました。
しかし、この方法だとモデルに余計なスクリプトが追加されてしまいますし、テクスチャの多いモデルは設定が大変です。

モデルをそのままに、ゲームオブジェクト自体を動的に追加した場合は SetPass Call は個別に発生するのか検証してみます。
以下のような起動時に prefab を動的に追加するスクリプトを作成しました。
・InstantiatePrefab.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiatePrefab : MonoBehaviour {
    /// <summary>
    /// 動的に追加するプレハブ
    /// </summary>
    public GameObject setPrefab;

	// Use this for initialization
	void Start () {
        // 子オブジェクトとしてプレハブを生成
        Instantiate(setPrefab, transform);
    }
}

試しにスクリプトをアタッチしたゲームオブジェクトをシーンに配置します。
ホロ恋子ローポリモデルの prefab を引数に設定します。
f:id:bluebirdofoz:20190515093236j:plain

シーンを再生すると、Prefab がシーン上に動的に追加されました。
f:id:bluebirdofoz:20190515093247j:plain

こちらも同じく25個の同様のゲームオブジェクトを配置し、シーンを再生してみます。
するとこちらは SetPass calls が 2 になりました。
f:id:bluebirdofoz:20190515093257j:plain
マテリアルを動的に変更しない限り、同じ Prefab のマテリアルの SetPass Call は統合されることが分かります。