Матрицы вида-проекции солнца

This commit is contained in:
parent ac9e887ab8
commit 15795389da
2 changed files with 30 additions and 23 deletions

View File

@ -4,6 +4,7 @@
#include <GLM/glm.hpp> #include <GLM/glm.hpp>
#include "Model.h" #include "Model.h"
#include "Camera.h"
// Максимальное число источников света // Максимальное число источников света
#define MAX_LIGHTS 300 #define MAX_LIGHTS 300
@ -81,7 +82,7 @@ class Sun
alignas(16) glm::vec3 direction; // Направление лучей источника alignas(16) glm::vec3 direction; // Направление лучей источника
alignas(16) glm::vec3 color; // Цвет alignas(16) glm::vec3 color; // Цвет
alignas(16) glm::mat4 vp; // Матрица вида-проекции источника alignas(16) glm::mat4 vp[CAMERA_CASCADE_COUNT]; // Матрица вида-проекции источника
void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции

View File

@ -305,38 +305,44 @@ glm::vec3& Sun::e_color()
// Пересчитывает по необходимости матрицу вида-проекции // Пересчитывает по необходимости матрицу вида-проекции
void Sun::recalcVP() void Sun::recalcVP()
{ {
std::pair <bool, const glm::vec4*> camProjCoords = Camera::current().getProjCoords(); // Точки по краям проекции камеры
std::pair <bool, const glm::vec4(*)[8]> camProjCoords = Camera::current().getProjCoords();
// Есть изменения по источнику или камере // Есть изменения по источнику или камере
if (uploadReq || camProjCoords.first) if (uploadReq || camProjCoords.first)
{ {
uploadReq = true; // Требуется загрузка в следствии пересчета матрицы uploadReq = true; // Требуется загрузка в следствии пересчета матрицы
glm::vec3 mean = glm::vec3(0); // Среднее арифметическое glm::vec3 mean; // Среднее арифметическое
glm::vec4 max, min; // макс и мин координаты glm::vec4 max, min; // макс и мин координаты
glm::vec4 point; // Точка приведенная в пространство источника света glm::vec4 point; // Точка приведенная в пространство источника света
// Найдем среднее арифметическое от точек для нахождения центра прямоугольника
for (int i = 0; i < 8; i++)
mean += glm::vec3(camProjCoords.second[i]);
mean /= 8;
// Используем среднее арифметическое для получения матрицы вида параллельного источника
glm::mat4 lightView = glm::lookAt(mean + glm::normalize(direction), mean, CAMERA_UP_VECTOR);
// Примем первую точку как минимальную и максимальную (приведя в пространство вида источника) for (int cascade = 0; cascade < CAMERA_CASCADE_COUNT; cascade++)
min = max = lightView * camProjCoords.second[0];
// Для оставшихся точек
for (int i = 1; i < 8; i++)
{ {
// Приведем в пространство вида источника mean = glm::vec3(0);
point = lightView * camProjCoords.second[i]; // Найдем среднее арифметическое от точек для нахождения центра прямоугольника
max = glm::max(max, point); for (int i = 0; i < 8; i++)
min = glm::min(min, point); mean += glm::vec3(camProjCoords.second[cascade][i]);
} mean /= 8;
// Используем среднее арифметическое для получения матрицы вида параллельного источника
glm::mat4 lightView = glm::lookAt(mean + glm::normalize(direction), mean, CAMERA_UP_VECTOR);
// Максимальное значение глубины // Примем первую точку как минимальную и максимальную (приведя в пространство вида источника)
max.z = std::max(fabs(max.z), fabs(min.z)); min = max = lightView * camProjCoords.second[cascade][0];
// На основании максимальных и минимальных координат создадим матрицу проекции источника // Для оставшихся точек
vp = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView; for (int i = 1; i < 8; i++)
{
// Приведем в пространство вида источника
point = lightView * camProjCoords.second[cascade][i];
max = glm::max(max, point);
min = glm::min(min, point);
}
// Максимальное значение глубины
max.z = std::max(fabs(max.z), fabs(min.z));
// На основании максимальных и минимальных координат создадим матрицу проекции источника
vp[cascade] = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView;
}
} }
} }