[Unity]シェーダでテクスチャを張る

VRChatのおかげでシェーダについていろいろ教わったのでとりあえず記録
もし自作シェーダを作りたい人がいたらその人の参考になれるように

しかし猫並みの脳なので間違ってることも多いと思われます

まず初回はテクスチャを張ってみます
#シェーダの作り方#
次の章でコードについて触れるので知ってたら飛ばしてください～

1.まずunityのProject欄で右クリック
2.Create → Shader → UnlitShader をクリック
![1.png](https://qiita-image-store.s3.amazonaws.com/0/299484/c7beb6ba-2a56-f6ff-82a0-35f9b978f1ce.png)

これでシェーダ(unlit)が完成
![2.png](https://qiita-image-store.s3.amazonaws.com/0/299484/b8d87f41-eeeb-c6d7-2643-9ebca2a799f0.png)

次にテスト用にシェーダと同じようにマテリアルを作成
![3.png](https://qiita-image-store.s3.amazonaws.com/0/299484/e8074fda-b264-3590-3db5-3fcca669c26f.png)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/299484/e0fe0c11-3d4d-2431-8b25-2897fb3406a1.png)

このままだとこのマテリアルのシェーダはStandardなので さっき作ったシェーダをマテリアルにドラッグ&ドロップ
右のInspectorの上のほうにShedarがあるので そこがStandardではなければ完成
![5.png](https://qiita-image-store.s3.amazonaws.com/0/299484/b06f8faf-5310-dbee-de34-5ce4d7b351bf.png)

##テスト##
![6.png](https://qiita-image-store.s3.amazonaws.com/0/299484/e7a3b353-3ac7-9536-623e-af179840fa36.png)
マテリアルに髪の毛のテクスチャを入れてキューブやスフィアに適用しました
テクスチャが表示されているので ちゃんとできてます

#コード#
長くなりましたがコードを見てみましょう

```
Shader "Unlit/unlit"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}
```

けっこうC言語の形があるので 知らない場合は少し勉強してみてもいいかも（構造体とか関数の形とか）
昔知りたかったこととかをゆる～く解説します

(もっと詳しくてわかりやすいサイト様)

[Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた](http://tips.hecomi.com/entry/2014/03/16/233943)
[Unity Shader まとめ](http://unitech.hatenablog.com/entry/2015/03/11/001953)
[Unityのシェーダーまとめスライドを作ってみた](http://esprog.hatenablog.com/entry/2016/03/06/135828)

##シェーダの名前##

```
Shader "Unlit/unlit"
{
```

ここは　このシェーダがさっきのInspector上でどのように表示されるかです
**Unlit/**　 はどこに分類されているかを表していて
**unlit**　　というのがこのシェーダの名前になっています
![7.png](https://qiita-image-store.s3.amazonaws.com/0/299484/7103203f-5d4b-0c33-da4c-f729ca70f292.png)

名前は最初にシェーダを作った時の名前になります
自分は unlit という名前で作った後、 Shader_unlit という名前に変えたため unlit となっています

##Inspector上での変数##

```
Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
```

ここはInspector上で値を変更したり、テクスチャを追加するときに使います
**_MainTex**　がこの変数の名前
**"Texture"**　がInspector上で表示される名前
**2D**　　がこの変数の種類
= から右側が初期値となっています（たぶん）
![8.png](https://qiita-image-store.s3.amazonaws.com/0/299484/9c1559de-b419-4661-e353-46fb51b4b1c6.png)
（自分はInspector上で値を変えることが多いのでこれからたくさん出てくるかもしれません...）

##シェーダ内部##

```
SubShader
	{
		...
		Pass
		{
```

ここはPass内に処理を書いていくぐらいの認識しか...
複数の処理をするときにPassを何個か書きます
詳しくは上のURLの凹みさんやリファレンスを参照してください

```
Tags { "RenderType"="Opaque" }
		LOD 100
```

Tagは結構重要なのでいつか記事で書きます　多分

**LOD**とはLevel of Detailの略でレベルの低いハードウェアでは表示させないみたいな認識...？
あんまり使わないしわからないです；；
[詳しくはリファレンス！　Debugging DirectX 11 shaders with Visual Studio　シェーダ LOD](https://docs.unity3d.com/jp/460/Manual/SL-ShaderLOD.html)

```
CGPROGRAM
...
ENDCG
```

ここからシェーダの処理を書いていく　～　処理終わり みたいな宣言です

```
#pragma vertex vert
#pragma fragment frag
```

頂点シェーダやフラグメントシェーダを使うときに書きます
**vert** が頂点シェーダ使うときの名前になります(**frag**はフラグメントシェーダの)
これを変えるときは関数の名前も変えましょう

FOGはいま勉強中です...

```
#include "UnityCG.cginc"
```

シェーダで使う関数などまとめて書かれています
そのほかいろいろ定義されていたり

##構造体や変数##

```
struct appdata
{
	float4 vertex : POSITION;
	float2 uv : TEXCOORD0;
};
```

構造体です　Ｃ言語をやったことがある人はなんとなくわかるかもしれません
いろいろな変数をまとめておくみたいな

この構造体ではUnityからどのような値をもらってくるかを宣言しています
たとえば float4 vertex : POSITION; は
float4 **vertex**　にローカル座標の値を入れるみたいな

```
struct v2f
{
		float2 uv : TEXCOORD0;
		UNITY_FOG_COORDS(1)
		float4 vertex : SV_POSITION;
};
```

もう一つの構造体です
これは頂点シェーダで決めた値をフラグメントシェーダに渡すときに使う箱ですね

初心者の時に一番知りたかったこととして **v2f** が謎だったんですが ただの vertex to fragment だったんですね
変えても大丈夫なので読みにくい人は変えましょう（）

```
sampler2D _MainTex;
float4 _MainTex_ST;
```

Propertiesで宣言した変数を使いたい場合はここらへんで宣言しときましょう

##頂点シェーダ##

```
v2f vert (appdata v)
{
	v2f o;
	o.vertex = UnityObjectToClipPos(v.vertex);
	o.uv = TRANSFORM_TEX(v.uv, _MainTex);
	UNITY_TRANSFER_FOG(o,o.vertex);
	return o;
}
```

これが頂点シェーダですね
appdata型の変数を受け取って v2f型の変数を返す（さっき定義した構造体）
構造体を作って　それぞれの変数に値を入れて　returnしてます

**UnityObjectToClipPos** ： 同次座標において、オブジェクト空間からカメラのクリップ空間へ点を変換します。これは、mul(UNITY_MATRIX_MVP, float4(pos, 1.0)) と同等に使用されます。(リファレンスより)
**TRANSFORM_TEX** ： 使うテクスチャ（_MainTex）とのuv座標を関連づける

##フラグメントシェーダ##

```
fixed4 frag (v2f i) : SV_Target
{
	// sample the texture
	fixed4 col = tex2D(_MainTex, i.uv);
	// apply fog
	UNITY_APPLY_FOG(i.fogCoord, col);
	return col;
}
```

これがフラグメントシェーダです
処理としては**tex2D**を行ってその値をreturnしてます

そしてそのreturnする対象ですが **: SV_Target** と書かれてます
これは**セマンティクス**と言って返す対象をきめます
種類については [Unityのシェーダーセマンティクスまとめ](https://qiita.com/sune2/items/fa5d50d9ea9bd48761b2) 様で

最初はセマンティクスはこのまま覚えればよいと思います　あとその型がfixed4なのも

受け取る構造体は v2f型 で名前を i としています（初心者なりの注意としては i なのでfor文使うときに二重に宣言しないように）

**tex2D** については　vertでテクスチャとuv座標を関係づけているので それに合わせて色を塗る　みたいな
詳しくは　[Unity Shaderの基礎 part 2](https://qiita.com/kaiware007/items/ffe7c546bc71136cf8da) 様

#終わりに#
はじめてQiitaを書くテストとして書きました
とても長くて見にくいと思います；；

自分もまだまだ初心者なので間違ったことを書いていたら教えていただければ光栄です

次記事を書くとしたら ランバート反射 と Propertiesの例　を書きたいですね