/* * 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 . */ #ifndef ANTKEEPER_RENDER_SKY_PASS_HPP #define ANTKEEPER_RENDER_SKY_PASS_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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& 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& 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& 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& 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& 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& 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 model); void set_moon_model(std::shared_ptr model); void set_stars_model(std::shared_ptr model); void set_icrf_to_eus(const math::se3& 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 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 m_transmittance_lut_resolution{256, 64}; std::unique_ptr m_transmittance_lut_texture; std::unique_ptr m_transmittance_lut_framebuffer; std::shared_ptr m_transmittance_lut_shader_template; std::unique_ptr m_transmittance_lut_shader_program; std::vector> 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 m_multiscattering_lut_resolution{32, 32}; std::unique_ptr m_multiscattering_lut_texture; std::unique_ptr m_multiscattering_lut_framebuffer; std::shared_ptr m_multiscattering_lut_shader_template; std::unique_ptr m_multiscattering_lut_shader_program; std::vector> m_multiscattering_lut_command_buffer; bool m_render_multiscattering_lut{false}; // Luminance std::uint16_t m_luminance_lut_sample_count{30}; math::vec2 m_luminance_lut_resolution{200, 100}; std::unique_ptr m_luminance_lut_texture; std::unique_ptr m_luminance_lut_framebuffer; std::shared_ptr m_luminance_lut_shader_template; std::unique_ptr m_luminance_lut_shader_program; std::vector> m_luminance_lut_command_buffer; bool m_render_luminance_lut{false}; // Sky probe std::shared_ptr m_sky_probe; std::vector> m_sky_probe_framebuffers; std::shared_ptr m_sky_probe_shader_template; std::unique_ptr m_sky_probe_shader_program; std::vector> 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 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 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 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 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 m_moon_albedo_map; std::shared_ptr m_moon_normal_map; std::shared_ptr 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 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 sun_position_tween; tween sun_luminance_tween; tween sun_illuminance_tween; math::fvec3 sun_transmitted_illuminance; tween icrf_to_eus_translation; tween icrf_to_eus_rotation; tween moon_position_tween; tween moon_rotation_tween; tween moon_angular_radius_tween; tween moon_sunlight_direction_tween; tween moon_sunlight_illuminance_tween; tween moon_planetlight_direction_tween; tween moon_planetlight_illuminance_tween; tween moon_illuminance_tween; math::fvec3 moon_transmitted_illuminance; float sun_angular_radius; float atmosphere_upper_limit; math::fvec4 atmosphere_radii; float observer_elevation; tween 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