Матрица вида-проекции направленного источника
This commit is contained in:
parent
ce3b28c054
commit
86de8dc102
|
@ -81,7 +81,10 @@ class Sun
|
|||
|
||||
alignas(16) glm::vec3 direction; // Направление лучей источника
|
||||
alignas(16) glm::vec3 color; // Цвет
|
||||
alignas(16) glm::mat4 vp; // Матрица вида-проекции источника
|
||||
|
||||
void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции
|
||||
|
||||
static Sun instance; // Экземпляр синглтона
|
||||
static bool uploadReq; // Необходимость загрузки в следствии изменений
|
||||
};
|
||||
|
|
|
@ -264,6 +264,8 @@ Sun& Sun::get()
|
|||
// Загрузка данных об источнике на шейдер
|
||||
void Sun::upload(UBO& sun_data)
|
||||
{
|
||||
instance.recalcVP(); // Пересчет матрицы вида-проекции источника по необходимости (влияет на флаг uploadReq)
|
||||
|
||||
if (uploadReq)
|
||||
{
|
||||
sun_data.loadSub(&instance, sizeof(instance));
|
||||
|
@ -299,3 +301,42 @@ glm::vec3& Sun::e_color()
|
|||
|
||||
return instance.color;
|
||||
}
|
||||
|
||||
// Пересчитывает по необходимости матрицу вида-проекции
|
||||
void Sun::recalcVP()
|
||||
{
|
||||
std::pair <bool, const glm::vec4*> camProjCoords = Camera::current().getProjCoords();
|
||||
|
||||
// Есть изменения по источнику или камере
|
||||
if (uploadReq || camProjCoords.first)
|
||||
{
|
||||
uploadReq = true; // Требуется загрузка в следствии пересчета матрицы
|
||||
|
||||
glm::vec3 mean = glm::vec3(0); // Среднее арифметическое
|
||||
glm::vec4 max, min; // макс и мин координаты
|
||||
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);
|
||||
|
||||
// Примем первую точку как минимальную и максимальную (приведя в пространство вида источника)
|
||||
min = max = lightView * camProjCoords.second[0];
|
||||
// Для оставшихся точек
|
||||
for (int i = 1; i < 8; i++)
|
||||
{
|
||||
// Приведем в пространство вида источника
|
||||
point = lightView * camProjCoords.second[i];
|
||||
max = glm::max(max, point);
|
||||
min = glm::min(min, point);
|
||||
}
|
||||
|
||||
// Максимальное значение глубины
|
||||
max.z = std::max(fabs(max.z), fabs(min.z));
|
||||
// На основании максимальных и минимальных координат создадим матрицу проекции источника
|
||||
vp = glm::ortho(min.x, max.x, min.y, max.y, min.z, max.z) * lightView;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue