X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Feffects%2Fsky.cpp;fp=source%2Feffects%2Fsky.cpp;h=8fa00cfbd4d44e884cdfadfd6268226705e039d2;hb=06d83c11e10208478487dea864ddd7822630c391;hp=0000000000000000000000000000000000000000;hpb=e98956208676c77e74462f17932ac530077a0540;p=libs%2Fgl.git diff --git a/source/effects/sky.cpp b/source/effects/sky.cpp new file mode 100644 index 00000000..8fa00cfb --- /dev/null +++ b/source/effects/sky.cpp @@ -0,0 +1,135 @@ +#include "light.h" +#include "mesh.h" +#include "renderer.h" +#include "resources.h" +#include "sky.h" + +using namespace std; + +namespace Msp { +namespace GL { + +Sky::Sky(Resources &resources, Renderable &r, const Light &s): + Effect(r), + sun(s), + transmittance_shprog(resources.get("_sky_transmittance.glsl.shader")), + transmittance_lookup_dirty(true), + distant_shprog(resources.get("_sky_distant.glsl.shader")), + fullscreen_mesh(resources.get("_fullscreen_quad.mesh")), + backdrop_shprog(resources.get("_sky_backdrop.glsl.shader")), + sampler(resources.get("_linear_clamp.samp")), + wrap_sampler(resources.get("_linear_clamp_v.samp")), + rendered(false) +{ + transmittance_lookup.storage(RGB16F, 128, 64, 1); + transmittance_fbo.attach(COLOR_ATTACHMENT0, transmittance_lookup); + + distant.storage(RGB16F, 256, 128, 1); + distant_fbo.attach(COLOR_ATTACHMENT0, distant); + + shdata.uniform("n_steps", 50); + + set_planet(Planet::earth()); + set_view_height(5.0f); +} + +void Sky::set_planet(const Planet &planet) +{ + shdata.uniform("events.rayleigh_scatter", planet.rayleigh_scatter.r, planet.rayleigh_scatter.g, planet.rayleigh_scatter.b); + shdata.uniform("events.mie_scatter", planet.mie_scatter.r, planet.mie_scatter.g, planet.mie_scatter.b); + shdata.uniform("events.mie_absorb", planet.mie_absorb.r, planet.mie_absorb.g, planet.mie_absorb.b); + shdata.uniform("events.ozone_absorb", planet.ozone_absorb.r, planet.ozone_absorb.g, planet.ozone_absorb.b); + shdata.uniform("rayleigh_density_decay", planet.rayleigh_density_decay); + shdata.uniform("mie_density_decay", planet.mie_density_decay); + shdata.uniform("ozone_band_center", planet.ozone_band_center); + shdata.uniform("ozone_band_extent", planet.ozone_band_extent); + shdata.uniform("atmosphere_thickness", planet.atmosphere_thickness); + shdata.uniform("planet_radius", planet.planet_radius); + shdata.uniform("ground_albedo", planet.ground_albedo.r, planet.ground_albedo.g, planet.ground_albedo.b); +} + +void Sky::set_view_height(float h) +{ + shdata.uniform("view_height", h); +} + +void Sky::setup_frame(Renderer &renderer) +{ + if(rendered) + return; + + rendered = true; + + shdata.uniform("light_color", sun.get_color()); + shdata.uniform("light_dir", sun.get_position().slice<3>(0)); + + Renderer::Push push(renderer); + + if(transmittance_lookup_dirty) + { + transmittance_lookup_dirty = false; + Bind bind_fbo(transmittance_fbo); + renderer.set_shader_program(&transmittance_shprog, &shdata); + fullscreen_mesh.draw(renderer); + } + + Bind bind_fbo(distant_fbo); + renderer.set_shader_program(&distant_shprog, &shdata); + renderer.set_texture("transmittance_lookup", &transmittance_lookup, &sampler); + fullscreen_mesh.draw(renderer); + + renderable.setup_frame(renderer); +} + +void Sky::finish_frame() +{ + if(rendered) + { + rendered = false; + renderable.finish_frame(); + } +} + +void Sky::render(Renderer &renderer, Tag tag) const +{ + renderable.render(renderer, tag); + + Renderer::Push push(renderer); + + renderer.set_shader_program(&backdrop_shprog, &shdata); + renderer.set_texture("distant", &distant, &wrap_sampler); + fullscreen_mesh.draw(renderer); +} + + +Sky::Planet::Planet(): + rayleigh_scatter(0.0f), + mie_scatter(0.0f), + mie_absorb(0.0f), + ozone_absorb(0.0f), + rayleigh_density_decay(1e3f), + mie_density_decay(1e3f), + ozone_band_center(1e4f), + ozone_band_extent(1e2f), + atmosphere_thickness(2e4f), + planet_radius(1e6f) +{ } + +Sky::Planet Sky::Planet::earth() +{ + Planet planet; + planet.rayleigh_scatter = Color(5.802e-6f, 13.558e-6f, 33.1e-6f); + planet.mie_scatter = Color(3.996e-6f, 3.996e-6f, 3.996e-6f); + planet.mie_absorb = Color(4.4e-6f, 4.4e-6f, 4.4e-6f); + planet.ozone_absorb = Color(0.65e-6f, 1.881e-6f, 0.085e-6f); + planet.rayleigh_density_decay = -8e3f; + planet.mie_density_decay = -1.2e3f; + planet.ozone_band_center = 25e3f; + planet.ozone_band_extent = 15e3f; + planet.atmosphere_thickness = 1e5f; + planet.planet_radius = 6.36e6f; + return planet; +} + +} // namespace GL +} // namespace Msp