diff --git a/Effects/stars.eff b/Effects/stars.eff
index 648f3dbd9..e6e950016 100644
--- a/Effects/stars.eff
+++ b/Effects/stars.eff
@@ -4,7 +4,7 @@
   <name>Effects/stars</name>
 
   <parameters>
-    <max-radiance type="float">2.0</max-radiance>
+    <max-radiance type="float">50.0</max-radiance>
   </parameters>
 
   <!-- Fixed-pipeline fallback -->
@@ -20,6 +20,7 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
+      <!-- Disable depth testing -->
       <depth>
         <enabled>false</enabled>
       </depth>
@@ -28,21 +29,44 @@
         <function>equal</function>
         <value>0</value>
       </stencil>
+      <!-- Make sure we render after the skydome -->
+      <render-bin>
+        <bin-number>-9</bin-number>
+        <bin-name>RenderBin</bin-name>
+      </render-bin>
       <cull-face>off</cull-face>
+      <!-- Additive blending to add the sky in-scattering from the skydome -->
       <blend>
         <active>true</active>
-        <source>src-alpha</source>
-        <destination>one-minus-src-alpha</destination>
+        <source>one</source>
+        <destination>one</destination>
       </blend>
       <program>
         <vertex-shader>Shaders/HDR/stars.vert</vertex-shader>
         <fragment-shader>Shaders/HDR/stars.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
       </program>
       <uniform>
         <name>max_radiance</name>
         <type>float</type>
         <value><use>max-radiance</use></value>
       </uniform>
+      <uniform>
+        <name>transmittance_tex</name>
+        <type>sampler-2d</type>
+        <value type="int">12</value>
+      </uniform>
+      <!-- exposure.glsl -->
+      <uniform>
+        <name>lum_tex</name>
+        <type>sampler-2d</type>
+        <value type="int">14</value>
+      </uniform>
+      <uniform>
+        <name>exposure_compensation</name>
+        <type>float</type>
+        <value><use>exposure-compensation</use></value>
+      </uniform>
     </pass>
   </technique>
 </PropertyList>
diff --git a/Shaders/HDR/stars.frag b/Shaders/HDR/stars.frag
index ff56fb78b..ed0130ccc 100644
--- a/Shaders/HDR/stars.frag
+++ b/Shaders/HDR/stars.frag
@@ -4,11 +4,49 @@ layout(location = 0) out vec4 fragColor;
 
 in VS_OUT {
     vec4 color;
+    vec3 view_vector;
 } fs_in;
 
+uniform sampler2D transmittance_tex;
+
 uniform float max_radiance;
 
+uniform float fg_CameraDistanceToEarthCenter;
+uniform float fg_EarthRadius;
+uniform vec3 fg_CameraViewUp;
+
+const float ATMOSPHERE_RADIUS = 6471e3;
+
+// exposure.glsl
+vec3 apply_exposure(vec3 color);
+
 void main()
 {
-    fragColor = vec4(fs_in.color.rgb * max_radiance, fs_in.color.a);
+    vec3 color = fs_in.color.rgb * fs_in.color.a * max_radiance;
+
+    vec3 V = normalize(fs_in.view_vector);
+
+    // Apply aerial perspective
+    float normalized_altitude =
+        (fg_CameraDistanceToEarthCenter - fg_EarthRadius)
+        / (ATMOSPHERE_RADIUS - fg_EarthRadius);
+    float cos_theta = dot(-V, fg_CameraViewUp);
+
+    vec2 uv = vec2(cos_theta * 0.5 + 0.5, clamp(normalized_altitude, 0.0, 1.0));
+    vec4 transmittance = texture(transmittance_tex, uv);
+
+    // The proper thing would be to have spectral data for the stars' radiance.
+    // This could be approximated by taking the star's temperature and using
+    // Plank's law to obtain the spectral radiance for our 4 wavelengths.
+    // That's too complicated for now, so instead we just average the four
+    // spectral samples from the atmospheric transmittance.
+    color *= dot(transmittance, vec4(0.25));
+
+    // Pre-expose
+    color = apply_exposure(color);
+
+    // Final color = transmittance * star radiance + sky inscattering
+    // In this frag shader we output the multiplication part, and the sky
+    // in-scattering is added by doing additive blending on top of the skydome.
+    fragColor = vec4(color, 1.0);
 }
diff --git a/Shaders/HDR/stars.vert b/Shaders/HDR/stars.vert
index cca905cd2..fa3f02758 100644
--- a/Shaders/HDR/stars.vert
+++ b/Shaders/HDR/stars.vert
@@ -5,12 +5,15 @@ layout(location = 2) in vec4 vertex_color;
 
 out VS_OUT {
     vec4 color;
+    vec3 view_vector;
 } vs_out;
 
+uniform mat4 osg_ModelViewMatrix;
 uniform mat4 osg_ModelViewProjectionMatrix;
 
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
     vs_out.color = vertex_color;
+    vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
 }