MRが楽しい

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

ユニティちゃんのマテリアルのSetPass Callをモデル毎に発生させる

本日はホロ恋子ローポリモデルの負荷試験のおまけ枠です。
ユニティちゃんのマテリアルのSetPass Callをモデル毎に発生させてみます。
前回記事の続きです。
bluebirdofoz.hatenablog.com

モデル増加時のレンダリング負荷

ユニティちゃんのモデル増加時の負荷を確認するため、2体のユニティちゃんのオブジェクトを用意します。
そのままシーンを再生すると、Batches 78、SetPass calls 14 となります。
f:id:bluebirdofoz:20190517092850j:plain

前回、1体辺りのユニティちゃんの負荷を計測したところ、Batches 41、SetPass calls 14 でした。
bluebirdofoz.hatenablog.com

ホロ恋子の拳商事と同様に「同じマテリアルの SetPass Call は統合」されていることが分かります。
更に Batches についてもまとめられているためか期待値の 81 よりも低い値になっています。
(Batches の内、1つはバッファクリアの Batches のため、1 + 40(1体のユニティちゃん) * 2(体) = 81 が期待値になります)

ユニティちゃんのマテリアルをモデル毎に変更する

前回記事ではホロ恋子モデルのマテリアルを動的に変更することで、モデル毎にSetPass Callが発生するようにしました。
ユニティちゃん相当のモデル増加時の負荷も計測するため、ユニティちゃんにも同じ処理を行うスクリプトを作成します。

ホロ恋子モデルとの違い、ユニティちゃんはマテリアルが複数のスキンメッシュ毎に設定されており、かつ、複数のスキンメッシュが同じマテリアルを参照しています。
よって、オブジェクトの子オブジェクトに含まれる Renderer を探査し、同名のマテリアルの変更を共有するスクリプトを作成しました。
・SetTextureChildren.cs

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

public class SetTextureChildren : MonoBehaviour {

    /// <summary>
    /// 起動時処理
    /// </summary>
    void Start () {
        // 自オブジェクトまたは子オブジェクトから Renderer コンポーネントを取得する
        // GetComponentsInChildren は再帰的に探査される
        Component[] renderers;
        renderers = GetComponentsInChildren(typeof(Renderer));

        // 動的に変更したマテリアルは同名のものを共有するため
        // 連想配列でマテリアル名とマテリアルを保持しておく
        Dictionary<string, Material> materialList = new Dictionary<string, Material>();

        if (renderers != null)
        {
            // 取得した Renderer オブジェクトを1つずつ処理する
            foreach (Renderer renderer in renderers)
            {
                // マテリアルとマテリアル名を取得する
                Material setMaterial = renderer.material;
                string materialName = setMaterial.name;
                // 既に同名のマテリアルを動的に変更したか
                if (materialList.ContainsKey(materialName))
                {
                    // 既に動的に変更した同名のマテリアルがあれば、それを再設定する
                    renderer.material = materialList[materialName];
                }
                else
                {
                    // 未編集のマテリアルであれば、カラーを再設定することでマテリアルの共有を切る
                    Color setColor = setMaterial.color;
                    setMaterial.color = setColor;
                    // 変更後のマテリアルは同じモデル内の同名マテリアルで共有するため
                    // 連装配列にマテリアル名と一緒に保持しておく
                    materialList.Add(materialName, setMaterial);
                }
            }
        }
    }
}

ユニティちゃんのオブジェクトに本スクリプトを以下のようにアタッチしました。
f:id:bluebirdofoz:20190517092916j:plain

この状態でシーンを再生してみると……。
f:id:bluebirdofoz:20190517092929j:plain
Batches 81、SetPass calls 27 となりました。想定通りの数値です。