Матрицы вида-проекции солнца
This commit is contained in:
parent
ac9e887ab8
commit
15795389da
|
@ -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(); // Пересчитывает по необходимости матрицу вида-проекции
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue