--- /dev/null
+vertex_shader "
+ varying vec3 eye_look_dir;
+ void main()
+ {
+ vec4 eye_pos = vec4(mat3(gl_ModelViewMatrix)*gl_Vertex.xyz, 1);
+ gl_Position = gl_ProjectionMatrix*eye_pos;
+ eye_look_dir = eye_pos.xyz;
+ }";
+
+fragment_shader "
+ uniform vec3 eye_sky_dir;
+ uniform vec3 wavelengths;
+ uniform float scatter_constant;
+ uniform float sun_intensity;
+ uniform float sun_size;
+ varying vec3 eye_look_dir;
+ float thickness(float c, float r)
+ {
+ float rc = r*c;
+ return sqrt(2.0*r+1.0+rc*rc)-rc;
+ }
+ float srgb(float c)
+ {
+ if(c<0.0031308)
+ return 12.92*c;
+ else
+ return (1.055)*pow(c, 1.0/2.4)-0.055;
+ }
+ void main()
+ {
+ vec3 n_eye_look_dir = normalize(eye_look_dir);
+ vec3 n_eye_sun_dir = normalize(gl_LightSource[0].position.xyz);
+
+ if(dot(n_eye_look_dir, eye_sky_dir)>0)
+ {
+ float look_scale = thickness(dot(n_eye_look_dir, eye_sky_dir), 635.0);
+ float sun_scale = thickness(dot(n_eye_sun_dir, eye_sky_dir), 635.0);
+ float c = dot(n_eye_look_dir, n_eye_sun_dir);
+ float scatter_strength = (1.0+c*c)/2.0;
+ vec3 scatter_factor = scatter_constant/pow(wavelengths, vec3(4.0));
+
+ vec3 color;
+ float scale_ratio = look_scale/sun_scale;
+ if(scale_ratio>0.999 && scale_ratio<1.001)
+ color = sun_intensity*scatter_strength*scatter_factor*sun_scale*exp(-scatter_factor*sun_scale);
+ else
+ color = sun_intensity*scatter_strength*(exp(-scatter_factor*sun_scale)-exp(-scatter_factor*look_scale))/(1.0-sun_scale/look_scale);
+ if(dot(n_eye_look_dir, n_eye_sun_dir)>cos(sun_size))
+ color += exp(-scatter_factor*look_scale)*sun_intensity;
+ gl_FragColor = vec4(srgb(color.r), srgb(color.g), srgb(color.b), 1.0);
+ }
+ else
+ gl_FragColor = vec4(vec3(0.0), 1.0);
+ }";
--- /dev/null
+#include <msp/gl/renderer.h>
+#include "catalogue.h"
+#include "sky.h"
+
+using namespace Msp;
+
+namespace R2C2 {
+
+Sky3D::Sky3D(Catalogue3D &cat):
+ GL::ObjectInstance(cat.get<GL::Object>("sky.object"))
+{ }
+
+void Sky3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const
+{
+ GL::Vector4 sky_dir = renderer.matrix_stack().top()*GL::Vector4(0, 0 ,1, 0);
+ shdata.uniform("eye_sky_dir", sky_dir.x, sky_dir.y, sky_dir.z);
+ renderer.add_shader_data(shdata);
+}
+
+} // namespace R2C2
--- /dev/null
+#ifndef R2C2_3D_SKY_H_
+#define R2C2_3D_SKY_H_
+
+#include <msp/gl/objectinstance.h>
+#include <msp/gl/programdata.h>
+#include <msp/gl/renderable.h>
+
+namespace R2C2 {
+
+class Catalogue3D;
+
+class Sky3D: public Msp::GL::ObjectInstance
+{
+private:
+ mutable Msp::GL::ProgramData shdata;
+
+public:
+ Sky3D(Catalogue3D &);
+
+private:
+ virtual void setup_render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
+};
+
+} // namespace R2C2
+
+#endif
layout(l),
width(w),
height(h),
- pipeline(w, h)
+ pipeline(w, h),
+ sky(layout.get_catalogue())
{
pipeline.set_camera(&camera);
+ pipeline.add_renderable(sky);
pipeline.add_renderable_for_pass(layout.get_scene(), 0);
pipeline.add_renderable_for_pass(layout.get_scene(), "translucent");
- GL::Pipeline::Pass *pass = &pipeline.add_pass(0);
+ GL::Pipeline::Pass *pass = &pipeline.add_pass("sky");
+
+ pass = &pipeline.add_pass(0);
pass->set_lighting(&layout.get_lighting());
pass->set_depth_test(&GL::DepthTest::lequal());