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.