Browse Source

Add transmittance LUT generation step to sky pass

master
C. J. Howard 2 years ago
parent
commit
e2ab1a99f2
3 changed files with 101 additions and 17 deletions
  1. +1
    -1
      src/game/state/nuptial-flight.cpp
  2. +82
    -14
      src/render/passes/sky-pass.cpp
  3. +18
    -2
      src/render/passes/sky-pass.hpp

+ 1
- 1
src/game/state/nuptial-flight.cpp View File

@ -323,7 +323,7 @@ void nuptial_flight::setup_camera()
ctx.entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack); ctx.entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack);
} }
ctx.surface_camera->set_exposure(15.0f);
ctx.surface_camera->set_exposure(15.5f);
ctx.astronomy_system->set_camera(ctx.surface_camera); ctx.astronomy_system->set_camera(ctx.surface_camera);
} }

+ 82
- 14
src/render/passes/sky-pass.cpp View File

@ -68,7 +68,7 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
clouds_model_vao(nullptr), clouds_model_vao(nullptr),
cloud_material(nullptr), cloud_material(nullptr),
cloud_shader_program(nullptr), cloud_shader_program(nullptr),
observer_elevation_tween(0.0f, math::lerp<float, float>),
observer_position_tween({0, 0, 0}, math::lerp<float3, float>),
sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
@ -82,24 +82,84 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
moon_planetlight_direction_tween(float3{0, 0, 0}, math::lerp<float3, float>), moon_planetlight_direction_tween(float3{0, 0, 0}, math::lerp<float3, float>),
moon_planetlight_illuminance_tween(float3{0, 0, 0}, math::lerp<float3, float>), moon_planetlight_illuminance_tween(float3{0, 0, 0}, math::lerp<float3, float>),
magnification(1.0f) magnification(1.0f)
{}
{
// Build quad VBO and VAO
const float quad_vertex_data[] =
{
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
std::size_t quad_vertex_size = 3;
std::size_t quad_vertex_stride = sizeof(float) * quad_vertex_size;
std::size_t quad_vertex_count = 6;
quad_vbo = new gl::vertex_buffer(sizeof(float) * quad_vertex_size * quad_vertex_count, quad_vertex_data);
quad_vao = new gl::vertex_array();
gl::vertex_attribute quad_position_attribute;
quad_position_attribute.buffer = quad_vbo;
quad_position_attribute.offset = 0;
quad_position_attribute.stride = quad_vertex_stride;
quad_position_attribute.type = gl::vertex_attribute_type::float_32;
quad_position_attribute.components = 3;
quad_vao->bind(render::vertex_attribute::position, quad_position_attribute);
// Create transmittance LUT texture and framebuffer (32F color, no depth)
int transmittance_width = 256;
int transmittance_height = 64;
transmittance_inverse_lut_resolution = {1.0f / static_cast<float>(transmittance_width), 1.0f / static_cast<float>(transmittance_height)};
transmittance_texture = new gl::texture_2d(transmittance_width, transmittance_height, gl::pixel_type::float_32, gl::pixel_format::rgb);
transmittance_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
transmittance_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
transmittance_texture->set_max_anisotropy(0.0f);
transmittance_framebuffer = new gl::framebuffer(transmittance_width, transmittance_height);
transmittance_framebuffer->attach(gl::framebuffer_attachment_type::color, transmittance_texture);
// Load transmittance LUT shader
transmittance_shader_program = resource_manager->load<gl::shader_program>("transmittance-lut.glsl");
transmittance_atmosphere_radii_input = transmittance_shader_program->get_input("atmosphere_radii");
transmittance_rayleigh_parameters_input = transmittance_shader_program->get_input("rayleigh_parameters");
transmittance_mie_parameters_input = transmittance_shader_program->get_input("mie_parameters");
transmittance_ozone_distribution_input = transmittance_shader_program->get_input("ozone_distribution");
transmittance_ozone_absorption_input = transmittance_shader_program->get_input("ozone_absorption");
transmittance_inverse_lut_resolution_input = transmittance_shader_program->get_input("inverse_lut_resolution");
}
sky_pass::~sky_pass() sky_pass::~sky_pass()
{}
{
delete transmittance_framebuffer;
delete transmittance_texture;
delete quad_vao;
delete quad_vbo;
}
void sky_pass::render(const render::context& ctx, render::queue& queue) const void sky_pass::render(const render::context& ctx, render::queue& queue) const
{ {
rasterizer->use_framebuffer(*framebuffer);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
// Render transmittance LUT
auto transmittance_viewport = transmittance_framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(transmittance_viewport), std::get<1>(transmittance_viewport));
rasterizer->use_framebuffer(*transmittance_framebuffer);
rasterizer->use_program(*transmittance_shader_program);
transmittance_atmosphere_radii_input->upload(atmosphere_radii);
transmittance_rayleigh_parameters_input->upload(rayleigh_parameters);
transmittance_mie_parameters_input->upload(mie_parameters);
transmittance_ozone_distribution_input->upload(ozone_distribution);
transmittance_ozone_absorption_input->upload(ozone_absorption);
if (transmittance_inverse_lut_resolution_input)
transmittance_inverse_lut_resolution_input->upload(transmittance_inverse_lut_resolution);
rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangles, 0, 6);
rasterizer->use_framebuffer(*framebuffer);
auto viewport = framebuffer->get_dimensions(); auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))}; float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))};
const scene::camera& camera = *ctx.camera; const scene::camera& camera = *ctx.camera;
@ -113,8 +173,8 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
float4x4 view_projection = projection * view; float4x4 view_projection = projection * view;
float4x4 model_view_projection = projection * model_view; float4x4 model_view_projection = projection * model_view;
// Interpolate observer elevation
float observer_elevation = observer_elevation_tween.interpolate(ctx.alpha);
// Interpolate observer position
float3 observer_position = observer_position_tween.interpolate(ctx.alpha);
// Construct tweened ICRF to EUS transformation // Construct tweened ICRF to EUS transformation
math::transformation::se3<float> icrf_to_eus = math::transformation::se3<float> icrf_to_eus =
@ -157,8 +217,8 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
sun_angular_radius_input->upload(sun_angular_radius * magnification); sun_angular_radius_input->upload(sun_angular_radius * magnification);
if (atmosphere_radii_input) if (atmosphere_radii_input)
atmosphere_radii_input->upload(atmosphere_radii); atmosphere_radii_input->upload(atmosphere_radii);
if (observer_elevation_input)
observer_elevation_input->upload(observer_elevation);
if (observer_position_input)
observer_position_input->upload(observer_position);
if (rayleigh_parameters_input) if (rayleigh_parameters_input)
rayleigh_parameters_input->upload(rayleigh_parameters); rayleigh_parameters_input->upload(rayleigh_parameters);
if (mie_parameters_input) if (mie_parameters_input)
@ -167,6 +227,10 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
ozone_distribution_input->upload(ozone_distribution); ozone_distribution_input->upload(ozone_distribution);
if (ozone_absorption_input) if (ozone_absorption_input)
ozone_absorption_input->upload(ozone_absorption); ozone_absorption_input->upload(ozone_absorption);
if (transmittance_lut_input)
transmittance_lut_input->upload(transmittance_texture);
if (inverse_transmittance_lut_resolution_input)
inverse_transmittance_lut_resolution_input->upload(transmittance_inverse_lut_resolution);
sky_material->upload(ctx.alpha); sky_material->upload(ctx.alpha);
@ -295,11 +359,13 @@ void sky_pass::set_sky_model(const model* model)
sun_illuminance_input = sky_shader_program->get_input("sun_illuminance"); sun_illuminance_input = sky_shader_program->get_input("sun_illuminance");
sun_angular_radius_input = sky_shader_program->get_input("sun_angular_radius"); sun_angular_radius_input = sky_shader_program->get_input("sun_angular_radius");
atmosphere_radii_input = sky_shader_program->get_input("atmosphere_radii"); atmosphere_radii_input = sky_shader_program->get_input("atmosphere_radii");
observer_elevation_input = sky_shader_program->get_input("observer_elevation");
observer_position_input = sky_shader_program->get_input("observer_position");
rayleigh_parameters_input = sky_shader_program->get_input("rayleigh_parameters"); rayleigh_parameters_input = sky_shader_program->get_input("rayleigh_parameters");
mie_parameters_input = sky_shader_program->get_input("mie_parameters"); mie_parameters_input = sky_shader_program->get_input("mie_parameters");
ozone_distribution_input = sky_shader_program->get_input("ozone_distribution"); ozone_distribution_input = sky_shader_program->get_input("ozone_distribution");
ozone_absorption_input = sky_shader_program->get_input("ozone_absorption"); ozone_absorption_input = sky_shader_program->get_input("ozone_absorption");
transmittance_lut_input = sky_shader_program->get_input("transmittance_lut");
inverse_transmittance_lut_resolution_input = sky_shader_program->get_input("inverse_transmittance_lut_resolution");
} }
} }
} }
@ -424,7 +490,7 @@ void sky_pass::set_clouds_model(const model* model)
void sky_pass::update_tweens() void sky_pass::update_tweens()
{ {
observer_elevation_tween.update();
observer_position_tween.update();
sun_position_tween.update(); sun_position_tween.update();
sun_luminance_tween.update(); sun_luminance_tween.update();
sun_illuminance_tween.update(); sun_illuminance_tween.update();
@ -476,6 +542,7 @@ void sky_pass::set_planet_radius(float radius)
atmosphere_radii.x = radius; atmosphere_radii.x = radius;
atmosphere_radii.y = atmosphere_radii.x + atmosphere_upper_limit; atmosphere_radii.y = atmosphere_radii.x + atmosphere_upper_limit;
atmosphere_radii.z = atmosphere_radii.y * atmosphere_radii.y; atmosphere_radii.z = atmosphere_radii.y * atmosphere_radii.y;
observer_position_tween[1] = {0.0f, atmosphere_radii.x + observer_elevation, 0.0f};
} }
void sky_pass::set_atmosphere_upper_limit(float limit) void sky_pass::set_atmosphere_upper_limit(float limit)
@ -487,7 +554,8 @@ void sky_pass::set_atmosphere_upper_limit(float limit)
void sky_pass::set_observer_elevation(float elevation) void sky_pass::set_observer_elevation(float elevation)
{ {
observer_elevation_tween[1] = elevation;
observer_elevation = elevation;
observer_position_tween[1] = {0.0f, atmosphere_radii.x + observer_elevation, 0.0f};
} }
void sky_pass::set_rayleigh_parameters(float scale_height, const float3& scattering) void sky_pass::set_rayleigh_parameters(float scale_height, const float3& scattering)

+ 18
- 2
src/render/passes/sky-pass.hpp View File

@ -85,6 +85,20 @@ public:
private: private:
virtual void handle_event(const mouse_moved_event& event); virtual void handle_event(const mouse_moved_event& event);
gl::vertex_buffer* quad_vbo;
gl::vertex_array* quad_vao;
gl::texture_2d* transmittance_texture;
gl::framebuffer* transmittance_framebuffer;
float2 transmittance_inverse_lut_resolution;
gl::shader_program* transmittance_shader_program;
const gl::shader_input* transmittance_atmosphere_radii_input;
const gl::shader_input* transmittance_rayleigh_parameters_input;
const gl::shader_input* transmittance_mie_parameters_input;
const gl::shader_input* transmittance_ozone_distribution_input;
const gl::shader_input* transmittance_ozone_absorption_input;
const gl::shader_input* transmittance_inverse_lut_resolution_input;
gl::shader_program* sky_shader_program; gl::shader_program* sky_shader_program;
const gl::shader_input* model_view_projection_input; const gl::shader_input* model_view_projection_input;
@ -97,11 +111,13 @@ private:
const gl::shader_input* sun_illuminance_input; const gl::shader_input* sun_illuminance_input;
const gl::shader_input* sun_angular_radius_input; const gl::shader_input* sun_angular_radius_input;
const gl::shader_input* atmosphere_radii_input; const gl::shader_input* atmosphere_radii_input;
const gl::shader_input* observer_elevation_input;
const gl::shader_input* observer_position_input;
const gl::shader_input* rayleigh_parameters_input; const gl::shader_input* rayleigh_parameters_input;
const gl::shader_input* mie_parameters_input; const gl::shader_input* mie_parameters_input;
const gl::shader_input* ozone_distribution_input; const gl::shader_input* ozone_distribution_input;
const gl::shader_input* ozone_absorption_input; const gl::shader_input* ozone_absorption_input;
const gl::shader_input* transmittance_lut_input;
const gl::shader_input* inverse_transmittance_lut_resolution_input;
gl::shader_program* moon_shader_program; gl::shader_program* moon_shader_program;
const gl::shader_input* moon_model_input; const gl::shader_input* moon_model_input;
@ -158,7 +174,6 @@ private:
const gl::texture_2d* sky_gradient2; const gl::texture_2d* sky_gradient2;
float2 mouse_position; float2 mouse_position;
tween<float> observer_elevation_tween;
tween<float3> sun_position_tween; tween<float3> sun_position_tween;
tween<float3> sun_luminance_tween; tween<float3> sun_luminance_tween;
tween<float3> sun_illuminance_tween; tween<float3> sun_illuminance_tween;
@ -177,6 +192,7 @@ private:
float atmosphere_upper_limit; float atmosphere_upper_limit;
float3 atmosphere_radii; float3 atmosphere_radii;
float observer_elevation; float observer_elevation;
tween<float3> observer_position_tween;
float4 rayleigh_parameters; float4 rayleigh_parameters;
float4 mie_parameters; float4 mie_parameters;
float3 ozone_distribution; float3 ozone_distribution;

Loading…
Cancel
Save