//================================================================================================= //Mip Fog for STALKER Anomaly //Inspired by Uncharted 4 //================================================================================================= #define HEIGHTFOGMAX 60 #define HEIGHTFOGMIN -75 #define FOGMAXSHARPNESS 0.895 #define FOGROUGHCURVE 1.0 #define MIPFOGAMOUNT 2.0 #define SUNFOGAMOUNT 0.35 #define MINFOGDENSITY 0.35 #define MAXFOGDENSITY 6.5 #define HEIGHTFOGCURVE 5.5 //================================================================================================= float Calc_Exponent(float a) { return 1 / (pow(2, a)); } float Calc_Height(float3 wpos) { return 1 - saturate((wpos.y - HEIGHTFOGMIN) / (HEIGHTFOGMAX-HEIGHTFOGMIN)); } float Calc_FinalFog(float fog, float height) { float HeightLerp = pow(height, HEIGHTFOGCURVE); /* float CamHeight = Calc_Height(eye_position); float CamLerp = pow(CamHeight, HEIGHTFOGCURVE); //HeightLerp = max(HeightLerp, CamLerp); HeightLerp = (HeightLerp * (1-CamLerp)) + CamLerp; */ float Fog = Calc_Exponent(fog * lerp(MINFOGDENSITY, MAXFOGDENSITY, HeightLerp)); return saturate(1 - Fog); } float3 Calc_SunFog(float3 pos, float3 fogrough) { float3 SunFog = saturate(dot(normalize(Ldynamic_dir), -normalize(pos))); float gloss = lerp(FOGMAXSHARPNESS*0.5, 0, fogrough); gloss = gloss*gloss; gloss = pow(8192, gloss); SunFog = pow(SunFog, gloss) * ((gloss + 2)/(8 * PI)); //BLOPS2 blinn SunFog *= SRGBToLinear(Ldynamic_color.rgb); return SunFog * SUNFOGAMOUNT; } float3 Calc_MipFog(float3 sky, float3 fogrough) { sky = normalize(sky); //cubemap projection float3 skyabs = abs(sky); float skymax = max(skyabs.x, max(skyabs.y, skyabs.z)); sky /= skymax; if (sky.y < 0.999) sky.y = sky.y*2-1; //fake remapping sky = normalize(sky); float FogMip = lerp(CUBE_MIPS - (CUBE_MIPS * FOGMAXSHARPNESS), CUBE_MIPS, fogrough); //don't use base mip float3 s0 = env_s0.SampleLevel(smp_base, sky, FogMip); float3 s1 = env_s1.SampleLevel(smp_base, sky, FogMip); float3 MipFog = lerp(s0,s1,env_color.w); //srgb tint float3 FogTint = lerp(fog_color.rgb * 2.0, env_color.rgb, fogrough*fogrough); //env for close, fog for far MipFog *= FogTint; //linear cubemap MipFog = SRGBToLinear(MipFog); return MipFog * MIPFOGAMOUNT; } float3 Calc_Fog(float3 pos, float3 color) { color = SRGBToLinear(color.rgb); //view to world space float3 sky = mul(m_inv_V, pos ); float3 wpos = sky + eye_position; float distance = length(pos); float fog = saturate(distance * fog_params.w + fog_params.x); float height = Calc_Height(wpos); float FinalFog = Calc_FinalFog(fog, height); float fogrough = fog; fogrough = pow(1 - fogrough , FOGROUGHCURVE); float3 MipFog = Calc_MipFog(sky, fogrough); float3 SunFog = Calc_SunFog(pos, fogrough); float3 FogColor = MipFog + SunFog; //fog blend float3 FogBlend = FinalFog; //fog alpha float fogalpha = fog * fog; FogBlend *= 1 - fogalpha; FogBlend += fogalpha; float3 Final = lerp(color, FogColor, FogBlend); Final = LinearTosRGB(Final); return Final; }