Help us understand the problem. What is going on with this article?

【Shader Forge】コードからshaderのプロパティにアクセスする

More than 3 years have passed since last update.

コードからShaderのプロパティにアクセスするにはどうすれば良いか悩んだので解決策を書きます。

できたもの
3月 19, 2016 00:49.gif
Outline Widthに影響しているプロパティを作成し、コードから制御しています。

流れとしては、
1:shaderにプロパティを作成する
2:プロパティ名を確認する
3:コードからプロパティを更新する
になります。

あと大切なマテリアルの取得についても書きます。

1:shaderにプロパティを作成する

スクリーンショット 2016-03-19 0.59.00.png
まずは、コードから変更するためのプロパティを作成します。
右クリックでメニューを出し、Properties/以下のメニューを選択して、PropertieNodeを作成します。
このとき、どのタイプのプロパティを作成したのかちゃんと確認しておくこと。

スクリーンショット 2016-03-19 1.01.29.png
今回は、Outline widthに使用するプロパティなので、float型のプロパティを作成しました。

スクリーンショット 2016-03-19 0.50.08.png
プロパティノードを作成した直後だと、node_****みたいな名前になのでとりあえず aaa に変更しました。
あとは普通にOutline widthに接続しました。

2:プロパティ名を確認する

スクリーンショット 2016-03-19 0.50.16.png
Shader Forgeによって作成されたシェーダーをプロジェクトviewで選択し、インスペクターを見ます。

スクリーンショット 2016-03-19 0.50.25.png
Properties という欄があり、そこに
_Color と _aaa というプロパティの存在が確認できます。
ここに記載されているプロパティ名を使ってコードからアクセスしていきます。

3:コードからプロパティを更新する

    public GameObject sphere;
    public Slider slider;

    void Awake ()
    {
        slider.OnValueChangedAsObservable ()
            .Subscribe (value => {
            sphere.GetComponent <Renderer> ().sharedMaterial.SetFloat ("_aaa", value);      
        });
    }

めっちゃ適当なのですが、
UniRxを使って、sliderの値が変化したときにシェーダーのプロパティを更新しています。
ようは、
shaderを管理しているマテリアルを取得し、そいつにSetHoge("name",value)してあげることでプロパティを更新することができます。
(Hogeの部分はプロパティの型が入ります。今回はfloat型を使ったのでSetFlot()ですね)

大切なマテリアルの取得について

マテリアルはRendererクラスが管理しています。
Rendererからマテリアルを取得する方法は、2種類あり、取得の仕方によって動作が大きく変わってしまうので注意が必要です。

1つめの取り方

GetComponent <Renderer> ().sharedMaterial

ですね。
sharedMaterialでマテリアルを取得し、シェーダーのプロパティを更新すると、
そのシェーダーを使っている全てのオブジェクトに影響が及びます。
3月 19, 2016 01:16.gif
こんな感じに。
マテリアルが共通で使われているのでstatusの SetPass callsも4 のままになっています。

2つめの取り方

GetComponent <Renderer> ().material

ですね。sharedMaterialがただのmaterialになりました。
そのため、1つのmaterialに対しプロパティを更新することができます。
3月 19, 2016 01:21.gif
こんな感じですね。
しかし、見てください。
statusの SetPass callsが6 になっています。
今回作成したシェーダーは2だけSetPass callsを増やします。
しかし、GetComponent ().materialで1つのマテリアルを取得し、プロパティを更新すると全く違うmaterialとしてゲーム世界に存在するので、またSetPass callsが2増えてしまいます。
SetPass callsの値が大きくなるとゲームパフォーマンスに影響してくるので安易に増やさないようにしましょう。

といっても僕もよくわからないので今後記事にしていきたいと思います

ドローコールやSetPass callsについては
http://qiita.com/baba_s/items/5260807ced7fc3c02ca6
これが良い感じにまとまってるのかな・・・?

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした