Initially I wanted to reduce count of the compiled shader variants, since Unity's fog adds extra compiled variants for each fog type (linear, exp, exp2). I decided to make custom fog using lookup texture generated from adjustable curve, instead of hardcoded functions. But then I realized, if I use texture for the fog, why not use gradients, as it would give even more flexibility and interesting results
and here's a comparison of non-gradient vs gradient fog adjusted by artists:
gradient
So I made a script with fog settings which generates 16x1 lookup texture and sets it as a global shader texture. And I made FogHelpers.cginc
with 2 macros, so it can be reused in any shader
sampler2D _FogTex;
float _FogDensity;
#define CALCULATE_FOG(fog, clipPos) fog = UNITY_Z_0_FAR_FROM_CLIPSPACE(clipPos.z) * _FogDensity
#define APPLY_FOG(fog, col)\
fixed4 fogValue = tex2D(_FogTex, float2(saturate(fog), 0));\
col.rgb = lerp(col.rgb, fogValue.rgb, fogValue.a)
Here are some examples from different levels