From ebc1002139674744ba34d3aef1205fd2124be375 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Thu, 8 Mar 2012 23:20:39 +0100
Subject: [PATCH] Sunrises 1.2 by Thorsten Renk

---
 Effects/cloud-static.eff                      |  84 ++++++
 Effects/cloud.eff                             | 108 ++++++-
 Effects/model-default.eff                     | 101 ++++++-
 Effects/rain-layer.eff                        |  91 +++++-
 Effects/skydome.eff                           | 247 +++++++--------
 Effects/terrain-default.eff                   | 180 +++++++++--
 Environment/environment.xml                   |   3 +-
 Environment/local-weather-defaults.xml        |   1 +
 Nasal/local_weather/cloud_definitions.nas     |  12 +-
 Nasal/local_weather/compat_layer.nas          |  90 +++++-
 Nasal/local_weather/local_weather.nas         |  53 ++--
 Nasal/local_weather/weather_dynamics.nas      |  20 +-
 .../local_weather/weather_tile_management.nas |  13 +-
 Nasal/local_weather/weather_tiles.nas         |  86 ++++--
 Shaders/3dcloud-lightfield.frag               |  15 +
 Shaders/3dcloud-lightfield.vert               | 169 +++++++++++
 Shaders/cloud-static-lightfield.frag          |  12 +
 Shaders/cloud-static-lightfield.vert          | 119 ++++++++
 Shaders/rain-layer-lightfield.frag            |  12 +
 Shaders/rain-layer-lightfield.vert            | 122 ++++++++
 Shaders/skydome.frag                          | 175 +++++++++--
 Shaders/skydome.vert                          | 144 +++++++--
 Shaders/terrain-haze.frag                     | 285 ++++++++++++++++++
 Shaders/terrain-haze.vert                     | 233 ++++++++++++++
 gui/dialogs/local_weather_tiles.xml           |  20 +-
 25 files changed, 2132 insertions(+), 263 deletions(-)
 create mode 100644 Shaders/3dcloud-lightfield.frag
 create mode 100644 Shaders/3dcloud-lightfield.vert
 create mode 100644 Shaders/cloud-static-lightfield.frag
 create mode 100644 Shaders/cloud-static-lightfield.vert
 create mode 100644 Shaders/rain-layer-lightfield.frag
 create mode 100644 Shaders/rain-layer-lightfield.vert
 create mode 100644 Shaders/terrain-haze.frag
 create mode 100644 Shaders/terrain-haze.vert

diff --git a/Effects/cloud-static.eff b/Effects/cloud-static.eff
index 52870a571..55543d9c4 100644
--- a/Effects/cloud-static.eff
+++ b/Effects/cloud-static.eff
@@ -4,7 +4,81 @@
   <parameters>
     <texture n ="0">
     </texture>
+    <terminator>
+      <use>/environment/terminator-relative-position-m</use>
+    </terminator>
+   <altitude>
+      <use>/sim/rendering/eye-altitude-m</use>
+    </altitude>
   </parameters>
+
+<technique n="9">
+    <predicate>
+      <and>
+        <property>/sim/rendering/shaders/skydome</property>
+        <property>/sim/rendering/clouds3d-enable</property>
+        <less-equal>
+          <value type="float">1.0</value>
+          <shader-language/>
+        </less-equal>
+      </and>
+    </predicate>
+    <pass n="0">
+      <!-- This is apparently not used, so maybe we'll blow it way soon. -->
+      <lighting>true</lighting>
+      <material>
+        <ambient type="vec4d">0.5 0.5 0.5 1.0</ambient>
+        <diffuse type="vec4d">0.5 0.5 0.5 1.0</diffuse>
+        <color-mode>off</color-mode>
+      </material>
+      <alpha-test>
+        <comparison>greater</comparison>
+        <reference type="float">0.01</reference>
+      </alpha-test>
+      <shade-model>smooth</shade-model>
+      <blend>
+        <source>src-alpha</source>
+        <destination>one-minus-src-alpha</destination>
+      </blend>
+      <depth>
+        <write-mask>false</write-mask>
+      </depth>
+      <render-bin>
+        <bin-number>9</bin-number>
+        <bin-name>DepthSortedBin</bin-name>
+      </render-bin>
+      <texture-unit>
+        <unit>0</unit>
+	<type><use>texture[0]/type</use></type>
+        <image><use>texture[0]/image</use></image>
+        <filter><use>texture[0]/filter</use></filter>
+        <wrap-s><use>texture[0]/wrap-s</use></wrap-s>
+        <wrap-t><use>texture[0]/wrap-t</use></wrap-t>
+        <!--<wrap-s>clamp</wrap-s>
+        <wrap-t>clamp</wrap-t>-->
+      </texture-unit>
+      <program>
+        <vertex-shader>Shaders/cloud-static-lightfield.vert</vertex-shader>
+        <fragment-shader>Shaders/cloud-static-lightfield.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>baseTexture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>altitude</name>
+        <type>float</type>
+        <value><use>altitude</use></value>
+      </uniform>
+      <vertex-program-two-side>true</vertex-program-two-side>
+    </pass>
+  </technique>
   <technique n="10">
     <predicate>
       <and>
@@ -58,6 +132,16 @@
         <type>sampler-2d</type>
         <value type="int">0</value>
       </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>altitude</name>
+        <type>float</type>
+        <value><use>altitude</use></value>
+      </uniform>
       <vertex-program-two-side>true</vertex-program-two-side>
     </pass>
   </technique>
diff --git a/Effects/cloud.eff b/Effects/cloud.eff
index 0dc464100..fa43fbb0f 100644
--- a/Effects/cloud.eff
+++ b/Effects/cloud.eff
@@ -6,8 +6,99 @@
     </texture>
     <range>
       <use>/sim/rendering/clouds3d-vis-range</use>
-    </range>    
+    </range>   
+    <scattering>
+      <use>/rendering/scene/scattering</use>
+    </scattering>   
+    <terminator>
+      <use>/environment/terminator-relative-position-m</use>
+    </terminator>
+   <!--<altitude>
+      <use>/position/altitude-ft</use>
+    </altitude>-->
+  <altitude><use>/sim/rendering/eye-altitude-m</use></altitude>
   </parameters>
+<technique n="9">
+    <predicate>
+      <and>
+       <property>/sim/rendering/shaders/skydome</property>
+       <less-equal>
+        <value type="float">1.0</value>
+        <shader-language/>
+      </less-equal>
+     </and>
+    </predicate>
+    <pass n="0">
+      <!-- This is apparently not used, so maybe we'll blow it way soon. -->
+      <lighting>true</lighting>
+      <material>
+        <ambient type="vec4d">0.5 0.5 0.5 1.0</ambient>
+        <diffuse type="vec4d">0.5 0.5 0.5 1.0</diffuse>
+        <color-mode>off</color-mode>
+      </material>
+      <alpha-test>
+        <comparison>greater</comparison>
+        <reference type="float">0.01</reference>
+      </alpha-test>
+      <shade-model>smooth</shade-model>
+      <blend>
+        <source>src-alpha</source>
+        <destination>one-minus-src-alpha</destination>
+      </blend>
+      <depth>
+        <write-mask>false</write-mask>
+      </depth>
+      <render-bin>
+        <bin-number>10</bin-number>
+        <bin-name>DepthSortedBin</bin-name>
+      </render-bin>
+      <texture-unit>
+        <unit>0</unit>
+        <type>2d</type>
+        <image><use>texture[0]/image</use></image>
+        <wrap-s>clamp</wrap-s>
+        <wrap-t>clamp</wrap-t>
+      </texture-unit>
+      <program>
+        <vertex-shader>Shaders/3dcloud-lightfield.vert</vertex-shader>
+        <fragment-shader>Shaders/3dcloud-lightfield.frag</fragment-shader>
+        <attribute>
+          <name>usrAttr1</name>
+          <index>10</index>
+        </attribute>
+        <attribute>
+          <name>usrAttr2</name>
+          <index>11</index>
+        </attribute>
+      </program>
+      <uniform>
+        <name>baseTexture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <uniform>
+        <name>range</name>
+        <type>float</type>
+        <value><use>range</use></value>
+      </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>altitude</name>
+        <type>float</type>
+        <value><use>altitude</use></value>
+      </uniform>
+      <vertex-program-two-side>true</vertex-program-two-side>
+    </pass>
+  </technique>
   <technique n="10">
     <predicate>
       <less-equal>
@@ -68,6 +159,21 @@
         <type>float</type>
         <value><use>range</use></value>
       </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>altitude</name>
+        <type>float</type>
+        <value><use>altitude</use></value>
+      </uniform>
       <vertex-program-two-side>true</vertex-program-two-side>
     </pass>
   </technique>
diff --git a/Effects/model-default.eff b/Effects/model-default.eff
index a332b8245..d2e313cf4 100644
--- a/Effects/model-default.eff
+++ b/Effects/model-default.eff
@@ -32,6 +32,105 @@
 		</fogtype>
 		<!-- 		END fog include -->
 	</parameters>
+
+  <technique n="7">
+    <predicate>
+      <and>
+        <property>/sim/rendering/shaders/skydome</property>
+        <or>
+          <less-equal>
+            <value type="float">2.0</value>
+            <glversion/>
+          </less-equal>
+          <and>
+            <extension-supported>GL_ARB_shader_objects</extension-supported>
+            <extension-supported>GL_ARB_shading_language_100</extension-supported>
+            <extension-supported>GL_ARB_vertex_shader</extension-supported>
+            <extension-supported>GL_ARB_fragment_shader</extension-supported>
+          </and>
+        </or>
+      </and>
+    </predicate>
+    <pass>
+      <lighting>true</lighting>
+      <material>
+        <active><use>material/active</use></active>
+        <ambient><use>material/ambient</use></ambient>
+        <diffuse><use>material/diffuse</use></diffuse>
+        <specular><use>material/specular</use></specular>
+        <emissive><use>material/emissive</use></emissive>
+        <shininess><use>material/shininess</use></shininess>
+        <color-mode><use>material/color-mode</use></color-mode>
+      </material>
+      <blend>
+        <active><use>blend/active</use></active>
+        <source><use>blend/source</use></source>
+        <destination><use>blend/destination</use></destination>
+      </blend>
+      <shade-model><use>shade-model</use></shade-model>
+      <cull-face><use>cull-face</use></cull-face>
+      <rendering-hint><use>rendering-hint</use></rendering-hint>
+      <texture-unit>
+        <!-- The texture unit is always active because the shaders expect
+             that. -->
+        <unit>0</unit>
+        <!-- If there is a texture, the type in the derived effect
+        will be "2d". -->
+        <type><use>texture[0]/type</use></type>
+        <image><use>texture[0]/image</use></image>
+        <filter><use>texture[0]/filter</use></filter>
+        <wrap-s><use>texture[0]/wrap-s</use></wrap-s>
+        <wrap-t><use>texture[0]/wrap-t</use></wrap-t>
+        <!--
+        <internal-format>
+          <use>texture[0]/internal-format</use>
+        </internal-format>
+        -->
+      </texture-unit>
+      <vertex-program-two-side>
+        <use>vertex-program-two-side</use>
+      </vertex-program-two-side>
+      <!--<program>
+        <vertex-shader>Shaders/default.vert</vertex-shader>
+        <fragment-shader>Shaders/default.frag</fragment-shader>
+      </program>-->
+      <program>
+        <vertex-shader>Shaders/terrain-haze.vert</vertex-shader>
+      <fragment-shader>Shaders/terrain-haze.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>visibility</name>
+        <type>float</type>
+        <value><use>visibility</use></value>
+      </uniform>
+      <uniform>
+        <name>avisibility</name>
+        <type>float</type>
+        <value><use>avisibility</use></value>
+      </uniform>
+       <uniform>
+        <name>hazeLayerAltitude</name>
+        <type>float</type>
+        <value><use>lthickness</use></value>
+      </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>texture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <uniform>
+        <name>colorMode</name>
+        <type>int</type>
+        <value><use>material/color-mode-uniform</use></value>
+      </uniform>
+    </pass>
+  </technique>
+
 	<technique n="10">
 		<predicate>
 			<and>
@@ -126,7 +225,7 @@
 				<use>vertex-program-two-side</use>
 			</vertex-program-two-side>
 			<program>
-<!-- 				<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader> -->
+				<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>
 				<!--fog include-->
 				<vertex-shader n="1">Shaders/default.vert</vertex-shader>
 				<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
diff --git a/Effects/rain-layer.eff b/Effects/rain-layer.eff
index 828237fb6..ee9c78c5d 100644
--- a/Effects/rain-layer.eff
+++ b/Effects/rain-layer.eff
@@ -4,10 +4,88 @@
   <parameters>
     <texture n ="0">
     </texture>
-    <range>
+  <range>
       <use>/sim/rendering/clouds3d-vis-range</use>
     </range>   
+    <scattering>
+      <use>/rendering/scene/scattering</use>
+    </scattering>   
+ <terminator>
+      <use>/environment/terminator-relative-position-m</use>
+    </terminator>
   </parameters>
+<technique n="9">
+    <predicate>
+      <and>
+        <property>/sim/rendering/shaders/skydome</property>
+        <property>/sim/rendering/clouds3d-enable</property>
+        <less-equal>
+          <value type="float">1.0</value>
+          <shader-language/>
+        </less-equal>
+      </and>
+    </predicate>
+    <pass n="0">
+      <!-- This is apparently not used, so maybe we'll blow it way soon. -->
+      <lighting>true</lighting>
+      <material>
+        <ambient type="vec4d">0.5 0.5 0.5 1.0</ambient>
+        <diffuse type="vec4d">0.5 0.5 0.5 1.0</diffuse>
+        <color-mode>off</color-mode>
+      </material>
+      <alpha-test>
+        <comparison>greater</comparison>
+        <reference type="float">0.01</reference>
+      </alpha-test>
+      <shade-model>smooth</shade-model>
+      <blend>
+        <source>src-alpha</source>
+        <destination>one-minus-src-alpha</destination>
+      </blend>
+      <depth>
+        <write-mask>false</write-mask>
+      </depth>
+      <render-bin>
+        <bin-number>9</bin-number>
+        <bin-name>DepthSortedBin</bin-name>
+      </render-bin>
+      <texture-unit>
+        <unit>0</unit>
+	<type><use>texture[0]/type</use></type>
+        <image><use>texture[0]/image</use></image>
+        <filter><use>texture[0]/filter</use></filter>
+        <wrap-s><use>texture[0]/wrap-s</use></wrap-s>
+        <wrap-t><use>texture[0]/wrap-t</use></wrap-t>
+        <!--<wrap-s>clamp</wrap-s>
+        <wrap-t>clamp</wrap-t>-->
+      </texture-unit>
+      <program>
+        <vertex-shader>Shaders/rain-layer-lightfield.vert</vertex-shader>
+        <fragment-shader>Shaders/rain-layer-lightfield.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>baseTexture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <uniform>
+        <name>range</name>
+        <type>float</type>
+        <value><use>range</use></value>
+      </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <vertex-program-two-side>true</vertex-program-two-side>
+    </pass>
+  </technique>
   <technique n="10">
     <predicate>
       <and>
@@ -66,7 +144,16 @@
         <type>float</type>
         <value><use>range</use></value>
       </uniform>
-
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
       <vertex-program-two-side>true</vertex-program-two-side>
     </pass>
   </technique>
diff --git a/Effects/skydome.eff b/Effects/skydome.eff
index 849af3f32..09fd3ede9 100644
--- a/Effects/skydome.eff
+++ b/Effects/skydome.eff
@@ -1,145 +1,112 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PropertyList>
-	<name>Effects/skydome</name>
-	<parameters>
-		<mie>
-			<use>/sim/rendering/mie</use>
-		</mie>
-		<rayleigh>
-			<use>/sim/rendering/rayleigh</use>
-		</rayleigh>
-		<density>
-			<use>/sim/rendering/dome-density</use>
-		</density>
-		<overcast>
-			<use>/rendering/scene/overcast</use>
-		</overcast>
-		<saturation>
-			<use>/rendering/scene/saturation</use>
-		</saturation>
-		<scattering>
-			<use>/rendering/scene/scattering</use>
-		</scattering>
-		<visibility>
-			<use>/environment/ground-visibility-m</use>
-		</visibility>
-		<avisibility>
-			<use>/environment/visibility-m</use>
-		</avisibility>
-		<lthickness>
-			<use>/environment/ground-haze-thickness-m</use>
-		</lthickness>
-		<terminator>
-			<use>/environment/terminator-relative-position-m</use>
-		</terminator>
-	</parameters>
-	<technique n="8">
-		<predicate>
-			<and>
-				<property>/sim/rendering/shaders/skydome</property>
-				<or>
-					<less-equal>
-						<value type="float">2.0</value>
-						<glversion/>
-					</less-equal>
-					<and>
-						<extension-supported>GL_ARB_shader_objects</extension-supported>
-						<extension-supported>GL_ARB_shading_language_100</extension-supported>
-						<extension-supported>GL_ARB_vertex_shader</extension-supported>
-						<extension-supported>GL_ARB_fragment_shader</extension-supported>
-					</and>
-				</or>
-			</and>
-		</predicate>
+  <name>Effects/skydome</name>
+  <parameters>
+    <mie><use>/sim/rendering/mie</use></mie>
+    <rayleigh><use>/sim/rendering/rayleigh</use></rayleigh>
+    <density><use>/sim/rendering/dome-density</use></density>
+    <overcast><use>/rendering/scene/overcast</use></overcast>
+    <saturation><use>/rendering/scene/saturation</use></saturation>
+    <scattering><use>/rendering/scene/scattering</use></scattering>
+    <visibility><use>/environment/ground-visibility-m</use></visibility>
+    <avisibility><use>/environment/visibility-m</use></avisibility>
+    <lthickness><use>/environment/ground-haze-thickness-m</use></lthickness>
+    <terminator><use>/environment/terminator-relative-position-m</use></terminator>
+    <terrain_alt><use>/environment/mean-terrain-elevation-m</use></terrain_alt>
+  </parameters>
+  <technique n="8">
+    <predicate>
+      <and>
+        <property>/sim/rendering/shader-effects</property>
+        <property>/sim/rendering/shaders/skydome</property>
+        <or>
+          <less-equal>
+            <value type="float">2.0</value>
+            <glversion/>
+          </less-equal>
+          <and>
+            <extension-supported>GL_ARB_shader_objects</extension-supported>
+            <extension-supported>GL_ARB_shading_language_100</extension-supported>
+            <extension-supported>GL_ARB_vertex_shader</extension-supported>
+            <extension-supported>GL_ARB_fragment_shader</extension-supported>
+          </and>
+        </or>
+      </and>
+    </predicate>
 
-		<pass>
-			<lighting>true</lighting>
-			<shade-model>smooth</shade-model>
-			<cull-face>back</cull-face>
-			<program>
-				<vertex-shader>Shaders/skydome.vert</vertex-shader>
-				<fragment-shader>Shaders/skydome.frag</fragment-shader>
-			</program>
-			<uniform>
-				<name>mK</name>
-				<type>float</type>
-				<value>
-					<use>mie</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>rK</name>
-				<type>float</type>
-				<value>
-					<use>rayleigh</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>density</name>
-				<type>float</type>
-				<value>
-					<use>density</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>overcast</name>
-				<type>float</type>
-				<value>
-					<use>overcast</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>saturation</name>
-				<type>float</type>
-				<value>
-					<use>saturation</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>scattering</name>
-				<type>float</type>
-				<value>
-					<use>scattering</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>visibility</name>
-				<type>float</type>
-				<value>
-					<use>visibility</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>hazeLayerAltitude</name>
-				<type>float</type>
-				<value>
-					<use>lthickness</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>terminator</name>
-				<type>float</type>
-				<value>
-					<use>terminator</use>
-				</value>
-			</uniform>
-			<uniform>
-				<name>avisibility</name>
-				<type>float</type>
-				<value>
-					<use>avisibility</use>
-				</value>
-			</uniform>
-		</pass>
-	</technique>
+    <pass>
+      <lighting>true</lighting>
+      <shade-model>smooth</shade-model>
+      <cull-face>back</cull-face>
+      <program>
+        <vertex-shader>Shaders/skydome.vert</vertex-shader>
+        <fragment-shader>Shaders/skydome.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>mK</name>
+        <type>float</type>
+        <value><use>mie</use></value>
+      </uniform>
+      <uniform>
+        <name>rK</name>
+        <type>float</type>
+        <value><use>rayleigh</use></value>
+      </uniform>
+      <uniform>
+        <name>density</name>
+        <type>float</type>
+        <value><use>density</use></value>
+      </uniform>
+      <uniform>
+        <name>overcast</name>
+        <type>float</type>
+        <value><use>overcast</use></value>
+      </uniform>
+      <uniform>
+        <name>saturation</name>
+        <type>float</type>
+        <value><use>saturation</use></value>
+      </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>visibility</name>
+        <type>float</type>
+        <value><use>visibility</use></value>
+      </uniform>
+       <uniform>
+        <name>hazeLayerAltitude</name>
+        <type>float</type>
+        <value><use>lthickness</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>avisibility</name>
+        <type>float</type>
+        <value><use>avisibility</use></value>
+      </uniform>
+      <uniform>
+        <name>terrain_alt</name>
+        <type>float</type>
+        <value><use>terrain_alt</use></value>
+      </uniform>
+    </pass>
+  </technique>
 
-	<!-- fall back without shaders -->
-	<technique n="11">
-		<pass>
-			<lighting>false</lighting>
-			<shade-model>smooth</shade-model>
-			<cull-face>back</cull-face>
-		</pass>
-	</technique>
+  <!-- fall back without shaders -->
+  <technique n="11">
+    <pass>
+      <lighting>false</lighting>
+      <shade-model>smooth</shade-model>
+      <cull-face>back</cull-face>
+    </pass>
+  </technique>
 
-</PropertyList>
\ No newline at end of file
+</PropertyList>
diff --git a/Effects/terrain-default.eff b/Effects/terrain-default.eff
index 9f01dfa6d..d4f259abc 100644
--- a/Effects/terrain-default.eff
+++ b/Effects/terrain-default.eff
@@ -35,28 +35,166 @@
 			<bin-number>0</bin-number>
 			<bin-name>RenderBin</bin-name>
 		</render-bin>
-		<visibility>
-			<use>/environment/ground-visibility-m</use>
-		</visibility>
-		<avisibility>
-			<use>/environment/visibility-m</use>
-		</avisibility>
-		<lthickness>
-			<use>/environment/ground-haze-thickness-m</use>
-		</lthickness>
-		<scattering>
-			<use>/rendering/scene/scattering</use>
-		</scattering>
-		<terminator>
-			<use>/environment/terminator-relative-position-m</use>
-		</terminator>
-		<fogtype>
-			<use>/sim/rendering/shaders/skydome</use>
-		</fogtype>
+		<visibility><use>/environment/ground-visibility-m</use></visibility>
+		<avisibility><use>/environment/visibility-m</use></avisibility>
+		<lthickness><use>/environment/ground-haze-thickness-m</use></lthickness>
+		<scattering><use>/rendering/scene/scattering</use></scattering>
+		<terminator><use>/environment/terminator-relative-position-m</use></terminator>
+		<terrain_alt><use>/environment/mean-terrain-elevation-m</use></terrain_alt>
+    		<overcast><use>/rendering/scene/overcast</use></overcast>
+    		<eye_alt><use>/sim/rendering/eye-altitude-m</use></eye_alt>
+		<fogtype><use>/sim/rendering/shaders/skydome</use></fogtype>
 	</parameters>
 	<!-- put techniques at a "high" index to allow derived effects to
        insert their own techniques first. -->
-	<technique n="10">
+<technique n="7">
+    <predicate>
+      <and>
+        <property>/sim/rendering/shaders/skydome</property>
+        <or>
+          <less-equal>
+            <value type="float">2.0</value>
+            <glversion/>
+          </less-equal>
+          <and>
+            <extension-supported>GL_ARB_shader_objects</extension-supported>
+            <extension-supported>GL_ARB_shading_language_100</extension-supported>
+            <extension-supported>GL_ARB_vertex_shader</extension-supported>
+            <extension-supported>GL_ARB_fragment_shader</extension-supported>
+          </and>
+        </or>
+      </and>
+    </predicate>
+    <pass>
+      <lighting>true</lighting>
+      <material>
+        <ambient><use>material/ambient</use></ambient>
+        <diffuse><use>material/diffuse</use></diffuse>
+        <specular><use>material/specular</use></specular>
+        <emissive><use>material/emissive</use></emissive>
+        <shininess><use>material/shininess</use></shininess>
+        <color-mode>ambient-and-diffuse</color-mode>
+      </material>
+      <alpha-test><use>transparent</use></alpha-test>
+      <shade-model>smooth</shade-model>
+      <cull-face>back</cull-face>
+      <render-bin>
+        <bin-number>-1</bin-number>
+        <bin-name>RenderBin</bin-name>
+      </render-bin>
+      <texture-unit>
+        <unit>0</unit>
+          <image><use>texture[0]/image</use></image>
+          <filter><use>texture[0]/filter</use></filter>
+          <wrap-s><use>texture[0]/wrap-s</use></wrap-s>
+          <wrap-t><use>texture[0]/wrap-t</use></wrap-t>
+          <internal-format>
+            <use>texture[0]/internal-format</use>
+          </internal-format>
+      </texture-unit>
+      <program>
+	<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>
+	<vertex-shader n="1">Shaders/default.vert</vertex-shader>
+	<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
+	<fragment-shader n="1">Shaders/terrain-nocolor.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>texture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <color-mask type="vec4d">0 0 0 0</color-mask>
+    </pass>
+    <pass>
+      <lighting>true</lighting>
+      <material>
+        <ambient><use>material/ambient</use></ambient>
+        <diffuse><use>material/diffuse</use></diffuse>
+        <specular><use>material/specular</use></specular>
+        <emissive><use>material/emissive</use></emissive>
+        <shininess><use>material/shininess</use></shininess>
+        <color-mode>ambient-and-diffuse</color-mode>
+      </material>
+      <blend><use>transparent</use></blend>
+      <alpha-test><use>transparent</use></alpha-test>
+      <shade-model>smooth</shade-model>
+      <cull-face>back</cull-face>
+      <render-bin>
+        <bin-number><use>render-bin/bin-number</use></bin-number>
+        <bin-name><use>render-bin/bin-name</use></bin-name>
+      </render-bin>
+      <texture-unit>
+        <unit>0</unit>
+          <image><use>texture[0]/image</use></image>
+          <filter><use>texture[0]/filter</use></filter>
+          <wrap-s><use>texture[0]/wrap-s</use></wrap-s>
+          <wrap-t><use>texture[0]/wrap-t</use></wrap-t>
+          <internal-format>
+            <use>texture[0]/internal-format</use>
+          </internal-format>
+      </texture-unit>
+      <program>
+        <vertex-shader>Shaders/terrain-haze.vert</vertex-shader>
+        <fragment-shader>Shaders/terrain-haze.frag</fragment-shader>
+      </program>
+      <uniform>
+        <name>visibility</name>
+        <type>float</type>
+        <value><use>visibility</use></value>
+      </uniform>
+      <uniform>
+        <name>avisibility</name>
+        <type>float</type>
+        <value><use>avisibility</use></value>
+      </uniform>
+       <uniform>
+        <name>hazeLayerAltitude</name>
+        <type>float</type>
+        <value><use>lthickness</use></value>
+      </uniform>
+      <uniform>
+        <name>scattering</name>
+        <type>float</type>
+        <value><use>scattering</use></value>
+      </uniform>
+      <uniform>
+        <name>terminator</name>
+        <type>float</type>
+        <value><use>terminator</use></value>
+      </uniform>
+      <uniform>
+        <name>terrain_alt</name>
+        <type>float</type>
+        <value><use>terrain_alt</use></value>
+      </uniform>
+      <uniform>
+        <name>overcast</name>
+        <type>float</type>
+        <value><use>overcast</use></value>
+      </uniform>
+     <uniform>
+        <name>eye_alt</name>
+        <type>float</type>
+        <value><use>eye_alt</use></value>
+      </uniform>
+      <uniform>
+        <name>texture</name>
+        <type>sampler-2d</type>
+        <value type="int">0</value>
+      </uniform>
+      <uniform>
+        <name>colorMode</name>
+        <type>int</type>
+        <value>2</value> <!-- AMBIENT_AND_DIFFUSE -->
+      </uniform>
+      <depth>
+        <function>lequal</function>
+        <write-mask type="bool">false</write-mask>
+      </depth>
+    </pass>
+  </technique>
+
+<technique n="10">
 		<predicate>
 			<and>
 				<property>/sim/rendering/shaders/generic</property>
@@ -123,7 +261,7 @@
 				</internal-format>
 			</texture-unit>
 			<program>
-<!-- 				<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader> -->
+				<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>
 				<vertex-shader n="1">Shaders/default.vert</vertex-shader>
 				<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
 				<fragment-shader n="1">Shaders/terrain-nocolor.frag</fragment-shader>
@@ -254,6 +392,8 @@
 			</depth>
 		</pass>
 	</technique>
+
+	
 	<technique n="11">
 		<pass>
 			<lighting>true</lighting>
diff --git a/Environment/environment.xml b/Environment/environment.xml
index 9b17450e7..b1fb84d58 100644
--- a/Environment/environment.xml
+++ b/Environment/environment.xml
@@ -309,6 +309,7 @@
 
   </params>
 
+
   <wildfire>
     <enabled type="bool" userarchive="y">false</enabled>
     <share-events type="bool" userarchive="y">false</share-events>
@@ -330,7 +331,7 @@
 
   <sea>
     <config>
-      <wind-filter-time type="double">0.05</wind-filter-time>
+      <wind-filter-time type="double">60.0</wind-filter-time>
     </config>
   </sea>
 
diff --git a/Environment/local-weather-defaults.xml b/Environment/local-weather-defaults.xml
index bd5dcf320..6826b38e7 100644
--- a/Environment/local-weather-defaults.xml
+++ b/Environment/local-weather-defaults.xml
@@ -25,6 +25,7 @@
     <large-scale-persistence type="double" userarchive="y">1.0</large-scale-persistence>
     <small-scale-persistence type="double" userarchive="y">0.0</small-scale-persistence>
     <ground-haze-factor type="double" userarchive="y">1.0</ground-haze-factor>
+    <aux-max-vis-range-m type="double" userarchive="y">11.69524</aux-max-vis-range-m>
     <max-vis-range-m type="double" userarchive="y">120000.0</max-vis-range-m>
   </config>
  <tmp>
diff --git a/Nasal/local_weather/cloud_definitions.nas b/Nasal/local_weather/cloud_definitions.nas
index 495fd4f6b..2f6ffd5d4 100644
--- a/Nasal/local_weather/cloud_definitions.nas
+++ b/Nasal/local_weather/cloud_definitions.nas
@@ -53,7 +53,7 @@ else if (type == "Cumulus (cloudlet)"){
 			cloudAssembly.min_height = 500.0;
 			cloudAssembly.max_height = 700.0;
 			cloudAssembly.min_cloud_width = 1300;
-			cloudAssembly.min_cloud_height = 700;
+			cloudAssembly.min_cloud_height = 750;
 			cloudAssembly.bottom_shade = 0.7;
 			}
 		else
@@ -65,7 +65,7 @@ else if (type == "Cumulus (cloudlet)"){
 			cloudAssembly.min_height = 600.0;
 			cloudAssembly.max_height = 900.0;
 			cloudAssembly.min_cloud_width = 1300;
-			cloudAssembly.min_cloud_height = 700;
+			cloudAssembly.min_cloud_height = 950;
 			cloudAssembly.bottom_shade = 0.4;
 			}
 			
@@ -139,7 +139,7 @@ else if (type == "Cu (volume)"){
 		cloudAssembly.min_height = 800.0;
 		cloudAssembly.max_height = 1100.0;
 		cloudAssembly.min_cloud_width = 1500;
-		cloudAssembly.min_cloud_height = 1000;
+		cloudAssembly.min_cloud_height = 1150;
 		cloudAssembly.bottom_shade = 0.4;
 		}
 			
@@ -365,8 +365,8 @@ else if (type == "Cumulus (whisp)"){
 		cloudAssembly.max_width = 600.0 * mult;
 		cloudAssembly.min_height = 400.0 * mult;
 		cloudAssembly.max_height = 600.0 * mult;
-		cloudAssembly.min_cloud_width = 800 * mult * mult;
-		cloudAssembly.min_cloud_height = 800 * mult * mult;
+		cloudAssembly.min_cloud_width = 800;
+		cloudAssembly.min_cloud_height = 800;
 		cloudAssembly.z_scale = 1.0;
 
 		#signal that new routines are used
@@ -952,7 +952,7 @@ else if (type == "Stratus") {
 		cloudAssembly.min_height = 2000.0 * mult;
 		cloudAssembly.max_height = 2500.0 * mult;
 		cloudAssembly.min_cloud_width = 5000.0;
-		cloudAssembly.min_cloud_height = 1.1 *  cloudAssembly.max_height;
+		cloudAssembly.min_cloud_height = 50; #1.1 *  cloudAssembly.max_height;
 
 
 		#signal that new routines are used
diff --git a/Nasal/local_weather/compat_layer.nas b/Nasal/local_weather/compat_layer.nas
index a0b4e985d..d4db29730 100644
--- a/Nasal/local_weather/compat_layer.nas
+++ b/Nasal/local_weather/compat_layer.nas
@@ -23,7 +23,7 @@
 # create_cloud_array		to place clouds from storage arrays into the scenery
 # get_elevation			to get the terrain elevation at given coordinates
 # get_elevation_vector		to get terrain elevation at given coordinate vector
-
+# set_wxradarecho_storm		to provide info about a storm to the wxradar
 
 
 # This file contains portability wrappers for the local weather system: 
@@ -126,12 +126,17 @@ print("Compatibility layer: tests done.");
 
 # features of a 2.4 binary
 
+# switch terrainsampler to active, should be initialized
+
+
 features.can_set_light = 1;
 features.can_set_scattering = 1;
 features.terrain_presampling = 1;
 features.terrain_presampling_active = 1;
 features.can_disable_environment = 1;
 
+
+
 # features of a current GIT binary
 
 features.fast_geodinfo = 1;
@@ -750,6 +755,36 @@ if (local_weather.dynamics_flag == 1)
 }
 
 
+
+###########################################################
+# place a model
+###########################################################
+
+var place_model = func(path, lat, lon, alt, heading) {
+
+
+
+var m = props.globals.getNode("models", 1);
+		for (var i = 0; 1; i += 1)
+			if (m.getChild("model", i, 0) == nil)
+				break;
+var model = m.getChild("model", i, 1);
+
+
+model.getNode("path", 1).setValue(path);
+model.getNode("latitude-deg", 1).setValue(lat);
+model.getNode("longitude-deg", 1).setValue(lon);
+model.getNode("elevation-ft", 1).setValue(alt);
+model.getNode("heading-deg", 1).setValue(heading);
+model.getNode("load", 1).remove();
+
+
+}
+
+
+
+
+
 ###########################################################
 # place a single cloud using hard-coded system
 ###########################################################
@@ -953,12 +988,65 @@ for(var i = 0; i < n; i=i+1)
 return elevation;
 }
 
+###########################################################
+# set the wxradar echo of a storm
+###########################################################
 
+var set_wxradarecho_storm = func (lat, lon, base, top, radius, ref, turb, type) {
+
+# look for the next free index in the wxradar property tree entries
+
+var n = props.globals.getNode("/instrumentation/wxradar", 1);
+		for (var i = 0; 1; i += 1)
+			if (n.getChild("storm", i, 0) == nil)
+				break;
+var s = n.getChild("storm", i, 1);
+
+
+s.getNode("latitude-deg",1).setValue(lat);
+s.getNode("longitude-deg",1).setValue(lon);
+s.getNode("heading-deg",1).setValue(0.0);
+s.getNode("base-altitude-ft",1).setValue(base);
+s.getNode("top-altitude-ft",1).setValue(top);
+s.getNode("radius-nm",1).setValue(radius * m_to_nm);
+s.getNode("reflectivity-norm",1).setValue(ref);
+s.getNode("turbulence-norm",1).setValue(turb);
+s.getNode("type",1).setValue(type);
+s.getNode("show",1).setValue(1);
+}
+
+###########################################################
+# remove unused echos
+###########################################################
+
+var remove_wxradar_echos = func { 
+
+var distance_to_remove = 70000.0;
+
+var storms = props.globals.getNode("/instrumentation/wxradar", 1).getChildren("storm");
+
+var pos = geo.aircraft_position();
+
+foreach (s; storms)
+	{
+	var d_sq = local_weather.calc_d_sq(pos.lat(), pos.lon(), s.getNode("latitude-deg").getValue(), s.getNode("longitude-deg").getValue());
+	if (d_sq > distance_to_remove * distance_to_remove)
+		{
+		s.remove();
+		}
+	}
+
+}
 
 ############################################################
 # global variables
 ############################################################
 
+# conversions
+
+var nm_to_m = 1852.00;
+var m_to_nm = 1.0/nm_to_m; 
+
 # some common abbreviations
 
 var lw = "/local-weather/";
diff --git a/Nasal/local_weather/local_weather.nas b/Nasal/local_weather/local_weather.nas
index 1262ddb64..95a61e4c0 100644
--- a/Nasal/local_weather/local_weather.nas
+++ b/Nasal/local_weather/local_weather.nas
@@ -928,6 +928,8 @@ setprop(lw~"current/wind-speed-kt",windspeed_current);
 setprop("/environment/config/boundary/entry[0]/wind-from-heading-deg",winddir);
 setprop("/environment/config/boundary/entry[0]/wind-speed-kt",windspeed_ground);
 
+#setprop("/environment/sea/surface/wind-from-east-fps",windspeed_ground * math.sin(winddir * math.pi/180.0));
+#setprop("/environment/sea/surface/wind-from-east-fps",windspeed_ground * math.cos(winddir * math.pi/180.0));
 # end hack
 
 
@@ -1609,6 +1611,12 @@ settimer ( func { setsize(weather_dynamics.cloudQuadtrees,0);},0.1); # to avoid
 setsize(effectVolumeArray,0);
 n_effectVolumeArray = 0;
 
+
+# clear any wxradar echos
+
+if (wxradar_support_flag ==1)
+	{props.globals.getNode("/instrumentation/wxradar", 1).removeChildren("storm");}
+
 # if we have used METAR, we may no longer want to do so
 
 metar_flag = 0;
@@ -2887,8 +2895,8 @@ var terrain_presampling_start = func (blat, blon, nc, size, alpha) {
 	
 # initialize the result vector
 
-setsize(terrain_n,20);
-for(var j=0;j<20;j=j+1){terrain_n[j]=0;}
+setsize(terrain_n,40);
+for(var j=0;j<40;j=j+1){terrain_n[j]=0;}
 
 if (thread_flag == 1)
 	{
@@ -2911,10 +2919,10 @@ else
 	setprop(lw~"tmp/presampling-status", "finished");
 	}
 	
-if (compat_layer.features.terrain_presampling_active == 1)
+if (compat_layer.features.terrain_presampling == 1)
 	{
 	print("Starting hard-coded terrain presampling");
-
+	setprop("/environment/terrain/area[0]/enabled",1);
 	setprop(lw~"tmp/presampling-status", "sampling");
 	setprop("/environment/terrain/area[0]/enabled", 1 );
 	setprop("/environment/terrain/area[0]/input/latitude-deg", blat );
@@ -3000,7 +3008,7 @@ var elevation_vec = compat_layer.get_elevation_array(lat_vec, lon_vec);
 	
 for (i=0; i<ntries;i=i+1)
 	{
-	for(j=0;j<20;j=j+1)
+	for(j=0;j<30;j=j+1)
 		{
 		if ((elevation_vec[i] != -1.0) and (elevation_vec[i] < 500.0 * (j+1))) 
 			{terrain_n[j] = terrain_n[j]+1;  break;}
@@ -3028,35 +3036,35 @@ if ((compat_layer.features.terrain_presampling_active == 0) or (getprop(lw~"tile
 	var alt_low_min = 0;
 
 
-	for (var i=0; i<20;i=i+1)
+	for (var i=0; i<40;i=i+1)
 		{sum = sum + terrain_n[i];}
 
 	var n_tot = sum;
 
 	sum = 0;
-	for (var i=0; i<20;i=i+1)
+	for (var i=0; i<40;i=i+1)
 		{
 		sum = sum + terrain_n[i];
 		if (sum > int(0.5 *n_tot)) {alt_med = i * 500.0; break;}		
 		}
 
 	sum = 0;
-	for (var i=0; i<20;i=i+1)
+	for (var i=0; i<40;i=i+1)
 		{
 		sum = sum + terrain_n[i];
 		if (sum > int(0.3 *n_tot)) {alt_20 = i * 500.0; break;}		
 		}
 
 
-	for (var i=0; i<20;i=i+1) {alt_mean = alt_mean + terrain_n[i] * i * 500.0;}
+	for (var i=0; i<40;i=i+1) {alt_mean = alt_mean + terrain_n[i] * i * 500.0;}
 	alt_mean = alt_mean/n_tot;
 
-	for (var i=0; i<20;i=i+1) {if (terrain_n[i] > 0) {alt_min = i * 500.0; break;}}
+	for (var i=0; i<40;i=i+1) {if (terrain_n[i] > 0) {alt_min = i * 500.0; break;}}
 
 	var n_max = 0;
 	sum = 0;
 
-	for (var i=0; i<19;i=i+1) 
+	for (var i=0; i<39;i=i+1) 
 		{
 		sum = sum + terrain_n[i];
 		if (terrain_n[i] > n_max) {n_max = terrain_n[i];}
@@ -3090,6 +3098,11 @@ append(alt_50_array, alt_med);
 append(alt_20_array, alt_20);
 append(alt_min_array, alt_min);
 append(alt_mean_array, alt_mean);
+
+
+current_mean_alt = 0.5 * (current_mean_alt + alt_20);
+
+
 }
 
 
@@ -3592,7 +3605,7 @@ debug_output_flag = getprop(lw~"config/debug-output-flag");
 fps_control_flag = getprop(lw~"config/fps-control-flag");
 realistic_visibility_flag = getprop(lw~"config/realistic-visibility-flag");
 detailed_terrain_interaction_flag = getprop(lw~"config/detailed-terrain-interaction-flag");
-scattering_shader_flag = getprop("/sim/rendering/scattering-shader");
+scattering_shader_flag = getprop("/sim/rendering/shaders/skydome");
 
 }
 
@@ -4257,11 +4270,11 @@ setlistener(lw~"config/target-framerate", func {target_framerate = getprop(lw~"c
 
 setlistener(lw~"config/small-scale-persistence", func {weather_tiles.small_scale_persistence = getprop(lw~"config/small-scale-persistence");});
 setlistener(lw~"config/ground-haze-factor", func {ground_haze_factor = getprop(lw~"config/ground-haze-factor");});
-setlistener(lw~"config/max-vis-range-m", func {max_vis_range = getprop(lw~"config/max-vis-range-m");});
+setlistener(lw~"config/aux-max-vis-range-m", func {max_vis_range = math.exp(getprop(lw~"config/aux-max-vis-range-m")); setprop(lw~"config/max-vis-range-m",max_vis_range);});
 
 setlistener(lw~"config/temperature-offset-degc", func {temperature_offset = getprop(lw~"config/temperature-offset-degc");});
 
-setlistener("/sim/rendering/scattering-shader", func {scattering_shader_flag = getprop("/sim/rendering/scattering-shader"); });
+setlistener("/sim/rendering/shaders/skydome", func {scattering_shader_flag = getprop("/sim/rendering/shaders/skydome"); });
 }
 
 
@@ -4273,6 +4286,7 @@ var test = func {
 
 var lat = getprop("position/latitude-deg");
 var lon = getprop("position/longitude-deg");
+var alt = getprop("position/altitude-ft");
 
 thread_flag = 0;
 dynamics_flag = 0;
@@ -4294,11 +4308,11 @@ presampling_flag = 0;
 
 #var pos = geo.aircraft_position();
 
-debug.dump(geodinfo(lat, lon));
+# debug.dump(geodinfo(lat, lon));
 
 #create_cumulonimbus_cloud(lat, lon, 6000.0, 2.5);
 
-# geo.put_model("Models/Astro/Earth.ac",lat, lon);
+local_weather.place_model("Models/Weather/cloudsphere.ac",lat, lon, alt-10000.0, 0.0);
 
 #setprop("/environment/terrain/area[0]/input/latitude-deg", lat );
 #setprop("/environment/terrain/area[0]/input/longitude-deg", lon );
@@ -4586,7 +4600,7 @@ var ec = "/environment/config/";
 
 # a hash map of the strength for convection associated with terrain types
 
-var landcover_map = {BuiltUpCover: 0.35, Town: 0.35, Freeway:0.35, BarrenCover:0.3, HerbTundraCover: 0.25, GrassCover: 0.2, CropGrassCover: 0.2, EvergreenBroadCover: 0.2, EvergreenNeedleCover: 0.2, Sand: 0.25, Grass: 0.2, Ocean: 0.01, Marsh: 0.05, Lake: 0.01, ShrubCover: 0.15, Landmass: 0.2, CropWoodCover: 0.15, MixedForestCover: 0.15, DryCropPastureCover: 0.25, MixedCropPastureCover: 0.2, IrrCropPastureCover: 0.15, DeciduousBroadCover: 0.1, DeciduousNeedleCover: 0.1, Bog: 0.05, pa_taxiway : 0.35, pa_tiedown: 0.35, pc_taxiway: 0.35, pc_tiedown: 0.35, Glacier: 0.03, SnowCover: 0.04, DryLake: 0.3, IntermittentStream: 0.2, DryCrop: 0.2, Lava: 0.3, GolfCourse: 0.2, Rock: 0.3, Construction: 0.35};
+var landcover_map = {BuiltUpCover: 0.35, Town: 0.35, Freeway:0.35, BarrenCover:0.3, HerbTundraCover: 0.25, GrassCover: 0.2, CropGrassCover: 0.2, EvergreenBroadCover: 0.2, EvergreenNeedleCover: 0.2, Sand: 0.25, Grass: 0.2, Ocean: 0.01, Marsh: 0.05, Lake: 0.01, ShrubCover: 0.15, Landmass: 0.2, CropWoodCover: 0.15, MixedForestCover: 0.15, DryCropPastureCover: 0.25, MixedCropPastureCover: 0.2, IrrCropPastureCover: 0.15, DeciduousBroadCover: 0.1, DeciduousNeedleCover: 0.1, Bog: 0.05, pa_taxiway : 0.35, pa_tiedown: 0.35, pc_taxiway: 0.35, pc_tiedown: 0.35, Glacier: 0.03, SnowCover: 0.04, DryLake: 0.3, IntermittentStream: 0.2, DryCrop: 0.2, Lava: 0.3, GolfCourse: 0.2, Rock: 0.3, Construction: 0.35, PackIce: 0.04, NaturalCrop: 0.2};
 
 # a hash map of average vertical cloud model sizes
 
@@ -4694,11 +4708,12 @@ var detailed_terrain_interaction_flag = 1;
 var hardcoded_clouds_flag = 1;
 var realistic_visibility_flag = 0;
 var scattering_shader_flag = 0;
+var wxradar_support_flag = 1;
 
 var ground_haze_factor = 1.0;
 var max_vis_range = 120000.0;
 var temperature_offset = 0.0;
-
+var current_mean_alt = 0.0;
 
 # globals for framerate controlled cloud management
 
@@ -4758,6 +4773,8 @@ setprop(lw~"effect-volumes/number-active-sat",0);
 # setprop(lw~"config/max-vis-range-m", 120000.0);
 setprop(lw~"config/temperature-offset-degc", 0.0);
 
+setprop("/sim/rendering/eye-altitude-m", getprop("/position/altitude-ft") * ft_to_m);
+
 # create properties for tile management
 
 setprop(lw~"tiles/tile-counter",0);
diff --git a/Nasal/local_weather/weather_dynamics.nas b/Nasal/local_weather/weather_dynamics.nas
index 49ff8dae2..8f1615676 100644
--- a/Nasal/local_weather/weather_dynamics.nas
+++ b/Nasal/local_weather/weather_dynamics.nas
@@ -117,10 +117,24 @@ time_lw = time_lw + dt_lw;
 # directly referencing /sim/time/sun-angle-rad as uniform doesn't
 # work since that is a tied property
 
-var sun_angle = 1.57079632675 - getprop("/sim/time/sun-angle-rad");
+#var sun_angle = 1.57079632675 - getprop("/sim/time/sun-angle-rad");
 
-var terminator_offset = sun_angle /  0.017451 * 110000.0 + 250000.0;
-setprop("/environment/terminator-relative-position-m",terminator_offset);
+#var terminator_offset = sun_angle /  0.017451 * 110000.0;# + 250000.0;
+#setprop("/environment/terminator-relative-position-m",terminator_offset);
+
+var viewpos = geo.viewer_position();
+
+# setprop("/environment/alt-in-haze-m", getprop("/environment/ground-haze-thickness-m")-viewpos.alt());
+
+setprop("/sim/rendering/eye-altitude-m", viewpos.alt());
+
+if (local_weather.presampling_flag == 1)
+	{
+	var mean_terrain_elevation_m = ft_to_m * local_weather.current_mean_alt ; }
+else	
+	{var mean_terrain_elevation_m = 0.0;}
+
+setprop("/environment/mean-terrain-elevation-m", mean_terrain_elevation_m);
 
 if (getprop(lw~"timing-loop-flag") ==1) {settimer(timing_loop, 0);}
 
diff --git a/Nasal/local_weather/weather_tile_management.nas b/Nasal/local_weather/weather_tile_management.nas
index 25b741d21..aebf4f015 100644
--- a/Nasal/local_weather/weather_tile_management.nas
+++ b/Nasal/local_weather/weather_tile_management.nas
@@ -53,7 +53,7 @@ var this_frame_action_flag = 0; # use this flag to avoid overlapping tile operat
 setsize(active_tile_list,0);
 #append(active_tile_list,0); # tile zero formally containing static objects is always active 
 
-var distance_to_load = current_visibility;
+var distance_to_load = current_visibility + 10000.0;
 
 if (distance_to_load > 65000.0) {distance_to_load = 65000.0;}
 if (distance_to_load < 29000.0) {distance_to_load = 29000.0;}
@@ -64,7 +64,9 @@ if (distance_to_load < 29000.0) {distance_to_load = 29000.0;}
 #if (distance_to_load < 29000.0)
 #	{distance_to_load = 29000.0;}
 
-var distance_to_remove = distance_to_load + 500.0;
+var distance_to_remove = distance_to_load + 20000.0;
+if (distance_to_remove > 65500.0) {distance_to_remove = 65500.0;}
+
 
 # check here if we have a new weather station if METAR is running
 
@@ -202,7 +204,7 @@ foreach (var t; tNode) {
 
 	
 
-if (getprop(lw~"tile-loop-flag") ==1) {settimer(tile_management_loop, 5.0);}
+if (getprop(lw~"tile-loop-flag") ==1) {settimer(tile_management_loop, 4.0);}
 
 }
 
@@ -713,6 +715,11 @@ if (local_weather.dynamics_flag ==1)
 
 local_weather.assemble_effect_array(); 
 
+if (local_weather.wxradar_support_flag == 1)
+	{
+	local_weather.remove_wxradar_echos();
+	}
+
 }
 
 
diff --git a/Nasal/local_weather/weather_tiles.nas b/Nasal/local_weather/weather_tiles.nas
index ffc41e383..e3d28581a 100644
--- a/Nasal/local_weather/weather_tiles.nas
+++ b/Nasal/local_weather/weather_tiles.nas
@@ -112,14 +112,21 @@ alt_offset = 0.0;
 
 #create_4_8_cirrocumulus_streaks(blat, blon, 10000.0 + alt_offset, alpha);
 #create_4_8_alttstratus_streaks(blat, blon, 5000+alt_offset, alpha) ;
+# create_4_8_alttstratus_streaks(blat, blon, 5000+alt_offset, alpha) ;
 #create_2_8_cirrocumulus_patches(blat, blon, 13000+alt_offset, alpha) ;
 
-#create_8_8_nimbus_rain(blat, blon, 3000+alt_offset, alpha, 0.3) ;
+# create_8_8_nimbus_rain(blat, blon, 3000.0, alpha, 0.3) ;
 #create_8_8_tstratus(blat, blon, 5000+alt_offset, alpha);
-#create_8_8_cirrostratus(blat, blon, 5000+alt_offset, alpha);
-create_thunderstorm_scenario (blat, blon, 3000.0, alpha);
+
+# create_8_8_cirrostratus(blat, blon, 30000.0, alpha);
+
+#create_thunderstorm_scenario (blat, blon, 3000.0, alpha);
 #create_big_thunderstorm (blat, blon, 3000.0, alpha);
 
+#create_2_8_cirrus(blat, blon, 30000.0, alpha);
+#create_2_8_cirrus(blat, blon, 20000.0, alpha);
+create_4_8_cirrus(blat, blon, 30000.0, alpha);
+
 #create_4_8_altocumulus_perlucidus(blat, blon, 5000+alt_offset, alpha) ;
 
 #create_detailed_stratocumulus_bank(blat, blon, 4000+alt_offset,alpha);
@@ -193,7 +200,7 @@ else
 
 #rn = 0.1;
 
-if (rn > 0.8)
+if (rn > 0.833)
 	{
 	# cloud scenario 1: weak cumulus development and blue thermals
 
@@ -213,7 +220,7 @@ if (rn > 0.8)
 	# and specify the atmosphere
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, 25000.0, 30000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
 	}
-else if (rn > 0.6)
+else if (rn > 0.666)
 	{
 	# cloud scenario 2: some Cirrocumulus patches
 	
@@ -227,7 +234,7 @@ else if (rn > 0.6)
 	# and specify the atmosphere
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.1, alt+alt_offset +30000.0, alt+alt_offset + 35000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
 	}
-else if (rn > 0.4)
+else if (rn > 0.5)
 	{
 	# cloud scenario 3: Cirrostratus undulatus over weak cumulus
 		
@@ -240,7 +247,7 @@ else if (rn > 0.4)
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
 
 	}
-else if (rn > 0.2)
+else if (rn > 0.333)
 	{
 	# cloud scenario 4: Cirrostratus undulatus streak
 
@@ -252,7 +259,7 @@ else if (rn > 0.2)
 	# and specify the atmosphere
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
 	}
-else if (rn > 0.0)
+else if (rn > 0.166)
 	{
 	# cloud scenario 5: Cirrus
 
@@ -267,7 +274,13 @@ else if (rn > 0.0)
 	# and specify the atmosphere
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
 	}
+else if (rn > 0.0)
+	{
+	# cloud scenario 6: strong Cirrus cover
 
+	create_4_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
+	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
+	}
 
 # store convective altitude and strength
 
@@ -528,18 +541,12 @@ else if (rn > 0.666)
 	}
 else if (rn > 0.555)
 	{
-	# cloud scenario 4: Cumulonimbus banks
+	# cloud scenario 4: thin Stratus streaks
 
 	strength = 0.7 + rand() * 0.3;
 	local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
 
-	for (var i = 0; i < 3; i = i + 1)
-		{
-		x = 2.0 * (rand()-0.5) * 16000;
-		y = 2.0 * (rand()-0.5) * 16000;
-	
-		create_cloud_bank("Cumulonimbus", blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, 1600.0, 800.0, 3000.0, 9, alpha);
-		}
+	create_4_8_alttstratus_streaks(blat, blon, alt+alt_offset +10000.0, alpha);
 
 	# and specify the atmosphere
 	local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
@@ -854,8 +861,6 @@ if (rand() < small_scale_persistence)
 else
 	{rnd_store = rn;}
 
-#rn = 0.1;
-
 
 if (rn > 0.8)
 	{
@@ -1001,7 +1006,7 @@ local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_i
 
 # set a closed Nimbostratus layer
 
-var alt = spread * 400.0;
+var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
 var strength = 0.0;
 
 #var alt = 3000.0;
@@ -2533,7 +2538,7 @@ var create_8_8_cirrostratus = func (lat, lon, alt, alpha) {
 
 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
 
-local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,30,1250.0,0.0,400.0,30,1250.0,0.0,400.0,alpha,1.0);
+local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,30,1300.0,0.0,400.0,30,1300.0,0.0,400.0,alpha,1.0);
 }
 
 var create_8_8_nimbus = func (lat, lon, alt, alpha) {
@@ -3060,6 +3065,19 @@ else
 }
 
 
+var create_4_8_cirrus = func (lat, lon, alt, alpha) {
+
+var phi = alpha * math.pi/180.0;
+
+var x = 2.0 * (rand()-0.5) * 1000;
+var y = 2.0 * (rand()-0.5) * 1000; 
+	
+
+local_weather.create_streak("Cirrus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,1500.0,4,10000.0,0.0, 3000.0, 4,10000.0,0.0,3000.0,alpha,1.0);
+
+}
+
+
 var create_2_8_stratus = func (lat, lon, alt, alpha) {
 
 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
@@ -3430,7 +3448,14 @@ append(elat, lat); append(elon, lon); append(erad, 4000.0 * scale * 1.2);
 
 # set precipitation, visibility, updraft and turbulence in the cloud
 
-local_weather.create_effect_volume(1, lat, lon, 4000.0 * 0.7 * scale, 4000.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 600.0, 0.8, -1, 0.6, 15.0,1 ,-1);
+local_weather.create_effect_volume(1, lat, lon, 4000.0 * 0.7 * scale, 4000.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 1100.0, 0.8, -1, 0.6, 15.0,1 ,-1);
+
+# set the wxradar echo
+
+if (local_weather.wxradar_support_flag == 1)
+	{
+	compat_layer.set_wxradarecho_storm (lat, lon, alt, 20000.0, 4000.0 * 0.7 * scale, 1.0, 0.6, "single_cell");
+	}
 
 }
 
@@ -3458,7 +3483,15 @@ append(elat, lat); append(elon, lon); append(erad, 6000.0 * scale * 1.2);
 
 # set precipitation, visibility, updraft and turbulence in the cloud
 
-local_weather.create_effect_volume(1, lat, lon, 6000.0 * 0.7 * scale, 6000.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 500.0, 1.0, -1, 0.8, 20.0,1,-1 );
+local_weather.create_effect_volume(1, lat, lon, 6000.0 * 0.7 * scale, 6000.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 1100.0, 1.0, -1, 0.8, 20.0,1,-1 );
+
+# set the wxradar echo
+
+if (local_weather.wxradar_support_flag == 1)
+	{
+	compat_layer.set_wxradarecho_storm (lat, lon, alt, 20000.0, 6000.0 * 0.7 * scale, 1.0, 0.8, "single_cell");
+	}
+
 
 }
 
@@ -3492,7 +3525,14 @@ local_weather.create_layer("Stratus (thin)", lat+get_lat(0,-4000,phi), lon+get_l
 # set the exclusion region for the Cumulus layer
 append(elat, lat); append(elon, lon); append(erad, 7500.0 * scale * 1.2);
 
-local_weather.create_effect_volume(1, lat, lon, 7500.0 * 0.7 * scale, 7500.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 500.0, 1.0, -1, 1.0, 25.0,1,-1 );
+local_weather.create_effect_volume(1, lat, lon, 7500.0 * 0.7 * scale, 7500.0 * 0.7 * scale , 0.0, 0.0, 20000.0, 1100.0, 1.0, -1, 1.0, 25.0,1,-1 );
+
+# set the wxradar echo
+
+if (local_weather.wxradar_support_flag == 1)
+	{
+	compat_layer.set_wxradarecho_storm (lat, lon, alt, 24000.0, 7500.0 * 0.7 * scale, 1.0, 1.0, "single_cell");
+	}
 
 }
 
diff --git a/Shaders/3dcloud-lightfield.frag b/Shaders/3dcloud-lightfield.frag
new file mode 100644
index 000000000..dd90fdddf
--- /dev/null
+++ b/Shaders/3dcloud-lightfield.frag
@@ -0,0 +1,15 @@
+uniform sampler2D baseTexture;
+varying float fogFactor;
+
+varying vec3 hazeColor;
+
+void main(void)
+{
+      vec4 base = texture2D( baseTexture, gl_TexCoord[0].st);
+      vec4 finalColor = base * gl_Color;
+      //gl_FragColor.rgb = mix(gl_Fog.color.rgb, finalColor.rgb, fogFactor );
+      gl_FragColor.rgb = mix(hazeColor, finalColor.rgb, fogFactor );
+      //gl_FragColor.a = mix(0.0, finalColor.a, fogFactor);
+      gl_FragColor.a = mix(0.0, finalColor.a, 1.0 - 0.5 * (1.0 - fogFactor));
+}
+
diff --git a/Shaders/3dcloud-lightfield.vert b/Shaders/3dcloud-lightfield.vert
new file mode 100644
index 000000000..0f512fbea
--- /dev/null
+++ b/Shaders/3dcloud-lightfield.vert
@@ -0,0 +1,169 @@
+// -*-C++-*-
+#version 120
+
+varying float fogFactor;
+varying vec3 hazeColor;
+
+uniform float range; // From /sim/rendering/clouds3d-vis-range
+uniform float scattering;
+uniform float terminator;
+uniform float altitude;
+
+attribute vec3 usrAttr1;
+attribute vec3 usrAttr2;
+
+float shade_factor = usrAttr1.g;
+float cloud_height = usrAttr1.b;
+float bottom_factor = usrAttr2.r;
+float middle_factor = usrAttr2.g;
+float top_factor = usrAttr2.b;
+
+const float EarthRadius = 5800000.0;
+
+// light_func is a generalized logistic function fit to the light intensity as a function
+// of scaled terminator position obtained from Flightgear core
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+x = x-0.5;
+
+// use the asymptotics to shorten computations
+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 main(void)
+{
+
+  float intensity;
+  gl_TexCoord[0] = gl_MultiTexCoord0;
+  vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
+  vec4 l  = gl_ModelViewMatrixInverse * vec4(0.0,0.0,1.0,1.0);
+  vec3 u = normalize(ep.xyz - l.xyz);
+
+  // Find a rotation matrix that rotates 1,0,0 into u. u, r and w are
+  // the columns of that matrix.
+  vec3 absu = abs(u);
+  vec3 r = normalize(vec3(-u.y, u.x, 0.0));
+  vec3 w = cross(u, r);
+
+  // Do the matrix multiplication by [ u r w pos]. Assume no
+  // scaling in the homogeneous component of pos.
+  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+  gl_Position.xyz = gl_Vertex.x * u;
+  gl_Position.xyz += gl_Vertex.y * r;
+  gl_Position.xyz += gl_Vertex.z * w;
+  // Apply Z scaling to allow sprites to be squashed in the z-axis
+  gl_Position.z = gl_Position.z * gl_Color.w;
+
+  // Now shift the sprite to the correct position in the cloud.
+  gl_Position.xyz += gl_Color.xyz;
+
+  // Determine a lighting normal based on the vertex position from the
+  // center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker.
+  float n = dot(normalize(-gl_LightSource[0].position.xyz),
+                normalize(vec3(gl_ModelViewMatrix * vec4(- gl_Position.x, - gl_Position.y, - gl_Position.z, 0.0))));
+
+  // Determine the position - used for fog and shading calculations
+  vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position);
+  float fogCoord = abs(ecPosition.z);
+  
+  // Determine the shading of the vertex. We shade it based on it's position
+  // in the cloud relative to the sun, and it's vertical position in the cloud.
+  float shade = mix(shade_factor, top_factor,  smoothstep(-0.3, 0.3, n));
+  //if (n < 0) {
+  //  shade = mix(top_factor, shade_factor, abs(n));
+  //} 
+  
+  if (gl_Position.z < 0.5 * cloud_height) {
+    shade = min(shade, mix(bottom_factor, middle_factor, gl_Position.z * 2.0 / cloud_height));
+  } else {
+    shade = min(shade, mix(middle_factor, top_factor, gl_Position.z * 2.0 / cloud_height - 1.0));
+  }
+                
+  //float h = gl_Position.z / cloud_height;
+  //if (h < 0.5) {
+  //  shade = min(shade, mix(bottom_factor, middle_factor, smoothstep(0.0, 0.5, h)));
+  //} else {
+  //  shade = min(shade, mix(middle_factor, top_factor, smoothstep(2.0 * (h - 0.5)));    
+ // }
+  
+  // Final position of the sprite
+  vec3 relVector = gl_Position.xyz - ep.xyz;
+  gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
+
+
+
+ // Light at the final position
+
+ // first obtain normal to sun position
+
+  vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
+  vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
+
+ // yprime is the distance of the vertex into sun direction, corrected for altitude
+ // the altitude correction is clamped to reasonable values, sometimes altitude isn't parsed correctly, leading
+ // to overbright or overdark clouds
+ // float vertex_alt = clamp(altitude * 0.30480 + relVector.z,1000.0,10000.0); 
+  float vertex_alt = clamp(altitude + relVector.z, 300.0, 10000.0); 
+  float yprime = -dot(relVector, lightHorizon);
+  float yprime_alt = yprime -sqrt(2.0 * EarthRadius * vertex_alt);
+
+  // compute the light at the position
+  vec4 light_diffuse;
+  
+  float lightArg = (terminator-yprime_alt)/100000.0;
+
+  light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 2.227, 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 = 0.0;
+
+   intensity = length(light_diffuse);
+  light_diffuse = intensity * normalize(mix(light_diffuse, 2.0*vec4 (0.55, 0.6, 0.8, 1.0), (1.0 - smoothstep(0.3,0.8, scattering))));   
+
+
+
+
+  //gl_FrontColor = gl_LightSource[0].diffuse * shade + gl_FrontLightModelProduct.sceneColor;
+  gl_FrontColor = light_diffuse * shade + gl_FrontLightModelProduct.sceneColor;
+
+  // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out.
+  gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1.0 - smoothstep(range*0.9, range, fogCoord));
+  //gl_BackColor = gl_FrontColor;
+
+ // Fog doesn't affect clouds as much as other objects.
+  float fadeScale = 0.05 + 0.2 * log(fogCoord/1000.0);
+  if (fadeScale < 0.05) fadeScale = 0.05;
+  fogFactor = exp( -gl_Fog.density * fogCoord * fadeScale);
+
+
+  // Fog doesn't affect clouds as much as other objects.
+  //fogFactor = exp( -gl_Fog.density * fogCoord * 0.5);
+  //fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+// haze of ground haze shader is slightly bluish
+  //hazeColor = vec3 (gl_LightSource[0].diffuse.x, gl_LightSource[0].diffuse.y, gl_LightSource[0].diffuse.z);
+  hazeColor = light_diffuse.xyz;
+  hazeColor.x = hazeColor.x * 0.83;
+  hazeColor.y = hazeColor.y * 0.9; 
+  hazeColor = hazeColor * scattering;
+
+  // in sunset or sunrise conditions, do extra shading of clouds
+  
+  // two times terminator width governs how quickly light fades into shadow
+  float terminator_width = 200000.0;
+  float earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
+
+  // change haze color to blue hue for strong fogging
+  intensity = length(hazeColor);
+  hazeColor = intensity * normalize(mix(hazeColor,  2.0* vec3 (0.55, 0.6, 0.8), (1.0 - smoothstep(0.3,0.8,scattering)))); 	
+  
+
+  	hazeColor = hazeColor * earthShade;
+  	gl_FrontColor.xyz = gl_FrontColor.xyz * earthShade;
+  	gl_BackColor = gl_FrontColor;
+}
diff --git a/Shaders/cloud-static-lightfield.frag b/Shaders/cloud-static-lightfield.frag
new file mode 100644
index 000000000..1c84c0a47
--- /dev/null
+++ b/Shaders/cloud-static-lightfield.frag
@@ -0,0 +1,12 @@
+uniform sampler2D baseTexture;
+varying float fogFactor;
+
+varying vec3 hazeColor;
+
+void main(void)
+{
+      vec4 base = texture2D( baseTexture, gl_TexCoord[0].st);
+      vec4 finalColor = base * gl_Color;
+      gl_FragColor.rgb = mix(hazeColor, finalColor.rgb, fogFactor );
+      gl_FragColor.a = mix(0.0, finalColor.a, 1.0 - 0.5 * (1.0 - fogFactor));
+}
diff --git a/Shaders/cloud-static-lightfield.vert b/Shaders/cloud-static-lightfield.vert
new file mode 100644
index 000000000..1efb10a4e
--- /dev/null
+++ b/Shaders/cloud-static-lightfield.vert
@@ -0,0 +1,119 @@
+// -*-C++-*-
+#version 120
+
+varying float fogFactor;
+varying vec3 hazeColor;
+
+uniform float terminator;
+uniform float altitude;
+
+const float shade = 1.0;
+const float cloud_height = 1000.0;
+const float EarthRadius = 5800000.0;
+
+// light_func is a generalized logistic function fit to the light intensity as a function
+// of scaled terminator position obtained from Flightgear core
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+x = x-0.5;
+
+// use the asymptotics to shorten computations
+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 main(void)
+{	
+
+  gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+  //gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0);
+  vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
+  vec4 l  = gl_ModelViewMatrixInverse * vec4(0.0,0.0,1.0,1.0);
+  vec3 u = normalize(ep.xyz - l.xyz);
+
+  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+  gl_Position.x = gl_Vertex.x;
+  gl_Position.y += gl_Vertex.y;
+  gl_Position.z += gl_Vertex.z;
+  gl_Position.xyz += gl_Color.xyz;
+
+
+  // Determine a lighting normal based on the vertex position from the
+  // center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker.
+  float n = dot(normalize(-gl_LightSource[0].position.xyz),
+                normalize(mat3x3(gl_ModelViewMatrix) * (- gl_Position.xyz)));;
+
+  // Determine the position - used for fog and shading calculations
+  vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position);
+  float fogCoord = abs(ecPosition.z);
+  float fract = smoothstep(0.0, cloud_height, gl_Position.z + cloud_height);
+
+  vec3 relVector = gl_Position.xyz - ep.xyz;
+  gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
+
+ // Light at the final position
+
+ // first obtain normal to sun position
+
+  vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
+  vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
+
+ // yprime is the distance of the vertex into sun direction, corrected for altitude
+  //float vertex_alt = max(altitude * 0.30480 + relVector.z,100.0); 
+  float vertex_alt = altitude + relVector.z; 
+  float yprime = -dot(relVector, lightHorizon);
+  float yprime_alt = yprime -sqrt(2.0 * EarthRadius * vertex_alt);
+
+  // compute the light at the position
+  vec4 light_diffuse;
+  
+  float lightArg = (terminator-yprime_alt)/100000.0;
+
+  light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 2.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 = 0.0;
+
+
+// Determine the shading of the sprite based on its vertical position and position relative to the sun.
+  n = min(smoothstep(-0.5, 0.0, n), fract);
+// Determine the shading based on a mixture from the backlight to the front
+  vec4 backlight = light_diffuse * shade;
+
+  gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);
+  gl_FrontColor += gl_FrontLightModelProduct.sceneColor;
+
+  // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out.
+  gl_FrontColor.a = min(smoothstep(100.0, 250.0, fogCoord), 1.0 - smoothstep(70000.0, 75000.0, fogCoord));
+
+  // Fog doesn't affect rain as much as other objects.
+  //fogFactor = exp( -gl_Fog.density * fogCoord * 0.4);
+  //fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+float fadeScale = 0.05 + 0.2 * log(fogCoord/1000.0);
+  if (fadeScale < 0.05) fadeScale = 0.05;
+  fogFactor = exp( -gl_Fog.density * fogCoord * fadeScale);
+
+  hazeColor = light_diffuse.xyz;
+  hazeColor.x = hazeColor.x * 0.83;
+  hazeColor.y = hazeColor.y * 0.9; 
+
+ // in sunset or sunrise conditions, do extra shading of clouds
+  
+  	
+
+  // two times terminator width governs how quickly light fades into shadow
+  float terminator_width = 200000.0;
+
+  // now dim the light
+  float earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
+
+  hazeColor = hazeColor * earthShade;
+  gl_FrontColor.xyz = gl_FrontColor.xyz * earthShade;
+  gl_BackColor = gl_FrontColor;
+
+}
diff --git a/Shaders/rain-layer-lightfield.frag b/Shaders/rain-layer-lightfield.frag
new file mode 100644
index 000000000..000da97c8
--- /dev/null
+++ b/Shaders/rain-layer-lightfield.frag
@@ -0,0 +1,12 @@
+uniform sampler2D baseTexture;
+varying float fogFactor;
+
+varying vec3 hazeColor;
+
+void main(void)
+{
+      vec4 base = texture2D( baseTexture, gl_TexCoord[0].st);
+      vec4 finalColor = base * gl_Color;
+      gl_FragColor.rgb = mix(hazeColor, finalColor.rgb, fogFactor );
+      gl_FragColor.a = mix(0.0, finalColor.a, fogFactor);
+}
diff --git a/Shaders/rain-layer-lightfield.vert b/Shaders/rain-layer-lightfield.vert
new file mode 100644
index 000000000..b212a867a
--- /dev/null
+++ b/Shaders/rain-layer-lightfield.vert
@@ -0,0 +1,122 @@
+// -*-C++-*-
+#version 120
+
+varying float fogFactor;
+varying vec3 hazeColor;
+
+uniform float range; // From /sim/rendering/clouds3d-vis-range
+uniform float scattering;
+uniform float terminator;
+uniform float altitude;
+
+
+float shade = 0.8;
+float cloud_height = 1000.0;
+const float EarthRadius = 5800000.0;
+
+// light_func is a generalized logistic function fit to the light intensity as a function
+// of scaled terminator position obtained from Flightgear core
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+x = x-0.5;
+return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
+}
+
+void main(void)
+{	
+
+  gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+  //gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0);
+  vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
+  vec4 l  = gl_ModelViewMatrixInverse * vec4(0.0,0.0,1.0,1.0);
+  vec3 u = normalize(ep.xyz - l.xyz);
+
+  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+  gl_Position.x = gl_Vertex.x;
+  gl_Position.y += gl_Vertex.y;
+  gl_Position.z += gl_Vertex.z;
+  gl_Position.xyz += gl_Color.xyz;
+
+
+
+  // Determine a lighting normal based on the vertex position from the
+  // center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker.
+  float n = dot(normalize(-gl_LightSource[0].position.xyz),
+                normalize(mat3x3(gl_ModelViewMatrix) * (- gl_Position.xyz)));;
+
+  // Determine the position - used for fog and shading calculations
+  vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position);
+  float fogCoord = abs(ecPosition.z);
+  float fract = smoothstep(0.0, cloud_height, gl_Position.z + cloud_height);
+
+  vec3 relVector = gl_Position.xyz - ep.xyz;
+  gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
+
+
+// Light at the final position
+
+ // first obtain normal to sun position
+
+  vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
+  vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
+
+ // yprime is the distance of the vertex into sun direction, corrected for altitude
+  float vertex_alt = max(altitude * 0.30480 + relVector.z,100.0); 
+  float yprime = -dot(relVector, lightHorizon);
+  float yprime_alt = yprime -sqrt(2.0 * EarthRadius * vertex_alt);
+
+  // compute the light at the position
+  vec4 light_diffuse;
+  
+  float lightArg = (terminator-yprime_alt)/100000.0;
+
+  light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 2.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 = 0.0;
+  
+  //light_diffuse = light_diffuse * scattering;
+  float intensity = length(light_diffuse);
+  light_diffuse = intensity * normalize(mix(light_diffuse, 2.0*vec4 (0.55, 0.6, 0.8, 1.0), (1.0 - smoothstep(0.3,0.8, scattering))));   
+
+// Determine the shading of the sprite based on its vertical position and position relative to the sun.
+  n = min(smoothstep(-0.5, 0.0, n), fract);
+// Determine the shading based on a mixture from the backlight to the front
+  vec4 backlight = gl_LightSource[0].diffuse * shade;
+
+  gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);
+  gl_FrontColor += gl_FrontLightModelProduct.sceneColor;
+
+  // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out.
+  gl_FrontColor.a = min(smoothstep(100.0, 250.0, fogCoord), 1.0 - smoothstep(range*0.9, range, fogCoord));
+  gl_BackColor = gl_FrontColor;
+
+  // Fog doesn't affect rain as much as other objects.
+  //fogFactor = exp( -gl_Fog.density * fogCoord * 0.4);
+  //fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+float fadeScale = 0.05 + 0.2 * log(fogCoord/1000.0);
+  if (fadeScale < 0.05) fadeScale = 0.05;
+  fogFactor = exp( -gl_Fog.density * 1.0 * fogCoord * fadeScale);
+
+  hazeColor = light_diffuse.xyz;
+  hazeColor.x = hazeColor.x * 0.83;
+  hazeColor.y = hazeColor.y * 0.9; 
+  hazeColor = hazeColor * scattering;
+
+// change haze color to blue hue for strong fogging
+  intensity = length(hazeColor);
+  hazeColor = intensity * normalize(mix(hazeColor,  2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,scattering)))); 
+
+ // two times terminator width governs how quickly light fades into shadow
+  float terminator_width = 200000.0;
+
+  // now dim the light
+  float earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
+
+  hazeColor = hazeColor * earthShade;
+  gl_FrontColor.xyz = gl_FrontColor.xyz * earthShade;
+  gl_BackColor = gl_FrontColor;
+
+}
diff --git a/Shaders/skydome.frag b/Shaders/skydome.frag
index c50309fc5..a65f5e5d9 100644
--- a/Shaders/skydome.frag
+++ b/Shaders/skydome.frag
@@ -7,8 +7,21 @@
 varying vec3 rayleigh;
 varying vec3 mie;
 varying vec3 eye;
-varying float ct;
- 
+varying vec3 hazeColor;
+varying float ct;
+//varying float cosphi;
+varying float delta_z;
+varying float alt;
+varying float earthShade;
+ 
+uniform float overcast;
+uniform float saturation;
+uniform float visibility;
+uniform float avisibility;
+uniform float scattering;
+
+const float EarthRadius = 5800000.0;
+
 float miePhase(in float cosTheta, in float g)
 {
   float g2 = g*g;
@@ -32,36 +45,154 @@ void main()
 {
   float cosTheta = dot(normalize(eye), gl_LightSource[0].position.xyz);
  
+  // position of the horizon line
+
+  float lAltitude = alt + delta_z;
+  float radiusEye = EarthRadius + alt;
+  float radiusLayer = EarthRadius + lAltitude;
+  float cthorizon;
+  float ctterrain;
+
+  if (radiusEye > radiusLayer) cthorizon = -sqrt(radiusEye * radiusEye - radiusLayer * radiusLayer)/radiusEye;
+  else cthorizon = sqrt(radiusLayer * radiusLayer - radiusEye * radiusEye)/radiusLayer;
+
+  ctterrain = -sqrt(radiusEye * radiusEye - EarthRadius * EarthRadius)/radiusEye;
 
   vec3 color = rayleigh * rayleighPhase(cosTheta);
   color += mie * miePhase(cosTheta, -0.8);
 
-  vec3 white = vec3(1.0,1.0,1.0);
-
-
-  //float scale = dot(normalize(white),normalize(color));
-  //float scale1 = 1.0 - exp(-5.0 * length(color));
-  //float scale2 = length(color)/length(white);	
-
-  //if (scale1>1.0) color = color/scale1;
-	
-  //color = color/scale1;
-
+  vec3 black = vec3(0.0,0.0,0.0);
 
   
-  if (color.x > 0.8) color.x = 0.8 + 0.8* log(color.x/0.8);
-  if (color.y > 0.8) color.y = 0.8 + 0.8* log(color.y/0.8);
-  if (color.z > 0.8) color.z = 0.8 + 0.8* log(color.z/0.8);
+  float ovc = overcast;
 
-   vec3 fogColor = vec3 (gl_Fog.color.x, gl_Fog.color.y, gl_Fog.color.z);
 
- 
-  if (ct > -0.03) color = mix(color, fogColor ,smoothstep(0.2, -0.2, ct));
-   else color = mix (color, fogColor, smoothstep(0.2,-0.2,-0.03));
+
+  float sat = 1.0 - ((1.0 - saturation) * 2.0);
+  if (sat < 0.3) sat = 0.3;
+
+
+ // float wscale = 1.732;
   
+// an overexposure filter, the log() seems to be pretty expensive though
 
- 
+//  if (color.x > 0.8) color.x = 0.8 + 0.8* log(color.x/0.8);
+//  if (color.y > 0.8) color.y = 0.8 + 0.8* log(color.y/0.8);
+//  if (color.z > 0.8) color.z = 0.8 + 0.8* log(color.z/0.8);
+
+//vec3 fogColor = vec3 (gl_Fog.color.x, gl_Fog.color.y, gl_Fog.color.z);
+    
+  
+// reduce the whiteout near the horizon generated by the single scattering approximation
+
+if (ct > cthorizon) color = mix(color, black ,smoothstep(0.2+cthorizon, -0.2+cthorizon, ct));
+else color = mix (color, black, smoothstep(0.2+cthorizon,-0.2+cthorizon,  cthorizon));
+
+
+
+
+// fog computations for a ground haze layer, extending from zero to lAltitude
+
+
+
+float transmission;
+float vAltitude;
+float delta_zv;
+
+float costheta = ct;
+
+float vis= visibility;
+
+// hack - in an effect volume the visibility only may be reduced, so we take care here
+if (avisibility < visibility){vis = avisibility;}
+
+ if (delta_z > 0.0) // we're inside the layer
+	{
+  	if (costheta>0.0 + ctterrain) // looking up, view ray intersecting upper layer edge
+		{
+		transmission  = exp(-min((delta_z/max(costheta,0.1)),25000.0)/vis);
+		//transmission = 1.0;
+		vAltitude = min(vis * costheta, delta_z);
+  		delta_zv = delta_z - vAltitude;
+		}
+
+	else // looking down, view range intersecting terrain (which may not be drawn)
+		{
+		transmission = exp(alt/vis/costheta);
+		vAltitude = min(-vis * costheta, alt);
+  		delta_zv = delta_z + vAltitude;
+		}
+	}
+  else // we see the layer from above
+	{	
+	if (costheta < 0.0 + cthorizon) 
+		{
+		transmission = exp(-min(lAltitude/abs(costheta),25000.0)/vis);
+		transmission = transmission * exp(-alt/avisibility/abs(costheta));
+		transmission = 1.0 - (1.0 - transmission) * smoothstep(0+cthorizon, -0.02+cthorizon, costheta);
+   		vAltitude = min(lAltitude, -vis * costheta);
+		delta_zv = vAltitude; 
+		}
+	else
+		{	
+		transmission = 1.0;
+		delta_zv = 0.0;
+		}
+	}
+
+// combined intensity reduction by cloud shading and fog self-shading, corrected for Weber-Fechner perception law
+
+float eqColorFactor;
+	eqColorFactor = 1.0 - 0.1 * delta_zv/vis - (1.0 -scattering);
+
+
+
+
+
+// there's always residual intensity, we should never be driven to zero
+if (eqColorFactor < 0.2) eqColorFactor = 0.2;
+
+
+// postprocessing of haze color
+vec3 hColor = hazeColor;
+
+// high altitude desaturation
+float intensity = length(hColor);
+hColor = intensity * normalize (mix(hColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));
+
+// blue hue
+hColor.x = 0.83 * hColor.x;
+hColor.y = 0.9 * hColor.y;
+
+
+
+// further blueshift when in shadow, either cloud shadow, or self-shadow or Earth shadow, dependent on indirect 
+// light
+
+float fade_out = max(0.65 - 0.3 *overcast, 0.45);
+intensity = length(hColor);
+hColor = intensity * normalize(mix(hColor,  1.5* vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.25, fade_out,earthShade) ));
+hColor = intensity * normalize(mix(hColor,  2.0 * vec3 (0.55, 0.6, 0.8), (1.0 - smoothstep(0.3,0.8,eqColorFactor)))); 
+hColor = hColor * earthShade;
+
+// accounting for overcast and saturation 
+
+
+color = ovc *  mix(color, hazeColor * earthShade ,smoothstep(-0.1+ctterrain, 0.0+ctterrain, ct)) + (1-ovc) * color;
+color = sat * color + (1.0 - sat) * mix(color, black, smoothstep(0.4+cthorizon,0.2+cthorizon,ct));
+
+
+// the terrain below the horizon gets drawn in one optical thickness
+vec3 terrainHazeColor = eqColorFactor * hColor;	
+color = mix(color, terrainHazeColor ,smoothstep(0.01 + ctterrain, 0.0+ctterrain, ct));
+
+// mix fog the skydome with the right amount of haze
+
+color = transmission * color  + (1.0-transmission) * eqColorFactor * hColor;
+
+
   gl_FragColor = vec4(color, 1.0);
-  gl_FragDepth = 0.1;
+  gl_FragDepth = 0.1;
+
 }
 
diff --git a/Shaders/skydome.vert b/Shaders/skydome.vert
index 5c3505f01..58219e6e6 100644
--- a/Shaders/skydome.vert
+++ b/Shaders/skydome.vert
@@ -6,19 +6,30 @@
  
  
 uniform mat4 osg_ViewMatrix;
-uniform mat4 osg_ViewMatrixInverse;
- 
+uniform mat4 osg_ViewMatrixInverse;
+uniform float hazeLayerAltitude;
+uniform float terminator;
+uniform float avisibility;
+uniform float visibility;
+uniform float terrain_alt; 
+
 varying vec3 rayleigh;
 varying vec3 mie;
 varying vec3 eye;
-varying float ct;
- 
+varying vec3 hazeColor;
+varying float ct;
+//varying float cosphi;
+varying float delta_z;
+varying float alt; 
+varying float earthShade;
+
 // Dome parameters from FG and screen
 const float domeSize = 80000.0;
 const float realDomeSize = 100000.0;
 const float groundRadius = 0.984503332 * domeSize;
 const float altitudeScale = domeSize - groundRadius;
- 
+const float EarthRadius = 5800000.0; 
+
 // Dome parameters when calculating scattering
 // Assuming dome size is 5.0
 const float groundLevel = 0.984503332 * 5.0;
@@ -35,7 +46,22 @@ uniform float density = 0.5; //1.0
 vec3 rayleighK = rK * vec3(5.602, 7.222, 19.644);
 vec3 mieK = vec3(mK);
 vec3 sunIntensity = 10.0*vec3(120.0, 125.0, 130.0);
- 
+ 
+// light_func is a generalized logistic function fit to the light intensity as a function
+// of scaled terminator position obtained from Flightgear core
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+x = x - 0.5;
+
+// use the asymptotics to shorten computations
+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));
+}
+
+
 // Find intersections of ray to skydome
 // ray must be normalized
 // cheight is camera height
@@ -51,7 +77,6 @@ float intersection (in float cheight, in vec3 ray, in float rad2)
 float outscatterscale(in float costheta)
 {
 
-  if (costheta < -0.12) costheta = -0.12 - 4.0* (costheta+0.12) ;
 
   float x = 1.0 - costheta;
  
@@ -89,7 +114,12 @@ void main()
     // Make it so that 0.0 is ground level and 1.0 is 100km (space) level
     float altitude = distance(groundPoint, vec4(0.0, 0.0, 0.0, 1.0));
     float scaledAltitude = altitude / realDomeSize;
- 
+
+    // the local horizon angle
+    float radiusEye = EarthRadius + altitude;
+    float ctterrain = -sqrt(radiusEye * radiusEye - EarthRadius * EarthRadius)/radiusEye; 
+
+
     // Camera's position, z is up!
     float cameraRealAltitude = groundLevel + heightScale*scaledAltitude;
     vec3 camera = vec3(0.0, 0.0, cameraRealAltitude);
@@ -110,21 +140,27 @@ void main()
     vec3 lightDirection = gl_LightSource[0].position.xyz;
  
     // Cos theta of camera's position and sample point
-    // Since camera is 0,0,z, dot porduct is just the z coordinate
+    // Since camera is 0,0,z, dot product is just the z coordinate
     float cameraCosTheta;
  
     // If sample is above camera, reverse ray direction
     if(positionDelta.z < 0.0) cameraCosTheta = -positionDelta.z / deltaLength;
     else cameraCosTheta = positionDelta.z / deltaLength;
  
+    
     float cameraCosTheta1 = -positionDelta.z / deltaLength;
+
 
     // Total attenuation from camera to skydome
     float totalCameraScatter = outscatter(cameraCosTheta, scaledAltitude);
  
  
-    // Do numerical integration of scsattering function from skydome to camera
-    vec3 color = vec3(0.0);
+    // Do numerical integration of scattering function from skydome to camera
+    vec3 color = vec3(0.0);
+
+    // no scattering integrations where terrain is later drawn
+    if (cameraCosTheta1 > (ctterrain-0.05))
+    {
     for(int i = 0; i < nSamples; i++) 
     {
       // Altitude of the sample point 0...1
@@ -158,24 +194,98 @@ void main()
       color += inScatter * deltaLength;
       sample += positionDelta;
     }
- 
+    }
     color *= sunIntensity;
     ct = cameraCosTheta1;
     rayleigh = rayleighK * color;
     mie = mieK * color;
     eye = gl_NormalMatrix * positionDelta;
  
-   
- 
- 
-    // We need to move the camera so that the dome appears to be centered around earth
+
+   // We need to move the camera so that the dome appears to be centered around earth
     // to make the dome render correctly!
     float moveDown = -altitude; // Center dome on camera
     moveDown += groundRadius;
     moveDown += scaledAltitude * altitudeScale; // And move correctly according to altitude
  
     // Vertex transformed correctly so that at 100km we are at space border
-    vec4 finalVertex = realVertex - vec4(0.0, 0.0, 1.0, 0.0) * moveDown;
+    vec4 finalVertex = realVertex - vec4(0.0, 0.0, 1.0, 0.0) * moveDown;
+
+    // prepare some stuff for a ground haze layer
+  
+    delta_z = hazeLayerAltitude - altitude;
+    alt = altitude;
+    
+
+    // establish coordinates relative to sun position
+    vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
+    vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
+    vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0) );
+ 
+
+    vec3 relVector = normalize(finalVertex.xyz - ep.xyz);
+    
+    // and compute the twilight shading
+    
+
+    // yprime is the coordinate from/towards terminator
+    float yprime;
+	
+    if (alt > hazeLayerAltitude) // we're looking from above and can see far
+	{
+    	if (ct < 0.0)
+    		{
+		yprime = -dot(relVector,lightHorizon) * altitude/-(ct-0.001);
+		yprime = yprime -sqrt(2.0 * EarthRadius * hazeLayerAltitude);
+		}
+   	 else  // the only haze we see looking up is overcast, assume its altitude
+		{
+		yprime = -dot(relVector,lightHorizon) * avisibility; 
+		yprime = yprime -sqrt(2.0 * EarthRadius * 10000.0);
+		}
+	}
+     else 
+	{yprime = -dot(relVector,lightHorizon) * avisibility;
+	yprime = yprime -sqrt(2.0 * EarthRadius * hazeLayerAltitude);
+	}
+
+    if (terminator > 1000000.0){yprime = -sqrt(2.0 * EarthRadius * hazeLayerAltitude);}
+
+    //float edgeAlt = max(hazeLayerAltitude - (alt-terrain_alt)/avisibility * visibility, terrain_alt);
+    
+    //yprime = yprime -sqrt(2.0 * EarthRadius * edgeAlt);
+
+    float terminator_width = 200000.0;
+    earthShade = 0.9 * smoothstep((terminator_width+ terminator), (-terminator_width + terminator), yprime) + 0.1;
+
+
+//hazeColor = vec3 (gl_LightSource[0].diffuse.x, gl_LightSource[0].diffuse.y, gl_LightSource[0].diffuse.z);
+
+    //hazeColor.x = hazeColor.x * 0.83;
+    //hazeColor.y = hazeColor.y * 0.9;  
+
+     float lightArg = (terminator-yprime)/100000.0;
+     vec4 light_diffuse;
+     light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 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 = 0.0;
+     hazeColor = light_diffuse.xyz;
+
+     float intensity = length(hazeColor.xyz);
+     float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator -sqrt(2.0 * EarthRadius * terrain_alt)); 
+     float mie_angle = (0.5 *  dot(normalize(relVector), normalize(lightFull)) ) + 0.5;
+     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 - would be best here this causes a box-like bug for some reason
+// so it moved to the fragment shader where it has no issues
+
+//float intensity = length(hazeColor.xyz);
+//hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.8* smoothstep(5000.0, 50000.0, alt)));
+
+    
+
     // Transform
     gl_Position = gl_ModelViewProjectionMatrix * finalVertex;
 }
diff --git a/Shaders/terrain-haze.frag b/Shaders/terrain-haze.frag
new file mode 100644
index 000000000..bf14090b9
--- /dev/null
+++ b/Shaders/terrain-haze.frag
@@ -0,0 +1,285 @@
+// -*-C++-*-
+
+// 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;
+
+//varying vec3 hazeColor;
+//varying float fogCoord;
+
+uniform sampler2D texture;
+
+//varying float ct;
+//varying float delta_z;
+//varying float alt;
+
+varying float earthShade;
+//varying float yprime;
+//varying float vertex_alt;
+varying float yprime_alt;
+varying float mie_angle;
+
+
+uniform float visibility;
+uniform float avisibility;
+uniform float scattering;
+uniform float terminator;
+uniform float terrain_alt; 
+uniform float hazeLayerAltitude;
+uniform float overcast;
+//uniform float altitude;
+uniform float eye_alt;
+
+const float EarthRadius = 5800000.0;
+const float terminator_width = 200000.0;
+
+float alt;
+
+float luminance(vec3 color)
+{
+    return dot(vec3(0.212671, 0.715160, 0.072169), color);
+}
+
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+x = x - 0.5;
+
+// use the asymptotics to shorten computations
+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));
+}
+
+// this determines how light is attenuated in the distance
+// physically this should be exp(-arg) but for technical reasons we use a sharper cutoff
+// for distance > visibility
+
+float fog_func (in float targ)
+{
+
+
+float fade_mix;
+
+// for large altitude > 30 km, we switch to some component of quadratic distance fading to
+// create the illusion of improved visibility range
+
+targ = 1.25 * targ; // need to sync with the distance to which terrain is drawn
+
+
+if (alt < 30000.0)
+	{return exp(-targ - targ * targ * targ * targ);}
+else if (alt < 50000.0)
+	{
+	fade_mix = (alt - 30000.0)/20000.0;
+	return fade_mix * exp(-targ*targ - pow(targ,4.0)) + (1.0 - fade_mix) * exp(-targ - pow(targ,4.0));	
+	}
+else 
+	{
+	return exp(- targ * targ - pow(targ,4.0));
+	}
+
+}
+
+void main()
+{
+
+// 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 fragColor;
+    vec4 specular = vec4(0.0);
+    float intensity;
+
+
+
+    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) {
+        color += diffuse_term * NdotL;
+        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));
+    }
+    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);
+    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);
+
+
+if (dist > 40.0)
+{
+
+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;
+		//lambda = visibility;
+		vAltitude = min(distance_in_layer,visibility) * 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;}
+		//lambda = visibility;
+		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 -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 -scattering);
+	}
+
+
+transmission =  fog_func(transmission_arg);
+
+// 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;
+
+hazeColor.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
+hazeColor.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
+hazeColor.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
+
+
+// now dim the light for haze
+earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
+
+// Mie-like factor
+
+if (lightArg < 5.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* vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.25, fade_out,earthShade) )); 
+
+// change haze color to blue hue for strong fogging
+//intensity = length(hazeColor);
+hazeColor = intensity * normalize(mix(hazeColor,  2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,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));
+
+
+// determine the right mix of transmission and haze
+
+//fragColor.xyz = transmission * fragColor.xyz + (1.0-transmission)  * eqColorFactor * hazeColor * earthShade;
+
+fragColor.xyz = mix(eqColorFactor * hazeColor * earthShade, fragColor.xyz,transmission);
+
+gl_FragColor = fragColor;
+
+}
+else // if dist < 40.0 no fogging at all 
+{
+gl_FragColor = fragColor;
+}
+
+}
+
diff --git a/Shaders/terrain-haze.vert b/Shaders/terrain-haze.vert
new file mode 100644
index 000000000..f1cd4732d
--- /dev/null
+++ b/Shaders/terrain-haze.vert
@@ -0,0 +1,233 @@
+// -*-C++-*-
+
+// Shader that uses OpenGL state values to do per-pixel lighting
+//
+// The only light used is gl_LightSource[0], which is assumed to be
+// directional.
+//
+// Diffuse colors come from the gl_Color, ambient from the material. This is
+// equivalent to osg::Material::DIFFUSE.
+// Haze part added by Thorsten Renk, Oct. 2011
+
+
+#define MODE_OFF 0
+#define MODE_DIFFUSE 1
+#define MODE_AMBIENT_AND_DIFFUSE 2
+
+// The constant term of the lighting equation that doesn't depend on
+// the surface normal is passed in gl_{Front,Back}Color. The alpha
+// component is set to 1 for front, 0 for back in order to work around
+// bugs with gl_FrontFacing in the fragment shader.
+varying vec4 diffuse_term;
+varying vec3 normal;
+varying vec3 relPos;
+
+varying float earthShade;
+//varying float yprime;
+//varying float vertex_alt;
+varying float yprime_alt;
+varying float mie_angle;
+
+
+
+
+uniform int colorMode;
+uniform float hazeLayerAltitude;
+uniform float terminator;
+uniform float terrain_alt; 
+uniform float avisibility;
+uniform float visibility;
+uniform float overcast;
+uniform float scattering;
+
+
+// This is the value used in the skydome scattering shader - use the same here for consistency?
+const float EarthRadius = 5800000.0;
+const float terminator_width = 200000.0;
+
+float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
+{
+//x = x - 0.5;
+
+// use the asymptotics to shorten computations
+if (x < -15.0) {return 0.0;}
+
+return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
+}
+
+
+void main()
+{
+
+  vec4 light_diffuse;
+  vec4 light_ambient;
+
+  //float yprime_alt;
+  float yprime;
+  float lightArg;
+  float intensity;
+  float vertex_alt;
+
+// this code is copied from default.vert
+
+    //vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
+    gl_Position = ftransform();
+    gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+    normal = gl_NormalMatrix * gl_Normal;
+    vec4 ambient_color, diffuse_color;
+    if (colorMode == MODE_DIFFUSE) {
+        diffuse_color = gl_Color;
+        ambient_color = gl_FrontMaterial.ambient;
+    } else if (colorMode == MODE_AMBIENT_AND_DIFFUSE) {
+        diffuse_color = gl_Color;
+        ambient_color = gl_Color;
+    } else {
+        diffuse_color = gl_FrontMaterial.diffuse;
+        ambient_color = gl_FrontMaterial.ambient;
+    }
+   
+    
+
+    // here start computations for the haze layer
+    // we need several geometrical quantities
+
+    // first current altitude of eye position in model space
+    vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
+    
+    // and relative position to vector
+    relPos = gl_Vertex.xyz - ep.xyz;
+
+    // unfortunately, we need the distance in the vertex shader, although the more accurate version
+    // is later computed in the fragment shader again
+    float dist = length(relPos);
+ 
+    // branch dependent on daytime
+
+if (terminator < 1000000.0) // the full, sunrise and sunset computation
+{
+    // altitude of the vertex in question, somehow zero leads to artefacts, so ensure it is at least 100m
+    vertex_alt = max(gl_Vertex.z,100.0);
+
+    // establish coordinates relative to sun position
+
+    vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
+    vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
+  
+
+    
+    // yprime is the distance of the vertex into sun direction
+    yprime = -dot(relPos, lightHorizon);
+
+    // this gets an altitude correction, higher terrain gets to see the sun earlier
+    yprime_alt = yprime - sqrt(2.0 * EarthRadius * vertex_alt);
+
+    // two times terminator width governs how quickly light fades into shadow
+    // now the light-dimming factor
+    earthShade = 0.6 * (1.0 - smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt)) + 0.4;
+  
+   // parametrized version of the Flightgear ground lighting function
+    lightArg = (terminator-yprime_alt)/100000.0;
+
+    // directional scattering for low sun
+    if (lightArg < 5.0)
+    	{mie_angle = (0.5 *  dot(normalize(relPos), normalize(lightFull)) ) + 0.5;}
+    else 
+	{mie_angle = 1.0;}
+
+
+   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 = 0.0;
+   light_diffuse = light_diffuse * scattering;
+
+   light_ambient.b = light_func(lightArg, 0.000506, 0.131, -3.315, 0.000457, 0.5);
+   light_ambient.g = light_func(lightArg, 2.264e-05, 0.134, 0.967, 3.66e-05, 0.4);
+   light_ambient.r = light_func(lightArg, 0.236, 0.253, 1.073, 0.572, 0.33);
+   light_ambient.a = 0.0;
+
+
+
+
+// correct ambient light intensity and hue before sunrise
+if (earthShade < 0.5)
+	{
+	light_ambient = light_ambient * (0.4 + 0.6 * smoothstep(0.2, 0.5, earthShade));
+	intensity = length(light_ambient.xyz); 
+
+	light_ambient.xyz = intensity * normalize(mix(light_ambient.xyz,  vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.1, 0.5,earthShade) ));
+
+	intensity = length(light_diffuse.xyz); 
+	light_diffuse.xyz = intensity * normalize(mix(light_diffuse.xyz,  vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.1, 0.5,earthShade) ));
+	}
+
+
+// the haze gets the light at the altitude of the haze top if the vertex in view is below
+// but the light at the vertex if the vertex is above
+
+vertex_alt = max(vertex_alt,hazeLayerAltitude);
+
+if (vertex_alt > hazeLayerAltitude)
+	{
+	if (dist > 0.8 * avisibility)
+		{
+		vertex_alt = mix(vertex_alt, hazeLayerAltitude, smoothstep(0.8*avisibility, avisibility, dist));
+		yprime_alt = yprime -sqrt(2.0 * EarthRadius * vertex_alt);
+		}
+	}
+else
+	{
+	vertex_alt = hazeLayerAltitude;
+	yprime_alt = yprime -sqrt(2.0 * EarthRadius * vertex_alt);
+	}
+
+}
+else // the faster, full-day version without lightfields
+{
+    //vertex_alt = max(gl_Vertex.z,100.0);
+ 
+    earthShade = 1.0;
+    mie_angle = 1.0;
+    
+    if (terminator > 3000000.0)
+    	{light_diffuse = vec4 (1.0, 1.0, 1.0, 0.0);
+	light_ambient = vec4 (0.33, 0.4, 0.5, 0.0); }
+    else
+	{
+
+	lightArg = (terminator/100000.0 - 10.0)/20.0;
+	light_diffuse.b = 0.78  + lightArg * 0.21;
+	light_diffuse.g = 0.907 + lightArg * 0.091;
+	light_diffuse.r = 0.904 + lightArg * 0.092;
+	light_diffuse.a = 0.0;
+
+	light_ambient.b = 0.41 + lightArg * 0.08;
+	light_ambient.g = 0.333 + lightArg * 0.06;
+	light_ambient.r = 0.316 + lightArg * 0.016;
+	light_ambient.a = 0.0;
+	}  
+    
+    light_diffuse = light_diffuse * scattering;
+    yprime_alt = -sqrt(2.0 * EarthRadius * hazeLayerAltitude);
+
+
+}
+ 
+
+// default lighting based on texture and material using the light we have just computed
+
+ diffuse_term = diffuse_color* light_diffuse;
+    vec4 constant_term = gl_FrontMaterial.emission + ambient_color *
+        (gl_LightModel.ambient +  light_ambient);
+    // Super hack: if diffuse material alpha is less than 1, assume a
+    // transparency animation is at work
+    if (gl_FrontMaterial.diffuse.a < 1.0)
+        diffuse_term.a = gl_FrontMaterial.diffuse.a;
+    else
+        diffuse_term.a = gl_Color.a;
+    // Another hack for supporting two-sided lighting without using
+    // gl_FrontFacing in the fragment shader.
+    gl_FrontColor.rgb = constant_term.rgb;  gl_FrontColor.a = 1.0;
+    gl_BackColor.rgb = constant_term.rgb; gl_BackColor.a = 0.0;
+}
+
diff --git a/gui/dialogs/local_weather_tiles.xml b/gui/dialogs/local_weather_tiles.xml
index c21db9feb..9863855c4 100644
--- a/gui/dialogs/local_weather_tiles.xml
+++ b/gui/dialogs/local_weather_tiles.xml
@@ -399,7 +399,7 @@
 <text>
    <x>160</x>
    <y>100</y>
-   <label>30 km</label>
+   <label>20 km</label>
 </text>
 
 <slider>
@@ -407,9 +407,9 @@
    <y>100</y>
    <width>90</width>
    <height>20</height>
-   <min>30000.0</min>
-   <max>140000.0</max>
-   <property>/local-weather/config/max-vis-range-m</property>
+   <min>9.90348</min>
+   <max>12.429216196</max>
+   <property>/local-weather/config/aux-max-vis-range-m</property>
    <binding>
      <command>dialog-apply</command>
    </binding>
@@ -418,7 +418,17 @@
 <text>
    <x>330</x>
    <y>100</y>
-   <label>140 km</label>
+   <label>250 km</label>
+</text>
+
+
+<text>
+   <x>380</x>
+   <y>100</y>
+   <label>12345678</label>
+   <format>%.fm</format>
+   <live>true</live>
+   <property>/local-weather/config/max-vis-range-m</property>
 </text>