2022-11-30

(UNITY, SHADER)Can you draw the same texture multiple times in a single pass?

I'm new to shaders, and I'm trying to make an outline of a tk2d spine object(a 2d character). I know there are other ways to obtain the outline effect, but this approach got me curious. (Please don't suggest another way to draw outlines, respectfully, because that is not my question.)

So basically how I'm trying to get the outline effect is by getting the vertexes of my object, input a color, and draw it 8 directions(top, down, left, right, 4 diagonal directions) by setting offsets to each direction.

I got this working, and it looks fine, but my shader code doesn't, because I have a total of 9 passes, 8 of which do the exact same thing(draw the same texture), with the only difference being the offset direction, and the last pass drawing the tk2d spine character. I don't like that I have 8 almost-exactly repeated codes, it seems to be a waste because there is an area where the same calculation is done 8 times, and I suppose performance would be affected as well.

So, my question is : can I compress the 8 passes into one? i.e. saving the vertex position for each direction, and passing that information to the fragment shader.

I tried upscaling the vertexes, but this didn't get me the effect I wanted, because the characters do not have smooth edges, and therefore the "outline" became rigged.

this is my current code:

Shader "Custom/Shader_Spine_Battle_Red" 
{
   Properties 
   {
      
      _Color ("Color", color) = (1, 0, 0, 1)
      _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
      _OutlineWidth ("OutlineWidth", float) = 1
   }
   
   SubShader
   {
      Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
      ZWrite Off Lighting Off Cull Off Fog { Mode Off } Blend SrcAlpha OneMinusSrcAlpha
      LOD 110
      
      Stencil{
         Comp Equal
         }
      
      Pass 
      {
         CGPROGRAM
         #pragma vertex vert_vct
         #pragma fragment frag_mult 
         #pragma fragmentoption ARB_precision_hint_fastest
         #include "UnityCG.cginc"

         sampler2D _MainTex;
         fixed4 _Color;
         float _OutlineWidth;

         struct vin_vct 
         {
            float4 vertex : POSITION;
            float4 color : COLOR;
            float2 texcoord : TEXCOORD0;
         };

         struct v2f_vct
         {
            float4 vertex : SV_POSITION;
            fixed4 color : COLOR;
            float2 texcoord : TEXCOORD0;
         };

         v2f_vct vert_vct(vin_vct v)
         {
            v2f_vct o;

            // the only difference in the 8 passes is the two lines below
            v.vertex.x += _OutlineWidth * 0.1;
            v.vertex.y += _OutlineWidth * 0.1;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.color = _Color;
            o.texcoord = v.texcoord;
            return o;
         }

         fixed4 frag_mult(v2f_vct i) : SV_Target
         {
            fixed4 col = tex2D(_MainTex, i.texcoord);
            _Color.a *= ceil(col.a);
            col.rgb = _Color;
            col.a *= _Color.a;
            return col;
         }
         
         ENDCG
      }
      // (x 8 with only the rows mentioned above different

Pass { CGPROGRAM #pragma vertex vert_vct #pragma fragment frag_mult #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc"

     sampler2D _MainTex;
     fixed4 _Color;
     float _OutlineWidth;

     struct vin_vct 
     {
        float4 vertex : POSITION;
        float4 color : COLOR;
        float2 texcoord : TEXCOORD0;
     };

     struct v2f_vct
     {
        float4 vertex : SV_POSITION;
        fixed4 color : COLOR;
        float2 texcoord : TEXCOORD0;
     };

     v2f_vct vert_vct(vin_vct v)
     {
        v2f_vct o;

        o.vertex = UnityObjectToClipPos(v.vertex);
        o.color = v.color;
        o.texcoord = v.texcoord;
        return o;
     }

     fixed4 frag_mult(v2f_vct i) : SV_Target
     {
        fixed4 col = tex2D(_MainTex, i.texcoord) * i.color;
        return col;
     }
     
     ENDCG
  } 

} }






No comments:

Post a Comment