💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

374 lines
13 KiB

/*
* Copyright (C) 2023 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_RENDER_SKY_PASS_HPP
#define ANTKEEPER_RENDER_SKY_PASS_HPP
#include <engine/render/pass.hpp>
#include <engine/gl/shader-template.hpp>
#include <engine/math/vector.hpp>
#include <engine/animation/tween.hpp>
#include <engine/math/quaternion.hpp>
#include <engine/gl/shader-program.hpp>
#include <engine/gl/shader-variable.hpp>
#include <engine/gl/vertex-buffer.hpp>
#include <engine/gl/vertex-array.hpp>
#include <engine/gl/texture-2d.hpp>
#include <engine/gl/drawing-mode.hpp>
#include <engine/math/se3.hpp>
#include <engine/scene/object.hpp>
#include <engine/scene/light-probe.hpp>
class resource_manager;
namespace render {
class material;
class model;
/**
*
*
* @see Hillaire, Sébastien. "A scalable and production ready sky and atmosphere rendering technique." Computer Graphics Forum. Vol. 39. No. 4. 2020.
*/
class sky_pass: public pass
{
public:
sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager);
virtual ~sky_pass() = default;
void render(render::context& ctx) override;
/// @name Transmittance LUT
/// @{
/**
* Sets the number of transmittance integration samples.
*
* @param count Integration sample count.
*
* @note Triggers rebuilding of transmittance LUT shader.
* @note Triggers rendering of transmittance LUT.
*/
void set_transmittance_lut_sample_count(std::uint16_t count);
/**
* Sets the resolution of the transmittance LUT.
*
* @param resolution Resolution of the transmittance LUT texture, in pixels.
*
* @note Triggers rendering of transmittance LUT.
*/
void set_transmittance_lut_resolution(const math::vec2<std::uint16_t>& resolution);
/// Returns the number of transmittance integration samples.
[[nodiscard]] inline std::uint16_t get_transmittance_lut_sample_count() const noexcept
{
return m_transmittance_lut_sample_count;
}
/// Returns the resolution of the transmittance LUT texture, in pixels.
[[nodiscard]] inline const math::vec2<std::uint16_t>& get_transmittance_lut_resolution() const noexcept
{
return m_transmittance_lut_resolution;
}
/// @}
/// @name Multiscattering LUT
/// @{
/**
* Sets the number of multiscattering directions to sample.
*
* @param count Multiscattering direction sample count.
*
* @note Triggers rebuilding of multiscattering LUT shader.
* @note Triggers rendering of multiscattering LUT.
*/
void set_multiscattering_lut_direction_sample_count(std::uint16_t count);
/**
* Sets the number of multiscattering scatter events to sample per sample direction.
*
* @param count Multiscattering scatter sample count.
*
* @note Triggers rebuilding of multiscattering LUT shader.
* @note Triggers rendering of multiscattering LUT.
*/
void set_multiscattering_lut_scatter_sample_count(std::uint16_t count);
/**
* Sets the resolution of the multiscattering LUT.
*
* @param resolution Resolution of the multiscattering LUT texture, in pixels.
*
* @note Triggers rendering of multiscattering LUT.
*/
void set_multiscattering_lut_resolution(const math::vec2<std::uint16_t>& resolution);
/// Returns the number of multiscattering direction samples.
[[nodiscard]] inline std::uint16_t get_multiscattering_lut_direction_sample_count() const noexcept
{
return m_multiscattering_lut_direction_sample_count;
}
/// Returns the number of multiscattering scatter samples per direction.
[[nodiscard]] inline std::uint16_t get_multiscattering_lut_scatter_sample_count() const noexcept
{
return m_multiscattering_lut_scatter_sample_count;
}
/// Returns the resolution of the multiscattering LUT texture, in pixels.
[[nodiscard]] inline const math::vec2<std::uint16_t>& get_multiscattering_lut_resolution() const noexcept
{
return m_multiscattering_lut_resolution;
}
/// @}
/// @name Luminance LUT
/// @{
/**
* Sets the number of luminance integration samples.
*
* @param count Integration sample count.
*
* @note Triggers rebuilding of luminance LUT shader.
* @note Triggers rendering of luminance LUT.
*/
void set_luminance_lut_sample_count(std::uint16_t count);
/**
* Sets the resolution of the luminance LUT.
*
* @param resolution Resolution of the luminance LUT texture, in pixels.
*
* @note Triggers rendering of luminance LUT.
*/
void set_luminance_lut_resolution(const math::vec2<std::uint16_t>& resolution);
/// Returns the number of luminance integration samples.
[[nodiscard]] inline std::uint16_t get_luminance_lut_sample_count() const noexcept
{
return m_luminance_lut_sample_count;
}
/// Returns the resolution of the luminance LUT texture, in pixels.
[[nodiscard]] inline const math::vec2<std::uint16_t>& get_luminance_lut_resolution() const noexcept
{
return m_luminance_lut_resolution;
}
/// @}
void update_tweens();
void set_magnification(float scale);
void set_sky_model(std::shared_ptr<render::model> model);
void set_moon_model(std::shared_ptr<render::model> model);
void set_stars_model(std::shared_ptr<render::model> model);
void set_icrf_to_eus(const math::se3<float>& transformation);
void set_sun_position(const math::fvec3& position);
void set_sun_luminance(const math::fvec3& luminance);
void set_sun_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance);
void set_sun_angular_radius(float radius);
void set_planet_radius(float radius);
void set_atmosphere_upper_limit(float limit);
void set_observer_elevation(float elevation);
void set_rayleigh_parameters(float scale_height, const math::fvec3& scattering);
void set_mie_parameters(float scale_height, float scattering, float extinction, float anisotropy);
void set_ozone_parameters(float lower_limit, float upper_limit, float mode, const math::fvec3& absorption);
void set_airglow_luminance(const math::fvec3& luminance);
void set_ground_albedo(const math::fvec3& albedo);
void set_moon_position(const math::fvec3& position);
void set_moon_rotation(const math::fquat& rotation);
void set_moon_angular_radius(float angular_radius);
void set_moon_sunlight_direction(const math::fvec3& direction);
void set_moon_sunlight_illuminance(const math::fvec3& illuminance);
void set_moon_planetlight_direction(const math::fvec3& direction);
void set_moon_planetlight_illuminance(const math::fvec3& illuminance);
void set_moon_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance);
void set_sky_probe(std::shared_ptr<scene::light_probe> probe);
/**
* Sets the layer mask of the sky.
*
* @param mask 32-bit layer mask in which each set bit represents a layer in which the sky is visible.
*/
inline constexpr void set_layer_mask(std::uint32_t mask) noexcept
{
m_layer_mask = mask;
}
private:
void rebuild_transmittance_lut_shader_program();
void rebuild_transmittance_lut_command_buffer();
void rebuild_multiscattering_lut_shader_program();
void rebuild_multiscattering_lut_command_buffer();
void rebuild_luminance_lut_shader_program();
void rebuild_luminance_lut_command_buffer();
void rebuild_sky_lut_command_buffer();
void rebuild_sky_probe_command_buffer();
// Transmittance
std::uint16_t m_transmittance_lut_sample_count{40};
math::vec2<std::uint16_t> m_transmittance_lut_resolution{256, 64};
std::unique_ptr<gl::texture_2d> m_transmittance_lut_texture;
std::unique_ptr<gl::framebuffer> m_transmittance_lut_framebuffer;
std::shared_ptr<gl::shader_template> m_transmittance_lut_shader_template;
std::unique_ptr<gl::shader_program> m_transmittance_lut_shader_program;
std::vector<std::function<void()>> m_transmittance_lut_command_buffer;
bool m_render_transmittance_lut{false};
// Multiscattering
std::uint16_t m_multiscattering_lut_direction_sample_count{64};
std::uint16_t m_multiscattering_lut_scatter_sample_count{20};
math::vec2<std::uint16_t> m_multiscattering_lut_resolution{32, 32};
std::unique_ptr<gl::texture_2d> m_multiscattering_lut_texture;
std::unique_ptr<gl::framebuffer> m_multiscattering_lut_framebuffer;
std::shared_ptr<gl::shader_template> m_multiscattering_lut_shader_template;
std::unique_ptr<gl::shader_program> m_multiscattering_lut_shader_program;
std::vector<std::function<void()>> m_multiscattering_lut_command_buffer;
bool m_render_multiscattering_lut{false};
// Luminance
std::uint16_t m_luminance_lut_sample_count{30};
math::vec2<std::uint16_t> m_luminance_lut_resolution{200, 100};
std::unique_ptr<gl::texture_2d> m_luminance_lut_texture;
std::unique_ptr<gl::framebuffer> m_luminance_lut_framebuffer;
std::shared_ptr<gl::shader_template> m_luminance_lut_shader_template;
std::unique_ptr<gl::shader_program> m_luminance_lut_shader_program;
std::vector<std::function<void()>> m_luminance_lut_command_buffer;
bool m_render_luminance_lut{false};
// Sky probe
std::shared_ptr<scene::light_probe> m_sky_probe;
std::vector<std::unique_ptr<gl::framebuffer>> m_sky_probe_framebuffers;
std::shared_ptr<gl::shader_template> m_sky_probe_shader_template;
std::unique_ptr<gl::shader_program> m_sky_probe_shader_program;
std::vector<std::function<void()>> m_sky_probe_command_buffer;
math::fvec3 dominant_light_direction;
math::fvec3 dominant_light_illuminance;
math::fvec3 observer_position;
float camera_exposure;
std::shared_ptr<gl::shader_program> sky_shader_program;
const gl::shader_variable* model_view_projection_var;
const gl::shader_variable* mouse_var;
const gl::shader_variable* resolution_var;
const gl::shader_variable* light_direction_var;
const gl::shader_variable* sun_luminance_var;
const gl::shader_variable* sun_angular_radius_var;
const gl::shader_variable* atmosphere_radii_var;
const gl::shader_variable* observer_position_var;
const gl::shader_variable* sky_transmittance_lut_var;
const gl::shader_variable* sky_transmittance_lut_resolution_var;
const gl::shader_variable* sky_luminance_lut_var;
const gl::shader_variable* sky_luminance_lut_resolution_var;
std::shared_ptr<gl::shader_program> moon_shader_program;
const gl::shader_variable* moon_model_var;
const gl::shader_variable* moon_view_projection_var;
const gl::shader_variable* moon_normal_model_var;
const gl::shader_variable* moon_camera_position_var;
const gl::shader_variable* moon_sunlight_direction_var;
const gl::shader_variable* moon_sunlight_illuminance_var;
const gl::shader_variable* moon_planetlight_direction_var;
const gl::shader_variable* moon_planetlight_illuminance_var;
const gl::shader_variable* moon_albedo_map_var;
const gl::shader_variable* moon_normal_map_var;
const gl::shader_variable* moon_observer_position_var;
const gl::shader_variable* moon_sky_transmittance_lut_var;
const gl::shader_variable* moon_atmosphere_radii_var;
std::shared_ptr<render::model> sky_model;
const material* sky_material;
const gl::vertex_array* sky_model_vao;
gl::drawing_mode sky_model_drawing_mode;
std::size_t sky_model_start_index;
std::size_t sky_model_index_count;
std::shared_ptr<render::model> moon_model;
const material* moon_material;
const gl::vertex_array* moon_model_vao;
gl::drawing_mode moon_model_drawing_mode;
std::size_t moon_model_start_index;
std::size_t moon_model_index_count;
std::shared_ptr<gl::texture_2d> m_moon_albedo_map;
std::shared_ptr<gl::texture_2d> m_moon_normal_map;
std::shared_ptr<render::model> stars_model;
const material* star_material;
const gl::vertex_array* stars_model_vao;
gl::drawing_mode stars_model_drawing_mode;
std::size_t stars_model_start_index;
std::size_t stars_model_index_count;
std::unique_ptr<gl::shader_program> star_shader_program;
const gl::shader_variable* star_model_view_projection_var;
const gl::shader_variable* star_exposure_var;
const gl::shader_variable* star_inv_resolution_var;
math::fvec2 mouse_position;
tween<math::fvec3> sun_position_tween;
tween<math::fvec3> sun_luminance_tween;
tween<math::fvec3> sun_illuminance_tween;
math::fvec3 sun_transmitted_illuminance;
tween<math::fvec3> icrf_to_eus_translation;
tween<math::fquat> icrf_to_eus_rotation;
tween<math::fvec3> moon_position_tween;
tween<math::fquat> moon_rotation_tween;
tween<float> moon_angular_radius_tween;
tween<math::fvec3> moon_sunlight_direction_tween;
tween<math::fvec3> moon_sunlight_illuminance_tween;
tween<math::fvec3> moon_planetlight_direction_tween;
tween<math::fvec3> moon_planetlight_illuminance_tween;
tween<math::fvec3> moon_illuminance_tween;
math::fvec3 moon_transmitted_illuminance;
float sun_angular_radius;
float atmosphere_upper_limit;
math::fvec4 atmosphere_radii;
float observer_elevation;
tween<math::fvec3> observer_position_tween;
math::fvec4 rayleigh_parameters;
math::fvec4 mie_parameters;
math::fvec3 ozone_distribution;
math::fvec3 ozone_absorption;
math::fvec3 airglow_luminance;
math::fvec3 m_ground_albedo{};
float magnification;
std::uint32_t m_layer_mask{1};
};
} // namespace render
#endif // ANTKEEPER_RENDER_SKY_PASS_HPP