Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Black fog color?

Discussion in 'Unity 5 Pre-order Beta' started by AustinRichards, Jan 9, 2015.

  1. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    I am using the new GlobalFog image effect for unity 5 for the new deferred.
    One feature (amongst others) was that it lost its ability for black fog. I'd use black fog for dungeon maps etc. It seems to take the luminosity of the color as the alpha.

    I am really bad with shaders, it's my weakest area and I really need some help with getting the black fog color to work with the fogshader.

    You can download the fogshader through the sample assets, but here it is right here:
    Code (CSharp):
    1. Shader "Hidden/GlobalFog" {
    2. Properties {
    3.     _MainTex ("Base (RGB)", 2D) = "black" {}
    4. }
    5.  
    6. CGINCLUDE
    7.  
    8.     #include "UnityCG.cginc"
    9.  
    10.     uniform sampler2D _MainTex;
    11.     uniform sampler2D_float _CameraDepthTexture;
    12.  
    13.     // x = fog height
    14.     // y = FdotC (CameraY-FogHeight)
    15.     // z = k (FdotC > 0.0)
    16.     // w = a/2
    17.     uniform float4 _HeightParams;
    18.  
    19.     // x = start distance
    20.     uniform float4 _DistanceParams;
    21.  
    22.     int4 _SceneFogMode; // x = fog mode, y = use radial flag
    23.     float4 _SceneFogParams;
    24.     #ifndef UNITY_APPLY_FOG
    25.     half4 unity_FogColor;
    26.     half4 unity_FogDensity;
    27.     #endif  
    28.  
    29.     uniform float4 _MainTex_TexelSize;
    30.  
    31.     // for fast world space reconstruction
    32.     uniform float4x4 _FrustumCornersWS;
    33.     uniform float4 _CameraWS;
    34.  
    35.     struct v2f {
    36.         float4 pos : SV_POSITION;
    37.         float2 uv : TEXCOORD0;
    38.         float2 uv_depth : TEXCOORD1;
    39.         float4 interpolatedRay : TEXCOORD2;
    40.     };
    41.  
    42.     v2f vert (appdata_img v)
    43.     {
    44.         v2f o;
    45.         half index = v.vertex.z;
    46.         v.vertex.z = 0.1;
    47.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    48.         o.uv = v.texcoord.xy;
    49.         o.uv_depth = v.texcoord.xy;
    50.      
    51.         #if UNITY_UV_STARTS_AT_TOP
    52.         if (_MainTex_TexelSize.y < 0)
    53.             o.uv.y = 1-o.uv.y;
    54.         #endif              
    55.      
    56.         o.interpolatedRay = _FrustumCornersWS[(int)index];
    57.         o.interpolatedRay.w = index;
    58.      
    59.         return o;
    60.     }
    61.  
    62.     // Applies one of standard fog formulas, given fog coordinate (i.e. distance)
    63.     half ComputeFogFactor (float coord)
    64.     {
    65.         float fogFac = 0.0;
    66.         if (_SceneFogMode.x == 1) // linear
    67.         {
    68.             // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
    69.             fogFac = coord * _SceneFogParams.z + _SceneFogParams.w;
    70.         }
    71.         if (_SceneFogMode.x == 2) // exp
    72.         {
    73.             // factor = exp(-density*z)
    74.             fogFac = _SceneFogParams.y * coord; fogFac = exp2(-fogFac);
    75.         }
    76.         if (_SceneFogMode.x == 3) // exp2
    77.         {
    78.             // factor = exp(-(density*z)^2)
    79.             fogFac = _SceneFogParams.x * coord; fogFac = exp2(-fogFac*fogFac);
    80.         }
    81.         return saturate(fogFac);
    82.     }
    83.  
    84.     // Distance-based fog
    85.     float ComputeDistance (float3 camDir, float zdepth)
    86.     {
    87.         float dist;
    88.         if (_SceneFogMode.y == 1)
    89.             dist = length(camDir);
    90.         else
    91.             dist = zdepth * _ProjectionParams.z;
    92.         // Built-in fog starts at near plane, so match that by
    93.         // subtracting the near value. Not a perfect approximation
    94.         // if near plane is very large, but good enough.
    95.         dist -= _ProjectionParams.y;
    96.         return dist;
    97.     }
    98.  
    99.     // Linear half-space fog, from https://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf
    100.     float ComputeHalfSpace (float3 wsDir)
    101.     {
    102.         float3 wpos = _CameraWS + wsDir;
    103.         float FH = _HeightParams.x;
    104.         float3 C = _CameraWS;
    105.         float3 V = wsDir;
    106.         float3 P = wpos;
    107.         float3 aV = _HeightParams.w * V;
    108.         float FdotC = _HeightParams.y;
    109.         float k = _HeightParams.z;
    110.         float FdotP = P.y-FH;
    111.         float FdotV = wsDir.y;
    112.         float c1 = k * (FdotP + FdotC);
    113.         float c2 = (1-2*k) * FdotP;
    114.         float g = min(c2, 0.0);
    115.         g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
    116.         return g;
    117.     }
    118.  
    119.     half4 ComputeFog (v2f i, bool distance, bool height) : SV_Target
    120.     {
    121.         half4 sceneColor = tex2D(_MainTex, i.uv);
    122.         // Reconstruct world space position & direction
    123.         // towards this screen pixel.
    124.         float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
    125.         float dpth = Linear01Depth(rawDepth);
    126.         float4 wsDir = dpth * i.interpolatedRay;
    127.         float4 wsPos = _CameraWS + wsDir;
    128.  
    129.         // Compute fog distance
    130.         float g = _DistanceParams.x;
    131.         if (distance)
    132.             g += ComputeDistance (wsDir, dpth);
    133.         if (height)
    134.             g += ComputeHalfSpace (wsDir);
    135.  
    136.         // Compute fog amount
    137.         half fogFac = ComputeFogFactor (max(0.0,g));
    138.         // Do not fog skybox
    139.         if (rawDepth >= 0.999999)
    140.             fogFac = 1.0;
    141.         //return fogFac; // for debugging
    142.      
    143.         // Lerp between fog color & original scene color
    144.         // by fog amount
    145.         return lerp (unity_FogColor, sceneColor, fogFac);
    146.     }
    147.  
    148. ENDCG
    149.  
    150. SubShader
    151. {
    152.     ZTest Always Cull Off ZWrite Off Fog { Mode Off }
    153.  
    154.     // 0: distance + height
    155.     Pass
    156.     {
    157.         CGPROGRAM
    158.         #pragma vertex vert
    159.         #pragma fragment frag
    160.         half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, true); }
    161.         ENDCG
    162.     }
    163.     // 1: distance
    164.     Pass
    165.     {
    166.         CGPROGRAM
    167.         #pragma vertex vert
    168.         #pragma fragment frag
    169.         half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, false); }
    170.         ENDCG
    171.     }
    172.     // 2: height
    173.     Pass
    174.     {
    175.         CGPROGRAM
    176.         #pragma vertex vert
    177.         #pragma fragment frag
    178.         half4 frag (v2f i) : SV_Target { return ComputeFog (i, false, true); }
    179.         ENDCG
    180.     }
    181. }
    182.  
    183. Fallback off
    184.  
    185. }
    186.  
    Does anyone think they could help? Is it supported even?
    And also if anyone has a way to have the fog color match the skybox... making it actually blend with the skybox (as if the objects were getting transparent), you'd be my hero.
     
  2. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
  3. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    It doesn't look like it's using the luminosity:

    return lerp (unity_FogColor, sceneColor, fogFac);

    That's just doing a straight lap from the fog color to the color in the scene. Are you sure you have the alpha set to 1 on your black?
     
  4. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    Yes I made sure the alpha was set to 1.
     
  5. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    I just tested black fog in my scene, and it worked like I expected. In deferred mode, it didn't effect the water (but that was expected also). I tested with both the global fog effect on the camera, and normal fog. Guess you found a bug - I'd suggest to report it with the project attached.
     
    Last edited: Jan 11, 2015
  6. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    Ok I got it to work. Unsure why it wasn't working before.... but it is now. Sorry about that. I appreciate the help :)