夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Unityでアウトラインを持つオリジナルShaderを書く

本日はShader勉強枠です。

今回はUnityでアウトラインを持つShaderを書いていきます。

〇アウトラインシェーダー

アウトラインとはオブジェクトの輪郭が表示されるような見た目のShaderです。

f:id:Holomoto-Sumire:20210527210628j:plain

 これを実現するためには[アウトラインを表示するShader]、[通常の色を表示するためのShader]の二つで一つのShaderを作成します。

 

Shader "ImaCreate/Toon Outline"
{
    Properties
    {
       _Color("MainColor", Color) = (1,1,1,1)
    [Header(OutLine)]
     //OutlineSize
     _OutLineColor("OutLineColor",color) = (0,0,0,0)
          _OutLine("Outline",Range(0,1)) = 0
    }
        SubShader
     {//OutLineShader
          Pass{
              Tags {
                "RenderType" = "Transparent"

             "Queue" = "Geometry" }
               Cull Front
               CGPROGRAM
               #pragma  vertex vert
               #pragma  fragment frag
               #include  "UnityCG.cginc"
              struct  appdata_t
              {
                 float4 vertex:Position;
               float3 normal : NORMAL;
              };
               struct v2f
               {
                 float4 pos: SV_POSITION;
               };
                 float _OutLine;
               float4 _OutLineColor;
               v2f vert(appdata_t v)
               {
                  v2f f;
                 v.vertex += float4(v.normal * (_OutLine * 1 / 5),0);
                  f.pos = UnityObjectToClipPos(v.vertex);
                 return f;
               }
               float4 frag(v2f i) :SV_Target
               {
                 return _OutLineColor;
               }
               ENDCG
             }
        Pass
        {
           Cull Back
           Tags
           {
                "PassFlags" = "OnlyDirectional"
             }
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #include "UNITYCG.cginc"
                   struct appdata_t {
                              float4 vertex:Position;
                   };
               struct v2f {
                   float4 pos: SV_POSITION;
               };
               float4 _Color;
               v2f vert(appdata_t v)
               {
                   v2f f;
                   f.pos = UnityObjectToClipPos(v.vertex);
                   return f;
               }
               float4 frag(v2f i) :SV_Target
               {
                 return _Color;
               }
                   ENDCG
                }                  
     }
}

ここでのポイントはPassブロックを二つ持っている点です。

最初のPassブロックではアウトラインのみを表示しています。

このPassでは

Cull Front

によってカリングが働きメッシュの裏面のみが表示されます。

この際に頂点shaderで頂点を法線方向に展開しています。

                 v.vertex += float4(v.normal * (_OutLine * 1 / 5),0);
                  f.pos = UnityObjectToClipPos(v.vertex);

これは_OutLineの値によって閾値を成業しています。これによってアウトラインの太さを自在に変えることができます。

f:id:Holomoto-Sumire:20210527211047j:plain

f:id:Holomoto-Sumire:20210527210628j:plain

2つ目のPassでは単に色を付けているだけです。

しかしこのシェーダーではカリングが裏面で表面が描画されるため、結果的にアウトラインに埋もれることなく描画されます。

以上でアウトラインを持つオリジナルShaderがかけました。