Shaderメモ【固定関数シェーダ】

#Shaderが書けないUnityエンジニアという事に危機感を感じてきたので、メモ書きしながら覚えていく事にする。

##現時点でのShaderの知識
ほぼなし。
頂点カラーとかをいじることによってキレイ描画できたりするもの。
そもそも頂点カラーについてもまともに説明できない。。

###◆コードを書きながら学んで行くことにする
参考にさせて頂いたサイト
http://tips.hecomi.com/entry/2014/03/16/233943

##Shaderのコードの構造
```
Shader "Structure Example" {
    Properties {
    	// インスペクタに表示されるプロパティ（色やテクスチャ等）
    }
    SubShader {
    	// ...頂点/断片プログラムを使用するサブシェーダ...
    }
    SubShader {
    	// ...パスごとに 4 つのテクスチャを使用するサブシェーダ...
    }
    SubShader {
    	// ...パスごとに 2 つのテクスチャを使用するサブシェーダ...
    }
    SubShader {
    	// ...見た目は悪いが、いずれでも実行するサブシェーダ :)
    }
    Fallback "Other Shader Name" // SubShader がいずれもダメだったときに試す別のシェーダ
} 
```
↑のサイトからほぼコピペしてきたものである。
正直今のところ、Propertiesの項目しか役割がわからない。
さらに言えば、インスペクタからどのようにデータを受け取って、どのように使うのかすらもわからない。
まぁこれから覚えていこう。。。


#固定関数シェーダ
「固定関数シェーダはプログラマブルシェーダをサポートしないGPUのために記述します」とのこと。
プログラマブルシェーダとは
「DirectX8から使われるようになった、頂点情報やピクセル描画方法をプログラマが独自にカスタマイズできる技術のこと。
昨今の素晴らしいエフェクトや画面効果の殆どはプログラマブルシェーダーを用いて作られており、今や必須の技術となってきている。」
ってはてなに書いてあった。

なるほど。
ということは表現の幅があまりない、GPUのパワーが弱いデバイス向けのシェーダーて感じかな。
DirectX7以前のデバイスと言われてもピンと来ないので、例えばどんなデバイスがあるのかとかは今度調べる。

###サンプルコード1
```
Shader "Custom/1" {
	SubShader{
		Pass{
			Color(1,0,0,0)
			}
	}
}
```
![SnapCrab_NoName_2016-7-13_23-55-15_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/30163/3333ffb4-5d12-7ff7-ee25-10e79a7a19d1.png)
こんな感じ。Passの中でColorを指定すると適用したマテリアルが真っ赤に塗りつぶされる。
どうも固定関数シェーダはPassだけで構成されるらしい。


## サンプルコード2
```
Shader "Custom/2" {
	SubShader{
		Pass{
			Material{
				Diffuse(1,1,1,1)
				Ambient(1,0,0,1)
			}
		Lighting On
		}
	}
}

```
![SnapCrab_NoName_2016-7-14_0-6-38_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/30163/60f00578-83c1-d48b-fc84-dc5229cd14b1.png)

影がついた。(ちなみにLighting Onの行をコメントアウトしたら影もつかず真っ白になった)
Diffuseはオブジェクトのベースカラー。
AmbientはRenderSettingsから設定できる、AmbientLight(環境光)の色。
らしい。

確かに上の例ではAmbientで赤をしているため、赤色の光で照らされたようになってる。



##サンプルコード3
```
Shader "Custom/3" {
	Properties{
			_Color("Main Color", COLOR) = (1,0,0,1)
			}
			SubShader{
				Pass{
					Material{
						Diffuse[_Color]
						Ambient[_Color]
			}
			Lighting On
		}
	}
}

```
Propertiesの指定が増えた。
変数の書き方は　
```
変数名(Inspectorでの表示名, 型) = 値
```
って感じかな。
SubShaderの中では[変数名]みたいに書いて使う感じか。

![SnapCrab_NoName_2016-7-14_0-13-42_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/30163/0860934c-f89b-f394-c07a-a04711349e0f.png)

確かにインスペクタから値を変更できる様になってる。
値(色)を変更するとインタラクティブに表示が変わる。

##サンプルコード4
```
Shader "Custom/4" {
	Properties{
		_Color("Main Color", Color) = (1,1,1,0)
		_SpecColor("Spec Color", Color) = (1,1,1,1)
		_Emission("Emmisive Color", Color) = (0,0,0,0)
		_Shininess("Shininess", Range(0.01, 1)) = 0.7
		_MainTex("Base (RGB)", 2D) = "white" {}
		}
		SubShader{
			Pass{
				Material{
					Diffuse[_Color] //メイン色
					Ambient[_Color] //環境光の色
					Shininess[_Shininess] //光沢の強さ？
					Specular[_SpecColor] //反射光の色？
					Emission[_Emission] //表面から放出される光の色
		}
		Lighting On
		SeparateSpecular On
		SetTexture[_MainTex]{
				Combine texture * primary DOUBLE, texture * primary
			}
		}
	}
}

```
急に難しくなった。

以下雑メモ

・Emmissionは自己発光したい時に使う。
(http://docs.unity3d.com/jp/current/Manual/StandardShaderMaterialParameterEmission.html)
・SpparateSpecular Onにするとスペキュラ効果(光の反射)がシェーダの最後に適用されるようになる。
・SetTextureの{}内で行っている処理については
http://docs.unity3d.com/ja/current/Manual/ShaderTut1.html
を参照

##指定できるプロパティの型
```
Properties
{
    _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // sliders
    _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5
    _RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4
    _RefrColor ("Refraction color", Color) = (.34, .85, .92, 1) // color
    _ReflectionTex ("Environment Reflection", 2D) = "" {} // textures
    _RefractionTex ("Environment Refraction", 2D) = "" {}
    _Fresnel ("Fresnel (A) ", 2D) = "" {}
    _BumpMap ("Bumpmap (RGB) ", 2D) = "" {}
}
```
ふむふむ。
シンプルなシェーダだけあってそこそこ覚えやすかった。
参考にさせて頂いてるサイトもわかりやすくていい感じ。
次の記事ではサーフェイスシェーダについて書いていく。