【Unity】続・スクリプトからMaterialをオブジェクトごとに変更ーMaterialPropertyBlock編
久しぶりに更新します。
今回は以前の記事についての補足、応用編です。
前回の記事では、スクリプトから任意のMeshごとにMaterialの情報をSetする方法を記載しました。
この方法より処理が軽くする方法がありました。
複数のMeshのMaterial情報を、毎フレーム更新するような場合には特に効果が見られます。
複数のcubeをMaterialのEmissionの値を変えて光らせたいと思います。
※光っていることが分かりやすいようにPostProcessのBloomを設定しておきます。
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の値を変えてみると、、、
光りましたね。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);
}
}
}
実行してみると、、、
光りました。
先ほどとやっていることは変わりませんが、Batchesは20になり先ほどの5分の1の処理で済んでいます。
まとめ
Meshごと個別にMaterialの情報を頻繁に変えたい場合はMaterialPropertyBlockを使うと格段に処理が速くなります。使用してみてください。
参考ページ