【Unity】シェーダプロパティアトリビュートまとめ

あまりまとまっているところがなかったので備忘録を兼ねてまとめました

# シェーダプロパティアトリビュートってなに？
プロパティに追加の属性を付加できるもの
主にはマテリアルのインスペクタエディタを拡張できたり、GPUに対して追加で情報を付加できます

## HideInInspector
c#レイヤーで毎度おなじみ`HideInInspector`
インスペクタ上からプロパティを隠すことができます
主にコードから弄るプロパティに対して付加します

```hoge.shader
Properties
{
	_MainTex ("Texture", 2D) = "white" {}
	[HideInInspector]_Hoge ("HogeValue", int) = 0
	_Fuga ("FugaValue", int) = 0
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/36911ba4-e49b-d8a0-775c-c09ee8262dc0.png)

## NoScaleOffset
テクスチャデータ形式(`3D`/`2D`/`Cube`)のtiling/offset欄を非表示にします

```hoge.shader
Properties
{
	[NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
	_Hoge ("HogeValue", int) = 0
	_Fuga ("FugaValue", int) = 0
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/d775bef7-35a7-2bc4-efc1-f0897a983d7b.png)

## Normal
テクスチャデータ形式(`3D`/`2D`/`Cube`)にノーマルマップ以外のテクスチャが指定された場合警告が表示されます
警告内の`FixNow`を押すと選択されたテクスチャがノーマルマップ指定になります

```hoge.shader
Properties
{
	[Normal]_MainTex ("Texture", 2D) = "white" {}
	_Hoge ("HogeValue", int) = 0
	_Fuga ("FugaValue", int) = 0
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/5cbaf6ca-6526-9343-f5d7-be40f561c209.png)

## HDR
テクスチャデータ形式(`3D`/`2D`/`Cube`)に選択されたテクスチャがHDRテクスチャであることを示します

## Gamma
[リニアカラー空間](https://docs.unity3d.com/jp/current/Manual/LinearLighting.html)を使う場合、`Color`プロパティについてはsRGBで提供されシェーダで渡される時にリニアカラーに変換されます。
`Float`/`Vector`についてはカラーデータかどうかはUnityから検知することはできないので明示的に`Gamma`アトリビュートを付与することによりカラー変換が適用されるようになります。

## PerRendererData
テクスチャデータ形式(`3D`/`2D`/`Cube`)に使用でき、対象のデータは`MaterialPropertyBlock`クラス
のインスタンス値で初期化されます。主にテクスチャデータを動的にスクリプトからセットする場合に使われます。
インスペクタ上では`HideInInspector`同様非表示になります。

## Toggle
データ形式が`Int`/`Float`の場合に利用できます。インスペクタ上で対象のプロパティがチェックボックスに変わりオンの時は`1`、オフの時は`0`となります。
また、トグルがオンの時はコンパイル時`(プロパティ名の大文字)_ON`のキーワードが有効になります。このキーワードは`#ifdef`などのプリプロセッサで使えます。（キーワードを利用するためには [multi_compile](https://docs.unity3d.com/jp/current/Manual/SL-MultipleProgramVariants.html)指定が必要です
キーワード名を指定したい場合が`Toggle(KEYWORD_NAME)`のように記述すれば指定することが可能です

```hoge.shader
_MainTex ("Texture", 2D) = "white" {}
[Toggle]_Hoge ("HogeValue", int) = 0
[Toggle(FUGA_ENABLE)]_Fuga ("FugaValue", Float) = 0
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/ba3baaec-a652-34f0-2838-9ac1d71f92e9.png)

## Enum
データ形式が`Int`/`Float`の場合に利用できます。インスペクタ上にプルダウンリストを表示します。
列挙する値を指定の仕方はオプションに`Foo,2,Bar,4`のような記述をすると`Foo`時は2,`Bar`時は4が設定されることになります。
また、C#上のenum値を指定することが可能でその場合はオプションに`NameSpace.EnumName`のような記述をします

```hoge.shader
Properties
{
	_MainTex ("Texture", 2D) = "white" {}
	[Enum(Foo,2,Bar,4)]_Hoge ("HogeValue", int) = 0
	[Enum(Product.TestEnum)]_Fuga ("FugaValue", Float) = 0
}
```

```TestEnum.cs
namespace Product
{
    public enum TestEnum
    {
        Foo,
        Bar
    }
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/71c22fad-8194-2b6f-fd52-00b69bc26657.png)

## KeywordEnum
基本的にはEnumと同じですが`KeywordEnum`の場合は選択された対象名のキーワードが有効になります。
例えば`[Enum(Foo,Bar)]_Hoge ("HogeValue", int) = 0`と定義した場合、Fooの場合は`_HOGE_FOO`, Barの場合は`_HOGE_BAR`のキーワードが有効になります。

## PowerSlider
データ形式がRangeに対してのみ使えます。オプションに値を設定することでインスペクタ上のスライダーを指数関数的にすることができます。なおオプション値に`1`を指定すると通常のRangeと同様の状態になります

```Hoge.shader
Properties
{
	[PowerSlider(0.5)]_PosX ("PositionX", Range(0.01, 1)) = 0
	_PosY ("PositionY", Range(0.01, 1)) = 0
	[PowerSlider(2.0)]_PosZ ("PositionZ", Range(0.01, 1)) = 0
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/263605/3be0a236-ca4f-546d-26db-6b46dcab9222.png)