Search Unity

outline shader, build error

Discussion in 'Shaders' started by a0100101, Mar 15, 2017.

  1. a0100101

    a0100101

    Joined:
    Feb 9, 2014
    Posts:
    15
    hello guys,
    Yesterday I was messing around with this shader:

    Code (CSharp):
    1.  
    2. Shader "Sprites/Outline"
    3. {
    4.     Properties
    5.     {
    6.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    7.         _Color("Tint", Color) = (1,1,1,1)
    8.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    9.  
    10.         // Add values to determine if outlining is enabled and outline color.
    11.         [PerRendererData] _Outline("Outline", Float) = 0
    12.         [PerRendererData] _OutlineColor("Outline Color", Color) = (1,1,1,1)
    13.         [PerRendererData] _OutlineSize("Outline Size", int) = 1
    14.         [PerRendererData] _Rect ("Rect Display", Vector) = (0,0,1,1)
    15.  
    16.     }
    17.  
    18.     SubShader
    19.     {
    20.         Tags
    21.         {
    22.         ///
    23.             "Queue" = "Transparent"
    24.             "IgnoreProjector" = "True"
    25.             "RenderType" = "Transparent"
    26.             "PreviewType" = "Plane"
    27.             "CanUseSpriteAtlas" = "True"
    28.         }
    29.  
    30.         Cull Off
    31.         Lighting Off
    32.         ZWrite Off
    33.         Blend One OneMinusSrcAlpha
    34.  
    35.         Pass
    36.         {
    37.             CGPROGRAM
    38.             #pragma vertex vert
    39.             #pragma fragment frag
    40.             #pragma multi_compile _ PIXELSNAP_ON
    41.             #pragma shader_feature ETC1_EXTERNAL_ALPHA
    42.             #include "UnityCG.cginc"
    43.  
    44.             struct appdata_t
    45.             {
    46.                 float4 vertex   : POSITION;
    47.                 float4 color    : COLOR;
    48.                 float2 texcoord : TEXCOORD0;
    49.             };
    50.  
    51.             struct v2f
    52.             {
    53.                 float4 vertex   : SV_POSITION;
    54.                 fixed4 color : COLOR;
    55.                 float2 texcoord  : TEXCOORD0;
    56.             };
    57.  
    58.             fixed4 _Color;
    59.             float _Outline;
    60.             fixed4 _OutlineColor;
    61.             int _OutlineSize;
    62.             fixed4 _Rect;
    63.  
    64.             v2f vert(appdata_t IN)
    65.             {
    66.                 v2f OUT;
    67.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    68.                 OUT.texcoord = IN.texcoord;
    69.                 OUT.color = IN.color * _Color;
    70.                 #ifdef PIXELSNAP_ON
    71.                 OUT.vertex = UnityPixelSnap(OUT.vertex);
    72.                 #endif
    73.  
    74.                 return OUT;
    75.             }
    76.  
    77.             sampler2D _MainTex;
    78.             sampler2D _AlphaTex;
    79.             float4 _MainTex_TexelSize;
    80.  
    81.             fixed4 SampleSpriteTexture(float2 uv)
    82.             {
    83.                 fixed4 color = tex2D(_MainTex, uv);
    84.  
    85.                 #if ETC1_EXTERNAL_ALPHA
    86.                 // get the color from an external texture (usecase: Alpha support for ETC1 on android)
    87.                 color.a = tex2D(_AlphaTex, uv).r;
    88.                 #endif //ETC1_EXTERNAL_ALPHA
    89.  
    90.                 return color;
    91.             }
    92.  
    93.             fixed4 frag(v2f IN) : SV_Target
    94.             {
    95.                 fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
    96.              
    97.                 // If outline is enabled and there is a pixel, try to draw an outline.
    98.                 if (_Outline > 0 && c.a != 0) {
    99.                     float totalAlpha = 1.0;
    100.                  
    101.                     if (IN.texcoord.x < _Rect.x + _OutlineSize*_MainTex_TexelSize.x || IN.texcoord.y < _Rect.y + _OutlineSize*_MainTex_TexelSize.y ||
    102.                         IN.texcoord.x > _Rect.z - _OutlineSize*_MainTex_TexelSize.x || IN.texcoord.y > _Rect.w - _OutlineSize*_MainTex_TexelSize.y)
    103. {
    104.                         totalAlpha = 0;
    105.                     }
    106.                     else
    107.                     {
    108.                         [unroll(16)]
    109.                         for (int i = 1; i < _OutlineSize + 1; i++) {
    110.                             fixed4 pixelUp = tex2D(_MainTex, IN.texcoord + fixed2(0, i * _MainTex_TexelSize.y));
    111.                             fixed4 pixelDown = tex2D(_MainTex, IN.texcoord - fixed2(0, i *  _MainTex_TexelSize.y));
    112.                             fixed4 pixelRight = tex2D(_MainTex, IN.texcoord + fixed2(i * _MainTex_TexelSize.x, 0));
    113.                             fixed4 pixelLeft = tex2D(_MainTex, IN.texcoord - fixed2(i * _MainTex_TexelSize.x, 0));
    114.  
    115.                             totalAlpha = totalAlpha * pixelUp.a * pixelDown.a * pixelRight.a * pixelLeft.a;
    116.                         }
    117.                     }                
    118.  
    119.                     if (totalAlpha == 0) {
    120.                         c.rgba = fixed4(1, 1, 1, 1) * _OutlineColor;
    121.                     }
    122.                 }
    123.  
    124.                 c.rgb *= c.a;
    125.  
    126.                 return c;
    127.             }
    128.             ENDCG
    129.         }
    130.     }
    131. }
    132.  
     
  2. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    It's an awfully not optimized shader but I don't see any error here, can you explain what's your problem ?
     
  3. a0100101

    a0100101

    Joined:
    Feb 9, 2014
    Posts:
    15
    missing part: (the forum does not let me edit the first post don't know why)
    it works like a charm in the editor, but when I try to compile the project the console returns this: "Shader error in 'Sprites/Outline': '[' : syntax error syntax error at line 107 (on gles)"
    this is the first time that I try to use a custom shader and I have not Idea why this error occurs

    I know what this error means of course, but I can't see any problem in the code.
    can someone enlight me, please?

    Ps: this shader is not mine, I found it surfing the internet
     
    Last edited: Mar 15, 2017
  4. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    You trying to build this shader on OpenGL ?
     
  5. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    I never had to use a "for" instruction neither unroll into a shader but after a fast research, DirectX 9 does not support well "for" instruction, that's why "unroll" exist, it will remove the for instruction and unroll it like you have wrote every step of it.

    "unroll" instruction is for DirectX only and it seems that Unity didn't convert it to an OpenGL equivalent shader code (it seems that the way to do it in opengl is very different).
     
  6. a0100101

    a0100101

    Joined:
    Feb 9, 2014
    Posts:
    15
    yes
    the strange thing is that it does not give me an error every time I try to build and sometimes it still give me an error but it compiles anyway and if i try to run the .apk it works fine.

    I will try to write my own shader, this one doesn't seem to be the right choice
     
    Last edited: Mar 15, 2017
  7. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    It is not indeed.

    Anyway, avoid the usage of "if" statements when you can, it can be replaced most of the time with a lerp or a step function.

    GPUs are really bad with multi branching code.

    When a shader give multi possibilities like yours with the "Outline enabled or not check" it's better to have a compilation condition instead, This way Unity will compile multiple version of your shader.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    FYI step() is an if.

    Also gles can't do loops, it always unrolls, but it also doesn't have a [unroll] command which is what it's failing on as it doesn't see that as proper syntax. You're better off using Unity's built in UNITY_UNROLL macro, or using:

    #if defined(UNITY_COMPILER_HLSL)
    [unroll(16)]
    #endif

    Or just remove that and let the shader compiler do it on it's own.
     
    Last edited: Mar 15, 2017
  9. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    Yes, step is an if but one if is not really a problem anymore.
    My point was about the fact that using a step avoid the usage of "else" or another "if" inside an if, a complex branching.