【Unity】アウトライン(拡大法)シェーダー

アウトライン拡大法とは

アウトライン拡大法とは、元のモデルを拡大して、アウトラインカラーで塗りつぶしたあとに、元のモデルを前に重ねて描画する手法です。
簡単に実装できますが、冒頭の画像にもある通り、色々な問題点を抱えています。具体的には以下のケースで問題が発生します。
- 同じ位置の頂点に複数の法線がある場合
- アウトラインと同じ位置に別のモデルがある場合
ShaderLabで実装する
環境
- Unity 2021.2.11f1
- Build-in Rendering Pipline
Outline.shader
https://gist.github.com/went5/27a418b3be8e83717c52034f80fdc24f
複数のパスを使う
SubShader内に2つのパスを指定しています。アウトラインはライティングを適用しないため、
LightModeタグ に Always を指定しています。
また、分かりやすいようにアウトラインの方にはパス名をつけています。
パス名は識別子としての機能だけではなく、C#側から参照できます。1
アウトライン部分を描画する
fixed4 _OutlineColor;
float _OutlineWidth;
v2f vert(appdata v):SV_POSITION
{
v2f o;
v.vertex.xyz += v.normal * _OutlineWidth;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i):SV_Target
{
return _OutlineColor;
}
頂点の座標を法線方向に拡大しています。 _OutlineWidth によって拡大率を変更できるようにしています。
下記の図はイメージ図です。

元のモデル部分を描画する
プロパティに入れた色をそのまま描画しています。
fixed4 _Color;
float4 vert(float4 vertex:POSITION) :SV_POSITION
{
return UnityObjectToClipPos(vertex);
}
fixed4 frag(float4 v:SV_POSITION):SV_Target
{
return _Color;
}
以上の処理で、冒頭の画像を再現できます。
参考
アウトラインと同じ位置に別モデルがある場合の問題への対処法が載っています。
https://light11.hatenadiary.com/entry/2018/04/10/000006
Footnotes
Table of contents