標準のシェーダーを改造しよう！　DecalShaderを２枚から３枚にしてみよう

この投稿は[UnityAdventCalender2014](http://qiita.com/advent-calendar/2014/unity) 14日目の投稿です。


## 標準シェーダーを改造しよう

まず[Unityのダウンロードページ](http://japan.unity3d.com/unity/download/archive)のここからシェーダーをダウンロード
![UNITY_-_以前の_Unity_のダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/12129/1aed9759-2788-1a35-20ca-5432458d9d9b.png)


### 今回やること

ダウンロードしてきたシェーダーの中のデカールシェーダーを改造してみる。

標準のデカールシェーダーがやれること
・ベースのテクスチャの上に違うテクスチャを重ねられる。

やりたいこと
・３枚のテクスチャを重ねてみたい

素材は[ジュエルセイバー](http://www.jewel-s.jp/)の素材を使ってます。

ここにある３つの素材を
![4644ffc70a543fb6a01e8501b5b630fd.png](https://qiita-image-store.s3.amazonaws.com/0/12129/0530a799-357c-e802-fcf7-05714e356c8f.png)

こうします
![0d9b2f10728934e5f8b7790257df548d.png](https://qiita-image-store.s3.amazonaws.com/0/12129/792185c8-ec06-e979-203e-ef01470f73af.png)

## シェーダーを改造する

### 改造元のシェーダーはこれ
```
Shader "Decal" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB)", 2D) = "white" {}
	_DecalTex ("Decal (RGBA)", 2D) = "black" {}
}

SubShader {
	Tags { "RenderType"="Opaque" }
	LOD 250
	
CGPROGRAM
\#pragma surface surf Lambert

sampler2D _MainTex;
sampler2D _DecalTex;
fixed4 _Color;

struct Input {
	float2 uv_MainTex;
	float2 uv_DecalTex;
};

void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
	half4 decal = tex2D(_DecalTex, IN.uv_DecalTex);
	c.rgb = lerp (c.rgb, decal.rgb, decal.a);
	c *= _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
}

Fallback "Diffuse"
}

```

### そして改造後
```
Shader "CustamDecal" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB)", 2D) = "white" {}
	_DecalTex ("Decal (RGBA)", 2D) = "black" {}
	_FrameTex ("Frame (RGBA)", 2D) = "black" {}
}

SubShader {
	Tags { "RenderType"="Opaque" }
	LOD 250
	
CGPROGRAM
\#pragma surface surf Lambert

sampler2D _MainTex;
sampler2D _DecalTex;
sampler2D _FrameTex;
fixed4 _Color;

struct Input {
	float2 uv_MainTex;
	float2 uv_DecalTex;
	float2 uv_FrameTex;
};

void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
	half4 decal = tex2D(_DecalTex, IN.uv_DecalTex);
	half4 frame = tex2D(_FrameTex, IN.uv_FrameTex);
	c.rgb = lerp (c.rgb, decal.rgb, decal.a);
	c.rgb = lerp (c.rgb, frame.rgb, frame.a);
	c *= _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
}

Fallback "Diffuse"
}
```


## 結果

こんな感じに設定して
![6f962700d9bc7df594c7667be7df4141.png](https://qiita-image-store.s3.amazonaws.com/0/12129/d2fc7004-9057-917f-07eb-94502328a879.png)


こうじゃ！
![5749d8acccfcd024c9377d1d9efd03f2.png](https://qiita-image-store.s3.amazonaws.com/0/12129/7c9c4ad5-9585-de10-f2aa-e7fe266977d2.png)

## やったこと

* パラメータのテクスチャを増やした。
* leap関数で合成した。

## Leap関数

```
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
half4 decal = tex2D(_DecalTex, IN.uv_DecalTex);
c.rgb = lerp (c.rgb, decal.rgb, decal.a);
```

c.rgb = lerp (c.rgb, decal.rgb, decal.a);

これが
cの上にdecalの色を上乗せするって処理
たとえばこれを
c.rgb = lerp (c.rgb, decal.rgb, 0.5);
にすると


![ebb468aece9a4625891d78aa16e8e867.png](https://qiita-image-store.s3.amazonaws.com/0/12129/38ea717a-8328-a833-c90f-58f5c0f079f5.png)
こうなる
(ここではdecalに女の子の絵が入っている。

### 何をしているの？

leap(a,b,c)
a と b の補間をしている
cはa->bのどの位置か？という事

cが0ならaのテクスチャだけしか表示されないし
cが1ならbのテクスチャしか表示されない
cが0.5ならaとbの色の中間になる。

leapのcにbのアルファの値入れているのは、アルファ0の所はaのテクスチャの色を使いたいから。


## おわりに

シェーダーはめっちゃ面白いしちょっとした改造でいろんなことができるので是非いろんな人に触ってみてほしい
そんな事を思ったのとあと同じ絵でレアリティが違うだけのアイコンを全部作るのはちょっと…って思ったのでなんとなく描いてみた

プログラム分かる人もわからない人もしぇーだーで遊んでみましょう！


おわり！


今回の素材は以下しようさせてもらいました。

タイトル：[ジュエルセイバーFREE]
URL：[http://www.jewel-s.jp/]