【Unity】頂点カラーで輪郭線の太さを制御する
最近、3Dでアニメ的な表現をするのが流行っているような気がしてなりません。
3Dでアニメ的な表現というと、どうしても3D臭さというか違和感がつきものだと思います。
しかし、ハードや技術の進歩に伴い、徐々にアニメらしく見せることができるものができてきていると感じています。
ここで、最近よく名前が挙がるタイトルがGUILTY GEAR Xrdというゲームです。
1年ほど前初めて公開された動画は、なかなかインパクトのあるものだったと思います。
(3DCGに触れたことのある人なら尚更だと思います)
CGWORLDや、4Gamerのサイトでグラフィックスの特集が組まれたりもしました。
予想はしていましたが、あまりの力の入りように戦慄したものです(笑)。
前置きが長くなりましたが、このゲームで導入されている技法のひとつに、
キャラクターの輪郭線の太さを変化させる表現があります。
輪郭線を同じ太さではなく、ペンを走らせたように太さに強弱をつけることで、
より手描きらしく表現するというものです。
ギルティギアXrdはUnreal Engine 3で開発されていますが、
この表現をUnityで実現できないか、実験してみることにしました。
ギルティギアXrdでは、頂点カラーを用いてさまざまな制御を行っています。
4Gamerの記事にも載せられていますが、頂点カラーのアルファ値を輪郭線の太さの係数としています。
そこで、UnityのToony-BasicOutline.shaderをもとに、同様の処理を実装しました。
まず、頂点カラーの設定されたモデルを作成し、Unityにインポートします。
Blenderで、テクスチャを頂点カラーとして焼き込むのが手っ取り早いです。
次に、Toony-BasicOutline.shaderを改造します。
以下は一部を抜き出したもので、赤文字の部分が追加、変更箇所です。
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 color : COLOR;//頂点カラーを扱えるようにするため追加。
};
v2f vert(appdata v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
float2 offset = TransformViewToProjection(norm.xy);
//輪郭線の太さを設定している箇所。ここで頂点カラーのR値で太さを制御する。
//v.color.rが頂点カラーのR値。
//このままこれを掛けた場合、R値が0の際に輪郭線がなくなるため、
//ここでは補正として0.5をプラスしている。
o.pos.xy += offset * (v.color.r + 0.5) * _Outline;
o.color = _OutlineColor;
return o;
}
これにより、以下のような表現ができました。
頂点カラーを可視化したものは、以下のようになります。
赤い部分ほど太く、黒い部分ほど細くなっていることがわかります。
頂点カラーの活用により、表現の幅が広がったのではないかと考えています。
・参考文献
デフォルトアウトラインの太さ 凛(kagring)のUnity(とQt)勉強中ブログ