Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Custom sprite shader not overlaying existing default sprites

Discussion in 'Shaders' started by SoftwareGeezers, Oct 7, 2015.

  1. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    900
    I have need of a custom shader. I'm starting with just a duplicate of the default sprite shader from the official source code archive: http://unity3d.com/get-unity/download/archive

    This builds fine, but the sprite drawn with this shader is always behind sprites drawn with the default shader. I've tried changing sorting value, z pos, and sorting layer, but the sprite is always behind others. The sorting values only adjust sprites drawn with this shader.

    How do I move this shader to always above default sprites?

    Code (CSharp):
    1. Shader "Sprites/TricolourSpriteShader"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             "PreviewType"="Plane"
    18.             "CanUseSpriteAtlas"="True"
    19.         }
    20.  
    21.         Cull Off
    22.         Lighting Off
    23.         ZWrite Off
    24.         Blend One OneMinusSrcAlpha
    25.  
    26.         Pass
    27.         {
    28.         CGPROGRAM
    29.             #pragma vertex vert
    30.             #pragma fragment frag
    31.             #pragma multi_compile _ PIXELSNAP_ON
    32.             #include "UnityCG.cginc"
    33.          
    34.             struct appdata_t
    35.             {
    36.                 float4 vertex   : POSITION;
    37.                 float4 color    : COLOR;
    38.                 float2 texcoord : TEXCOORD0;
    39.             };
    40.  
    41.             struct v2f
    42.             {
    43.                 float4 vertex   : SV_POSITION;
    44.                 fixed4 color    : COLOR;
    45.                 half2 texcoord  : TEXCOORD0;
    46.             };
    47.          
    48.             fixed4 _Color;
    49.  
    50.             v2f vert(appdata_t IN)
    51.             {
    52.                 v2f OUT;
    53.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    54.                 OUT.texcoord = IN.texcoord;
    55.                 OUT.color = IN.color * _Color;
    56.                 #ifdef PIXELSNAP_ON
    57.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    58.                 #endif
    59.  
    60.                 return OUT;
    61.             }
    62.  
    63.             sampler2D _MainTex;
    64.             sampler2D _AlphaTex;
    65.             float _AlphaSplitEnabled;
    66.  
    67.             fixed4 SampleSpriteTexture (float2 uv)
    68.             {
    69.                 fixed4 color = tex2D (_MainTex, uv);
    70.                 if (_AlphaSplitEnabled)
    71.                     color.a = tex2D (_AlphaTex, uv).r;
    72.  
    73.                 return color;
    74.             }
    75.  
    76.             fixed4 frag(v2f IN) : SV_Target
    77.             {
    78.                 fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
    79.                 c.rgb *= c.a;
    80.                 return c;
    81.             }
    82.         ENDCG
    83.         }
    84.     }
    85. }
    86.  
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    In order for the sprite's distance from the camera to matter, you need to write out the depths of each pixel, which you've disabled with the "ZWrite Off" command.

    If a quick and easy solution would be to make this sprite draw on top of everything that renders before it, add "ZTest Off". Note that this will NOT prevent things to draw on top of it if they are drawn after this sprite in the render queue.

    ("ZTest Off" means it doesn't check if it's in front or behind other objects... it just draws)
     
  3. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    900
    The above code is the Unity default sprite shader. It doesn't need Z testing because it's drawn on top of everything (or behind, depending on draw pass). The sprite sorting value determines draw order.

    What's strange here is the same shader code has a different response when in a custom material rather than the default sprite material.

    Okay, seems it's a bug. If I change the material's shader back to default sprite and then my custom sprite, it works using layer ordering value.
     
  4. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Does that solve your problem?
     
  5. holyfuzz

    holyfuzz

    Joined:
    Nov 16, 2010
    Posts:
    21
    I had this problem with Unity 5.2.1f1 and 5.2.1p3 (the latest patch release). And yes, changing the shader on my material to Sprites/Default and back to my custom shader fixed the issue. Looking at the diff for the .mat files, toggling the shader changed the render queue from 2000 ("Geometry") to 3000 ("Transparent") as specified in my shader. So yes, definitely a Unity bug, but it's an easy fix.
     
  6. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    900
    Yes. Filed a bug report.