Black fog color?

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:

Shader "Hidden/GlobalFog" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "black" {}
}

CGINCLUDE

    #include "UnityCG.cginc"

    uniform sampler2D _MainTex;
    uniform sampler2D_float _CameraDepthTexture;
  
    // x = fog height
    // y = FdotC (CameraY-FogHeight)
    // z = k (FdotC > 0.0)
    // w = a/2
    uniform float4 _HeightParams;
  
    // x = start distance
    uniform float4 _DistanceParams;
  
    int4 _SceneFogMode; // x = fog mode, y = use radial flag
    float4 _SceneFogParams;
    #ifndef UNITY_APPLY_FOG
    half4 unity_FogColor;
    half4 unity_FogDensity;
    #endif  

    uniform float4 _MainTex_TexelSize;
  
    // for fast world space reconstruction
    uniform float4x4 _FrustumCornersWS;
    uniform float4 _CameraWS;

    struct v2f {
        float4 pos : SV_POSITION;
        float2 uv : TEXCOORD0;
        float2 uv_depth : TEXCOORD1;
        float4 interpolatedRay : TEXCOORD2;
    };
  
    v2f vert (appdata_img v)
    {
        v2f o;
        half index = v.vertex.z;
        v.vertex.z = 0.1;
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
        o.uv = v.texcoord.xy;
        o.uv_depth = v.texcoord.xy;
      
        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
            o.uv.y = 1-o.uv.y;
        #endif              
      
        o.interpolatedRay = _FrustumCornersWS[(int)index];
        o.interpolatedRay.w = index;
      
        return o;
    }
  
    // Applies one of standard fog formulas, given fog coordinate (i.e. distance)
    half ComputeFogFactor (float coord)
    {
        float fogFac = 0.0;
        if (_SceneFogMode.x == 1) // linear
        {
            // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
            fogFac = coord * _SceneFogParams.z + _SceneFogParams.w;
        }
        if (_SceneFogMode.x == 2) // exp
        {
            // factor = exp(-density*z)
            fogFac = _SceneFogParams.y * coord; fogFac = exp2(-fogFac);
        }
        if (_SceneFogMode.x == 3) // exp2
        {
            // factor = exp(-(density*z)^2)
            fogFac = _SceneFogParams.x * coord; fogFac = exp2(-fogFac*fogFac);
        }
        return saturate(fogFac);
    }

    // Distance-based fog
    float ComputeDistance (float3 camDir, float zdepth)
    {
        float dist;
        if (_SceneFogMode.y == 1)
            dist = length(camDir);
        else
            dist = zdepth * _ProjectionParams.z;
        // Built-in fog starts at near plane, so match that by
        // subtracting the near value. Not a perfect approximation
        // if near plane is very large, but good enough.
        dist -= _ProjectionParams.y;
        return dist;
    }

    // Linear half-space fog, from https://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf
    float ComputeHalfSpace (float3 wsDir)
    {
        float3 wpos = _CameraWS + wsDir;
        float FH = _HeightParams.x;
        float3 C = _CameraWS;
        float3 V = wsDir;
        float3 P = wpos;
        float3 aV = _HeightParams.w * V;
        float FdotC = _HeightParams.y;
        float k = _HeightParams.z;
        float FdotP = P.y-FH;
        float FdotV = wsDir.y;
        float c1 = k * (FdotP + FdotC);
        float c2 = (1-2*k) * FdotP;
        float g = min(c2, 0.0);
        g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
        return g;
    }

    half4 ComputeFog (v2f i, bool distance, bool height) : SV_Target
    {
        half4 sceneColor = tex2D(_MainTex, i.uv);
        // Reconstruct world space position & direction
        // towards this screen pixel.
        float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
        float dpth = Linear01Depth(rawDepth);
        float4 wsDir = dpth * i.interpolatedRay;
        float4 wsPos = _CameraWS + wsDir;

        // Compute fog distance
        float g = _DistanceParams.x;
        if (distance)
            g += ComputeDistance (wsDir, dpth);
        if (height)
            g += ComputeHalfSpace (wsDir);

        // Compute fog amount
        half fogFac = ComputeFogFactor (max(0.0,g));
        // Do not fog skybox
        if (rawDepth >= 0.999999)
            fogFac = 1.0;
        //return fogFac; // for debugging
      
        // Lerp between fog color & original scene color
        // by fog amount
        return lerp (unity_FogColor, sceneColor, fogFac);
    }

ENDCG

SubShader
{
    ZTest Always Cull Off ZWrite Off Fog { Mode Off }

    // 0: distance + height
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, true); }
        ENDCG
    }
    // 1: distance
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, false); }
        ENDCG
    }
    // 2: height
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        half4 frag (v2f i) : SV_Target { return ComputeFog (i, false, true); }
        ENDCG
    }
}

Fallback off

}

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.

Bump :slight_smile:

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?

Yes I made sure the alpha was set to 1.

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.

Ok I got it to work. Unsure why it wasn’t working before… but it is now. Sorry about that. I appreciate the help :slight_smile: