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

147 lines
4.7 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_SCENE_LIGHT_PROBE_HPP
  20. #define ANTKEEPER_SCENE_LIGHT_PROBE_HPP
  21. #include <engine/scene/object.hpp>
  22. #include <engine/gl/texture-1d.hpp>
  23. #include <engine/gl/texture-cube.hpp>
  24. #include <engine/gl/framebuffer.hpp>
  25. #include <engine/math/matrix.hpp>
  26. #include <memory>
  27. #include <span>
  28. #include <vector>
  29. namespace scene {
  30. /**
  31. *
  32. */
  33. class light_probe: public object<light_probe>
  34. {
  35. public:
  36. /// Constructs a light probe.
  37. light_probe();
  38. /**
  39. * Updates the light probe's illuminance matrices from its illuminance texture.
  40. *
  41. * @warning Reads texture data from the GPU.
  42. */
  43. void update_illuminance_matrices();
  44. /**
  45. * Sets the light probe's luminance texture.
  46. *
  47. * @param texture Luminance cubemap texture.
  48. *
  49. * @note Marks the light probe's luminance as outdated if the luminance texture has changed.
  50. * @note Marks the light probe's illuminance as outdated if the luminance texture has changed.
  51. */
  52. void set_luminance_texture(std::shared_ptr<gl::texture_cube> texture);
  53. /**
  54. * Marks the light probe's luminance as either outdated or current.
  55. *
  56. * @param outdated `true` if the light probe's luminance is outdated, `false` otherwise.
  57. */
  58. void set_luminance_outdated(bool outdated);
  59. /**
  60. * Marks the light probe's illuminance as either outdated or current.
  61. *
  62. * @param outdated `true` if the light probe's illuminance is outdated, `false` otherwise.
  63. */
  64. void set_illuminance_outdated(bool outdated);
  65. /// Returns the light probe's luminance texture.
  66. [[nodiscard]] inline const std::shared_ptr<gl::texture_cube>& get_luminance_texture() const noexcept
  67. {
  68. return m_luminance_texture;
  69. }
  70. /// Returns the light probe's luminance framebuffers.
  71. [[nodiscard]] inline const std::vector<std::shared_ptr<gl::framebuffer>>& get_luminance_framebuffers() const noexcept
  72. {
  73. return m_luminance_framebuffers;
  74. }
  75. /**
  76. * Returns the light probe's illuminance texture.
  77. *
  78. * The illuminance texture is a 12x1 RGBA floating-point LUT which encodes the column vectors of three spherical harmonics illuminance matrices in the layout `R0,R1,R2,R3,G0,G1,G2,G3,B0,B1,B2,B3`. The matrices `R`, `G`, and `B` can be used to recover illuminance of the red, green, and blue color channels, respectively, for a given surface normal, `n`, as follows: `(dot(n, R * n), dot(n, G * n), dot(n, B * n))`, where `n = (x, y, z, 1)`.
  79. */
  80. [[nodiscard]] inline const std::shared_ptr<gl::texture_1d>& get_illuminance_texture() const noexcept
  81. {
  82. return m_illuminance_texture;
  83. }
  84. /// Returns the light probe's illuminance framebuffer.
  85. [[nodiscard]] inline const std::shared_ptr<gl::framebuffer>& get_illuminance_framebuffer() const noexcept
  86. {
  87. return m_illuminance_framebuffer;
  88. }
  89. /**
  90. * Returns the light probe's illuminance matrices.
  91. *
  92. * @return Red, green, and blue illuminance matrices.
  93. *
  94. * @warning The light probe's illuminance matrices must first be updated.
  95. *
  96. * @see light_probe::update_illuminance_matrices()
  97. */
  98. [[nodiscard]] inline std::span<const math::matrix4<float>, 3> get_illuminance_matrices() const noexcept
  99. {
  100. return m_illuminance_matrices;
  101. }
  102. /// Returns `true` if the light probe's luminance is outdated.
  103. [[nodiscard]] inline bool is_luminance_outdated() const noexcept
  104. {
  105. return m_luminance_outdated;
  106. }
  107. /// Returns `true` if the light probe's illuminance is outdated.
  108. [[nodiscard]] inline bool is_illuminance_outdated() const noexcept
  109. {
  110. return m_illuminance_outdated;
  111. }
  112. [[nodiscard]] inline const aabb_type& get_bounds() const noexcept override
  113. {
  114. return m_bounds;
  115. }
  116. private:
  117. void transformed() override;
  118. aabb_type m_bounds{};
  119. std::shared_ptr<gl::texture_cube> m_luminance_texture;
  120. std::vector<std::shared_ptr<gl::framebuffer>> m_luminance_framebuffers;
  121. std::shared_ptr<gl::texture_1d> m_illuminance_texture;
  122. std::shared_ptr<gl::framebuffer> m_illuminance_framebuffer;
  123. math::matrix4<float> m_illuminance_matrices[3];
  124. bool m_luminance_outdated{};
  125. bool m_illuminance_outdated{};
  126. };
  127. } // namespace scene
  128. #endif // ANTKEEPER_SCENE_LIGHT_PROBE_HPP