Search Unity

Fog Discrepancy between shaders

Discussion in 'Shaders' started by sfaok, Jan 31, 2017.

  1. sfaok

    sfaok

    Joined:
    Nov 27, 2012
    Posts:
    23
    I'm seeing some discrepancy between how shaders apply fog.

    Most of the objects in my scene use "Mobile/Unlit (Supports Lightmap)".
    However some use a custom shader (the splat mapped ground, vegetation, animals).

    For some reason they don't apply fog the same. On the left hand side of the screenshot below I have a plane and cube both with a Mobile/Unlit (Supports Lightmap) shader applied, while on the right hand side I have the exact same scene but with the ground shaded using the custom shader. As you can see the cube stands out a lot more on the right, while on the left it blends into the fog as expected.

    In my real scene this has the effect of making some objects glow as they are fading to the fog at different distances.

    Its almost as though the shaders are using different fog parameters.

    I'm using Unity 5.4.2f2. The exact same scene in Unity 4 works fine, with both types of (equivalent) shader blending together correctly.



    Here are the two shaders (stripped down for testing).

    Mobile Unlit (Supports Lightmap):

    Code (CSharp):
    1. Shader "Test/Mobile Unlit (Supports Lightmap)"
    2. {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.  
    7.     SubShader
    8.     {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 100
    11.      
    12.         // Non-lightmapped
    13.         Pass {
    14.             Tags { "LightMode" = "Vertex" }
    15.             Lighting Off
    16.             SetTexture [_MainTex] {
    17.                 constantColor (1,1,1,1)
    18.                 combine texture, constant // UNITY_OPAQUE_ALPHA_FFP
    19.             }
    20.         }
    21.  
    22.         // Lightmapped, encoded as RGBM
    23.         Pass {
    24.             Tags { "LightMode" = "VertexLMRGBM" }
    25.          
    26.             Lighting Off
    27.             BindChannels {
    28.                 Bind "Vertex", vertex
    29.                 Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
    30.                 Bind "texcoord", texcoord1 // main uses 1st uv
    31.             }
    32.          
    33.             SetTexture [unity_Lightmap] {
    34.                 matrix [unity_LightmapMatrix]
    35.                 combine texture * texture alpha DOUBLE
    36.             }
    37.             SetTexture [_MainTex] {
    38.                 constantColor (1,1,1,1)
    39.                 combine texture * previous QUAD, constant // UNITY_OPAQUE_ALPHA_FFP
    40.             }
    41.         }  
    42.     }
    43. }
    44.  

    Splatmap Custom Shader (Stripped down)

    Code (CSharp):
    1. Shader "Test/Splatmap Test"
    2. {
    3.   Properties {
    4.     _MainTex ("Layer 1", 2D) = "white" {}
    5.   }
    6.  
    7.   SubShader {
    8.     Tags { "RenderType" = "Opaque" }
    9.  
    10.     Pass {
    11.       // Disable lighting, we're only using the lightmap
    12.       Lighting Off
    13.  
    14.       CGPROGRAM
    15.       // Must be a vert/frag shader, not a surface shader: the necessary variables
    16.       // won't be defined yet for surface shaders.
    17.       #pragma vertex vert
    18.       #pragma fragment frag
    19.       #pragma multi_compile_fog
    20.  
    21.       #include "UnityCG.cginc"
    22.  
    23.       struct v2f {
    24.         float4 pos : SV_POSITION;
    25.  
    26.         float2 uv_MainTex : TEXCOORD0;
    27.         float2 uv1 : TEXCOORD1;
    28.  
    29.  
    30.         UNITY_FOG_COORDS(7)
    31.       };
    32.  
    33.       struct appdata_lightmap {
    34.         float4 vertex : POSITION;
    35.         float2 texcoord : TEXCOORD0;
    36.         float2 texcoord1 : TEXCOORD1;
    37.       };
    38.  
    39.  
    40.       sampler2D _MainTex;
    41.        float4 _MainTex_ST;
    42.  
    43.  
    44.       v2f vert(appdata_lightmap i) {
    45.  
    46.         v2f o;
    47.         UNITY_INITIALIZE_OUTPUT(v2f,o);
    48.  
    49.         o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
    50.         o.uv_MainTex =  TRANSFORM_TEX(i.texcoord, _MainTex);
    51.         o.uv1 = i.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    52.  
    53.         UNITY_TRANSFER_FOG(o, o.pos);
    54.         return o;
    55.       }
    56.  
    57.         half4 frag(v2f i) : COLOR {
    58.  
    59.             fixed3 tex = tex2D (_MainTex, i.uv_MainTex);
    60.                float4 col =  half4(tex,0);
    61.  
    62.                col.rgb *= DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv1));  //lightmap
    63.  
    64.               UNITY_APPLY_FOG(i.fogCoord * 1.0f, col);
    65.  
    66.             return col;
    67.       }
    68.       ENDCG
    69.     }
    70.   }
    71. }

    I'd be very grateful if someone has any ideas.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    As of Unity 5.0 fixed function shaders are no longer supported by the rendering pipeline. Instead fixed function shaders are converted to vertex fragment shaders. However I've found a number of cases where this conversion isn't quite 100% perfect.

    You may need to make your own version of the "mobile unlit" shader to fix the issues. You can start by putting a copy of the mobile unlit shader in your project, select it, and then click on "Show Generated" to see the resulting shader. You may be able to spot where the two diverge from there.
     
  3. sfaok

    sfaok

    Joined:
    Nov 27, 2012
    Posts:
    23
    Fantastic - thanks for the fast reply.

    As you said I changed the generated code so that it used the same method of fog calculation (UNITY_TRANSFER_FOG(..) etc). They now apply fog identically.