はらけんログ

unity触ったりバイクに乗ったり

【Unity】続・スクリプトからMaterialをオブジェクトごとに変更ーMaterialPropertyBlock編

久しぶりに更新します。

 

今回は以前の記事についての補足、応用編です。

haraken.hatenablog.com

 

haraken.hatenablog.com

 

 

前回の記事では、スクリプトから任意のMeshごとにMaterialの情報をSetする方法を記載しました。

 

この方法より処理が軽くする方法がありました。

複数のMeshのMaterial情報を、毎フレーム更新するような場合には特に効果が見られます。

 

 

複数のcubeをMaterialのEmissionの値を変えて光らせたいと思います。

※光っていることが分かりやすいようにPostProcessのBloomを設定しておきます。

f:id:HarakeN:20190227185009p:plain

 

 

1.前回までの方法で光らせてみる

下記のようなスクリプトになると思います。

public class SetMaterialPropertyManager : MonoBehaviour
{
    [SerializeField] MeshRenderer objMesh;

    int emissionID;

    [SerializeField] float emissionValue;

    void Start()
    {
        emissionID = Shader.PropertyToID("_EmissionColor");
    }

    void Update()
    {
    Color emissionColor = new Color(emissionValue, emissionValue, emissionValue);

    for (int i = 0; i < objMesh.Length; i++) {

        objMesh[i].material.SetColor(emissionID, emissionColor);
    }
}

 

実行して emissionValueの値を変えてみると、、、

f:id:HarakeN:20190227190043p:plain

光りましたね。Batchesは102でした。

 

 

2.MaterialPropertyBlockを使用する

 「Material.Set~」は新しくMaterialを生成しているので、レンダリングパスが増えて描画処理が重くななるようです。しかし、MaterialPropertyBlockを使用すると、新しくMaterialを生成せず、そのまま情報を流し込めるようです。

※詳しくは参考ページより

 

MaterialPropertyBlockを使う場合は、下記のようなスクリプトになります。

public class SetMaterialPropertyManager : MonoBehaviour
{
    [SerializeField] MeshRenderer objMesh;

    MaterialPropertyBlock block = null;
    int emissionID;

    [SerializeField] float emissionValue;

 

    void Start()
    {
        block = new MaterialPropertyBlock(); //初期化
        emissionID = Shader.PropertyToID("_EmissionColor");
    }

    void Update()
    {
        Color emissionColor = new Color(emissionValue, emissionValue, emissionValue);


        block.SetColor(emissionID, emissionColor); //materialにSetしたい処理

        for (int i = 0; i < objMesh.Length; i++) {
            objMesh[i].SetPropertyBlock(block);
        }
    }
}

 

実行してみると、、、

f:id:HarakeN:20190227192017p:plain

光りました。

先ほどとやっていることは変わりませんが、Batchesは20になり先ほどの5分の1の処理で済んでいます。

 

 

 

 

まとめ

Meshごと個別にMaterialの情報を頻繁に変えたい場合はMaterialPropertyBlockを使うと格段に処理が速くなります。使用してみてください。

 

 

 

参考ページ

tsubakit1.hateblo.jp