「今日まなび」は最低1日1h、ゲーム作るために学びたいことなんでもいいから学んでいくコーナー。
完全自分用でまとめることは考えなくてOK.1記事1h。(1hでどんだけ学べるかのスピード感もみていきたいので)
1hのうちに次回学ぶことも決定しておくこと
環境:unity2021.3.40f
今日の学び
元のMaterialに設定した値は継承されない。型のデフォ値?になるっぽい
単純にメッシュの色を指定した色に変えるだけのShaderとそのMaterialを作っておきます。
そして、Materialでの指定色は事前に「赤」にしておきます。
この状態で、以下のコードを実行してみます。
MaterialPropertyBlockを作って、メッシュから取得し、デバッグログで色を表示するだけのものです。
using UnityEngine; publicclassTest009 : MonoBehaviour { void Start() { MeshRenderer renderer = GetComponent<MeshRenderer>(); MaterialPropertyBlock materialPropertyBlock =new MaterialPropertyBlock(); renderer.GetPropertyBlock(materialPropertyBlock); Debug.Log(materialPropertyBlock.GetColor("_Color")); } }
【結果】
とれた色は「赤」ではなく「RGBA(0.000, 0.000, 0.000, 0.000)」でした。
元のマテリアルのコピーのようなイメージで値も引き継がれるのかと思っていましたが違う模様。
別のMaterialPropertyBlockのインスタンス作ってからGetした場合でも設定した値はとれる
using UnityEngine; publicclassTest009 : MonoBehaviour { void Start() { MeshRenderer renderer = GetComponent<MeshRenderer>(); MaterialPropertyBlock materialPropertyBlock =new MaterialPropertyBlock(); renderer.GetPropertyBlock(materialPropertyBlock); Debug.Log("newした直後にGet:"+ materialPropertyBlock.GetColor("_Color")); materialPropertyBlock.SetColor("_Color", Color.black); renderer.SetPropertyBlock(materialPropertyBlock); Debug.Log("Setした:"+ materialPropertyBlock.GetColor("_Color")); MaterialPropertyBlock materialPropertyBlock2 =new MaterialPropertyBlock(); renderer.GetPropertyBlock(materialPropertyBlock2); Debug.Log("新しいMaterialPropertyBlockで同じRendererからGetした結果:"+ materialPropertyBlock2.GetColor("_Color")); } }
【結果】
新しいMaterialPropertyBlockのインスタンスでも、同じRendererに対してGetPropertyBlock
をすれば、
別のMaterialPropertyBlockのインスタンスで設定した指定色がとれました。
newした直後にGet:RGBA(0.000, 0.000, 0.000, 0.000) Setした:RGBA(0.000, 0.000, 0.000, 1.000) 新しいMaterialPropertyBlockで同じRendererからGetした結果:RGBA(0.000, 0.000, 0.000, 1.000)
インスペクタの挙動:MaterialPropertyBlockで設定した値は実行時に変えられなくなる
Materialを使っている場合は、ゲームを実行しながら値を変えることができますが、
MaterialPropertyBlockを使っている場合は値を変えることができなくなります。
ただこれはSetPropertyBlock
しているプロパティのみで、触っていないプロパティはゲームを実行しながら変更できます。
この挙動をみるに、SetPropertyBlock
するとMaterialPropertyBlockが常に値を設定しているように見えます。
複数のMaterialPropertyBlockのインスタンスが同じプロパティを更新した場合は後勝ちになる
いろんなコードから変更される場合を考慮して、Setする直前に必ずGetするのがよい。
using UnityEngine; public class Test009 : MonoBehaviour { void Start() { MeshRenderer renderer = GetComponent<MeshRenderer>(); MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock(); renderer.GetPropertyBlock(materialPropertyBlock); Debug.Log("newした直後にGet:" + materialPropertyBlock.GetColor("_Color")); //元のマテリアルに関係なくColor.clearがとれる materialPropertyBlock.SetColor("_Color", Color.black); //materialPropertyBlock1で黒を指定 renderer.SetPropertyBlock(materialPropertyBlock); Debug.Log("Setした:" + materialPropertyBlock.GetColor("_Color")); //ちゃんと設定した値=黒がとれる MaterialPropertyBlock materialPropertyBlock2 = new MaterialPropertyBlock(); //別に新しいインスタンス作る renderer.GetPropertyBlock(materialPropertyBlock2); Debug.Log("2つ目のMaterialPropertyBlockで同じRendererからGetした結果:" + materialPropertyBlock2.GetColor("_Color")); //あらかじめ別のインスタンスで設定した値=黒がとれる materialPropertyBlock.SetColor("_Color", Color.blue); //materialPropertyBlock2で青を指定 renderer.SetPropertyBlock(materialPropertyBlock); Debug.Log("2つ目のMaterialPropertyBlockでSetした:" + materialPropertyBlock.GetColor("_Color")); //ちゃんと設定した値=青がとれる →後勝ち } }
TODO (調べたいこと、やりたいこととか疑問)
・CommandBufferってなに?
・Unityで深度バッファの値をどうやって取得できる?
・法線マップを扱う
・Unityのシャドウマップってなんだろう
・影を制御したい、動かしたり形を変えたり、色をかえたり
・StandardShaderでできることを把握しておきたい
・FrameDebuggerの使い方まなびたい
・shaderで図形描いたりするのによく使う関数と使い方まとめ
終わったやつ
・自作shaderを適応したQuadでも影を落としたい
・ポストプロセスで例えばモノクロを適応したときに、一部分(例えば特定のキャラの描画だけとか)には適応したくない場合がある。
これまでカメラをわけて対応してきたが1つのカメラでもそういった制御ができる方法はないか
・Quad内の不透明部分のピクセルだけステンシルバッファに書き込むことはできないか