渋谷ほととぎす通信

「Unityをわかりやすく」初心者のためのゲーム作りブログ

シェーダープロパティアクセスが2.5倍早くなるPropertyToID関数

シェーダープロパティアクセスが2.5倍早くなるPropertyToID関数

こんにちは、Unityエンジニアのオオバです。

Materialの任意のプロパティを操作をする際に、

  • SetFloat
  • SetTexture
  • SetInt
  • SetColor...

などの関数を使用します。

文法的には

material.SetFloat("_Prop", 100f);  

のように、第一引数にプロパティ名をString型、第2引数に値を渡します。また、オーバーロードで第1引数にプロパティユニークID(int型)を渡すことも出来ます。

すべてのマテリアルプロパティー関数に文字列を渡すよりもユニーク ID を使用したほうが効率的です。

Shader-PropertyToID - Unity スクリプトリファレンス

リファレンスを確認すると、ユニークIDを渡した方が効率が良いということで、どのくらいパフォーマンスに違いがあるのかを確認したいと思います。

また、このユニークIDは以下のShaderクラスのstatic関数で取得できます。

Shader.PropertyToID("PropertyName")  

コチラの検証コードとフローで負荷を確認します。

  1. インスペクタからtoggle変数のチェックボタンを切り替える
  2. SetFloatオーバーロードを切り替える
  3. Unity Profilerで負荷を確認

PropertyToIdPerformance.cs · GitHub

シェーダープロパティアクセスが2.5倍早くなるPropertyToID関数_0

このようにtoggleフラグを切り替えると、明らかなパフォーマンスの違いが出ました。

文字列プロパティ指定ユニークID指定
4.20ms1.73ms

ユニークID指定の方が約2.5倍パフォーマンスが良いという結果です。

プロファイラーで処理の確認

文字列でプロパティ指定

シェーダープロパティアクセスが2.5倍早くなるPropertyToID関数_1

ユニークIDでプロパティ指定

シェーダープロパティアクセスが2.5倍早くなるPropertyToID関数_2

文字列でプロパティ指定すると、内部的にPropertyToIDを実行して更にSetFloatが実行されていることが分かります。
※Deepプロファイラで実行しないと関数名まで表示されません

まとめ

これらの結果から、Materialに値を渡す場合は、
ユニークIDを使用一択だと思われます。

パフォーマンスを考慮する上では文字列指定を使う理由はなさそうです。

オススメ記事