💿🐜 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.

152 lines
6.0 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_LIGHT_PROBE_STAGE_HPP
#define ANTKEEPER_RENDER_LIGHT_PROBE_STAGE_HPP
#include <engine/render/stage.hpp>
#include <engine/gl/shader-template.hpp>
#include <engine/gl/shader-program.hpp>
#include <engine/gl/shader-variable.hpp>
#include <engine/gl/rasterizer.hpp>
#include <engine/gl/vertex-array.hpp>
#include <engine/gl/vertex-buffer.hpp>
#include <engine/resources/resource-manager.hpp>
#include <functional>
#include <memory>
#include <vector>
namespace render {
/**
* Updates light probes.
*/
class light_probe_stage: public stage
{
public:
/**
* Constructs a light probe stage.
*
* @param rasterizer GL rasterizer.
* @param resource_manager Resource manager for loading shader templates.
*
* @exception std::runtime_error Failed to build cubemap to spherical harmonics shader program.
* @exception std::runtime_error Cubemap to spherical harmonics shader program has no `cubemap` variable.
* @exception std::runtime_error Failed to build cubemap downsample shader program.
* @exception std::runtime_error Cubemap downsample shader program has no `cubemap` variable.
* @exception std::runtime_error Failed to build cubemap filter LUT shader program.
* @exception std::runtime_error Cubemap filter LUT shader program is missing one or more required shader variables.
*/
light_probe_stage(gl::rasterizer& rasterizer, ::resource_manager& resource_manager);
void execute(render::context& ctx) override;
/**
* Sets the number of samples to use when projecting luminance cubemaps into spherical harmonics.
*
* @param count Spherical harmonics sample count.
*
* @warning Triggers rebuilding of cubemap to spherical harmonics shader program.
* @warning Triggers recalculation of the illuminance of all light probes on next call to `execute()`.
*
* @exception std::runtime_error Failed to build cubemap to spherical harmonics shader program.
* @exception std::runtime_error Cubemap to spherical harmonics shader program has no `cubemap` variable.
*/
void set_sh_sample_count(std::size_t count);
/**
* Sets the number of samples to use when filtering luminance cubemap mip chains.
*
* @param count Cubemap filter sample count.
*/
void set_cubemap_filter_sample_count(std::size_t count);
/**
* Sets the mip bias to use when filtering luminance cubemap mip chains.
*
* @param bias Cubemap filter mip bias.
*
* @warning Triggers recalculation of the luminance of all light probes on next call to `execute()`.
*
* @exception std::runtime_error Failed to build cubemap filter LUT shader program.
* @exception std::runtime_error Cubemap filter LUT shader program is missing one or more required shader variables.
*/
void set_cubemap_filter_mip_bias(float bias);
/// Returns the number of samples used when projecting luminance cubemaps into spherical harmonics.
[[nodiscard]] inline std::size_t get_sh_sample_count() const noexcept
{
return m_sh_sample_count;
}
/// Returns the number of samples used when filtering luminance cubemaps.
[[nodiscard]] inline std::size_t get_cubemap_filter_sample_count() const noexcept
{
return m_cubemap_filter_sample_count;
}
private:
void rebuild_cubemap_to_sh_shader_program();
void rebuild_cubemap_downsample_shader_program();
void rebuild_cubemap_filter_lut_shader_program();
void rebuild_cubemap_filter_lut_texture();
void rebuild_cubemap_filter_shader_program();
void sh_parameters_changed();
void cubemap_filter_parameters_changed();
void update_light_probes_luminance(const std::vector<scene::object_base*>& light_probes);
void update_light_probes_illuminance(const std::vector<scene::object_base*>& light_probes);
gl::rasterizer* m_rasterizer;
std::shared_ptr<gl::shader_template> m_cubemap_to_sh_shader_template;
std::unique_ptr<gl::shader_program> m_cubemap_to_sh_shader_program;
const gl::shader_variable* m_cubemap_to_sh_cubemap_var{};
std::size_t m_sh_sample_count{512};
bool m_reproject_sh{true};
std::shared_ptr<gl::shader_template> m_cubemap_downsample_shader_template;
std::unique_ptr<gl::shader_program> m_cubemap_downsample_shader_program;
const gl::shader_variable* m_cubemap_downsample_cubemap_var{};
std::vector<std::unique_ptr<gl::framebuffer>> m_cubemap_downsample_framebuffers;
std::unique_ptr<gl::texture_cube> m_cubemap_downsample_texture;
std::unique_ptr<gl::texture_2d> m_cubemap_filter_lut_texture;
std::unique_ptr<gl::framebuffer> m_cubemap_filter_lut_framebuffer;
std::shared_ptr<gl::shader_template> m_cubemap_filter_lut_shader_template;
std::unique_ptr<gl::shader_program> m_cubemap_filter_lut_shader_program;
const gl::shader_variable* m_cubemap_filter_lut_resolution_var{};
const gl::shader_variable* m_cubemap_filter_lut_face_size_var{};
const gl::shader_variable* m_cubemap_filter_lut_mip_bias_var{};
std::shared_ptr<gl::shader_template> m_cubemap_filter_shader_template;
std::unique_ptr<gl::shader_program> m_cubemap_filter_shader_program;
const gl::shader_variable* m_cubemap_filter_cubemap_var{};
const gl::shader_variable* m_cubemap_filter_filter_lut_var{};
const gl::shader_variable* m_cubemap_filter_mip_level_var{};
std::size_t m_cubemap_filter_sample_count{32};
std::size_t m_cubemap_filter_mip_count{5};
float m_cubemap_filter_mip_bias{1.0f};
bool m_refilter_cubemaps{true};
};
} // namespace render
#endif // ANTKEEPER_RENDER_LIGHT_PROBE_STAGE_HPP