Search Unity

Missing fog in alpha testing material

Discussion in 'Shaders' started by BrightBit, Aug 8, 2015.

  1. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    In my current project I am using two materials: an opaque one with alpha testing for already loaded parts (chunks) of my world and a transparent one for recently loaded parts. The transparent one renders with fog but the opaque one with alpha testing doesn't! Here's an image to illustrate the problem:

    Note: Although the transparent material would be transparent in general, I set its alpha value to 1, so actually in the image above the world parts are NOT transparent! The brighter colors are due to the fog only.

    The interesting thing here is that, if I change "Queue" = "AlphaTest" in the alpha testing shader to "Queue" = "Transparent" I will get fog (but also loose shadows). So why does this happen? Is this a bug? Can this be solved somehow? I really would like to have some fog.

    These are the shaders I am using: The transparent shader that has fog:

    Code (csharp):
    1. Shader "TransparentMaterial"
    2. {
    3.   Properties
    4.   {
    5.   _Color ("Main Color", Color)  = (0.5,0.5,0.5,1)
    6.   _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.   }
    8.  
    9.   SubShader
    10.   {
    11.   Tags
    12.   {
    13.   "Queue"  = "Transparent"
    14.   "IgnoreProjector" = "True"
    15.   "RenderType"  = "Transparent"
    16.   }
    17.  
    18.   LOD 200
    19.  
    20.   CGPROGRAM
    21.   #pragma surface surf Lambert alpha
    22.  
    23.   sampler2D _MainTex;
    24.   fixed4 _Color;
    25.  
    26.   struct Input
    27.   {
    28.   float2 uv_MainTex;
    29.   float4 color : COLOR;
    30.   float3 worldNormal;
    31.   float3 worldPos;
    32.   };
    33.  
    34.   void surf(Input IN, inout SurfaceOutput o)
    35.   {
    36.   fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    37.  
    38.   o.Albedo = c.rgb;
    39.   o.Alpha  = _Color.a;
    40.   }
    41.  
    42.   ENDCG
    43.   }
    44.  
    45.   Fallback "Transparent/VertexLit"
    46. }
    ...and the opaque material with alpha testing (the shader that doesn't generate fog):

    Code (csharp):
    1. Shader "OpaqueAlphaTestingMaterial"
    2. {
    3.   Properties
    4.   {
    5.   _Color ("Main Color", Color)  = (0.5,0.5,0.5,1)
    6.   _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.   _Grid ("Base (RGA) Trans (A)", 2D)  = "white" {}
    8.   _Cutoff ("Alpha cutoff", Range(0,1))  = 0.5
    9.   }
    10.  
    11.   SubShader
    12.   {
    13.   Tags
    14.   {
    15.   "Queue"  = "AlphaTest"
    16.   "IgnoreProjector" = "True"
    17.   "RenderType"  = "TransparentCutout"
    18.   }
    19.  
    20.   LOD 200
    21.  
    22.   CGPROGRAM
    23.   #pragma surface surf Lambert alphatest:_Cutoff noforwardadd novertexlights nolightmap exclude_path:forward exclude_path:prepass nometa nodirlightmap nodynlightmap
    24.  
    25.   sampler2D _MainTex;
    26.   sampler2D _Grid;
    27.   fixed4 _Color;
    28.  
    29.   bool _RenderGrid;
    30.   float _GridAmount;
    31.  
    32.   struct Input
    33.   {
    34.   float2 uv_MainTex;
    35.   float4 color : COLOR;
    36.   float3 worldNormal;
    37.   float3 worldPos;
    38.   };
    39.  
    40.   float getGrid(Input IN)
    41.   {
    42.   return (_RenderGrid  &&
    43.   (IN.color.a  < 0.5)  &&
    44.   (IN.worldNormal.y > 0.01)  &&
    45.   !(IN.uv_MainTex.x < 0.0625 && IN.uv_MainTex.y < 0.03125) &&
    46.   !(IN.uv_MainTex.y > 0.03125))  *
    47.   _GridAmount * 0.2;
    48.   }
    49.  
    50.   float2 getGridUV(float3 worldPos)
    51.   {
    52.   float u = worldPos.x / 3.0;
    53.   float v = worldPos.z / 3.0;
    54.  
    55.   return float2(u, v);
    56.   }
    57.  
    58.   void surf(Input IN, inout SurfaceOutput o)
    59.   {
    60.   float gridFactor = getGrid(IN);
    61.  
    62.   fixed4 c  = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    63.   float gridAlpha  = tex2D(_Grid, getGridUV(IN.worldPos)).a * gridFactor;
    64.   fixed3 gridColor = fixed3(1,1,1);
    65.  
    66.   float darkeningFactor = 0.0;
    67.  
    68.   o.Albedo  = (c.rgb * (1.0 - gridAlpha) + gridColor.rgb * gridAlpha) * (1.0 - darkeningFactor);
    69.   o.Alpha  = c.a;
    70.   }
    71.  
    72.   ENDCG
    73.   }
    74.  
    75.   Fallback "Transparent/Cutout/VertexLit"
    76. }
     
  2. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    bump

    No one?
     
  3. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Fog no longer works in deferred that's why you get fog only on transparent objects that are rendered in forward.
    You will need to use a post-effect or code it in your shader.
     
  4. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    Thank you Phantomx. It doesn't solve my problem but at least I know the reasoning behind it now. I guess, I will have to investigate the global fog image effect, then.

    Again, thank you.
     
  5. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202