Antkeeper  0.0.1
directional-light.cpp
Go to the documentation of this file.
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 
22 #include <engine/debug/log.hpp>
23 
24 namespace scene {
25 
27 {
28  set_shadow_bias(m_shadow_bias);
29  update_shadow_cascade_distances();
30 }
31 
33 {
34  set_rotation(math::rotation(math::fvec3{0.0f, 0.0f, -1.0f}, direction));
35 }
36 
37 void directional_light::set_shadow_caster(bool caster) noexcept
38 {
39  m_shadow_caster = caster;
40 }
41 
42 void directional_light::set_shadow_framebuffer(std::shared_ptr<gl::framebuffer> framebuffer) noexcept
43 {
44  m_shadow_framebuffer = std::move(framebuffer);
45  if (m_shadow_framebuffer)
46  {
47  if (!m_shadow_texture)
48  {
49  m_shadow_texture = std::make_shared<gl::texture_2d>
50  (
51  std::static_pointer_cast<gl::image_view_2d>(m_shadow_framebuffer->attachments().front().image_view),
52  std::make_shared<gl::sampler>
53  (
60  0.0f,
61  0.0f,
62  true,
64  )
65  );
66  }
67  else
68  {
69  m_shadow_texture->set_image_view(std::static_pointer_cast<gl::image_view_2d>(m_shadow_framebuffer->attachments().front().image_view));
70  }
71  }
72  else
73  {
74  m_shadow_texture = nullptr;
75  }
76 }
77 
78 void directional_light::set_shadow_bias(float bias) noexcept
79 {
80  m_shadow_bias = bias;
81  update_shadow_scale_bias_matrices();
82 }
83 
85 {
86  m_shadow_cascade_count = std::min(std::max(count, 1u), 4u);
87  update_shadow_scale_bias_matrices();
88  update_shadow_cascade_distances();
89 }
90 
92 {
93  m_shadow_max_distance = distance;
94  update_shadow_cascade_distances();
95 }
96 
97 void directional_light::set_shadow_fade_range(float range) noexcept
98 {
99  m_shadow_fade_range = range;
100 }
101 
103 {
104  m_shadow_cascade_distribution = weight;
105  update_shadow_cascade_distances();
106 }
107 
108 void directional_light::transformed()
109 {
110  m_direction = get_rotation() * math::fvec3{0.0f, 0.0f, -1.0f};
111 }
112 
113 void directional_light::color_updated()
114 {
115  m_colored_illuminance = m_color * m_illuminance;
116 }
117 
118 void directional_light::illuminance_updated()
119 {
120  m_colored_illuminance = m_color * m_illuminance;
121 }
122 
123 void directional_light::update_shadow_scale_bias_matrices()
124 {
125  // Transform coordinate range from `[-1, 1]` to `[0, 1]` and apply shadow bias
126  auto m = math::translate(math::fvec3{0.5f, 0.5f, m_shadow_bias}) * math::scale(math::fvec3{0.5f, 0.5f, 1.0f});
127 
128  // Apply cascade scale
129  m = math::scale(math::fvec3{0.5f, 0.5f, 1.0f}) * m;
130 
131  for (unsigned int i = 0; i < m_shadow_cascade_count; ++i)
132  {
133  // Apply cascade bias
134  m_shadow_scale_bias_matrices[i] = math::translate(math::fvec3{static_cast<float>(i % 2) * 0.5f, static_cast<float>(i / 2) * 0.5f, 0.0f}) * m;
135  }
136 }
137 
138 void directional_light::update_shadow_cascade_distances()
139 {
140  if (!m_shadow_cascade_count)
141  {
142  return;
143  }
144 
145  m_shadow_cascade_distances[m_shadow_cascade_count - 1] = m_shadow_max_distance;
146  for (unsigned int i = 0; i < m_shadow_cascade_count - 1; ++i)
147  {
148  const auto weight = static_cast<float>(i + 1) / static_cast<float>(m_shadow_cascade_count);
149 
150  // Calculate linear and logarithmic distribution distances
151  const auto linear_distance = m_shadow_max_distance * weight;
152  // const auto log_distance = math::log_lerp(0.0f, m_shadow_max_distance, weight);
153 
154  // Interpolate between linear and logarithmic distribution distances
155  // cascade_distances[i] = math::lerp(linear_distance, log_distance, light.get_shadow_cascade_distribution());
156 
157  m_shadow_cascade_distances[i] = linear_distance;
158  }
159 }
160 
161 } // namespace scene
void set_shadow_fade_range(float range) noexcept
Sets the distance from the maximum shadow distance at which shadows will begin to fade out.
void set_direction(const math::fvec3 &direction)
Sets the direction of the directional light.
void set_shadow_framebuffer(std::shared_ptr< gl::framebuffer > framebuffer) noexcept
Sets the shadow map framebuffer.
void set_shadow_cascade_count(unsigned int count) noexcept
Sets the number of shadow cascades.
void set_shadow_max_distance(float distance) noexcept
Sets the maximum distance from a camera's near clipping plane up to which shadows are visible.
directional_light()
Creates a directional light.
void set_shadow_bias(float bias) noexcept
Sets the shadow bias factor for reducing self-shadowing.
void set_shadow_caster(bool caster) noexcept
Enables or disables shadow casting.
void set_shadow_cascade_distribution(float weight) noexcept
Sets the shadow cascade distribution.
void set_rotation(const quaternion_type &rotation)
Sets the rotation of the object.
Definition: object.hpp:96
constexpr const quaternion_type & get_rotation() const noexcept
Returns the rotation of the object.
Definition: object.hpp:139
constexpr int count(T x) noexcept
Returns the number of set bits in a value, known as a population count or Hamming weight.
Definition: bit-math.hpp:211
@ clamp_to_border
Clamp to border wrap mode.
@ linear
Linear filtering.
@ linear
Linear filtering.
@ greater
Comparison evaluates reference > test.
constexpr mat4< T > translate(const vec3< T > &v)
Constructs a translation matrix.
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1328
quaternion< T > rotation(const vec3< T > &from, const vec3< T > &to, T tolerance=T{1e-6})
Constructs a quaternion representing the minimum rotation from one direction to another direction.
Definition: quaternion.hpp:691
constexpr mat4< T > scale(const vec3< T > &v)
Constructs a scale matrix.
T distance(const vector< T, N > &p0, const vector< T, N > &p1)
Calculates the distance between two points.
Definition: vector.hpp:1106
constexpr vector< T, N > min(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the minimum elements of two vectors.
Definition: vector.hpp:1347
3D scene.
Definition: context.hpp:28
n-dimensional vector.
Definition: vector.hpp:44