3
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity(C#)】MaterialPropertyBlock使って一つのマテリアルを使いまわす

Last updated at Posted at 2020-03-25

##MaterialPropertyBlock

下記記事で作成していたVRお絵描きアプリに
色の変更機能を設けようとした際にMaterialPropertyBlockを活用しました。

【参考リンク】:【Unity(C#)】ハンドトラッキングで簡易版VRお絵かきアプリ

描いた線ごとに色を変更したかったのですが、
描く予定の線の分だけマテリアルを用意するのは
あまりにも手間ですし、その都度Instantiateするのも
負荷的にどうなの?と感じたので
MaterialPropertyBlockの使い方を学ぶことにしました。

##デモ

リアルタイムに色違いのキューブがランダムに生成されるデモです。

MaterialPropertyBlock.gif

マテリアルは1つしか使っていません。

##コード

using System.Collections;
using UnityEngine;

/// <summary>
/// 色違い場所違いキューブ自動生成プログラム
/// </summary>
public class CubeCreate : MonoBehaviour
{
    [SerializeField] private GameObject _cube;

    private MaterialPropertyBlock _materialPropertyBlock;

    private int propertyID;

    private void Start()
    {
        _materialPropertyBlock = new MaterialPropertyBlock();

        //プロパティーのIDを取得しておく SetColorをstringで指定しても結局intに変換してるらしく、無駄らしい
        propertyID = Shader.PropertyToID("_Color");

        StartCoroutine(InstantiateColorCube());
    }

    /// <summary>
    /// ランダムな位置にランダムな色のキューブを生成 
    /// </summary>
    private IEnumerator InstantiateColorCube()
    {
        while (true)
        {
            //ランダムな値
            float randomValueA = Random.Range(-1.0f, 1.0f);
            float randomValueB = Random.Range(-1.0f, 1.0f);
            float randomValueC = Random.Range(-1.0f, 1.0f);
        
            //ランダムな値
            float randomMagnification = Random.Range(0.0f, 5.0f);

            //ランダムな位置にキューブ生成
            Vector3 randomPos = new Vector3(randomValueA, randomValueB, randomValueC);
            GameObject tmp = Instantiate(_cube, randomPos*randomMagnification, Quaternion.identity);

            //MaterialPropertyBlockで色を変更 元のマテリアルの色はそのまま
            MeshRenderer mr = tmp.GetComponent<MeshRenderer>();
            Color randomColor = new Color(randomValueA, randomValueB, randomValueC);
            _materialPropertyBlock.SetColor(propertyID, randomColor*randomMagnification);
            mr.SetPropertyBlock(_materialPropertyBlock);
        
            yield return null;
        }
    }
}

##SetColor , SetPropertyBlock

色をセットするためにSetColor を使います。
第一引数にShaderで定義されている色のProperty名を指定します。
(今回はIDで指定しています)

その後、Rendererに反映させるためにSetPropertyBlockを呼び出します。

##Shader.PropertyToID
Shader.PropertyToIDを使うことで
Shader内で定義されている特定のプロパティ名を
ID(int型)に変換することができます。

先ほどのSetColorの第一引数に渡すことができます。

メリットしてはStart関数内でIDを取得しているので
何度も指定したShader内プロパティの文字列ID(int型)
という処理を行わずに済み、負荷が軽くなります。

##参考リンク
【Unity】【シェーダ】MaterialPropertyBlockの使い方

[【Unity】MaterialのPropertyIDについて]
(http://haraken.hatenablog.com/entry/2018/07/06/%E3%80%90Unity%E3%80%91Material%E3%81%AEPropertyID%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

3
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?