Search Unity

Fog gone when accessing vertex colors ( others) with surface shader

Discussion in 'Shaders' started by ElStephko, Mar 11, 2013.

  1. ElStephko

    ElStephko

    Joined:
    Feb 26, 2013
    Posts:
    5
    Hi there,

    just got into shaderwriting a bit and ran into a problem i dont fully understand as i have seen working examples of this.
    Bascially as i wanted to access the vertex colors of a provided mesh suddenly the fog on the model vanished.

    I came tor realize this also applies to IN.worldpos, maybe others i dont have a full overview.

    I tried accessing the the vertex colors via a vert programm, which worked (same as using the color input straight) however the fog is still gone. Feels like waling in circles a bit.

    Shadercode (beware Artist code!)


    As you can see i tried accessing fog from the shader but got a

    error back.



    On the screenie you see clearly all geometry vanishing into fog while the one with the shader are exluded

    Any help would be greatly appreciated :)


    $ShaderHelp.jpg
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    The error about the FOG semantic probably refers to FOG needing a scalar value, not a vector. Try it with a float rather than a float4.
     
  3. ElStephko

    ElStephko

    Joined:
    Feb 26, 2013
    Posts:
    5
    Hey thanks I give it whirl,

    i felt like it might be better idea to tackle it wihout adding fog "artificially" but whatever does the trick :)
     
  4. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Unfortunately I don't know a lot about Unity's fogging features, or fog in general, so I can't tell you what the best way to proceed is.
     
  5. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    with the new features of surface shaders, you can add your custom fog in final color function. Just check the documents for shaderlab for examples.
     
  6. ElStephko

    ElStephko

    Joined:
    Feb 26, 2013
    Posts:
    5
    Thanks Guys, but I think I nailed down to overall reason why i cant just mutiply the vertex color as i have seen it in other examples.

    We are using Defferred Rendering!

    As soon as i switch to forward rendering the fog is added as expected. I am not too familiar with all the shader pipeline but I suspect i might override some pass?

    Any ideas of about this? Do i need to make a seperate pass or something similar?
     
  7. CoastKid

    CoastKid

    Joined:
    Jan 8, 2013
    Posts:
    64
    I am new to Unity Shaders and i had problems with a Fog+vetexColor too, but i've found the solution (not sure it's the best one):

    You must exclude INTERNAL_DATA and "world*" inclusive Inputs from "struct input",
    and replicate it using "appdata_full" in vertex output

    here is part from my shader (beware Artist code too!) that works fine:
    Code (csharp):
    1.  
    2.     struct Input {
    3.       float2 uv_MainTex;
    4.       float2 uv2_Mask;
    5.       float3 worldP;
    6.       float4 color;
    7.       float3 Normal;
    8.       float4 Tangent;
    9.     };
    10.        
    11.       void vert (inout appdata_full v, out Input o) {
    12.       o.worldP =  mul(float4(v.vertex.xyz,1.0f),_World2Object).xyz + mul( _Object2World, float4(0,0,0,1) ).xyz;
    13.       o.Tangent =  float4(mul(v.tangent.xyz,(float3x3)_World2Object),v.tangent.w);
    14.       o.Normal =  mul(float4(v.normal.xyz,0.0f),_World2Object).xyz;
    15.       o.color = v.color;
    16.     }
    17.  
    Hope it helps
     
  8. ElStephko

    ElStephko

    Joined:
    Feb 26, 2013
    Posts:
    5
    Hey thanks for all the help thus far. Unfortunately i didnt yield any results, except i found out that that even a vert program will kill fog

    AND

    Vertex colors support + fog + defferred rendering in directx 9 seemingly doesnt work, it actually works as expected in directx11 with fog and all!

    No fingerpointing and all, Id suspect a bug, but maybe there some support issues for rendering deffered + vertex colors in dx9 ?
     
  9. CoastKid

    CoastKid

    Joined:
    Jan 8, 2013
    Posts:
    64
    I have change your shader to make it work with fog and vertex color (i've sacrifice the Reflection and uv_BumpMap inputs ), try it:

    Code (csharp):
    1.  
    2. Shader "Custom/testFog" {
    3.   Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _Paint ("Paint Color", Color) = (1,1,1,1)
    6.     _PaintWeight ("PaintWeight", Range (0.0, 0.9)) = 0.0
    7.     _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
    8.     _Shininess ("Shininess", Range (0.01, 2)) = 0.078125
    9.     _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
    10.     _MainTex ("Base (RGB) PaintWeight (A)", 2D) = "white" {}
    11.     _Fx ("FX Spec R Fres G Paint B", 2D) = "black" {}
    12.     _Decal ("Decal (RGB) Decalmask (A)", 2D) = "black" {}
    13.     _Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
    14.     _BumpMap ("Normalmap", 2D) = "bump" {}
    15.     _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
    16.     _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
    17.   }
    18.  
    19.  
    20.   SubShader {
    21.     Tags { "RenderType"="Opaque" }
    22.     LOD 200
    23.    
    24.     CGPROGRAM
    25.     #pragma surface surf BlinnPhong vertex:vert
    26.     #pragma target 3.0
    27.     #pragma only_renderers d3d9 d3d11
    28.     #include "UnityCG.cginc"
    29.  
    30.     sampler2D _MainTex;
    31.     sampler2D _Fx;
    32.     sampler2D _BumpMap;
    33.     sampler2D _Decal;
    34.     samplerCUBE _Cube;
    35.    
    36.     float4 _RimColor;
    37.     float _RimPower;
    38.    
    39.     fixed4 _Color;
    40.     fixed4 _Paint;
    41.     fixed _PaintWeight;
    42.     fixed4 _ReflectColor;
    43.    
    44.     half _Shininess;
    45.  
    46.     struct Input {
    47.       float2 uv_MainTex;
    48.       float2 uv2_Decal;
    49.       float3 viewDir;
    50.       float3 worldP;
    51.       float4 color;
    52.       float3 Normal;
    53.       float4 Tangent;
    54.     };
    55.    
    56.       void vert (inout appdata_full v, out Input o) {
    57.       o.worldP =  mul(float4(v.vertex.xyz,1.0f),_World2Object).xyz + mul( _Object2World, float4(0,0,0,1) ).xyz;
    58.       o.Tangent =  float4(mul(v.tangent.xyz,(float3x3)_World2Object),v.tangent.w);
    59.       o.Normal =  mul(float4(v.normal.xyz,0.0f),_World2Object).xyz;
    60.       o.color = v.color;
    61.     }
    62.  
    63.     void surf (Input IN, inout SurfaceOutput o) {
    64.       fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    65.       fixed4 fx = tex2D(_Fx, IN.uv_MainTex);
    66.       fixed4 dec = tex2D(_Decal,IN.uv2_Decal);
    67.       fixed4 nrm = tex2D(_BumpMap, IN.uv_MainTex);
    68.       fixed4 c = tex * _Color;
    69.      
    70.       //Adds Paint on surface effect
    71.       fixed paintweight = smoothstep(0, 1-tex.a, _PaintWeight)*(tex.a+0.2);
    72.       fixed4 paintover = lerp(c, _Paint, paintweight);
    73.       fixed4 result = lerp(paintover, dec, dec.a*(saturate(tex.a+0.5)));
    74.    
    75.       o.Albedo = IN.color.rgb;
    76.       o.Gloss = fx.r+dec.a+_PaintWeight ;
    77.       o.Specular = _Shininess+dec.a*0.1+_PaintWeight*2;
    78.       o.Normal = UnpackNormal(normalize(nrm));
    79.    
    80.       //adds RimLighting
    81.      
    82.       half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
    83.       half3 rimresult = _RimColor.rgb * pow (rim, _RimPower) * fx.a*(max(0, dot(float3(0, 1, 0), WorldNormalVector (IN, o.Normal))));
    84.       rimresult *= (paintweight+1);
    85.       o.Emission = rimresult;
    86.     }
    87.     ENDCG
    88.   }
    89.   FallBack "Reflective/Bumped Diffuse"
    90. }
    91.  
     
  10. ElStephko

    ElStephko

    Joined:
    Feb 26, 2013
    Posts:
    5
    Hey CoastKid,

    I tried your shader, thanks so much for going through it.

    I works dandy, till up to the point when i try adding the the reflection vector here is da code:

     
    Last edited: Mar 14, 2013
  11. CoastKid

    CoastKid

    Joined:
    Jan 8, 2013
    Posts:
    64
    The only way i see to fix this, is to to calc the reflection vector in pixel shader instead of vertex shader.
    Seems like this surface shader reaches the limit for vertex outputs number, and as result we see the fog problems instead of compilation warning/error.
     
  12. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Sorry for necroposting, but this thread pretty much describes the issue I am seeing with one of my shaders right now.
    It's a surface shader with custom lighting functions and a lot of instructions - no vertex function modifier yet.
    As soon as I add half3 worldRefl; to my Input struct and calculate the reflection vector per pixel normal I lose the fog. Unity just fails silently at this stage.
    If however I calculate the reflection vector inside the surface function via reflect(-IN.viewDir, fixed3(0, 1, 0) I reenter the world of fogged geometry. Using that crude kind of approximation only (kind of) works in my case because I know beforehand what type of surface the shader is going to act upon - planar up facing tiles. Though it has issues with mesh borders.

    I tried to calculate the worldPos or the worldRefl vectors inside a custom verex modifier function and pack their values into zw-components of float4 versions of uv_Tex0 and uv_Tex1.
    But that trick didn't work - Unity just gave up compiling the shader and threw an error at me with a line number that didn't even exist in the compiled shader.

    So again...
    This struct works:
    Code (csharp):
    1.  
    2. // Input structure for surface shader
    3.         struct Input
    4.         {
    5.             fixed2 uv_Diffuse0;
    6.             fixed2 uv_Normal0;
    7.             //fixed3 worldRefl;
    8.             fixed3 worldPos;
    9.             fixed3 viewDir;
    10.             fixed4 color : COLOR;
    11.             INTERNAL_DATA
    12.         };
    13.  
    This one doesn't:
    Code (csharp):
    1.  
    2. // Input structure for surface shader
    3.         struct Input
    4.         {
    5.             fixed2 uv_Diffuse0;
    6.             fixed2 uv_Normal0;
    7.             fixed3 worldRefl;
    8.             fixed3 worldPos;
    9.             fixed3 viewDir;
    10.             fixed4 color : COLOR;
    11.             INTERNAL_DATA
    12.         };
    13.  
    If any of you have got some tricks on how to pack worldPos and/or worldRefl into one variable I'd be very happy.
     
    Last edited: Nov 8, 2013
  13. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    It looks to me like Unity has a serious bug somewhere inside its surface-shader-compiler.
    Please have a look at these images and then scroll down to the code for each shader.

    $FoggedSummary.jpg

    Code (csharp):
    1.  
    2. Shader "Custom/Fogged0"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         #pragma surface surf BlinnPhong
    16.         #pragma target 3.0
    17.        
    18.         fixed4 _MainColor;
    19.        
    20.         struct Input
    21.         {
    22.             fixed null;
    23.         };
    24.  
    25.         void surf (Input IN, inout SurfaceOutput o)
    26.         {
    27.             o.Albedo = _MainColor.rgb;
    28.             o.Alpha = _MainColor.a;
    29.         }
    30.         ENDCG
    31.     }
    32.     FallBack "Diffuse"
    33. }
    34.  
    Code (csharp):
    1. Shader "Custom/Fogged1"
    2. {
    3.     Properties
    4.     {
    5.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    6.     }
    7.    
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 200
    12.        
    13.         CGPROGRAM
    14.         #pragma surface surf BlinnPhong
    15.         #pragma target 3.0
    16.        
    17.         fixed4 _MainColor;
    18.        
    19.         struct Input
    20.         {
    21.             fixed3 worldRefl;
    22.         };
    23.  
    24.         void surf (Input IN, inout SurfaceOutput o)
    25.         {
    26.             o.Albedo = _MainColor.rgb;
    27.             o.Alpha = _MainColor.a;
    28.             o.Emission = IN.worldRefl * 0.01;
    29.         }
    30.         ENDCG
    31.     }
    32.     FallBack "Diffuse"
    33. }
    34.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged2"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         #pragma surface surf BlinnPhong
    16.         #pragma target 3.0
    17.        
    18.         fixed4 _MainColor;
    19.        
    20.         struct Input
    21.         {
    22.             fixed3 worldRefl;
    23.             fixed4 color : COLOR;
    24.         };
    25.  
    26.         void surf (Input IN, inout SurfaceOutput o)
    27.         {
    28.             o.Albedo = _MainColor.rgb + 0.01 * IN.color.rgb;
    29.             o.Alpha = _MainColor.a + 0.01 * IN.color.a;
    30.             o.Emission = IN.worldRefl * 0.01;
    31.         }
    32.         ENDCG
    33.     }
    34.     FallBack "Diffuse"
    35. }
    36.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged3"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         #pragma surface surf BlinnPhong
    16.         #pragma target 3.0
    17.        
    18.         fixed4 _MainColor;
    19.        
    20.         struct Input
    21.         {
    22.             fixed3 worldRefl;
    23.             fixed4 color : COLOR;
    24.             INTERNAL_DATA
    25.         };
    26.  
    27.         void surf (Input IN, inout SurfaceOutput o)
    28.         {
    29.             o.Albedo = _MainColor.rgb + 0.01 * IN.color.rgb;
    30.             o.Alpha = _MainColor.a + 0.01 * IN.color.a;
    31.             o.Emission = IN.worldRefl * 0.01;
    32.         }
    33.         ENDCG
    34.     }
    35.     FallBack "Diffuse"
    36. }
    37.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged4"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.     }
    8.    
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         #pragma surface surf BlinnPhong
    16.         #pragma target 3.0
    17.        
    18.         fixed4 _MainColor;
    19.        
    20.         struct Input
    21.         {
    22.             fixed3 worldRefl;
    23.             fixed4 color : COLOR;
    24.             INTERNAL_DATA
    25.         };
    26.  
    27.         void surf (Input IN, inout SurfaceOutput o)
    28.         {
    29.             o.Albedo = _MainColor.rgb + 0.01 * IN.color.rgb;
    30.             o.Alpha = _MainColor.a + 0.01 * IN.color.a;
    31.             o.Normal = float3(0, 0, 1);
    32.             o.Emission = IN.worldRefl * 0.01;
    33.         }
    34.         ENDCG
    35.     }
    36.     FallBack "Diffuse"
    37. }
    38.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged5"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.         _MainTex ("_MainTex", 2D) = "white" {}
    8.     }
    9.    
    10.     SubShader
    11.     {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 200
    14.        
    15.         CGPROGRAM
    16.         #pragma surface surf BlinnPhong
    17.         #pragma target 3.0
    18.        
    19.         fixed4 _MainColor;
    20.         sampler2D _MainTex;
    21.        
    22.         struct Input
    23.         {
    24.             fixed2 uv_MainTex;
    25.             fixed3 worldRefl;
    26.             fixed4 color : COLOR;
    27.             INTERNAL_DATA
    28.         };
    29.  
    30.         void surf (Input IN, inout SurfaceOutput o)
    31.         {
    32.             fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
    33.             o.Albedo = mainTex.rgb * _MainColor.rgb + 0.01 * IN.color.rgb;
    34.             o.Alpha = mainTex.a * _MainColor.a + 0.01 * IN.color.a;
    35.             o.Normal = float3(0, 0, 1);
    36.             o.Emission = IN.worldRefl * 0.01;
    37.         }
    38.         ENDCG
    39.     }
    40.    
    41.     FallBack "Diffuse"
    42. }
    43.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged6"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.         _MainTex ("_MainTex", 2D) = "white" {}
    8.         _Cube ("_Cube", Cube) = "" {}
    9.     }
    10.    
    11.     SubShader
    12.     {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.        
    16.         CGPROGRAM
    17.         #pragma surface surf BlinnPhong
    18.         #pragma target 3.0
    19.        
    20.         fixed4 _MainColor;
    21.         sampler2D _MainTex;
    22.         samplerCUBE _Cube;
    23.        
    24.         struct Input
    25.         {
    26.             fixed2 uv_MainTex;
    27.             fixed3 worldRefl;
    28.             fixed4 color : COLOR;
    29.             INTERNAL_DATA
    30.         };
    31.  
    32.         void surf (Input IN, inout SurfaceOutput o)
    33.         {
    34.             fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
    35.             o.Albedo = mainTex.rgb * _MainColor.rgb + 0.01 * IN.color.rgb;
    36.             o.Alpha = mainTex.a * _MainColor.a + 0.01 * IN.color.a;
    37.             o.Normal = float3(0, 0, 1);
    38.             o.Emission = texCUBE(_Cube, IN.worldRefl).rgb * 0.01;
    39.         }
    40.         ENDCG
    41.     }
    42.    
    43.     FallBack "Diffuse"
    44. }
    45.  
    Code (csharp):
    1.  
    2. Shader "Custom/Fogged7"
    3. {
    4.     Properties
    5.     {
    6.         _MainColor ("_MainColor", Color) = (1, 1, 1, 1)
    7.         _MainTex ("_MainTex", 2D) = "white" {}
    8.         _Cube ("_Cube", Cube) = "" {}
    9.     }
    10.    
    11.     SubShader
    12.     {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.        
    16.         CGPROGRAM
    17.         #pragma surface surf BlinnPhong
    18.         #pragma target 3.0
    19.        
    20.         fixed4 _MainColor;
    21.         sampler2D _MainTex;
    22.         samplerCUBE _Cube;
    23.        
    24.         struct Input
    25.         {
    26.             fixed2 uv_MainTex;
    27.             fixed3 worldRefl;
    28.             INTERNAL_DATA
    29.         };
    30.  
    31.         void surf (Input IN, inout SurfaceOutput o)
    32.         {
    33.             fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
    34.             o.Albedo = mainTex.rgb * _MainColor.rgb;
    35.             o.Alpha = mainTex.a * _MainColor.a;
    36.             o.Normal = float3(0, 0, 1);
    37.             o.Emission = texCUBE(_Cube, IN.worldRefl).rgb * 0.01;
    38.         }
    39.         ENDCG
    40.     }
    41.    
    42.     FallBack "Diffuse"
    43. }
    44.  
    Long story short.
    As soon as you add both - texture UVs and vertex colors - to the Input structure that holds the worldRefl vector Untiy fails silently to render the fog when the object also receives shadows.
    If however you leave one of it out of the equation (texture UVs or vertex colors or shadows) Unity is able to fog the object correctly.

    But: leaving shadows out of the equation is a no go as is leaving out vertex colors or texture UVs.
    I seriously doubt that this stuff is working as intended.
     
  14. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    I've filed a bug report.