diff --git a/Effects/galaxy.eff b/Effects/galaxy.eff
index cfde20b46..369c81aa8 100644
--- a/Effects/galaxy.eff
+++ b/Effects/galaxy.eff
@@ -161,7 +161,4 @@
-
- hdr-geometry
-
diff --git a/Effects/moon.eff b/Effects/moon.eff
new file mode 100644
index 000000000..5d903b979
--- /dev/null
+++ b/Effects/moon.eff
@@ -0,0 +1,122 @@
+
+
+
+ Effects/moon
+
+
+
+ Textures/Sky/moon_color.png
+ 2d
+ linear-mipmap-linear
+ linear-mipmap-linear
+ clamp-to-edge
+ clamp-to-edge
+ normalized
+
+
+ Textures/Sky/moon_n.png
+ 2d
+ linear-mipmap-linear
+ linear-mipmap-linear
+ clamp-to-edge
+ clamp-to-edge
+ normalized
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ hdr-forward
+
+
+
+ false
+
+
+
+ equal
+ 0
+
+
+
+ -5
+ RenderBin
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+ back
+
+
+ true
+
+ one
+
+
+ Shaders/HDR/moon.vert
+ Shaders/HDR/moon.frag
+ Shaders/HDR/math.glsl
+ Shaders/HDR/color.glsl
+ Shaders/HDR/normalmap.glsl
+ Shaders/HDR/atmos_spectral.glsl
+ Shaders/HDR/exposure.glsl
+
+
+ color_tex
+ sampler-2d
+ 1
+
+
+ normal_tex
+ sampler-2d
+ 2
+
+
+ transmittance_tex
+ sampler-2d
+ 12
+
+
+
+ lum_tex
+ sampler-2d
+ 14
+
+
+ exposure_compensation
+ float
+
+
+
+
+
diff --git a/Effects/stars.eff b/Effects/stars.eff
index 47a638642..648f3dbd9 100644
--- a/Effects/stars.eff
+++ b/Effects/stars.eff
@@ -3,6 +3,10 @@
Effects/stars
+
+ 2.0
+
+
@@ -13,7 +17,32 @@
-
- hdr-geometry
+
+ hdr-forward
+
+
+ false
+
+
+
+ equal
+ 0
+
+ off
+
+ true
+
+ one-minus-src-alpha
+
+
+ Shaders/HDR/stars.vert
+ Shaders/HDR/stars.frag
+
+
+ max_radiance
+ float
+
+
+
diff --git a/Shaders/HDR/bloom_downsample.frag b/Shaders/HDR/bloom_downsample.frag
index 67899eb67..647481c5f 100644
--- a/Shaders/HDR/bloom_downsample.frag
+++ b/Shaders/HDR/bloom_downsample.frag
@@ -77,8 +77,6 @@ void main()
kw4 * group4;
downsample /= kw_sum;
} else {
- // Apply weighted distribution:
- // 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1
downsample = e*0.125;
downsample += (a+c+g+i)*0.03125;
downsample += (b+d+f+h)*0.0625;
diff --git a/Shaders/HDR/moon.frag b/Shaders/HDR/moon.frag
new file mode 100644
index 000000000..de097f626
--- /dev/null
+++ b/Shaders/HDR/moon.frag
@@ -0,0 +1,69 @@
+#version 330 core
+
+layout(location = 0) out vec4 fragColor;
+
+in VS_OUT {
+ vec2 texcoord;
+ vec3 vertex_normal;
+ vec3 view_vector;
+} fs_in;
+
+uniform sampler2D color_tex;
+uniform sampler2D transmittance_tex;
+
+uniform vec3 fg_SunDirection;
+uniform float fg_CameraDistanceToEarthCenter;
+uniform float fg_EarthRadius;
+uniform vec3 fg_CameraViewUp;
+
+const float ATMOSPHERE_RADIUS = 6471e3;
+
+// math.glsl
+float M_1_PI();
+// color.glsl
+vec3 eotf_inverse_sRGB(vec3 srgb);
+// normalmap.glsl
+vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord);
+// atmos_spectral.glsl
+vec4 get_sun_spectral_irradiance();
+vec3 linear_srgb_from_spectral_samples(vec4 L);
+// exposure.glsl
+vec3 apply_exposure(vec3 color);
+
+void main()
+{
+ vec3 albedo = eotf_inverse_sRGB(texture(color_tex, fs_in.texcoord).rgb);
+
+ vec3 N = normalize(fs_in.vertex_normal);
+ N = perturb_normal(N, fs_in.view_vector, fs_in.texcoord);
+
+ float NdotL = max(dot(N, fg_SunDirection), 0.0);
+
+ vec3 V = normalize(fs_in.view_vector);
+
+ // Simple Lambertian BRDF
+ vec3 color = albedo * M_1_PI() * NdotL
+ * linear_srgb_from_spectral_samples(get_sun_spectral_irradiance());
+
+ // 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 albedo data for the moon,
+ // but that's too much work for little return. Just approximate the
+ // transmittance by taking the average of the four spectral samples.
+ color *= dot(transmittance, vec4(0.25));
+
+ // Pre-expose
+ color = apply_exposure(color);
+
+ // Final color = transmittance * moon color + 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/moon.vert b/Shaders/HDR/moon.vert
new file mode 100644
index 000000000..e5019f3eb
--- /dev/null
+++ b/Shaders/HDR/moon.vert
@@ -0,0 +1,24 @@
+#version 330 core
+
+layout(location = 0) in vec4 pos;
+layout(location = 1) in vec3 normal;
+layout(location = 2) in vec4 vertex_color;
+layout(location = 3) in vec4 multitexcoord0;
+
+out VS_OUT {
+ vec2 texcoord;
+ vec3 vertex_normal;
+ vec3 view_vector;
+} vs_out;
+
+uniform mat4 osg_ModelViewProjectionMatrix;
+uniform mat4 osg_ModelViewMatrix;
+uniform mat3 osg_NormalMatrix;
+
+void main()
+{
+ gl_Position = osg_ModelViewProjectionMatrix * pos;
+ vs_out.texcoord = multitexcoord0.st;
+ vs_out.vertex_normal = osg_NormalMatrix * normal;
+ vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
+}
diff --git a/Shaders/HDR/shading_opaque.glsl b/Shaders/HDR/shading_opaque.glsl
index 4180cc80c..91ce271ba 100644
--- a/Shaders/HDR/shading_opaque.glsl
+++ b/Shaders/HDR/shading_opaque.glsl
@@ -20,6 +20,7 @@ vec3 eval_ibl(vec3 base_color, float metallic, float roughness, vec3 f0,
float occlusion, vec3 ws_N, vec3 ws_refl, float NdotV);
// aerial_perspective.glsl
vec3 add_aerial_perspective(vec3 color, vec2 coord, float depth);
+// sun.glsl
vec3 get_sun_radiance(vec3 p);
// clustered.glsl
vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0,
diff --git a/Shaders/HDR/stars.frag b/Shaders/HDR/stars.frag
new file mode 100644
index 000000000..ff56fb78b
--- /dev/null
+++ b/Shaders/HDR/stars.frag
@@ -0,0 +1,14 @@
+#version 330 core
+
+layout(location = 0) out vec4 fragColor;
+
+in VS_OUT {
+ vec4 color;
+} fs_in;
+
+uniform float max_radiance;
+
+void main()
+{
+ fragColor = vec4(fs_in.color.rgb * max_radiance, fs_in.color.a);
+}
diff --git a/Shaders/HDR/stars.vert b/Shaders/HDR/stars.vert
new file mode 100644
index 000000000..cca905cd2
--- /dev/null
+++ b/Shaders/HDR/stars.vert
@@ -0,0 +1,16 @@
+#version 330 core
+
+layout(location = 0) in vec4 pos;
+layout(location = 2) in vec4 vertex_color;
+
+out VS_OUT {
+ vec4 color;
+} vs_out;
+
+uniform mat4 osg_ModelViewProjectionMatrix;
+
+void main()
+{
+ gl_Position = osg_ModelViewProjectionMatrix * pos;
+ vs_out.color = vertex_color;
+}
diff --git a/Textures/Sky/moon_color.png b/Textures/Sky/moon_color.png
new file mode 100644
index 000000000..cc847fe35
Binary files /dev/null and b/Textures/Sky/moon_color.png differ
diff --git a/Textures/Sky/moon_n.png b/Textures/Sky/moon_n.png
new file mode 100644
index 000000000..d5851c6ad
Binary files /dev/null and b/Textures/Sky/moon_n.png differ