シェーディングのかからないイラスト風の見た目にしたい!
このような感じのイラスト風のぺったんこです。
今回は、Unityのデフォルトシェーダーと、波の表現など一部で使いました頂点カラーを利用したシェーダーについて説明します。
なお、ゲーム本編はこちら。
Unityのデフォルトシェーダーを使う!
単純にライティングやシェーディングがかからず、テクスチャカラーのみ表示したい場合、私は普段Unlit>Textureと、Unlit>Transparentを使っています。
アルファがない場合はTexture、ある場合はTransparentにします。
ちなみに今回は、キャラはアルファを使っていないのでUnlit>Textureにしました。
Unlit>Texture と デフォルトのStandard シェーダー
波打ち際に、自作シェーダーを使う!
ここですが、Unlit>Transparentは使っていません。なぜなら、下のようになるからです。
波うち際部分はUVスクロールを使ってアニメーションさせていますので、波がひいていくところでスパッとテクスチャが切れますね。ここをグラデーションさせてなじませたいです。これを実現するために、頂点カラーをモデルに適応するシェーダーを作りました。
※頂点カラーについて
その名の通り、頂点一個一個がもつRGBAのカラー値の事です。この値を使うことで、頂点一個一個にたいして色を乗せたり、透明にしたりできます。(頂点と頂点の間のカラーは通常グラデーション補完になります。)塗り方に関してはmayaや3dsmax等ソフトによりそれぞれ異なりますので、ご使用中のソフトのマニュアルをご参照ください。
頂点カラーをぬる
・・・というわけで、波ポリゴンのモデリングまで戻り、モデルに頂点カラーを塗ります。今回は、波が引いていく側の頂点をすべてRGBA[1,1,1,0](透明)、それ以外をRGBA[1,1,1,1](真っ白)としました。イメージとしては、こんな感じになります。波がひいていく側のふちが透明になっているのがお分かりいただけるでしょうか。
そして、このモデルをUnityに持っていきます。
頂点カラーを表示する
Create>Shaderから新しいshaderファイルを作成して、中身を以下のようにして保存します。Unityのシェーダーにはいくつか記法がありますが、今回はサーフェスシェーダーというものを使っています。
Shader "Custom/WaveColor" {
Properties{
_BaseColor("Base Color", Color) = (0,0,0,1)
_MainTex("Base (RGBA)", 2D) = "white" {}
}
SubShader{
Tags
{
"Queue" = "Transparent-1"
"RenderType" = "Transparent"
}
Cull Off
ZWrite On
CGPROGRAM
#pragma surface surf SimpleVertex alpha
half4 LightingSimpleVertex(SurfaceOutput s, half3 lightDir, half atten)
{
half4 c;
c.rgb = 0.0;
c.a = s.Alpha;
return c;
}
sampler2D _MainTex;
half4 _BaseColor;
struct Input {
float2 uv_MainTex;
float4 color : COLOR;
};
void surf(Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb +_BaseColor.rgb;
o.Alpha = c.a *IN.color.a;
}
ENDCG
}
}
モデルのマテリアルをWaveColorに変更します。これで、頂点カラー(アルファ)を拾って透明度に反映してくれるようになりました。こんな感じです。実になじんでいます。
簡単なシェーダー解説
細かく覚えなくてもいいですが、ある程度理解しておくと改造して使うときにも役に立つと思うので、簡単に解説をいれておきます。
Shader "Custom/WaveColor" {
ここでは、マテリアルからシェーダー選択ドロップダウンで表示される名前を決めています。ファイル名ではなくここの名前を見ていることに注意してください。(同じ名前が複数あるとめんどくさいことになりますので管理は適切に。)
Properties{
_BaseColor("Base Color", Color) = (0,0,0,1)
_MainTex("Base (RGBA)", 2D) = "white" {}
}
マテリアルでこのシェーダーを選択したとき、Inspectorに表示されるプロパティです。変数名(表示名, 変数の型 ) = 初期値 という感じです。
SubShader{
Tags
{
"Queue" = "Transparent-1"
"RenderType" = "Transparent"
}
Cull Off
ZWrite On
CGPROGRAM
#pragma surface surf SimplVertex alpha
描画順など宣言類です。おまじないとしてスルーしても良いですが、テクスチャや頂点カラーでアルファを使って透明を描画するあたって重要な部分でもあります。
"Queue" はUnityがレンダリングする順番を示します。今回はアルファが含まれているのでTransparentとかきます(中身は3000という数字)。-1というのは、2999にして、ほかより優先度をあげて前後関係がおかしくならないようにしています。
"RenderType" これは、アルファが含まれているのでTransparentにします。
#pragma surface surf SimpleVertex alpha
これはsurfという描画関数がありますよ、SimpleVertexというライティング関数がありまよ、alphaを使いますよ(アルファを使う場合はここを書き忘れるとおかしくなるので注意してください)という意味になります。
half4 LightingSimpleVertex(SurfaceOutput s, half3 lightDir, half atten)
{
half4 c;
c.rgb = 0.0;
c.a = s.Alpha;
return c;
}
上で宣言したライティング関数になります。surf関数が終わった後のライティングの処理を書きますが、今回ライティングはないので、rgb値は0にしています。が、aに関しては、無しにすると一切なにも表示されなくなるので、surfで生成したアルファをそのまま持っていきます。
sampler2D _MainTex;
half4 _BaseColor;
struct Input {
float2 uv_MainTex;
float4 color : COLOR;
};
void surf(Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb +_BaseColor.rgb;
o.Alpha = c.a *IN.color.a;
}
ENDCG
}
}
sampler2D _MainTex;
half4 _BaseColor;
これらは、一番上で宣言したプロパティ変数を使うときにはここでも宣言しないといけません。よく忘れます。
struct Input ...
これは、下記のsurfという描画関数に渡す頂点の情報になります。(頂点がどんな情報をもっているのかということです。)今回は、_MainTexのUV情報(float2型)と、頂点カラー(float4型)の2つを渡します。
void surf...
これは描画関数です。描画するピクセル一個一個に対して、テクスチャや頂点のカラーなどをどう料理するのかを書いていきます。
処理としては
テクスチャカラーを取得
出力カラー = テクスチャカラーとベースカラーをまぜる
出力アルファ= テクスチャアルファと頂点アルファをまぜる
見ていただくとわかるとおり、頂点カラーといいつつ、頂点アルファしか使っていませんね・・・。