Множество источников

This commit is contained in:
Ковалев Роман Евгеньевич 2023-10-19 16:15:03 +03:00 committed by re.kovalev
parent 721dc90c0c
commit 94cbecf491
4 changed files with 86 additions and 20 deletions

View File

@ -3,6 +3,11 @@
#include <GLM/glm.hpp>
#include "Buffers.h"
// Максимальное число источников света
#define MAX_LIGHTS 300
// Точечный источник света
struct LightData
{
@ -10,4 +15,15 @@ struct LightData
alignas(16) glm::vec3 color; // Цвет
};
// Источник света
class Light
{
public:
static int getUBOsize(); // Возвращает размер буфера в байтах
static void upload(UBO& lights_data); // Загрузка данных в буфер
static GLuint count; // количество используемых источников (должно быть <= MAX_LIGHTS)
static LightData data[MAX_LIGHTS]; // Массив данных по источникам света
};
#endif // LIGHTS_H

View File

@ -9,10 +9,16 @@ layout(std140, binding = 0) uniform Camera
vec3 position;
} camera;
layout(std140, binding = 2) uniform Light
struct LightData
{
vec3 position;
vec3 color;
};
layout(std140, binding = 2) uniform Light
{
LightData data[300];
int count;
} light_f;
uniform sampler2D gPosition;
@ -32,20 +38,35 @@ void main()
float ks = texture(gAmbientSpecular, texCoord).a;
float p = texture(gDiffuseP, texCoord).a;
// Данные о камере относительно фрагмента
vec3 Cam_vertex = normalize(camera.position - fragPos);
// Данные об источнике отностиельно фрагмента
vec3 L_vertex = normalize(light_f.position - fragPos);
// Диффузная составляющая
float diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0
// Переменные используемые в цикле:
vec3 L_vertex; // Данные об источнике относительно фрагмента
vec3 Cam_vertex = normalize(camera.position - fragPos); // Данные о камере относительно фрагмента
float diffuse; // Диффузная составляющая
vec3 H; // Вектор половины пути
float specular; // Зеркальная составляющая
// Вектор половины пути
vec3 H = normalize(L_vertex + Cam_vertex);
// Зеркальная составляющая
float specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p
// Фоновая освещенность
color = vec4(ka, 1);
color = vec4(ka, 1)
+ vec4(light_f.color*kd*diffuse, 1)
+ vec4(light_f.color*ks*specular, 1);
// Цикл по источникам света
int i;
for (i = 0; i < light_f.count; i++)
{
// Данные об источнике относительно фрагмента
L_vertex = light_f.data[i].position - fragPos;
// Нормирование вектора
L_vertex = normalize(L_vertex);
// Диффузная составляющая
diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0
// Вектор половины пути
H = normalize(L_vertex + Cam_vertex);
// Зеркальная составляющая
specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p
color += vec4(light_f.data[i].color*kd*diffuse, 1)
+ vec4(light_f.data[i].color*ks*specular, 1);
}
}

22
src/Lights.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "Lights.h"
GLuint Light::count = 0; // количество используемых источников (должно быть <= MAX_LIGHTS)
LightData Light::data[MAX_LIGHTS]; // Массив данных по источникам света
// возвращает размер буфера в байтах
int Light::getUBOsize()
{
return sizeof(LightData) * MAX_LIGHTS + sizeof(GLuint);
}
// Загрузка данных в буфер
void Light::upload(UBO& lights_data)
{
GLuint LightDataSize = sizeof(LightData); // Одного экземпляра структуры LightData
if (count)
lights_data.loadSub(data, sizeof(LightData)*count); // Загрузка данных об источниках
// Загружаем кол-во источников
lights_data.loadSub(&count, sizeof(count), LightDataSize*MAX_LIGHTS);
}

View File

@ -103,15 +103,20 @@ int main(void)
// Установка цвета очистки буфера цвета
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Источник света
LightData light = { {1.0f, 3.0f, 0.0f} // позиция
, {1.0f, 1.0f, 1.0f} // цвет
// Источники света
// Первый способ измений
Light::data[0] = { {0.3f, 0.1f, 0.5f} // позиция
, {1.0f, 0.0f, 0.0f} // цвет
};
Light::count++;
// Второй способ
Light::data[Light::count].position = {-0.3f, -0.1f, 0.5f}; // позиция
Light::data[Light::count++].color = { 0.0f, 0.0f, 1.0f}; // цвет
// Uniform-буферы
UBO cameraUB(sizeof(CameraData), 0);
UBO material_data(sizeof(Material), 1);
UBO light_data(&light, sizeof(LightData), 2);
UBO light_data(Light::getUBOsize(), 2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Использование уменьшенных версий mipmap
@ -155,6 +160,8 @@ int main(void)
{
// Загрузка данных о камере
cameraUB.loadSub(&Camera::current().getData(), sizeof(CameraData));
// Загрузим информацию об источниках света
Light::upload(light_data);
// Активируем G-кадра
gbuffer.use();