diff --git a/Compositor/Effects/ws30.eff b/Compositor/Effects/ws30.eff
new file mode 100644
index 000000000..3471da921
--- /dev/null
+++ b/Compositor/Effects/ws30.eff
@@ -0,0 +1,782 @@
+
+
+
+ Effects/ws30
+
+
+
+
+ 0.2 .2 0.2 1.0
+
+
+ .8 .8 .8 1.0
+
+
+ 0.0 0.0 0.0 1.0
+
+
+ 0.0 0.0 0.0 1.0
+
+ 1.2
+
+
+ Textures/Terrain/cropgrass1.png
+ 2d
+ linear-mipmap-linear
+
+ repeat
+ repeat
+
+
+ normalized
+
+
+ Textures/Terrain/city1.png
+ 2d
+ linear-mipmap-linear
+
+ repeat
+ repeat
+
+
+ normalized
+
+
+ Textures/Terrain/water.png
+ 2d
+ linear-mipmap-linear
+
+ repeat
+ repeat
+
+
+ normalized
+
+
+ Textures/Terrain/snow3.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+
+ Textures/Terrain/void.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+
+ Textures/Terrain/void.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+
+ Textures/Terrain/rock_alt.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+
+ Textures/Terrain/grain_texture.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+
+ Textures/Terrain/void.png
+ 2d
+ linear-mipmap-linear
+ repeat
+ repeat
+ normalized
+
+ false
+
+ 0
+ RenderBin
+
+ 0
+ 0.5
+ 0.0
+ 0.5
+ 0.0
+ 1.0
+ 1.0
+ 1.0
+ 0
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ als-lighting
+
+
+
+
+ 2.0
+
+
+
+ GL_ARB_shader_objects
+ GL_ARB_shading_language_100
+ GL_ARB_vertex_shader
+ GL_ARB_fragment_shader
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ambient-and-diffuse
+
+
+
+
+
+
+
+ smooth
+ back
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Shaders/ALS/generic-base.vert
+ Shaders/ALS/shadows-include.vert
+ Shaders/ALS/ws30.frag
+ Shaders/ALS/hazes.frag
+ Shaders/ALS/noise.frag
+ Shaders/ALS/filters.frag
+ Shaders/ALS/shadows-include.frag
+
+
+ visibility
+ float
+
+
+
+
+
+ avisibility
+ float
+
+
+
+
+
+ hazeLayerAltitude
+ float
+
+
+
+
+
+ scattering
+ float
+
+
+
+
+
+ ground_scattering
+ float
+
+
+
+
+
+ terminator
+ float
+
+
+
+
+
+ terrain_alt
+ float
+
+
+
+
+
+ overcast
+ float
+
+
+
+
+
+ eye_alt
+ float
+
+
+
+
+
+ cloud_self_shading
+ float
+
+
+
+
+
+ moonlight
+ float
+
+
+
+
+
+ air_pollution
+ float
+
+
+
+
+
+
+ gamma
+ float
+
+
+
+
+
+ brightness
+ float
+
+
+
+
+
+ use_night_vision
+ bool
+
+
+
+
+
+ use_IR_vision
+ bool
+
+
+
+
+
+ use_filtering
+ bool
+
+
+
+
+
+ delta_T
+ float
+
+
+
+
+
+ fact_grey
+ float
+
+
+
+
+
+ fact_black
+ float
+
+
+
+
+
+ display_xsize
+ int
+
+
+
+
+
+ display_ysize
+ int
+
+
+
+
+
+ landclass
+ sampler-2d
+ 0
+
+
+ texture1
+ sampler-2d
+ 1
+
+
+ texture2
+ sampler-2d
+ 2
+
+
+ texture3
+ sampler-2d
+ 3
+
+
+ colorMode
+ int
+ 2
+
+
+
+
+ shadow_tex
+ sampler-2d
+ 10
+
+
+ shadows_enabled
+ bool
+
+
+
+
+
+ sun_atlas_size
+ int
+
+
+
+
+
+
+ lequal
+
+
+
+
+
diff --git a/Compositor/Shaders/ALS/ws30.frag b/Compositor/Shaders/ALS/ws30.frag
new file mode 100644
index 000000000..f227d516a
--- /dev/null
+++ b/Compositor/Shaders/ALS/ws30.frag
@@ -0,0 +1,278 @@
+// WS30 FRAGMENT SHADER
+
+// -*-C++-*-
+#version 120
+
+// written by Thorsten Renk, Oct 2011, based on default.frag
+// Ambient term comes in gl_Color.rgb.
+varying vec4 diffuse_term;
+varying vec3 normal;
+varying vec3 relPos;
+
+
+uniform float fg_Fcoef;
+
+uniform sampler2D landclass;
+uniform sampler2D texture1;
+uniform sampler2D texture2;
+uniform sampler2D texture3;
+
+
+varying float yprime_alt;
+varying float mie_angle;
+
+varying float flogz;
+
+
+uniform float visibility;
+uniform float avisibility;
+uniform float scattering;
+uniform float terminator;
+uniform float terrain_alt;
+uniform float hazeLayerAltitude;
+uniform float overcast;
+uniform float eye_alt;
+uniform float cloud_self_shading;
+
+const float EarthRadius = 5800000.0;
+const float terminator_width = 200000.0;
+
+float alt;
+float eShade;
+
+float fog_func (in float targ, in float alt);
+vec3 get_hazeColor(in float light_arg);
+vec3 filter_combined (in vec3 color) ;
+
+float getShadowing();
+
+float luminance(vec3 color)
+{
+ return dot(vec3(0.212671, 0.715160, 0.072169), color);
+}
+
+
+
+void main()
+{
+
+ vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
+// this is taken from default.frag
+ vec3 n;
+ float NdotL, NdotHV, fogFactor;
+ vec4 color = gl_Color;
+ vec3 lightDir = gl_LightSource[0].position.xyz;
+ vec3 halfVector = gl_LightSource[0].halfVector.xyz;
+ vec4 texel;
+ vec4 lc;
+ vec4 fragColor;
+ vec4 specular = vec4(0.0);
+ float intensity;
+
+ float effective_scattering = min(scattering, cloud_self_shading);
+
+
+ vec4 light_specular = gl_LightSource[0].specular;
+
+ // If gl_Color.a == 0, this is a back-facing polygon and the
+ // normal should be reversed.
+ n = (2.0 * gl_Color.a - 1.0) * normal;
+ n = normalize(n);
+
+ NdotL = dot(n, lightDir);
+ if (NdotL > 0.0) {
+ float shadowmap = getShadowing();
+ color += diffuse_term * NdotL * shadowmap;
+ NdotHV = max(dot(n, halfVector), 0.0);
+ if (gl_FrontMaterial.shininess > 0.0)
+ specular.rgb = (gl_FrontMaterial.specular.rgb
+ * light_specular.rgb
+ * pow(NdotHV, gl_FrontMaterial.shininess)
+ * shadowmap);
+ }
+ color.a = diffuse_term.a;
+ // This shouldn't be necessary, but our lighting becomes very
+ // saturated. Clamping the color before modulating by the texture
+ // is closer to what the OpenGL fixed function pipeline does.
+ color = clamp(color, 0.0, 1.0);
+
+/*
+ landclass = texture2D(texture, gl_TexCoord[0].st);
+ texel = (landclass.r > 0.148) * texture2D(texture, gl_TexCoord[3].st) +
+ (landclass.g < 0.02) * texture2D(texture, gl_TexCoord[2].st) +
+ (1 - ((landclass.r > 0.148) || (landclass.g < 0.02))) * texture2D(texture, gl_TexCoord[1].st);
+*/
+ lc = texture2D(landclass, gl_TexCoord[0].st);
+ if (lc.r > 0.148) {
+ // Water
+ texel = texture2D(texture3, gl_TexCoord[0].st);
+ } else if (lc.g > 0.02) {
+ texel = texture2D(texture1, gl_TexCoord[0].st);
+ } else {
+ texel = texture2D(texture2, gl_TexCoord[0].st);
+ }
+
+ //texel = texture2D(texture, gl_TexCoord[0].st);
+ fragColor = color * texel + specular;
+
+
+
+// here comes the terrain haze model
+
+
+float delta_z = hazeLayerAltitude - eye_alt;
+float dist = length(relPos);
+
+float mvisibility = min(visibility,avisibility);
+
+if (dist > 0.04 * mvisibility)
+{
+
+alt = eye_alt;
+
+
+float transmission;
+float vAltitude;
+float delta_zv;
+float H;
+float distance_in_layer;
+float transmission_arg;
+
+// angle with horizon
+float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist;
+
+
+// we solve the geometry what part of the light path is attenuated normally and what is through the haze layer
+
+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;
+ }
+ }
+
+
+// ground haze cannot be thinner than aloft visibility in the model,
+// so we need to use aloft visibility otherwise
+
+
+transmission_arg = (dist-distance_in_layer)/avisibility;
+
+
+float eqColorFactor;
+
+
+
+if (visibility < avisibility)
+ {
+ transmission_arg = transmission_arg + (distance_in_layer/visibility);
+ // this combines the Weber-Fechner intensity
+ eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -effective_scattering);
+
+ }
+else
+ {
+ transmission_arg = transmission_arg + (distance_in_layer/avisibility);
+ // this combines the Weber-Fechner intensity
+ eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -effective_scattering);
+ }
+
+
+
+transmission = fog_func(transmission_arg, alt);
+
+// there's always residual intensity, we should never be driven to zero
+if (eqColorFactor < 0.2) {eqColorFactor = 0.2;}
+
+
+float lightArg = (terminator-yprime_alt)/100000.0;
+vec3 hazeColor = get_hazeColor(lightArg);
+
+
+
+// now dim the light for haze
+eShade = 1.0 - 0.9 * smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt);
+
+// Mie-like factor
+
+if (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)) );
+ }
+
+// high altitude desaturation of the haze color
+
+intensity = length(hazeColor);
+hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));
+
+// blue hue of haze
+
+hazeColor.x = hazeColor.x * 0.83;
+hazeColor.y = hazeColor.y * 0.9;
+
+
+// additional blue in indirect light
+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,eShade) ));
+
+// change haze color to blue hue for strong fogging
+//intensity = length(hazeColor);
+hazeColor = intensity * normalize(mix(hazeColor, shadedFogColor, (1.0-smoothstep(0.5,0.9,eqColorFactor))));
+
+
+// reduce haze intensity when looking at shaded surfaces, only in terminator region
+
+float shadow = mix( min(1.0 + dot(normal,lightDir),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));
+
+
+
+
+// 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 * eShade;
+hazeColor.rgb = max(hazeColor.rgb, minLight.rgb);
+
+// determine the right mix of transmission and haze
+
+fragColor.rgb = mix(hazeColor, fragColor.rgb,transmission);
+}
+
+fragColor.rgb = filter_combined(fragColor.rgb);
+
+gl_FragColor = fragColor;
+// logarithmic depth
+gl_FragDepth = log2(flogz) * fg_Fcoef * 0.5;
+}
+
diff --git a/Materials/base/materials-base.xml b/Materials/base/materials-base.xml
index 4bdc77d43..cf1fe4cf4 100644
--- a/Materials/base/materials-base.xml
+++ b/Materials/base/materials-base.xml
@@ -11,6 +11,33 @@
+
+ ws30
+ Effects/ws30
+ 2000
+ 2000
+ 4000000.0
+
+ 0.93
+ 0.95
+ 0.93
+ 1.0
+
+
+ 0.1
+ 0.12
+ 0.1
+ 1.0
+
+ 1.2
+ 1
+ 0.7
+ 0.1
+ 0.15
+ 1e30
+
+
+