1
0
Fork 0
fgdata/Shaders/road-ALS-ultra.frag
Nikolai V. Chr a206b3cb51 Change to the up vector used in sky irradiance light in ALS shader.
Models that are xml offset with pitch, heading or yaw should now be correct lighted.
2017-10-10 17:58:32 +02:00

823 lines
27 KiB
C

// -*- mode: C; -*-
// Licence: GPL v2
// Authors: Frederic Bouvier and Gijs de Rooy
// with major additions and revisions by
// Emilian Huminiuc and Vivian Meazza 2011
// ported to Atmospheric Light Scattering
// by Thorsten Renk, 2013
// changes for road and traffic rendering
// by Thorsten Renk 2017
#version 120
varying vec3 VBinormal;
varying vec3 VNormal;
varying vec3 VTangent;
varying vec3 rawpos;
varying vec3 reflVec;
varying vec3 vViewVec;
varying vec3 vertVec;
varying float alpha;
uniform sampler2D BaseTex;
uniform sampler2D NormalTex;
uniform sampler2D ReflMapTex;
uniform sampler2D ReflGradientsTex;
uniform sampler3D ReflNoiseTex;
uniform samplerCube Environment;
uniform sampler2D GrainTex;
uniform int dirt_enabled;
uniform int dirt_multi;
uniform int nmap_dds;
uniform int nmap_enabled;
uniform int refl_enabled;
uniform int refl_type;
uniform int refl_map;
uniform int grain_texture_enabled;
uniform int road_traffic_direction;
uniform int rain_enabled;
uniform int road_traffic_enabled;
uniform int cloud_shadow_flag;
uniform int use_searchlight;
uniform int use_landing_light;
uniform int use_alt_landing_light;
uniform float amb_correction;
uniform float dirt_b_factor;
uniform float dirt_g_factor;
uniform float dirt_r_factor;
uniform float nmap_tile;
uniform float refl_correction;
uniform float refl_fresnel;
uniform float refl_fresnel_factor;
uniform float refl_noise;
uniform float refl_rainbow;
uniform float grain_magnification;
uniform float wetness;
uniform float rain_norm;
uniform float road_traffic_density;
uniform float streetlight_factor;
uniform float road_traffic_variation;
uniform float avisibility;
uniform float cloud_self_shading;
uniform float eye_alt;
uniform float ground_scattering;
uniform float hazeLayerAltitude;
uniform float moonlight;
uniform float overcast;
uniform float scattering;
uniform float terminator;
uniform float terrain_alt;
uniform float visibility;
uniform float air_pollution;
uniform float snowlevel;
uniform float snow_thickness_factor;
uniform float osg_SimulationTime;
uniform mat4 osg_ViewMatrix;
uniform float landing_light1_offset;
uniform float landing_light2_offset;
uniform float landing_light3_offset;
uniform bool use_IR_vision;
// constants needed by the light and fog computations ###################################################
const float EarthRadius = 5800000.0;
const float terminator_width = 200000.0;
uniform vec3 dirt_r_color;
uniform vec3 dirt_g_color;
uniform vec3 dirt_b_color;
uniform vec3 streetlight_color;
float DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dot_density);
float shadow_func (in float x, in float y, in float noise, in float dist);
float fog_func (in float targ, in float altitude);
float rayleigh_in_func(in float dist, in float air_pollution, in float avisibility, in float eye_alt, in float vertex_alt);
float alt_factor(in float eye_alt, in float vertex_alt);
float light_distance_fading(in float dist);
float fog_backscatter(in float avisibility);
float rand2D(in vec2 co);
float Noise2D(in vec2 coord, in float wavelength);
vec3 rayleigh_out_shift(in vec3 color, in float outscatter);
vec3 get_hazeColor(in float lightArg);
vec3 searchlight();
vec3 landing_light(in float offset, in float offsetv);
vec3 filter_combined (in vec3 color) ;
vec3 addLights(in vec3 color1, in vec3 color2);
float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
{
if (x > 30.0) {return e;}
if (x < -15.0) {return 0.0;}
return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
}
void road_type_mapper (in vec2 coord, out float rtype_traffic_density, out float rtype_base_illumination, out float rtype_traffic_speed, out int rtype_dual_lane)
{
if (coord.s < 0.125) // railway
{
rtype_dual_lane = 0;
rtype_traffic_density = 0;
rtype_base_illumination = 0;
rtype_traffic_speed = 0.0;
}
else if (coord.s < 0.250) // residential
{
rtype_dual_lane = 0;
rtype_traffic_density = 0.3;
rtype_base_illumination = 0.65;
rtype_traffic_speed = 0.5;
}
else if (coord.s < 0.375) // single-lane major
{
rtype_dual_lane = 0;
rtype_traffic_density = 1.0;
rtype_base_illumination = 0.65;
rtype_traffic_speed = 1.0;
}
else if (coord.s < 0.5)
{
rtype_dual_lane = 0;
rtype_traffic_density = 0.0;
rtype_base_illumination = 0.0;
rtype_traffic_speed = 0.0;
}
else if (coord.s < 0.625) // grass
{
rtype_dual_lane = 0;
rtype_traffic_density = 0.0;
rtype_base_illumination = 0.0;
rtype_traffic_speed = 0.0;
}
else if (coord.s < 0.750) // dual-lane highway
{
rtype_dual_lane = 1;
rtype_traffic_density = 1.0;
rtype_base_illumination = 0.0;
rtype_traffic_speed = 1.0;
}
else if (coord.s < 0.875) // dirt
{
rtype_dual_lane = 0;
rtype_traffic_density = 0.1;
rtype_base_illumination = 0.0;
rtype_traffic_speed = 0.3;
}
else // tramway
{
rtype_dual_lane = 0;
rtype_traffic_density = 0.0;
rtype_base_illumination = 0.0;
rtype_traffic_speed = 0.0;
}
}
void main (void)
{
vec4 texel = texture2D(BaseTex, gl_TexCoord[0].st);
vec4 nmap = texture2D(NormalTex, gl_TexCoord[0].st * nmap_tile);
vec4 reflmap = texture2D(ReflMapTex, gl_TexCoord[0].st);
vec4 noisevec = texture3D(ReflNoiseTex, rawpos.xyz);
vec4 grainTexel;
vec3 mixedcolor;
vec3 N = vec3(0.0,0.0,1.0);
// noise
float noise_1m = Noise2D(rawpos.xy, 1.0);
float noise_5m = Noise2D(rawpos.xy, 5.0);
// road type characteristics
float rtype_traffic_density = 0.0;
float rtype_base_illumination = 0.0;
float rtype_traffic_speed = 0.0;
int rtype_dual_lane = 0;
road_type_mapper (gl_TexCoord[0].st, rtype_traffic_density, rtype_base_illumination, rtype_traffic_speed, rtype_dual_lane);
float pf = 0.0;
float pf1 = 0.0;
///some generic light scattering parameters
vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
vec3 moonLightColor = vec3 (0.095, 0.095, 0.15) * moonlight;
float alt = eye_alt;
float effective_scattering = min(scattering, cloud_self_shading);
/// BEGIN geometry for light
vec3 up = (osg_ViewMatrix * vec4(0.0,0.0,1.0,0.0)).xyz;
vec3 nVertVec = normalize(vertVec);
float dist = length(vertVec);
float vertex_alt = max(100.0,dot(up, vertVec) + alt);
float vertex_scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt);
vec3 lightHorizon = gl_LightSource[0].position.xyz - up * dot(up,gl_LightSource[0].position.xyz);
float yprime = -dot(vertVec, lightHorizon);
float yprime_alt = yprime - sqrt(2.0 * EarthRadius * vertex_alt);
float lightArg = (terminator-yprime_alt)/100000.0;
float earthShade = 0.6 * (1.0 - smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt)) + 0.4;
float mie_angle;
if (lightArg < 10.0)
{mie_angle = (0.5 * dot(nVertVec, normalize(gl_LightSource[0].position.xyz)) ) + 0.5;}
else
{mie_angle = 1.0;}
float fog_vertex_alt = max(vertex_alt,hazeLayerAltitude);
float fog_yprime_alt = yprime_alt;
if (fog_vertex_alt > hazeLayerAltitude)
{
if (dist > 0.8 * avisibility)
{
fog_vertex_alt = mix(fog_vertex_alt, hazeLayerAltitude, smoothstep(0.8*avisibility, avisibility, dist));
fog_yprime_alt = yprime -sqrt(2.0 * EarthRadius * fog_vertex_alt);
}
}
else
{
fog_vertex_alt = hazeLayerAltitude;
fog_yprime_alt = yprime -sqrt(2.0 * EarthRadius * fog_vertex_alt);
}
float fog_lightArg = (terminator-fog_yprime_alt)/100000.0;
float fog_earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, fog_yprime_alt) + 0.1;
float ct = dot(normalize(up), nVertVec);
vec3 relPos = (gl_ModelViewMatrixInverse * vec4 (vertVec,0.0)).xyz;
/// END geometry for light
/// BEGIN light
vec4 light_diffuse;
vec4 light_ambient;
float intensity;
light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 3.827, 1.08e-05, 1.0);
light_diffuse.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
light_diffuse.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
light_diffuse.a = 1.0;
light_diffuse = light_diffuse * vertex_scattering;
light_ambient.r = light_func(lightArg, 0.236, 0.253, 1.073, 0.572, 0.33);
light_ambient.g = light_ambient.r * 0.4/0.33;
light_ambient.b = light_ambient.r * 0.5/0.33;
light_ambient.a = 1.0;
if (earthShade < 0.5)
{
intensity = length(light_ambient.rgb);
light_ambient.rgb = intensity * normalize(mix(light_ambient.rgb, shadedFogColor, 1.0 -smoothstep(0.1, 0.8,earthShade) ));
light_ambient.rgb = light_ambient.rgb + moonLightColor * (1.0 - smoothstep(0.4, 0.5, earthShade));
intensity = length(light_diffuse.rgb);
light_diffuse.rgb = intensity * normalize(mix(light_diffuse.rgb, shadedFogColor, 1.0 -smoothstep(0.1, 0.7,earthShade) ));
}
vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
vec3 ecViewDir = (gl_ModelViewMatrix * (ep - vec4(rawpos, 1.0))).xyz;
vec3 HV = normalize(normalize(gl_LightSource[0].position.xyz) + normalize(ecViewDir));
/// END light
/// BEGIN grain overlay
if (grain_texture_enabled ==1)
{
grainTexel = texture2D(GrainTex, gl_TexCoord[0].st * grain_magnification);
texel.rgb = mix(texel.rgb, grainTexel.rgb, grainTexel.a );
}
else if (grain_texture_enabled == 2)
{
grainTexel = texture2D(GrainTex, rawpos.xy * grain_magnification);
texel.rgb = mix(texel.rgb, grainTexel.rgb, grainTexel.a );
}
/// END grain overlay
/// BEGIN procedural textures - cars and snow
vec2 roadCoords = gl_TexCoord[0].st;
roadCoords.s *=8.0;
roadCoords.s = fract(roadCoords.s);
vec4 snow_texel = vec4 (0.95, 0.95, 0.95, 1.0);
float noise_term = 0.5 * (noise_5m - 0.5);
noise_term += 0.5 * (noise_1m - 0.5);
snow_texel.a = snow_texel.a * 0.2+0.8* smoothstep(0.2,0.8, 0.3 +noise_term + 0.5*snow_thickness_factor +0.0001*(relPos.z +eye_alt -snowlevel) );
float noise_2000m = 0.0;
float noise_10m = 0.0;
float snowLaneShape = smoothstep(0.20, 0.28, roadCoords.s) * (1.0-smoothstep(0.42, 0.5, roadCoords.s));
snowLaneShape += smoothstep(0.6, 0.68, roadCoords.s) * (1.0-smoothstep(0.82, 0.9, roadCoords.s));
snow_texel.a *= (1.0 - 0.3* snowLaneShape * rtype_traffic_density);
texel.rgb = mix(texel.rgb, snow_texel.rgb, snow_texel.a* smoothstep(snowlevel, snowlevel+200.0, 1.0 * (relPos.z + eye_alt)+ (noise_2000m + 0.1 * noise_10m -0.55) *400.0));
float cTag = 0.0;
float cPresent = 0.0;
float cSign = 1.0;
float total_traffic_density = 0.0;
if (road_traffic_enabled == 1)
{
float cOffset = 0.0;
if (roadCoords.s > 0.5)
{
if (rtype_dual_lane == 0) {cSign = -1.0;}
else {cOffset = 5.0;}
}
if (rtype_dual_lane == 1) {cSign = -1.0;}
cSign *= road_traffic_direction;
total_traffic_density = road_traffic_density * rtype_traffic_density * road_traffic_variation;
float cCoord = roadCoords.t + cOffset;
cCoord += 0.3 * osg_SimulationTime * cSign * rtype_traffic_speed * (1.0 - (0.9 * smoothstep(1.0, 2.5, total_traffic_density)));
cCoord *= 5.0;
cTag = fract(cCoord);
float cDomain = cCoord - cTag;
float cRnd = rand2D(vec2 (cDomain, cSign));
cPresent = 0.0;
float cDisc = 0.2 * total_traffic_density;
if (cRnd > 1.0 - cDisc) {cPresent = 1.0;}
float cColorRnd = (cRnd - 1.0 + cDisc)/ max(cDisc, 0.05);
float cColorRnd2 = rand2D(vec2 (cDomain, 0.5));
vec3 cColor = vec3 (0.8 * (1.0 - cColorRnd), 0.8 * 2.0 * (0.5 - abs(cColorRnd - 0.5)) , 0.8 * cColorRnd);
cColor *= cColorRnd2;
float cPos = cTag;
if (cSign > 0.0) {cPos = 1.0 - cPos;}
float cShape = smoothstep(0.0, 0.05, cPos) * (1.0-smoothstep(0.35, 0.4, cPos));
float laneShape = smoothstep(0.25, 0.28, roadCoords.s) * (1.0-smoothstep(0.42, 0.45, roadCoords.s));
laneShape += smoothstep(0.65, 0.68, roadCoords.s) * (1.0-smoothstep(0.82, 0.85, roadCoords.s));
cShape *= laneShape;
texel.rgb = mix(texel.rgb, cColor, cPresent * cShape);
}
/// END procedural cars
vec3 reflVecN;
///BEGIN bump
if (nmap_enabled > 0){
N = nmap.rgb * 2.0 - 1.0;
// this is exact only for viewing under 90 degrees but much faster than the real solution
reflVecN = normalize (N.x * VTangent + N.y * VBinormal + N.z * reflVec);
N = normalize(N.x * VTangent + N.y * VBinormal + N.z * VNormal);
if (nmap_dds > 0)
N = -N;
} else {
N = normalize(VNormal);
reflVecN = reflVec;
}
///END bump
vec4 reflection = textureCube(Environment, reflVecN );
vec3 viewVec = normalize(vViewVec);
float v = abs(dot(viewVec, normalize(VNormal)));// Map a rainbowish color
vec4 fresnel = texture2D(ReflGradientsTex, vec2(v, 0.75));
vec4 rainbow = texture2D(ReflGradientsTex, vec2(v, 0.25));
float nDotVP = max(0.0, dot(N, normalize(gl_LightSource[0].position.xyz)));
//float nDotHV = max(0.0, dot(N, normalize(gl_LightSource[0].halfVector.xyz)));
float nDotHV = max(0.0, dot(N,HV));
//glare on the backside of tranparent objects
if ((gl_FrontMaterial.diffuse.a < 1.0 || texel.a < 1.0)
&& dot(N, normalize(gl_LightSource[0].position.xyz)) < 0.0) {
nDotVP = max(0.0, dot(-N, normalize(gl_LightSource[0].position.xyz)) * (1.0 -texel.a) );
nDotHV = max(0.0, dot(-N, HV) * (1.0 -texel.a) );
}
float nDotVP1 = 0.0;
float nDotHV1 = 0.0;
// try specular reflection of sky irradiance
nDotVP1 = max(0.0, dot(N, up));
nDotHV1 = max(0.0, dot(N, normalize(normalize(up) + normalize(-vertVec))));
if (nDotVP == 0.0)
{pf = 0.0;}
else
{pf = pow(nDotHV, gl_FrontMaterial.shininess);}
if (nDotVP1 == 0.0)
{pf1 = 0.0;}
else
{pf1 = pow(nDotHV1, 0.5*gl_FrontMaterial.shininess);}
if (cloud_shadow_flag == 1)
{
light_diffuse = light_diffuse * shadow_func(relPos.x, relPos.y, 1.0, dist);
}
vec3 secondary_light = vec3 (0.0,0.0,0.0);
if (use_searchlight == 1)
{
secondary_light += searchlight();
}
if (use_landing_light == 1)
{
secondary_light += landing_light(landing_light1_offset, landing_light3_offset);
}
if (use_alt_landing_light == 1)
{
secondary_light += landing_light(landing_light2_offset, landing_light3_offset);
}
vec4 Diffuse = light_diffuse * nDotVP;
Diffuse.rgb += secondary_light * light_distance_fading(dist);
if (use_IR_vision)
{
Diffuse.rgb = max(Diffuse.rgb, vec3 (0.5, 0.5, 0.5));
}
vec4 Specular = gl_FrontMaterial.specular * light_diffuse * pf + gl_FrontMaterial.specular * light_ambient * pf1;
Specular+= gl_FrontMaterial.specular * pow(max(0.0,-dot(N,nVertVec)),gl_FrontMaterial.shininess) * vec4(secondary_light,1.0);
//vec4 color = gl_Color + Diffuse * gl_FrontMaterial.diffuse;
vec4 color = Diffuse;// * gl_FrontMaterial.diffuse;
color = clamp( color, 0.0, 1.0 );
////////////////////////////////////////////////////////////////////
//BEGIN reflect
////////////////////////////////////////////////////////////////////
if (refl_enabled > 0){
float reflFactor = 0.0;
float transparency_offset = clamp(refl_correction, -1.0, 1.0);// set the user shininess offset
if(refl_map > 0){
// map the shininess of the object with user input
//float pam = (map.a * -2) + 1; //reverse map
reflFactor = reflmap.a + transparency_offset;
} else if (nmap_enabled > 0) {
// set the reflectivity proportional to shininess with user input
reflFactor = gl_FrontMaterial.shininess * 0.0078125 * nmap.a + transparency_offset;
} else {
reflFactor = gl_FrontMaterial.shininess* 0.0078125 + transparency_offset;
}
// enhance low angle reflection by a fresnel term
float fresnel_enhance = (1.0-smoothstep(0.0,0.4, dot(N,-nVertVec))) * refl_fresnel_factor;
reflFactor+=fresnel_enhance;
reflFactor = clamp(reflFactor, 0.0, 1.0);
// add fringing fresnel and rainbow effects and modulate by reflection
vec4 reflcolor = mix(reflection, rainbow, refl_rainbow * v);
//vec4 reflcolor = reflection;
vec4 reflfrescolor = mix(reflcolor, fresnel, refl_fresnel * v);
vec4 noisecolor = mix(reflfrescolor, noisevec, refl_noise);
//vec4 raincolor = vec4(noisecolor.rgb * reflFactor, 1.0);
vec4 raincolor = vec4(noisecolor.rgb, 1.0);
raincolor += Specular;
raincolor *= light_diffuse;
if (refl_type == 1)
{mixedcolor = mix(texel, raincolor, reflFactor).rgb;}
else if (refl_type == 2)
{mixedcolor = ((texel +(reflcolor * reflFactor))-(0.5*reflFactor)).rgb;}
} else {
mixedcolor = texel.rgb;
}
/////////////////////////////////////////////////////////////////////
//END reflect
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//begin DIRT
//////////////////////////////////////////////////////////////////////
if (dirt_enabled >= 1){
vec3 dirtFactorIn = vec3 (dirt_r_factor, dirt_g_factor, dirt_b_factor);
vec3 dirtFactor = reflmap.rgb * dirtFactorIn.rgb;
//dirtFactor.r = smoothstep(0.0, 1.0, dirtFactor.r);
mixedcolor.rgb = mix(mixedcolor.rgb, dirt_r_color, smoothstep(0.0, 1.0, dirtFactor.r));
if (dirt_multi > 0) {
//dirtFactor.g = smoothstep(0.0, 1.0, dirtFactor.g);
//dirtFactor.b = smoothstep(0.0, 1.0, dirtFactor.b);
mixedcolor.rgb = mix(mixedcolor.rgb, dirt_g_color, smoothstep(0.0, 1.0, dirtFactor.g));
mixedcolor.rgb = mix(mixedcolor.rgb, dirt_b_color, smoothstep(0.0, 1.0, dirtFactor.b));
}
}
//////////////////////////////////////////////////////////////////////
//END Dirt
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//begin WETNESS
//////////////////////////////////////////////////////////////////////
if (rain_enabled >0.0)
{
texel.rgb = texel.rgb * (1.0 - 0.6 * wetness);
float rain_factor = 0.0;
float rain_orientation = max(dot(VNormal, up),0.0);
if ((rain_norm > 0.0) && (rain_orientation > 0.0))
{
rain_factor += DotNoise2D(rawpos.xy, 0.2 ,0.5, rain_norm) * abs(sin(6.0*osg_SimulationTime));
rain_factor += DotNoise2D(rawpos.xy, 0.3 ,0.4, rain_norm) * abs(sin(6.0*osg_SimulationTime + 2.094));
rain_factor += DotNoise2D(rawpos.xy, 0.4 ,0.3, rain_norm)* abs(sin(6.0*osg_SimulationTime + 4.188));
}
// secondary reflection of sky irradiance in water film
float fresnelW = ((0.8 * wetness) ) * (1.0-smoothstep(0.0,0.4, dot(N,-nVertVec) * 1.0 - 0.2 * rain_factor * wetness));
float sky_factor = (1.0-ct*ct);
vec3 sky_light = vec3 (1.0,1.0,1.0) * length(light_diffuse.rgb) * (1.0-effective_scattering);
Specular.rgb += sky_factor * fresnelW * sky_light;
}
/////////////////////////////////////////////////////////////////////
//end WETNESS
//////////////////////////////////////////////////////////////////////
// set ambient adjustment to remove bluiness with user input
float ambient_offset = clamp(amb_correction, -1.0, 1.0);
vec4 ambient = gl_LightModel.ambient + light_ambient;
vec4 ambient_Correction = vec4(ambient.rg, ambient.b * 0.6, 1.0)
* ambient_offset ;
ambient_Correction = clamp(ambient_Correction, -1.0, 1.0);
color += ambient;
color.a = texel.a * alpha;
vec4 fragColor = vec4(color.rgb * mixedcolor + ambient_Correction.rgb, color.a);
fragColor += Specular * nmap.a;
//////////////////////////////////////////////////////////////////////
// BEGIN procedural lightmap
//////////////////////////////////////////////////////////////////////
vec3 pLMColor = streetlight_color;
float pLMIntensity = smoothstep(0.0, 0.4, roadCoords.s) * (1.0 - smoothstep(0.6, 1.0, roadCoords.s));
pLMIntensity = 0.25 * rtype_base_illumination * (1.0+ streetlight_factor) + 0.1 * max(0.0,sin(4.0 * roadCoords.t)) * streetlight_factor;
pLMIntensity = clamp(pLMIntensity, 0.0, 1.0);
if (gl_FrontMaterial.diffuse.r == 0.0) {pLMIntensity =0.0;}
pLMColor *= pLMIntensity;
if (road_traffic_enabled == 1)
{
float viewAngleFactor = smoothstep(-0.05, 0.0, cSign * dot(normalize(VBinormal), nVertVec));
vec3 pCLColor = vec3 (0.95, 1.0, 1.0);
// mean illumination by car headlights
pLMColor = pLMColor + 0.2 * min(1.0,total_traffic_density) * pCLColor;
float pCLIntensity = smoothstep(0.4, 0.6, cTag) * (1.0-smoothstep(0.6, 0.8, cTag));
float laneFact = smoothstep(0.25, 0.3, roadCoords.s) * (1.0-smoothstep(0.3, 0.35, roadCoords.s));
laneFact += smoothstep(0.35, 0.4, roadCoords.s) * (1.0-smoothstep(0.4, 0.45, roadCoords.s));
laneFact += smoothstep(0.65, 0.7, roadCoords.s) * (1.0-smoothstep(0.7, 0.75, roadCoords.s));
laneFact += smoothstep(0.75, 0.8, roadCoords.s) * (1.0-smoothstep(0.8, 0.85, roadCoords.s));
pCLIntensity = pCLIntensity * laneFact * cPresent;
pCLColor *= pCLIntensity;
pCLColor *= (0.7 + 0.3 * viewAngleFactor);
vec3 pTLColor = vec3 (0.95, 0.0, 0.0);
float pTLIntensity;
if (cSign == 1.0)
{
pTLIntensity = smoothstep(0.9, 0.94, cTag) * (1.0-smoothstep(0.96, 1.0, cTag));
}
else
{
pTLIntensity = smoothstep(0.0, 0.04, cTag) * (1.0-smoothstep(0.06, 0.1, cTag));
}
pTLIntensity = pTLIntensity * laneFact * cPresent * (1.0 - viewAngleFactor);
pCLColor = pCLColor + pTLColor * pTLIntensity;
pLMColor = clamp(pLMColor, 0.0, 1.0);
pLMColor = max(pLMColor,pCLColor);
}
//fragColor.rgb = max(fragColor.rgb, pLMColor * gl_FrontMaterial.diffuse.rgb * smoothstep(0.0, 1.0, mixedcolor*.5 + pLMColor*.5));
fragColor.rgb = max(fragColor.rgb, pLMColor * smoothstep(0.0, 1.0, mixedcolor*.5 + pLMColor*.5));
//////////////////////////////////////////////////////////////////////
// END procedural lightmap
//////////////////////////////////////////////////////////////////////
/// BEGIN fog amount
float transmission;
float vAltitude;
float delta_zv;
float H;
float distance_in_layer;
float transmission_arg;
float eqColorFactor;
float delta_z = hazeLayerAltitude - eye_alt;
float mvisibility = min(visibility, avisibility);
if (dist > 0.04 * mvisibility)
{
if (delta_z > 0.0) // we're inside the layer
{
if (ct < 0.0) // we look down
{
distance_in_layer = dist;
vAltitude = min(distance_in_layer,mvisibility) * ct;
delta_zv = delta_z - vAltitude;
}
else // we may look through upper layer edge
{
H = dist * ct;
if (H > delta_z) {distance_in_layer = dist/H * delta_z;}
else {distance_in_layer = dist;}
vAltitude = min(distance_in_layer,visibility) * ct;
delta_zv = delta_z - vAltitude;
}
}
else // we see the layer from above, delta_z < 0.0
{
H = dist * -ct;
if (H < (-delta_z)) // we don't see into the layer at all, aloft visibility is the only fading
{
distance_in_layer = 0.0;
delta_zv = 0.0;
}
else
{
vAltitude = H + delta_z;
distance_in_layer = vAltitude/H * dist;
vAltitude = min(distance_in_layer,visibility) * (-ct);
delta_zv = vAltitude;
}
}
transmission_arg = (dist-distance_in_layer)/avisibility;
if (visibility < avisibility)
{
transmission_arg = transmission_arg + (distance_in_layer/visibility);
eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -effective_scattering);
}
else
{
transmission_arg = transmission_arg + (distance_in_layer/avisibility);
eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -effective_scattering);
}
transmission = fog_func(transmission_arg, alt);
if (eqColorFactor < 0.2) eqColorFactor = 0.2;
}
else
{
eqColorFactor = 1.0;
transmission = 1.0;
}
/// END fog amount
/// BEGIN fog color
vec3 hazeColor = get_hazeColor(fog_lightArg);
float rShade = 1.0 - 0.9 * smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt + 420000.0);
float lightIntensity = length(hazeColor * effective_scattering) * rShade;
if (transmission< 1.0)
{
if (fog_lightArg < 10.0)
{
intensity = length(hazeColor);
float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator-sqrt(2.0 * EarthRadius * terrain_alt));
hazeColor = intensity * ((1.0 - mie_magnitude) + mie_magnitude * mie_angle) * normalize(mix(hazeColor, vec3 (0.5, 0.58, 0.65), mie_magnitude * (0.5 - 0.5 * mie_angle)) );
}
intensity = length(hazeColor);
hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));
hazeColor.r = hazeColor.r * 0.83;
hazeColor.g = hazeColor.g * 0.9;
float fade_out = max(0.65 - 0.3 *overcast, 0.45);
intensity = length(hazeColor);
hazeColor = intensity * normalize(mix(hazeColor, 1.5* shadedFogColor, 1.0 -smoothstep(0.25, fade_out,fog_earthShade) ));
hazeColor = intensity * normalize(mix(hazeColor, shadedFogColor, (1.0-smoothstep(0.5,0.9,eqColorFactor))));
float shadow = mix( min(1.0 + dot(VNormal,gl_LightSource[0].position.xyz),1.0), 1.0, 1.0-smoothstep(0.1, 0.4, transmission));
hazeColor = mix(shadow * hazeColor, hazeColor, 0.3 + 0.7* smoothstep(250000.0, 400000.0, terminator));
}
else
{
hazeColor = vec3 (1.0, 1.0, 1.0);
}
/// END fog color
fragColor = clamp(fragColor, 0.0, 1.0);
hazeColor = clamp(hazeColor, 0.0, 1.0);
///BEGIN Rayleigh fog ///
// Rayleigh color shift due to out-scattering
float rayleigh_length = 0.5 * avisibility * (2.5 - 1.9 * air_pollution)/alt_factor(eye_alt, eye_alt+relPos.z);
float outscatter = 1.0-exp(-dist/rayleigh_length);
fragColor.rgb = rayleigh_out_shift(fragColor.rgb,outscatter);
vec3 rayleighColor = vec3 (0.17, 0.52, 0.87) * lightIntensity;
float rayleighStrength = rayleigh_in_func(dist, air_pollution, avisibility/max(lightIntensity,0.05), eye_alt, eye_alt + relPos.z);
fragColor.rgb = mix(fragColor.rgb, rayleighColor,rayleighStrength);
/// END Rayleigh fog
// don't let the light fade out too rapidly
lightArg = (terminator + 200000.0)/100000.0;
float minLightIntensity = min(0.2,0.16 * lightArg + 0.5);
vec3 minLight = minLightIntensity * vec3 (0.2, 0.3, 0.4);
hazeColor *= eqColorFactor * fog_earthShade;
hazeColor.rgb = max(hazeColor.rgb, minLight.rgb);
fragColor.rgb = mix(hazeColor +secondary_light * fog_backscatter(mvisibility), fragColor.rgb,transmission);
fragColor.rgb = filter_combined(fragColor.rgb);
gl_FragColor = fragColor;
}