]> git.tdb.fi Git - r2c2.git/commitdiff
Render a sky in the upper hemisphere of a view's background
authorMikko Rasa <tdb@tdb.fi>
Sun, 24 Nov 2013 21:54:30 +0000 (23:54 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 24 Nov 2013 21:54:30 +0000 (23:54 +0200)
I'll have to do something about the lower hemisphere as well, but this
already makes train views look 46% better.

data/sky.object [new file with mode: 0644]
data/sky.shader [new file with mode: 0644]
source/3d/sky.cpp [new file with mode: 0644]
source/3d/sky.h [new file with mode: 0644]
source/3d/view.cpp
source/3d/view.h

diff --git a/data/sky.object b/data/sky.object
new file mode 100644 (file)
index 0000000..0e278f6
--- /dev/null
@@ -0,0 +1,32 @@
+mesh
+{
+       vertices VERTEX3
+       {
+               vertex3 -1 -1 -1;
+               vertex3 1 -1 -1;
+               vertex3 -1 1 -1;
+               vertex3 1 1 -1;
+               vertex3 -1 -1 1;
+               vertex3 1 -1 1;
+               vertex3 -1 1 1;
+               vertex3 1 1 1;
+       };
+       batch TRIANGLE_STRIP
+       {
+               indices 0 1 2 3 7 1 5 0 4 2 6 7 4 5;
+       };
+};
+technique
+{
+       pass "sky"
+       {
+               shader "sky.shader";
+               uniforms
+               {
+                       uniform3f "wavelengths" 0.56 0.53 0.42;
+                       uniform1f "scatter_constant" 0.0079;
+                       uniform1f "sun_intensity" 1.0;
+                       uniform1f "sun_size" 0.005;
+               };
+       };
+};
diff --git a/data/sky.shader b/data/sky.shader
new file mode 100644 (file)
index 0000000..66dd8ec
--- /dev/null
@@ -0,0 +1,54 @@
+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);
+       }";
diff --git a/source/3d/sky.cpp b/source/3d/sky.cpp
new file mode 100644 (file)
index 0000000..332b6d2
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/source/3d/sky.h b/source/3d/sky.h
new file mode 100644 (file)
index 0000000..88b170b
--- /dev/null
@@ -0,0 +1,26 @@
+#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
index 673daef0c5ca4d7e2443ffeb9f127bfab451ea52..b833605c87227951e798de68983bbaac46eead27 100644 (file)
@@ -13,13 +13,17 @@ View3D::View3D(Layout3D &l, unsigned w, unsigned h):
        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());
 
index 5e954a737da05baf07bd9ff963c0224b26345185..3b0d625df7456c74178becd3eb9476e01718ffb3 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <msp/gl/camera.h>
 #include <msp/gl/pipeline.h>
+#include "sky.h"
 
 namespace R2C2 {
 
@@ -16,6 +17,7 @@ protected:
        unsigned height;
        Msp::GL::Camera camera;
        Msp::GL::Pipeline pipeline;
+       Sky3D sky;
 
 public:
        View3D(Layout3D &, unsigned, unsigned);