I tinkered around with shader programming. You would have to create your own fog-shader or change the FOG-Code in the “UnityCG.cginc” file. I did not get far with it. I shifted this task back in my schedule because most of my shaders are vertex anyway. But this is the work in progress testing shader i got so far:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
// Simplified VertexLit shader. Differences from regular VertexLit one:
// - no per-material color
// - no specular
// - no emission
// - default "Mobile/VertexLit"
Shader "InfinityTerrain/ManualFog"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Tags { "LightMode" = "Vertex" }
//Tags { "LightMode" = "ForwardBase" }
// Cull Back
// Lighting On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#pragma glsl//tex2Dlod
#include "UnityCG.cginc"
struct appdata
{
fixed4 vertex : POSITION;
fixed2 uv : TEXCOORD0;
fixed3 normal : NORMAL;
fixed3 color : COLOR;
};
struct v2f
{
fixed2 uv : TEXCOORD0;
//UNITY_FOG_COORDS(1)
fixed4 vertex : SV_POSITION;
fixed3 color : COLOR;
};
sampler2D _MainTex;
fixed4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex); //#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw) //?v.uv.xy *_MainTex##_ST.xy +MainTex##_ST.zw;//
o.color = ShadeVertexLights(v.vertex,v.normal);
//Texture
//read tex in vert shader already, no need to do it in frag shader
fixed4 tex = tex2Dlod (_MainTex, fixed4(v.uv.xy,0,0));
o.color = tex *o.color;
//Distance
// o.fogDepth.x = length(mul (UNITY_MATRIX_MV, v.vertex).xyz);
// o.fogDepth.y = o.fogDepth.x * unity_FogDensity;
//
// fixed dist = length(mul (UNITY_MATRIX_MV, v.vertex).xyz);
// fixed fac = dist * 0.0025;
fixed dist = length(ObjSpaceViewDir(v.vertex));
fixed fac = clamp( (dist) * 0.0125, 0, 1);
// o.color = fixed3(fac,fac,fac);
o.color = lerp( o.color, unity_FogColor , fac );
// UNITY_LIGHTMODEL_AMBIENT
//debug
// o.color = lerp( o.color, fixed3(1,0,0) , fac );
//check edge popping
// if(fac<1){fac = 0;}
// o.color = lerp( fixed3(1,0,0), unity_FogColor , fac );
//UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
// fixed4
fixed3 frag (v2f i) : SV_Target
{
return i.color;
// fixed4 col;
// col.rgb = i.color;//fog debug
// col = tex2D(_MainTex, i.uv); // sample the texture
// col.rgb = col.rgb * i.color;//add lighting https://discussions.unity.com/t/519532
//UNITY_APPLY_FOG(i.fogCoord, col); // apply fog
// return col;
}
ENDCG
}
}
}
/* FROM "UnityCG.cginc"
// ------------------------------------------------------------------
// Fog helpers
//
// multi_compile_fog Will compile fog variants.
// UNITY_FOG_COORDS(texcoordindex) Declares the fog data interpolator.
// UNITY_TRANSFER_FOG(outputStruct,clipspacePos) Outputs fog data from the vertex shader.
// UNITY_APPLY_FOG(fogData,col) Applies fog to color "col". Automatically applies black fog when in forward-additive pass.
// Can also use UNITY_APPLY_FOG_COLOR to supply your own fog color.
// In case someone by accident tries to compile fog code in one of the g-buffer or shadow passes:
// treat it as fog is off.
#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)
#undef FOG_LINEAR
#undef FOG_EXP
#undef FOG_EXP2
#endif
#if defined(UNITY_REVERSED_Z)
//D3d with reversed Z => z clip range is [near, 0] -> remapping to [0, far]
//max is required to protect ourselves from near plane not being correct/meaningfull in case of oblique matrices.
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0)
#elif UNITY_UV_STARTS_AT_TOP
//D3d without reversed z => z clip range is [0, far] -> nothing to do
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#else
//Opengl => z clip range is [-near, far] -> should remap in theory but dont do it in practice to save some perf (range is close enought)
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#endif
#if defined(FOG_LINEAR)
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = (coord) * unity_FogParams.z + unity_FogParams.w
#elif defined(FOG_EXP)
// factor = exp(-density*z)
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.y * (coord); unityFogFactor = exp2(-unityFogFactor)
#elif defined(FOG_EXP2)
// factor = exp(-(density*z)^2)
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.x * (coord); unityFogFactor = exp2(-unityFogFactor*unityFogFactor)
#else
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = 0.0
#endif
#define UNITY_CALC_FOG_FACTOR(coord) UNITY_CALC_FOG_FACTOR_RAW(UNITY_Z_0_FAR_FROM_CLIPSPACE(coord))
#define UNITY_FOG_COORDS_PACKED(idx, vectype) vectype fogCoord : TEXCOORD##idx;
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#define UNITY_FOG_COORDS(idx) UNITY_FOG_COORDS_PACKED(idx, float1)
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
// mobile or SM2.0: calculate fog factor per-vertex
#define UNITY_TRANSFER_FOG(o,outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.fogCoord.x = unityFogFactor
#else
// SM3.0 and PC/console: calculate fog distance per-vertex, and fog factor per-pixel
#define UNITY_TRANSFER_FOG(o,outpos) o.fogCoord.x = (outpos).z
#endif
#else
#define UNITY_FOG_COORDS(idx)
#define UNITY_TRANSFER_FOG(o,outpos)
#endif
#define UNITY_FOG_LERP_COLOR(col,fogCol,fogFac) col.rgb = lerp((fogCol).rgb, (col).rgb, saturate(fogFac))
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE)
// mobile or SM2.0: fog factor was already calculated per-vertex, so just lerp the color
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_FOG_LERP_COLOR(col,fogCol,(coord).x)
#else
// SM3.0 and PC/console: calculate fog factor and lerp fog color
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_CALC_FOG_FACTOR((coord).x); UNITY_FOG_LERP_COLOR(col,fogCol,unityFogFactor)
#endif
#else
#define UNITY_APPLY_FOG_COLOR(coord,col,fogCol)
#endif
#ifdef UNITY_PASS_FORWARDADD
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))
#else
#define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)
#endif
*/
/*{
// https://discussions.unity.com/t/539834
Properties {
_MainTex ("Base (RGB)", 2D) = "black" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
Cull off
// Lighting Off
Blend SrcAlpha OneMinusSrcAlpha
Fog {Mode Off}
Pass {
CGPROGRAM
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
//#pragma exclude_renderers d3d11 xbox360 ps3 flash d3d11_9x
#include "UnityCG.cginc"
//uniform fixed3 unity_FogColor;
uniform half unity_FogDensity;
sampler2D _MainTex;
struct vertexInput {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
fixed4 color : COLOR;
};
struct v2f {
float4 scrPos : SV_POSITION;
half2 srcUVs: TEXCOORD0;
half2 fogDepth: TEXCOORD1; // linear depth in x and depth multiplied by density in y
float3 color : COLOR;
};
v2f vert (vertexInput v)
{
v2f o;
o.scrPos = UnityObjectToClipPos(v.vertex);
//o.srcUVs = TRANSFORM_TEX(v.texcoord, _MainTex);
o.srcUVs = v.texcoord;
o.color = ShadeVertexLights(v.vertex,v.normal);
// this is UNITY_FOG_COORDS
// o.fogDepth.x = length(mul (UNITY_MATRIX_MV, v.vertex).xyz);
// o.fogDepth.y = o.fogDepth.x * unity_FogDensity;
o.fogDepth.x = length(mul (UNITY_MATRIX_MV, v.vertex).xyz);
o.fogDepth.y = o.fogDepth.x * unity_FogDensity;
return o;
}
fixed4 frag (v2f i) : COLOR
{
fixed3 clr = tex2D(_MainTex, i.srcUVs).rgb;
clr.rgb = clr.rgb * i.color;
// Exp2 mode:
//float fogAmt = i.fogDepth.y * i.fogDepth.y;
// fogAmt = exp(-fogAmt);
float fogAmt = i.fogDepth.y;
clr = lerp( unity_FogColor, clr, fogAmt);
return fixed4(
clr,
1.0
);
}
ENDCG
}
}
}*/