173 lines
5.4 KiB
C++
173 lines
5.4 KiB
C++
// -*-C++-*-
|
|
#version 120
|
|
|
|
#define MAX_LAYERS 8
|
|
#define MAX_DISTANCE 3000.0
|
|
|
|
uniform float visibility;
|
|
uniform float avisibility;
|
|
uniform float scattering;
|
|
uniform float overlay_bias;
|
|
uniform float season;
|
|
uniform float dust_cover_factor;
|
|
uniform float overlay_max_height;
|
|
uniform float overlay_hardness;
|
|
uniform float overlay_density;
|
|
uniform float overlay_scale;
|
|
uniform float overlay_steepness_factor;
|
|
uniform float overlay_brightness_bottom;
|
|
uniform float overlay_brightness_top;
|
|
uniform float overlay_secondary_hardness;
|
|
uniform float overlay_secondary_density;
|
|
uniform float snowlevel;
|
|
uniform float wetness;
|
|
uniform float snow_thickness_factor;
|
|
|
|
uniform int overlay_autumn_flag;
|
|
uniform int overlay_secondary_flag;
|
|
uniform int cloud_shadow_flag;
|
|
|
|
uniform sampler2D overlayPrimaryTex;
|
|
uniform sampler2D overlaySecondaryTex;
|
|
|
|
|
|
uniform float osg_SimulationTime;
|
|
|
|
varying vec2 g_rawpos; // Horizontal position in model space
|
|
varying float g_distance_to_eye; // Distance to the camera. Layers were disregarded
|
|
varying vec3 g_normal;
|
|
varying in float g_altitude;
|
|
|
|
|
|
flat in float g_layer; // The layer where the fragment lives (0-1 range)
|
|
|
|
|
|
float rand2D(in vec2 co);
|
|
float Noise2D(in vec2 co, in float wavelength);
|
|
vec3 filter_combined (in vec3 color) ;
|
|
|
|
float shadow_func_nearest (in float x, in float y, in float noise, in float dist);
|
|
|
|
|
|
void main()
|
|
{
|
|
|
|
if (g_distance_to_eye > MAX_DISTANCE) {discard;}
|
|
|
|
vec2 texCoord = gl_TexCoord[0].st;
|
|
|
|
vec2 pos_rotated = vec2 (0.707 * g_rawpos.x + 0.707 * g_rawpos.y, 0.707 * g_rawpos.x - 0.707 * g_rawpos.y);
|
|
|
|
|
|
//float noise_1m = 0.5 * Noise2D(pos_rotated.xy, 1.0 * overlay_scale);
|
|
//noise_1m += 0.5 * Noise2D(g_rawpos.xy, 1.1 * overlay_scale);
|
|
|
|
float noise_1m = Noise2D(pos_rotated.xy, 1.0 * overlay_scale);
|
|
|
|
float noise_2m = Noise2D(g_rawpos.xy, 2.0 * overlay_scale); ;
|
|
float noise_10m = Noise2D(g_rawpos.xy, 10.0 * overlay_scale);
|
|
|
|
|
|
|
|
float value = 0.0;
|
|
|
|
float d_fade =smoothstep(100.0, MAX_DISTANCE, g_distance_to_eye);
|
|
|
|
float steepness = dot (normalize(g_normal), vec3 (0.0, 0.0, 1.0));
|
|
float steepness_bias = smoothstep(overlay_steepness_factor, overlay_steepness_factor + 0.1, steepness);
|
|
|
|
float overlayPattern = 0.2 * noise_10m + 0.3 * noise_2m + 0.5 * noise_1m - 0.2 * g_layer - 0.1 + 0.2 * overlay_density ;
|
|
overlayPattern *= steepness_bias;
|
|
|
|
float secondaryPattern = 0.2 * (1.0-noise_10m) + 0.3 * (1.0-noise_2m) + 0.5 * (1.0-noise_1m) - 0.4 * g_layer - 0.2 + 0.2 * overlay_secondary_density ;
|
|
secondaryPattern *= overlay_secondary_flag;
|
|
float secondaryMix = 0.0;
|
|
|
|
if (overlayPattern > 0.5)
|
|
{
|
|
value = smoothstep(0.5, (0.8 - 0.25 * overlay_hardness), overlayPattern);
|
|
}
|
|
else if (secondaryPattern > 0.5)
|
|
{
|
|
value = smoothstep(0.5, (0.8 - 0.25 * overlay_secondary_hardness), secondaryPattern);
|
|
secondaryMix = 1.0;
|
|
}
|
|
else {discard;}
|
|
|
|
vec3 texel = texture2D(overlayPrimaryTex, texCoord * 20.0).rgb;
|
|
vec3 secondary_texel = texture2D(overlaySecondaryTex, texCoord * 20.0).rgb;
|
|
|
|
// autumn coloring
|
|
|
|
if (overlay_autumn_flag == 1)
|
|
{
|
|
texel.r = min(1.0, (1.0 + 2.5 * 0.1 * season) * texel.r);
|
|
texel.g = texel.g;
|
|
texel.b = max(0.0, (1.0 - 4.0 * 0.1 * season) * texel.b);
|
|
float intensity = length(texel.rgb) * (1.0 - 0.5 * smoothstep(1.1,2.0,season));
|
|
texel.rgb = intensity * normalize(mix(texel.rgb, vec3(0.23,0.17,0.08), smoothstep(1.1,2.0, season)));
|
|
}
|
|
|
|
texel = mix (texel, secondary_texel, secondaryMix);
|
|
|
|
|
|
float layer_arg = mix(g_layer, 1.0, smoothstep(250.0, 5000.0, g_distance_to_eye));
|
|
texel.rgb *= (overlay_brightness_bottom + (overlay_brightness_top - overlay_brightness_bottom) * g_layer);
|
|
texel.rgb *= (1.0 - 0.5 * wetness);
|
|
|
|
// dust overlay
|
|
|
|
const vec3 dust_color = vec3 (0.76, 0.65, 0.45);
|
|
texel = mix (texel, dust_color, 0.7 * dust_cover_factor);
|
|
|
|
// snow overlay
|
|
|
|
//vec3 snow_texel = vec3 (0.95, 0.95, 0.95);
|
|
|
|
float snow_factor = 0.2+0.8* smoothstep(0.2,0.8, 0.3 + 0.5 * snow_thickness_factor +0.0001*(g_altitude -snowlevel) );
|
|
snow_factor *= smoothstep(0.5, 0.7, steepness);
|
|
|
|
snow_factor *= smoothstep(g_layer - 0.1, g_layer , snow_factor + 0.2);
|
|
|
|
//texel.rgb = mix(texel.rgb, snow_texel.rgb, snow_factor * smoothstep(snowlevel, snowlevel+200.0, g_altitude - 100.0));
|
|
value *= (1.0 - snow_factor * smoothstep(snowlevel, snowlevel+200.0, g_altitude - 100.0));
|
|
|
|
// do a conservative simple fog model, fading to alpha
|
|
|
|
float min_visibility = min(visibility, avisibility);
|
|
|
|
float base_alpha = clamp(0.4 * overlay_max_height/0.3, 0.4, 1.0);
|
|
value*= base_alpha * (1.0 - d_fade);
|
|
|
|
float targ = 8.0 * g_distance_to_eye/min_visibility;
|
|
value *= exp(-targ - targ * targ * targ * targ);
|
|
value= clamp(value, 0.0, 1.0);
|
|
|
|
// cloud shadows
|
|
|
|
float cloud_shade = 1.0;
|
|
|
|
if (cloud_shadow_flag == 1)
|
|
{
|
|
vec2 eyePos = (gl_ModelViewMatrixInverse * vec4 (0.0, 0.0, 0.0, 1.0)).xy;
|
|
vec2 relPos = g_rawpos - eyePos;
|
|
|
|
|
|
cloud_shade = shadow_func_nearest(relPos.x, relPos.y, 1.0, g_distance_to_eye);
|
|
}
|
|
|
|
// lighting is very simple, the ground underneath should do most of it
|
|
|
|
vec3 N = normalize (gl_NormalMatrix * g_normal);
|
|
float NdotL = 0.5 + 1.0 * clamp(dot (N, gl_LightSource[0].position.xyz), 0.0, 1.0) * cloud_shade;
|
|
|
|
texel *= length(gl_LightSource[0].diffuse.rgb)/1.73 * scattering * NdotL;
|
|
texel = clamp(texel, 0.0, 1.0);
|
|
|
|
|
|
vec4 fragColor = vec4 (texel, value);
|
|
fragColor.rgb = filter_combined(fragColor.rgb);
|
|
fragColor = clamp(fragColor, 0.0, 1.0);
|
|
|
|
gl_FragColor = fragColor;
|
|
}
|