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

245 lines
6.9 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_DIRECTIONAL_LIGHT_HPP
  20. #define ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP
  21. #include <engine/scene/light.hpp>
  22. #include <engine/gl/texture-2d.hpp>
  23. #include <engine/math/vector.hpp>
  24. #include <memory>
  25. #include <vector>
  26. #include <span>
  27. namespace scene {
  28. /**
  29. * Light source with parallel rays and constant intensity.
  30. */
  31. class directional_light: public light
  32. {
  33. public:
  34. /// Creates a directional light.
  35. directional_light();
  36. /// Returns light_type::directional.
  37. [[nodiscard]] inline light_type get_light_type() const noexcept override
  38. {
  39. return light_type::directional;
  40. }
  41. /// @name Light
  42. /// @{
  43. /**
  44. * Sets the direction of the directional light.
  45. *
  46. * @param direction Unit-length light direction vector.
  47. */
  48. void set_direction(const math::fvec3& direction);
  49. /**
  50. * Sets the color of the light.
  51. *
  52. * @param color Light color.
  53. */
  54. inline void set_color(const math::fvec3& color) noexcept
  55. {
  56. m_color = color;
  57. color_updated();
  58. }
  59. /**
  60. * Sets the illuminance of the light on a surface perpendicular to the light direction.
  61. *
  62. * @param illuminance Illuminance on a surface perpendicular to the light direction.
  63. */
  64. inline void set_illuminance(float illuminance) noexcept
  65. {
  66. m_illuminance = illuminance;
  67. illuminance_updated();
  68. }
  69. /// Returns a unit vector pointing in the light direction.
  70. [[nodiscard]] inline constexpr const math::fvec3& get_direction() const noexcept
  71. {
  72. return m_direction;
  73. }
  74. /// Returns the color of the light.
  75. [[nodiscard]] inline constexpr const math::fvec3& get_color() const noexcept
  76. {
  77. return m_color;
  78. }
  79. /// Returns the illuminance of the light on a surface perpendicular to the light direction.
  80. [[nodiscard]] inline constexpr float get_illuminance() const noexcept
  81. {
  82. return m_illuminance;
  83. }
  84. /// Returns the color-modulated illuminance of the light on a surface perpendicular to the light direction.
  85. [[nodiscard]] inline constexpr const math::fvec3& get_colored_illuminance() const noexcept
  86. {
  87. return m_colored_illuminance;
  88. }
  89. /// @}
  90. /// @name Shadow
  91. /// @{
  92. /**
  93. * Enables or disables shadow casting.
  94. *
  95. * @param caster `true` if the light should cast shadows, `false` otherwise.
  96. */
  97. void set_shadow_caster(bool caster) noexcept;
  98. /**
  99. * Sets the shadow map framebuffer.
  100. *
  101. * @param framebuffer Pointer to a shadow map framebuffer.
  102. */
  103. void set_shadow_framebuffer(std::shared_ptr<gl::framebuffer> framebuffer) noexcept;
  104. /**
  105. * Sets the shadow bias factor for reducing self-shadowing.
  106. *
  107. * @param bias Shadow bias factor.
  108. */
  109. void set_shadow_bias(float bias) noexcept;
  110. /**
  111. * Sets the number of shadow cascades.
  112. *
  113. * @param count Number of shadow cascades, on `[1, 4]`.
  114. *
  115. * @note The number of shadow cascades will be clamped to `[1, 4]`.
  116. */
  117. void set_shadow_cascade_count(unsigned int count) noexcept;
  118. /**
  119. * Sets the distance from the camera up to which shadows are visible.
  120. *
  121. * @param distance Shadow distance.
  122. */
  123. void set_shadow_distance(float distance) noexcept;
  124. /**
  125. * Sets the shadow cascade distribution.
  126. *
  127. * @param weight Linear interpolation weight between uniform and logarithmic cascade distributions. A weight of `0.0` results in a uniform cascade distribution, while `1.0` results in a logarithmic distribution.
  128. */
  129. void set_shadow_cascade_distribution(float weight) noexcept;
  130. /// Returns `true` if the light casts shadows, `false` otherwise.
  131. [[nodiscard]] inline constexpr bool is_shadow_caster() const noexcept
  132. {
  133. return m_shadow_caster;
  134. }
  135. /// Returns the shadow map framebuffer, of `nullptr` if no shadow map framebuffer is set.
  136. [[nodiscard]] inline constexpr const std::shared_ptr<gl::framebuffer>& get_shadow_framebuffer() const noexcept
  137. {
  138. return m_shadow_framebuffer;
  139. }
  140. /// Returns the shadow bias factor.
  141. [[nodiscard]] inline constexpr float get_shadow_bias() const noexcept
  142. {
  143. return m_shadow_bias;
  144. }
  145. /// Returns the number of shadow cascades.
  146. [[nodiscard]] inline constexpr unsigned int get_shadow_cascade_count() const noexcept
  147. {
  148. return m_shadow_cascade_count;
  149. }
  150. /// Returns the distance from the camera up to which shadows are visible.
  151. [[nodiscard]] inline constexpr float get_shadow_distance() const noexcept
  152. {
  153. return m_shadow_distance;
  154. }
  155. /// Returns the shadow cascade distribution weight.
  156. [[nodiscard]] inline constexpr float get_shadow_cascade_distribution() const noexcept
  157. {
  158. return m_shadow_cascade_distribution;
  159. }
  160. /// Returns the array of shadow cascade far clipping plane distances.
  161. /// @{
  162. [[nodiscard]] inline constexpr std::span<const float> get_shadow_cascade_distances() const noexcept
  163. {
  164. return m_shadow_cascade_distances;
  165. }
  166. [[nodiscard]] inline constexpr std::span<float> get_shadow_cascade_distances() noexcept
  167. {
  168. return m_shadow_cascade_distances;
  169. }
  170. /// @}
  171. /// Returns the array of shadow cascade scale-bias matrices.
  172. [[nodiscard]] inline constexpr std::span<const math::fmat4> get_shadow_scale_bias_matrices() const noexcept
  173. {
  174. return m_shadow_scale_bias_matrices;
  175. }
  176. /// Returns the array of world-space to cascade texture-space transformation matrices.
  177. /// @{
  178. [[nodiscard]] inline constexpr std::span<const math::fmat4> get_shadow_cascade_matrices() const noexcept
  179. {
  180. return m_shadow_cascade_matrices;
  181. }
  182. [[nodiscard]] inline constexpr std::span<math::fmat4> get_shadow_cascade_matrices() noexcept
  183. {
  184. return m_shadow_cascade_matrices;
  185. }
  186. /// @}
  187. /// @}
  188. private:
  189. void transformed() override;
  190. void color_updated();
  191. void illuminance_updated();
  192. void update_shadow_scale_bias_matrices();
  193. void update_shadow_cascade_distances();
  194. math::fvec3 m_direction{0.0f, 0.0f, -1.0f};
  195. math::fvec3 m_color{1.0f, 1.0f, 1.0f};
  196. float m_illuminance{};
  197. math::fvec3 m_colored_illuminance{};
  198. bool m_shadow_caster{false};
  199. std::shared_ptr<gl::framebuffer> m_shadow_framebuffer{nullptr};
  200. float m_shadow_bias{0.005f};
  201. unsigned int m_shadow_cascade_count{4};
  202. float m_shadow_distance{1000.0f};
  203. float m_shadow_cascade_distribution{0.8f};
  204. std::vector<float> m_shadow_cascade_distances;
  205. std::vector<math::fmat4> m_shadow_cascade_matrices;
  206. std::vector<math::fmat4> m_shadow_scale_bias_matrices;
  207. };
  208. } // namespace scene
  209. #endif // ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP