Search Unity

[SOLVED]Linear Fog shader only works with 2+ instances of the same object on-screen

Discussion in 'Shaders' started by Praevelox, Aug 5, 2019.

  1. Praevelox

    Praevelox

    Joined:
    Jul 15, 2017
    Posts:
    3
    Hi,

    I tried to change the sprite shader to produce a 2D linear fog effect where the shader lerps the color of the sprite to a predefined fog-color depending on the distance from the camera.
    This works, however only if there are at least two instances of the same object with this shader on it on the screen.
    The moment one of the instances leaves the screen, the fog-effect stops working.

    I have added an image so you can see the problem. On the left, both instances of the tree are on-screen in game view. The shader works.
    On the right, I moved one of the trees out of view.
    It stopped working.

    I have no idea what would cause this.

    Here's the code

    Code (CSharp):
    1. Shader "Custom/FogSprite"
    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.         _FogColor ("Fog Color", Color) = (0.5, 0.5, 0.5, 1.0)
    9.         _FogIntensity ("Fog Intensity", Range(0,1)) = 0
    10.     }
    11.  
    12.     SubShader
    13.     {
    14.         Tags
    15.         {
    16.             "Queue"="Transparent"
    17.             "IgnoreProjector"="True"
    18.             "RenderType"="Transparent"
    19.             "PreviewType"="Plane"
    20.             "CanUseSpriteAtlas"="True"
    21.         }
    22.  
    23.         Cull Off
    24.         Lighting Off
    25.         ZWrite Off
    26.         Blend One OneMinusSrcAlpha
    27.  
    28.         Pass
    29.         {
    30.         CGPROGRAM
    31.             #pragma vertex vert
    32.             #pragma fragment frag
    33.             #pragma multi_compile _ PIXELSNAP_ON
    34.             #include "UnityCG.cginc"
    35.          
    36.             struct appdata_t
    37.             {
    38.                 float4 vertex   : POSITION;
    39.                 float4 color    : COLOR;
    40.                 float2 texcoord : TEXCOORD0;
    41.             };
    42.  
    43.             struct v2f
    44.             {
    45.                 float4 vertex   : SV_POSITION;
    46.                 fixed4 color    : COLOR;
    47.                 float2 texcoord  : TEXCOORD0;
    48.                 float depth : TEXCOORD1;
    49.             };
    50.          
    51.             fixed3 worldpos;
    52.             fixed4 _Color;
    53.          
    54.             v2f vert(appdata_t IN)
    55.             {
    56.                 v2f OUT;
    57.                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
    58.                 OUT.texcoord = IN.texcoord;
    59.                 OUT.color = IN.color * _Color;
    60.                 OUT.depth = IN.vertex.z;
    61.                 #ifdef PIXELSNAP_ON
    62.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    63.                 OUT.vertex = mul(_ObjectToWorld, IN.vertex);
    64.                 #endif
    65.  
    66.                 return OUT;
    67.             }
    68.  
    69.             sampler2D _MainTex;
    70.             sampler2D _AlphaTex;
    71.             float _AlphaSplitEnabled;
    72.             fixed4 _FogColor;
    73.             float _FogIntensity;
    74.  
    75.             fixed4 SampleSpriteTexture (float2 uv)
    76.             {
    77.                 fixed4 color = tex2D (_MainTex, uv);
    78.  
    79.                 #if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    80.                 if (_AlphaSplitEnabled)
    81.                     color.a = tex2D (_AlphaTex, uv).r;
    82.                 #endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    83.  
    84.                 return color;
    85.             }
    86.  
    87.             fixed4 frag(v2f IN) : SV_Target
    88.             {
    89.                 fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
    90.                 c.rgb = lerp(c, _FogColor, saturate(_FogIntensity * (IN.depth))).rgb;
    91.                 c.rgb *= c.a;
    92.                 return c;
    93.                 //return IN.vertex.z;
    94.             }
    95.         ENDCG
    96.         }
    97.     }
    98. }
    Thanks!
     

    Attached Files:

    Last edited: Aug 5, 2019
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,411
    can you test adding this to Tags?
    "DisableBatching"="True"
     
  3. Praevelox

    Praevelox

    Joined:
    Jul 15, 2017
    Posts:
    3
    Thanks for the suggestion!
    However, unfortunately, the shader completely stopped working now.
     
  4. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    Your depth value in the vert shader is local space z. Sprites have no depth until they batch. You need to actually get the distance from the camera.
     
  5. Praevelox

    Praevelox

    Joined:
    Jul 15, 2017
    Posts:
    3
    That worked, thanks a ton!