45 pass(pipeline, framebuffer),
46 mouse_position({0.0f, 0.0f}),
48 sky_material(
nullptr),
49 sky_model_vao(
nullptr),
51 moon_model_vao(
nullptr),
52 moon_material(
nullptr),
53 moon_shader_program(
nullptr),
55 stars_model_vao(
nullptr),
56 star_material(
nullptr),
57 star_shader_program(
nullptr),
58 observer_position_tween({0, 0, 0}, math::lerp<math::fvec3, float>),
59 sun_position_tween(
math::fvec3{1.0f, 0.0f, 0.0f}, math::lerp<math::fvec3, float>),
60 sun_luminance_tween(
math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp<math::fvec3, float>),
61 sun_illuminance_tween(
math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp<math::fvec3, float>),
62 icrf_to_eus_translation({0, 0, 0}, math::lerp<math::fvec3, float>),
64 moon_position_tween(
math::fvec3{0, 0, 0}, math::lerp<math::fvec3, float>),
66 moon_angular_radius_tween(0.0f, math::lerp<float, float>),
67 moon_sunlight_direction_tween(
math::fvec3{0, 0, 0}, math::lerp<math::fvec3, float>),
68 moon_sunlight_illuminance_tween(
math::fvec3{0, 0, 0}, math::lerp<math::fvec3, float>),
69 moon_planetlight_direction_tween(
math::fvec3{0, 0, 0}, math::lerp<math::fvec3, float>),
70 moon_planetlight_illuminance_tween(
math::fvec3{0, 0, 0}, math::lerp<math::fvec3, float>),
71 moon_illuminance_tween(
math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp<math::fvec3, float>),
75 m_lut_sampler = std::make_shared<gl::sampler>
85 m_vertex_array = std::make_unique<gl::vertex_array>();
90 rebuild_transmittance_lut_framebuffer();
96 rebuild_transmittance_lut_shader_program();
99 rebuild_transmittance_lut_command_buffer();
105 rebuild_multiscattering_lut_framebuffer();
111 rebuild_multiscattering_lut_shader_program();
114 rebuild_multiscattering_lut_command_buffer();
120 rebuild_luminance_lut_framebuffer();
126 rebuild_luminance_lut_shader_program();
129 rebuild_luminance_lut_command_buffer();
136 m_sky_probe_shader_program = m_sky_probe_shader_template->
build({});
137 if (!m_sky_probe_shader_program->linked())
139 debug::log_error(
"Failed to build sky probe shader program: {}", m_sky_probe_shader_program->info());
160 if (m_render_transmittance_lut)
162 for (
const auto&
command: m_transmittance_lut_command_buffer)
167 m_render_transmittance_lut =
false;
171 if (m_render_multiscattering_lut)
173 for (
const auto&
command: m_multiscattering_lut_command_buffer)
178 m_render_multiscattering_lut =
false;
189 math::fmat4 model_view_projection = projection * model_view;
193 observer_position = observer_position_tween.interpolate(ctx.
alpha);
198 icrf_to_eus_translation.interpolate(ctx.
alpha),
199 icrf_to_eus_rotation.interpolate(ctx.
alpha)
207 math::fvec3 sun_illuminance = sun_illuminance_tween.interpolate(ctx.
alpha) * camera_exposure;
208 math::fvec3 sun_luminance = sun_luminance_tween.interpolate(ctx.
alpha) * camera_exposure;
212 math::fvec3 moon_illuminance = moon_illuminance_tween.interpolate(ctx.
alpha) * camera_exposure;
213 float moon_angular_radius = moon_angular_radius_tween.
interpolate(ctx.
alpha) * magnification;
217 dominant_light_direction = sun_direction;
218 dominant_light_illuminance = sun_illuminance;
230 for (
const auto&
command: m_luminance_lut_command_buffer)
237 for (
const auto&
command: m_sky_probe_command_buffer)
262 static_cast<float>(viewport_dimensions[0]),
263 static_cast<float>(viewport_dimensions[1])
269 if (sky_model && sky_shader_program)
274 if (model_view_projection_var)
275 model_view_projection_var->
update(model_view_projection);
280 if (view_projection_var)
282 view_projection_var->
update(view_projection);
284 if (inv_view_projection_var)
287 inv_view_projection_var->
update(inv_view_projection);
290 if (camera_position_var)
295 mouse_var->
update(mouse_position);
297 resolution_var->
update(resolution);
298 if (light_direction_var)
299 light_direction_var->
update(dominant_light_direction);
300 if (sun_luminance_var)
301 sun_luminance_var->
update(sun_luminance);
302 if (sun_angular_radius_var)
303 sun_angular_radius_var->
update(sun_angular_radius * magnification);
304 if (atmosphere_radii_var)
305 atmosphere_radii_var->
update(atmosphere_radii);
306 if (observer_position_var)
307 observer_position_var->
update(observer_position);
308 if (sky_transmittance_lut_var)
309 sky_transmittance_lut_var->
update(*m_transmittance_lut_texture);
310 if (sky_transmittance_lut_resolution_var)
311 sky_transmittance_lut_resolution_var->
update(
math::fvec2(m_transmittance_lut_resolution));
312 if (sky_luminance_lut_var)
313 sky_luminance_lut_var->
update(*m_luminance_lut_texture);
314 if (sky_luminance_lut_resolution_var)
315 sky_luminance_lut_resolution_var->
update(
math::fvec2(m_luminance_lut_resolution));
320 m_pipeline->
draw(sky_model_vertex_count, 1, sky_model_first_vertex, 0);
351 if (moon_shader_program)
354 float moon_radius = moon_angular_radius * moon_distance;
358 moon_transform.
rotation = moon_rotation_tween.interpolate(ctx.
alpha);
359 moon_transform.
scale = {moon_radius, moon_radius, moon_radius};
367 if (moon_view_projection_var)
368 moon_view_projection_var->
update(view_projection);
369 if (moon_normal_model_var)
370 moon_normal_model_var->
update(normal_model);
371 if (moon_camera_position_var)
373 if (moon_sunlight_direction_var)
375 if (moon_sunlight_illuminance_var)
376 moon_sunlight_illuminance_var->
update(moon_sunlight_illuminance_tween.interpolate(ctx.
alpha) * camera_exposure);
377 if (moon_planetlight_direction_var)
379 if (moon_planetlight_illuminance_var)
380 moon_planetlight_illuminance_var->
update(moon_planetlight_illuminance_tween.interpolate(ctx.
alpha) * camera_exposure);
381 if (moon_albedo_map_var && m_moon_albedo_map)
382 moon_albedo_map_var->
update(*m_moon_albedo_map);
383 if (moon_normal_map_var && m_moon_normal_map)
384 moon_normal_map_var->
update(*m_moon_normal_map);
385 if (moon_observer_position_var)
386 moon_observer_position_var->
update(observer_position);
387 if (moon_sky_transmittance_lut_var)
388 moon_sky_transmittance_lut_var->
update(*m_transmittance_lut_texture);
389 if (moon_atmosphere_radii_var)
390 moon_atmosphere_radii_var->
update(atmosphere_radii);
395 m_pipeline->
draw(moon_model_vertex_count, 1, moon_model_first_vertex, 0);
410 if (star_shader_program)
416 model_view_projection = view_projection *
model;
419 if (star_model_view_projection_var)
420 star_model_view_projection_var->
update(model_view_projection);
421 if (star_exposure_var)
422 star_exposure_var->
update(camera_exposure);
423 if (star_inv_resolution_var)
424 star_inv_resolution_var->
update(1.0f / resolution);
429 m_pipeline->
draw(stars_model_vertex_count, 1, stars_model_first_vertex, 0);
437 if (m_transmittance_lut_sample_count !=
count)
439 m_transmittance_lut_sample_count =
count;
442 rebuild_transmittance_lut_shader_program();
443 rebuild_transmittance_lut_command_buffer();
446 m_render_transmittance_lut =
true;
452 if (m_transmittance_lut_resolution.x() != resolution.
x() || m_transmittance_lut_resolution.y() != resolution.
y())
454 m_transmittance_lut_resolution = resolution;
456 rebuild_transmittance_lut_framebuffer();
459 m_render_transmittance_lut =
true;
465 if (m_multiscattering_lut_direction_sample_count !=
count)
467 m_multiscattering_lut_direction_sample_count =
count;
470 rebuild_multiscattering_lut_shader_program();
471 rebuild_multiscattering_lut_command_buffer();
474 m_render_multiscattering_lut =
true;
480 if (m_multiscattering_lut_scatter_sample_count !=
count)
482 m_multiscattering_lut_scatter_sample_count =
count;
485 rebuild_multiscattering_lut_shader_program();
486 rebuild_multiscattering_lut_command_buffer();
489 m_render_multiscattering_lut =
true;
495 if (m_multiscattering_lut_resolution.x() != resolution.
x() || m_multiscattering_lut_resolution.y() != resolution.
y())
497 m_multiscattering_lut_resolution = resolution;
499 rebuild_multiscattering_lut_framebuffer();
502 m_render_multiscattering_lut =
true;
508 if (m_luminance_lut_sample_count !=
count)
510 m_luminance_lut_sample_count =
count;
513 rebuild_luminance_lut_shader_program();
514 rebuild_luminance_lut_command_buffer();
517 m_render_luminance_lut =
true;
523 if (m_luminance_lut_resolution.x() != resolution.
x() || m_luminance_lut_resolution.y() != resolution.
y())
525 m_luminance_lut_resolution = resolution;
527 rebuild_luminance_lut_framebuffer();
530 m_render_luminance_lut =
true;
537 sky_shader_program =
nullptr;
546 sky_model_primitive_topology = group.primitive_topology;
547 sky_model_first_vertex = group.first_vertex;
548 sky_model_vertex_count = group.vertex_count;
549 sky_material = group.
material.get();
551 sky_model_vertex_offset = sky_model->get_vertex_offset();
552 sky_model_vertex_stride = sky_model->get_vertex_stride();
558 if (sky_shader_program->linked())
560 model_view_projection_var = sky_shader_program->variable(
"model_view_projection");
561 view_var = sky_shader_program->variable(
"view");
562 view_projection_var = sky_shader_program->variable(
"view_projection");
563 inv_view_projection_var = sky_shader_program->variable(
"inv_view_projection");
564 camera_position_var = sky_shader_program->variable(
"camera_position");
565 mouse_var = sky_shader_program->variable(
"mouse");
566 resolution_var = sky_shader_program->variable(
"resolution");
567 light_direction_var = sky_shader_program->variable(
"light_direction");
568 sun_luminance_var = sky_shader_program->variable(
"sun_luminance");
569 sun_angular_radius_var = sky_shader_program->variable(
"sun_angular_radius");
570 atmosphere_radii_var = sky_shader_program->variable(
"atmosphere_radii");
571 observer_position_var = sky_shader_program->variable(
"observer_position");
572 sky_transmittance_lut_var = sky_shader_program->variable(
"sky_transmittance_lut");
573 sky_transmittance_lut_resolution_var = sky_shader_program->variable(
"sky_transmittance_lut_resolution");
574 sky_luminance_lut_var = sky_shader_program->variable(
"sky_luminance_lut");
575 sky_luminance_lut_resolution_var = sky_shader_program->variable(
"sky_luminance_lut_resolution");
579 debug::log_error(
"Failed to build sky shader program: {}", sky_shader_program->info());
586 sky_model_vao =
nullptr;
593 moon_shader_program =
nullptr;
602 moon_model_primitive_topology = group.primitive_topology;
603 moon_model_first_vertex = group.first_vertex;
604 moon_model_vertex_count = group.vertex_count;
605 moon_material = group.
material.get();
607 moon_model_vertex_offset = moon_model->get_vertex_offset();
608 moon_model_vertex_stride = moon_model->get_vertex_stride();
614 if (moon_shader_program->linked())
616 moon_model_var = moon_shader_program->variable(
"model");
617 moon_view_projection_var = moon_shader_program->variable(
"view_projection");
618 moon_normal_model_var = moon_shader_program->variable(
"normal_model");
619 moon_camera_position_var = moon_shader_program->variable(
"camera_position");
620 moon_sunlight_direction_var = moon_shader_program->variable(
"sunlight_direction");
621 moon_sunlight_illuminance_var = moon_shader_program->variable(
"sunlight_illuminance");
622 moon_planetlight_direction_var = moon_shader_program->variable(
"planetlight_direction");
623 moon_planetlight_illuminance_var = moon_shader_program->variable(
"planetlight_illuminance");
624 moon_albedo_map_var = moon_shader_program->variable(
"albedo_map");
625 moon_normal_map_var = moon_shader_program->variable(
"normal_map");
626 moon_observer_position_var = moon_shader_program->variable(
"observer_position");
627 moon_sky_transmittance_lut_var = moon_shader_program->variable(
"sky_transmittance_lut");
628 moon_atmosphere_radii_var = moon_shader_program->variable(
"atmosphere_radii");
632 debug::log_error(
"Failed to build moon shader program: {}", moon_shader_program->info());
639 moon_model =
nullptr;
646 star_shader_program =
nullptr;
655 stars_model_primitive_topology = group.primitive_topology;
656 stars_model_first_vertex = group.first_vertex;
657 stars_model_vertex_count = group.vertex_count;
658 star_material = group.
material.get();
660 stars_model_vertex_offset = stars_model->get_vertex_offset();
661 stars_model_vertex_stride = stars_model->get_vertex_stride();
667 if (star_shader_program->linked())
669 star_model_view_projection_var = star_shader_program->variable(
"model_view_projection");
670 star_exposure_var = star_shader_program->variable(
"camera_exposure");
671 star_inv_resolution_var = star_shader_program->variable(
"inv_resolution");
675 debug::log_error(
"Failed to build star shader program: {}", star_shader_program->info());
682 stars_model =
nullptr;
688 observer_position_tween.update();
689 sun_position_tween.update();
690 sun_luminance_tween.update();
691 sun_illuminance_tween.update();
692 icrf_to_eus_translation.update();
693 icrf_to_eus_rotation.update();
695 moon_position_tween.update();
696 moon_rotation_tween.update();
697 moon_angular_radius_tween.
update();
698 moon_sunlight_direction_tween.update();
699 moon_sunlight_illuminance_tween.update();
700 moon_planetlight_direction_tween.update();
701 moon_planetlight_illuminance_tween.update();
702 moon_illuminance_tween.update();
707 this->magnification = magnification;
712 icrf_to_eus_translation[1] = transformation.
t;
713 icrf_to_eus_rotation[1] = transformation.
r;
723 sun_illuminance_tween[1] = illuminance;
724 sun_transmitted_illuminance = transmitted_illuminance;
729 sun_luminance_tween[1] = luminance;
734 sun_angular_radius = radius;
739 atmosphere_radii[0] = radius;
740 atmosphere_radii[1] = atmosphere_radii[0] + atmosphere_upper_limit;
741 atmosphere_radii[2] = atmosphere_radii[0] * atmosphere_radii[0];
742 atmosphere_radii[3] = atmosphere_radii[1] * atmosphere_radii[1];
744 observer_position_tween[1] = {0.0f, atmosphere_radii.x() + observer_elevation, 0.0f};
747 m_render_transmittance_lut =
true;
748 m_render_multiscattering_lut =
true;
753 atmosphere_upper_limit = limit;
754 atmosphere_radii[1] = atmosphere_radii[0] + atmosphere_upper_limit;
755 atmosphere_radii[3] = atmosphere_radii[1] * atmosphere_radii[1];
758 m_render_transmittance_lut =
true;
759 m_render_multiscattering_lut =
true;
764 observer_elevation = elevation;
765 observer_position_tween[1] = {0.0f, atmosphere_radii.
x() + observer_elevation, 0.0f};
770 rayleigh_parameters =
772 -1.0f / scale_height,
779 m_render_transmittance_lut =
true;
780 m_render_multiscattering_lut =
true;
787 -1.0f / scale_height,
794 m_render_transmittance_lut =
true;
795 m_render_multiscattering_lut =
true;
802 1.0f / (lower_limit - mode),
803 1.0f / (upper_limit - mode),
809 m_render_transmittance_lut =
true;
810 m_render_multiscattering_lut =
true;
815 airglow_luminance = luminance;
820 m_ground_albedo = albedo;
823 m_render_multiscattering_lut =
true;
843 moon_sunlight_direction_tween[1] = direction;
848 moon_sunlight_illuminance_tween[1] = illuminance;
853 moon_planetlight_direction_tween[1] = direction;
858 moon_planetlight_illuminance_tween[1] = illuminance;
863 moon_illuminance_tween[1] = illuminance;
864 moon_transmitted_illuminance = transmitted_illuminance;
871 if (m_sky_probe && m_sky_probe->get_luminance_texture())
873 const auto& luminance_texture = m_sky_probe->get_luminance_texture();
875 const auto face_size = luminance_texture->get_image_view()->get_image()->get_dimensions()[0];
876 const auto mip_count =
static_cast<std::uint32_t
>(std::bit_width(face_size));
878 m_sky_probe_framebuffers.resize(mip_count);
879 for (std::uint32_t i = 0; i < mip_count; ++i)
884 luminance_texture->get_image_view(),
887 m_sky_probe_framebuffers[i] = std::make_unique<gl::framebuffer>(attachments, face_size >> i, face_size >> i);
892 m_sky_probe_framebuffers.clear();
895 rebuild_sky_probe_command_buffer();
898 void sky_pass::rebuild_transmittance_lut_framebuffer()
901 m_transmittance_lut_texture = std::make_shared<gl::texture_2d>
903 std::make_shared<gl::image_view_2d>
905 std::make_shared<gl::image_2d>
908 m_transmittance_lut_resolution.x(),
909 m_transmittance_lut_resolution.y()
919 m_transmittance_lut_texture->get_image_view(),
922 m_transmittance_lut_framebuffer = std::make_shared<gl::framebuffer>(attachments, m_transmittance_lut_resolution.x(), m_transmittance_lut_resolution.y());
925 void sky_pass::rebuild_transmittance_lut_shader_program()
927 m_transmittance_lut_shader_program = m_transmittance_lut_shader_template->build
930 {
"SAMPLE_COUNT", std::to_string(m_transmittance_lut_sample_count)}
933 if (!m_transmittance_lut_shader_program->linked())
935 debug::log_error(
"Failed to build sky transmittance LUT shader program: {}", m_transmittance_lut_shader_program->info());
940 void sky_pass::rebuild_transmittance_lut_command_buffer()
942 m_transmittance_lut_command_buffer.clear();
944 if (!m_transmittance_lut_shader_program->linked() || !m_transmittance_lut_texture)
950 m_transmittance_lut_command_buffer.emplace_back
958 static_cast<float>(m_transmittance_lut_resolution.x()),
959 static_cast<float>(m_transmittance_lut_resolution.y())
969 if (
auto atmosphere_radii_var = m_transmittance_lut_shader_program->variable(
"atmosphere_radii"))
971 m_transmittance_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->
update(atmosphere_radii);});
973 if (
auto rayleigh_parameters_var = m_transmittance_lut_shader_program->variable(
"rayleigh_parameters"))
975 m_transmittance_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
977 if (
auto mie_parameters_var = m_transmittance_lut_shader_program->variable(
"mie_parameters"))
979 m_transmittance_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
981 if (
auto ozone_distribution_var = m_transmittance_lut_shader_program->variable(
"ozone_distribution"))
983 m_transmittance_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
985 if (
auto ozone_absorption_var = m_transmittance_lut_shader_program->variable(
"ozone_absorption"))
987 m_transmittance_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
989 if (
auto resolution_var = m_transmittance_lut_shader_program->variable(
"resolution"))
991 m_transmittance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->
update(
math::fvec2(m_transmittance_lut_resolution));});
994 m_transmittance_lut_command_buffer.emplace_back
1006 void sky_pass::rebuild_multiscattering_lut_framebuffer()
1009 m_multiscattering_lut_texture = std::make_shared<gl::texture_2d>
1011 std::make_shared<gl::image_view_2d>
1013 std::make_shared<gl::image_2d>
1016 m_multiscattering_lut_resolution.x(),
1017 m_multiscattering_lut_resolution.y()
1027 m_multiscattering_lut_texture->get_image_view(),
1030 m_multiscattering_lut_framebuffer = std::make_shared<gl::framebuffer>(attachments, m_multiscattering_lut_resolution.x(), m_multiscattering_lut_resolution.y());
1033 void sky_pass::rebuild_multiscattering_lut_shader_program()
1035 m_multiscattering_lut_shader_program = m_multiscattering_lut_shader_template->build
1038 {
"DIRECTION_SAMPLE_COUNT", std::to_string(m_multiscattering_lut_direction_sample_count)},
1039 {
"SCATTER_SAMPLE_COUNT", std::to_string(m_multiscattering_lut_scatter_sample_count)}
1042 if (!m_multiscattering_lut_shader_program->linked())
1044 debug::log_error(
"Failed to build sky multiscattering LUT shader program: {}", m_multiscattering_lut_shader_program->info());
1049 void sky_pass::rebuild_multiscattering_lut_command_buffer()
1051 m_multiscattering_lut_command_buffer.clear();
1053 if (!m_multiscattering_lut_shader_program->linked() || !m_multiscattering_lut_texture)
1059 m_multiscattering_lut_command_buffer.emplace_back
1067 static_cast<float>(m_multiscattering_lut_resolution.x()),
1068 static_cast<float>(m_multiscattering_lut_resolution.y())
1078 if (
auto atmosphere_radii_var = m_multiscattering_lut_shader_program->variable(
"atmosphere_radii"))
1080 m_multiscattering_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->
update(atmosphere_radii);});
1082 if (
auto rayleigh_parameters_var = m_multiscattering_lut_shader_program->variable(
"rayleigh_parameters"))
1084 m_multiscattering_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
1086 if (
auto mie_parameters_var = m_multiscattering_lut_shader_program->variable(
"mie_parameters"))
1088 m_multiscattering_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
1090 if (
auto ozone_distribution_var = m_multiscattering_lut_shader_program->variable(
"ozone_distribution"))
1092 m_multiscattering_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
1094 if (
auto ozone_absorption_var = m_multiscattering_lut_shader_program->variable(
"ozone_absorption"))
1096 m_multiscattering_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
1098 if (
auto ground_albedo_var = m_multiscattering_lut_shader_program->variable(
"ground_albedo"))
1100 m_multiscattering_lut_command_buffer.emplace_back([&, ground_albedo_var](){ground_albedo_var->update(m_ground_albedo);});
1102 if (
auto resolution_var = m_multiscattering_lut_shader_program->variable(
"resolution"))
1104 m_multiscattering_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->
update(
math::fvec2(m_multiscattering_lut_resolution));});
1106 if (
auto transmittance_lut_var = m_multiscattering_lut_shader_program->variable(
"transmittance_lut"))
1108 m_multiscattering_lut_command_buffer.emplace_back([&, transmittance_lut_var](){transmittance_lut_var->update(*m_transmittance_lut_texture);});
1111 m_multiscattering_lut_command_buffer.emplace_back
1123 void sky_pass::rebuild_luminance_lut_framebuffer()
1126 m_luminance_lut_texture = std::make_shared<gl::texture_2d>
1128 std::make_shared<gl::image_view_2d>
1130 std::make_shared<gl::image_2d>
1133 m_luminance_lut_resolution.x(),
1134 m_luminance_lut_resolution.y()
1144 m_luminance_lut_texture->get_image_view(),
1147 m_luminance_lut_framebuffer = std::make_shared<gl::framebuffer>(attachments, m_luminance_lut_resolution.x(), m_luminance_lut_resolution.y());
1150 void sky_pass::rebuild_luminance_lut_shader_program()
1152 m_luminance_lut_shader_program = m_luminance_lut_shader_template->build
1155 {
"SAMPLE_COUNT", std::to_string(m_luminance_lut_sample_count)}
1158 if (!m_luminance_lut_shader_program->linked())
1160 debug::log_error(
"Failed to build sky luminance LUT shader program: {}", m_luminance_lut_shader_program->info());
1165 void sky_pass::rebuild_luminance_lut_command_buffer()
1167 m_luminance_lut_command_buffer.clear();
1169 if (!m_luminance_lut_shader_program->linked() || !m_luminance_lut_texture)
1175 m_luminance_lut_command_buffer.emplace_back
1183 static_cast<float>(m_luminance_lut_resolution.x()),
1184 static_cast<float>(m_luminance_lut_resolution.y())
1194 if (
auto light_direction_var = m_luminance_lut_shader_program->variable(
"light_direction"))
1196 m_luminance_lut_command_buffer.emplace_back([&, light_direction_var](){light_direction_var->
update(dominant_light_direction);});
1198 if (
auto light_illuminance_var = m_luminance_lut_shader_program->variable(
"light_illuminance"))
1200 m_luminance_lut_command_buffer.emplace_back([&, light_illuminance_var](){light_illuminance_var->update(dominant_light_illuminance);});
1202 if (
auto atmosphere_radii_var = m_luminance_lut_shader_program->variable(
"atmosphere_radii"))
1204 m_luminance_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->
update(atmosphere_radii);});
1206 if (
auto observer_position_var = m_luminance_lut_shader_program->variable(
"observer_position"))
1208 m_luminance_lut_command_buffer.emplace_back([&, observer_position_var](){observer_position_var->
update(observer_position);});
1210 if (
auto rayleigh_parameters_var = m_luminance_lut_shader_program->variable(
"rayleigh_parameters"))
1212 m_luminance_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
1214 if (
auto mie_parameters_var = m_luminance_lut_shader_program->variable(
"mie_parameters"))
1216 m_luminance_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
1218 if (
auto ozone_distribution_var = m_luminance_lut_shader_program->variable(
"ozone_distribution"))
1220 m_luminance_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
1222 if (
auto ozone_absorption_var = m_luminance_lut_shader_program->variable(
"ozone_absorption"))
1224 m_luminance_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
1226 if (
auto airglow_luminance_var = m_luminance_lut_shader_program->variable(
"airglow_luminance"))
1228 m_luminance_lut_command_buffer.emplace_back([&, airglow_luminance_var](){airglow_luminance_var->update(airglow_luminance * camera_exposure);});
1230 if (
auto resolution_var = m_luminance_lut_shader_program->variable(
"resolution"))
1232 m_luminance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->
update(
math::fvec2(m_luminance_lut_resolution));});
1234 if (
auto transmittance_lut_var = m_luminance_lut_shader_program->variable(
"transmittance_lut"))
1236 m_luminance_lut_command_buffer.emplace_back([&, transmittance_lut_var](){transmittance_lut_var->update(*m_transmittance_lut_texture);});
1238 if (
auto multiscattering_lut_var = m_luminance_lut_shader_program->variable(
"multiscattering_lut"))
1240 m_luminance_lut_command_buffer.emplace_back([&, multiscattering_lut_var](){multiscattering_lut_var->update(*m_multiscattering_lut_texture);});
1243 m_luminance_lut_command_buffer.emplace_back
1255 void sky_pass::rebuild_sky_probe_command_buffer()
1257 m_sky_probe_command_buffer.clear();
1259 if (!m_sky_probe_shader_program->linked() || m_sky_probe_framebuffers.empty())
1265 m_sky_probe_command_buffer.emplace_back
1269 const auto resolution = m_sky_probe->get_luminance_texture()->get_image_view()->get_image()->get_dimensions()[0];
1274 static_cast<float>(resolution),
1275 static_cast<float>(resolution)
1285 if (
auto luminance_lut_var = m_sky_probe_shader_program->variable(
"luminance_lut"))
1287 m_sky_probe_command_buffer.emplace_back([&, luminance_lut_var](){luminance_lut_var->update(*m_luminance_lut_texture);});
1289 if (
auto light_direction_var = m_sky_probe_shader_program->variable(
"light_direction"))
1291 m_sky_probe_command_buffer.emplace_back([&, light_direction_var](){light_direction_var->
update(dominant_light_direction);});
1293 if (
auto light_illuminance_var = m_sky_probe_shader_program->variable(
"light_illuminance"))
1295 m_sky_probe_command_buffer.emplace_back([&, light_illuminance_var](){light_illuminance_var->update(dominant_light_illuminance);});
1297 if (
auto observer_position_var = m_sky_probe_shader_program->variable(
"observer_position"))
1299 m_sky_probe_command_buffer.emplace_back([&, observer_position_var](){observer_position_var->
update(observer_position);});
1301 if (
auto atmosphere_radii_var = m_sky_probe_shader_program->variable(
"atmosphere_radii"))
1303 m_sky_probe_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->
update(atmosphere_radii);});
1305 if (
auto ground_albedo_var = m_sky_probe_shader_program->variable(
"ground_albedo"))
1307 m_sky_probe_command_buffer.emplace_back([&, ground_albedo_var](){ground_albedo_var->update(m_ground_albedo);});
1311 m_sky_probe_command_buffer.emplace_back
1317 m_sky_probe->set_luminance_outdated(
true);
1318 m_sky_probe->set_illuminance_outdated(
true);
constexpr const std::array< std::uint32_t, 2 > & dimensions() const noexcept
Returns the dimensions of the framebuffer.
Graphics pipeline interface.
void set_stencil_op(std::uint8_t face_mask, stencil_op fail_op, stencil_op pass_op, stencil_op depth_fail_op, gl::compare_op compare_op)
Sets the stencil operations.
void set_primitive_topology(primitive_topology topology)
Sets the primitive topology to use for drawing.
void clear_attachments(std::uint8_t mask, const clear_value &value)
Clears the color, depth, or stencil buffers of current attachments.
void bind_shader_program(const gl::shader_program *shader_program)
Sets the vertex input.
void bind_framebuffer(const gl::framebuffer *framebuffer)
Sets the vertex input.
void set_stencil_write_mask(std::uint8_t face_mask, std::uint32_t write_mask)
Sets the stencil write mask.
void set_color_blend_enabled(bool enabled)
Controls whether blending is enabled for the corresponding color attachment.
void set_cull_mode(cull_mode mode)
Sets the triangle culling mode.
void set_stencil_test_enabled(bool enabled)
Controls whether stencil testing is enabled.
void set_viewport(std::uint32_t first_viewport, std::span< const viewport > viewports)
Sets one or more viewports.
void set_stencil_reference(std::uint8_t face_mask, std::uint32_t reference)
Sets the stencil reference value.
void bind_vertex_buffers(std::uint32_t first_binding, std::span< const vertex_buffer *const > buffers, std::span< const std::size_t > offsets, std::span< const std::size_t > strides)
Binds vertex buffers.
void set_color_blend_equation(const color_blend_equation &equation)
Sets the color blend factors and operations.
void draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance)
Draws primitives.
constexpr const std::array< std::uint32_t, 2 > & get_default_framebuffer_dimensions() const noexcept
Returns the dimensions of the default framebuffer.
void set_depth_test_enabled(bool enabled)
Controls whether depth testing is enabled.
void bind_vertex_array(const vertex_array *array)
Binds a vertex array.
void set_stencil_compare_mask(std::uint8_t face_mask, std::uint32_t compare_mask)
Sets the stencil compare mask.
Template used to for generating one or more shader variants from a single source.
std::unique_ptr< gl::shader_program > build(const dictionary_type &definitions={}) const
Configures and compiles shader objects, then links them into a shader program.
virtual void update(bool value) const
Updates the value of the variable.
const std::shared_ptr< gl::shader_template > & get_shader_template() const noexcept
Returns the shader template with which this material is associated.
material()=default
Constructs a material.
const std::shared_ptr< gl::vertex_buffer > & get_vertex_buffer() const noexcept
Returns the vertex buffer associated with this model.
const std::vector< model_group > & get_groups() const noexcept
Returns the model's model groups.
const std::shared_ptr< gl::vertex_array > & get_vertex_array() const noexcept
Returns the vertex array associated with this model.
gl::pipeline * m_pipeline
const gl::framebuffer * m_framebuffer
void set_magnification(float scale)
void set_sky_probe(std::shared_ptr< scene::light_probe > probe)
void set_luminance_lut_sample_count(std::uint16_t count)
Sets the number of luminance integration samples.
void set_mie_parameters(float scale_height, float scattering, float extinction, float anisotropy)
void set_moon_planetlight_direction(const math::fvec3 &direction)
void set_multiscattering_lut_direction_sample_count(std::uint16_t count)
Sets the number of multiscattering directions to sample.
void set_sun_position(const math::fvec3 &position)
void set_ground_albedo(const math::fvec3 &albedo)
void set_transmittance_lut_resolution(const math::vec2< std::uint16_t > &resolution)
Sets the resolution of the transmittance LUT.
void set_rayleigh_parameters(float scale_height, const math::fvec3 &scattering)
void set_moon_sunlight_direction(const math::fvec3 &direction)
void set_ozone_parameters(float lower_limit, float upper_limit, float mode, const math::fvec3 &absorption)
void set_multiscattering_lut_scatter_sample_count(std::uint16_t count)
Sets the number of multiscattering scatter events to sample per sample direction.
void set_transmittance_lut_sample_count(std::uint16_t count)
Sets the number of transmittance integration samples.
void set_airglow_luminance(const math::fvec3 &luminance)
void set_observer_elevation(float elevation)
void set_multiscattering_lut_resolution(const math::vec2< std::uint16_t > &resolution)
Sets the resolution of the multiscattering LUT.
void set_moon_sunlight_illuminance(const math::fvec3 &illuminance)
void set_moon_rotation(const math::fquat &rotation)
void set_icrf_to_eus(const math::se3< float > &transformation)
void set_moon_model(std::shared_ptr< render::model > model)
void set_atmosphere_upper_limit(float limit)
void set_luminance_lut_resolution(const math::vec2< std::uint16_t > &resolution)
Sets the resolution of the luminance LUT.
void render(render::context &ctx) override
void set_sun_illuminance(const math::fvec3 &illuminance, const math::fvec3 &transmitted_illuminance)
void set_moon_angular_radius(float angular_radius)
void set_moon_planetlight_illuminance(const math::fvec3 &illuminance)
void set_sun_angular_radius(float radius)
sky_pass(gl::pipeline *pipeline, const gl::framebuffer *framebuffer, resource_manager *resource_manager)
void set_moon_position(const math::fvec3 &position)
void set_moon_illuminance(const math::fvec3 &illuminance, const math::fvec3 &transmitted_illuminance)
void set_sky_model(std::shared_ptr< render::model > model)
void set_sun_luminance(const math::fvec3 &luminance)
void set_planet_radius(float radius)
void set_stars_model(std::shared_ptr< render::model > model)
Manages the loading, caching, and saving of resources.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
constexpr const math::fmat4 & get_projection() const noexcept
Returns the camera's projection matrix.
constexpr const math::fmat4 & get_view() const noexcept
Returns the camera's view matrix.
geom::ray< float, 3 > pick(const math::fvec2 &ndc) const
Constructs a picking ray from normalized device coordinates (NDC).
constexpr float get_clip_near() const noexcept
Returns the signed distance to the camera's near clipping plane.
constexpr float get_exposure_normalization() const noexcept
Returns the camera's exposure normalization factor.
constexpr const math::fmat4 & get_inv_view() const noexcept
Returns the inverse of the camera's view matrix.
constexpr const math::fmat4 & get_inv_projection() const noexcept
Returns the inverse of the camera's projection matrix.
constexpr std::uint32_t get_layer_mask() const noexcept
Returns the layer mask of the object.
constexpr const vector_type & get_translation() const noexcept
Returns the translation of the object.
void update()
Sets state 0 = state 1.
value_type interpolate(scalar_type a) const
Returns an interpolated state between state 0 and state 1.
T angular_radius(T radius, T distance)
Finds the angular radius of a celestial object, given its radius and distance.
constexpr int count(T x) noexcept
Returns the number of set bits in a value, known as a population count or Hamming weight.
Commands which operate on entity::id components.
log_message< log_message_severity::warning, Args... > log_warning
Formats and logs a warning message.
log_message< log_message_severity::error, Args... > log_error
Formats and logs an error message.
@ clamp_to_edge
Clamp to edge wrap mode.
@ color_attachment_bit
Framebuffer color attachment.
@ back
Back-facing triangles are discarded.
@ vertex
Vertex shader stage.
@ stencil_face_front_and_back
Both sets of stencil state are updated.
@ linear
Linear filtering.
@ linear
Linear filtering.
@ keep
Keeps the current value.
@ replace
Sets the value to reference.
@ point_list
Separate point primitives.
@ triangle_list
Separate triangle primitives.
@ color_clear_bit
Indicates the color buffer should be cleared.
@ depth_clear_bit
Indicates the depth buffer should be cleared.
@ stencil_clear_bit
Indicates the stencil buffer should be cleared.
@ not_equal
Comparison evaluates reference != test.
@ always
Comparison always evaluates true.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
quaternion< T > rotation(const vec3< T > &from, const vec3< T > &to, T tolerance=T{1e-6})
Constructs a quaternion representing the minimum rotation from one direction to another direction.
constexpr mat4< T > scale(const vec3< T > &v)
Constructs a scale matrix.
constexpr matrix< T, N, M >::column_vector_type & get(matrix< T, N, M > &m) noexcept
Extracts the Ith column from a matrix.
constexpr matrix< T, M, N > transpose(const matrix< T, N, M > &m) noexcept
Calculates the transpose of a matrix.
constexpr matrix< T, N, N > inverse(const matrix< T, N, N > &m) noexcept
Calculates the inverse of a square matrix.
T extinction(T scattering, T albedo)
Calculates an extinction coefficient.
T absorption(T scattering, T albedo)
Calculates an absorption coefficient.
T scattering(T density, T polarization, T wavelength)
Calculates a wavelength-dependent scattering coefficient.
@ position
Vertex position (vec3)
Viewport position, dimensions, and depth range.
float width
Width of the viewport.
float height
Height of the viewport.
n by m column-major matrix.
Quaternion composed of a real scalar part and imaginary vector part.
static constexpr quaternion identity() noexcept
Returns a rotation identity quaternion.
SE(3) proper rigid transformation (rototranslation).
quaternion_type r
Quaternion representing the rotation component of the transformation.
vector_type t
Vector representing the translation component of the transformation.
constexpr element_type & x() noexcept
Returns a reference to the first element.
constexpr element_type & y() noexcept
Returns a reference to the second element.
const scene::camera * camera
Pointer to the camera.
float alpha
Subframe interpolation factor.