Compare commits

..

No commits in common. "master" and "v0.1" have entirely different histories.
master ... v0.1

6 changed files with 40 additions and 192 deletions

View File

@ -18,7 +18,6 @@ struct LightData
alignas(16) glm::vec3 color; // Цвет
alignas(16) glm::vec3 attenuation; // Радиус действия источника, линейный и квадратичный коэф. угасания
alignas(16) glm::vec4 direction_angle; // Направление и половинный угол освещенности
alignas(16) glm::mat4 vp[6]; // Матрицы проекции и трансформации в пространство источника
};
// Источник света
@ -31,7 +30,6 @@ class Light : public Node
static Light& getNew(); // Возвращает ссылку на новый источник света
void destroy(); // Уничтожает источник света
static int getCount(); // Возвращает количество источников
const glm::vec3& c_color() const; // Константный доступ к цвету
glm::vec3& e_color(); // Неконстантная ссылка для изменений цвета
@ -60,7 +58,6 @@ class Light : public Node
void toData(); // Преобразует информацию об источнике в структуру LightData
virtual void recalcMatrices(); // Метод пересчета матрицы трансформации по необходимости, должен сбрасывать флаг changed
void recalcVP(); // Пересчитывает по необходимости матрицу вида-проекции
static GLuint count; // количество используемых источников (должно быть <= MAX_LIGHTS)
static LightData data[MAX_LIGHTS]; // Массив данных по источникам света

View File

@ -15,7 +15,6 @@ struct LightData
vec3 color;
vec3 attenuation;
vec4 direction_angle;
mat4 vp[6];
};
layout(std140, binding = 2) uniform Light
@ -38,7 +37,6 @@ uniform sampler2D gNormal;
uniform sampler2D gDiffuseP;
uniform sampler2D gAmbientSpecular;
uniform sampler2DArray sunShadowDepth;
uniform samplerCubeArray pointShadowDepth;
out vec4 color;
@ -65,10 +63,8 @@ void main()
vec3 fragPosLightSpace; // Фрагмент в пространстве источника
float shadowValue; // Значение затененности
vec2 texelSize = 1.0 / textureSize(sunShadowDepth, 0).xy; // Размер текселя текстуры теней
int x, y, z; // Счетчик для PCF
int x, y; // Счетчик для PCF
float pcfDepth; // Глубина PCF
float cubemap_offset = 0.05f; // Отступ в текстурных координатах для PCF
float cubemap_depth; // Дистанция между фрагментом и источником в диапазоне [0;1]
vec4 fragPosCamSpace = camera.view * vec4(fragPos, 1); // Фрагмент в пространстве камеры
int cascade_index; // Индекс текущего каскада для вычисления теней
@ -122,30 +118,6 @@ void main()
// Цикл по источникам света
int i;
for (i = 0; i < light_f.count; i++)
{
// Обнулим значение тени
shadowValue = 0;
// Позиция фрагмента относительно источника
fragPosLightSpace = fragPos - light_f.data[i].position;
// Дистанция между фрагментом и источником в диапазоне [0;1]
cubemap_depth = length(fragPosLightSpace) / light_f.data[i].attenuation.r;
// Сдвиг для решения проблемы акне
cubemap_depth -= max(0.05 * (1.0 - dot(N, light_f.data[i].direction_angle.xyz)), 0.005);
for(x = -1; x <= 1; ++x)
{
for(y = -1; y <= 1; ++y)
{
for(z = -1; z <= 1; ++z)
{
// Значение из кубической текстуры с учетом источника (i)
pcfDepth = texture(pointShadowDepth, vec4(fragPosLightSpace + vec3(x, y, z)*cubemap_offset, i)).r;
if(cubemap_depth > pcfDepth)
shadowValue += 1.0;
}
}
}
shadowValue /= (27);
if (shadowValue < 1.0)
{
// Данные об источнике относительно фрагмента
L_vertex = light_f.data[i].position - fragPos;
@ -182,9 +154,8 @@ void main()
specular *= intensity;
}
color += ( vec4(light_f.data[i].color*kd*diffuse * attenuation, 1)
+ vec4(light_f.data[i].color*ks*specular * attenuation, 1) ) * (1.0 - shadowValue);
}
color += vec4(light_f.data[i].color*kd*diffuse * attenuation, 1)
+ vec4(light_f.data[i].color*ks*specular * attenuation, 1);
}
}
}

View File

@ -1,17 +0,0 @@
#version 330 core
in vec4 FragPos;
in vec3 lightPos;
in float radius;
void main()
{
// Расстояние между источником и фрагментом
float lightDistance = length(FragPos.xyz - lightPos);
// Приведение к диапазону [0;1]
lightDistance = lightDistance / radius;
// Замена значения глубины
gl_FragDepth = lightDistance;
}

View File

@ -1,38 +0,0 @@
#version 420 core
layout (triangles, invocations = 6) in; // здесь invocations соответствует числу сторон кубической карты теней
layout (triangle_strip, max_vertices=18) out; // здесь max_vertices = 3 вершины * 6 вызовов на стороны куба
struct LightData
{
vec3 position;
vec3 color;
vec3 attenuation;
vec4 direction_angle;
mat4 vp[6];
};
layout(std140, binding = 2) uniform Light
{
LightData data[64];
int count;
} light_g;
uniform int light_i;
out vec4 FragPos;
out vec3 lightPos;
out float radius;
void main()
{
for(int i = 0; i < 3; ++i)
{
FragPos = gl_in[i].gl_Position;
lightPos = light_g.data[light_i].position;
radius = light_g.data[light_i].attenuation.r;
gl_Position = light_g.data[light_i].vp[gl_InvocationID] * gl_in[i].gl_Position;
gl_Layer = gl_InvocationID + light_i*6;
EmitVertex();
}
EndPrimitive();
}

View File

@ -98,15 +98,7 @@ void Light::toData()
{
check_id(); // Проверка на работу с корректным индексом
// Если позиция изменилась
if (data[index].position.x != result_transform[3].x
|| data[index].position.y != result_transform[3].y
|| data[index].position.z != result_transform[3].z
)
{
data[index].position = glm::vec3(result_transform[3]); // Позиция из матрицы трансформации
recalcVP(); // Пересчет матрицы вида-проекции для расчета теней
}
data[index].color = color; // Цвет
// Если радиус изменился
if (data[index].attenuation.r != radius)
@ -354,22 +346,3 @@ void Sun::recalcVP()
}
}
}
// Пересчитывает по необходимости матрицу вида-проекции
void Light::recalcVP()
{
float near_plane = 0.1f;
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), 1.0f, near_plane, radius);
data[index].vp[0] = shadowProj * glm::lookAt(position, position + glm::vec3( 1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f));
data[index].vp[1] = shadowProj * glm::lookAt(position, position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f));
data[index].vp[2] = shadowProj * glm::lookAt(position, position + glm::vec3( 0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
data[index].vp[3] = shadowProj * glm::lookAt(position, position + glm::vec3( 0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f));
data[index].vp[4] = shadowProj * glm::lookAt(position, position + glm::vec3( 0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f));
data[index].vp[5] = shadowProj * glm::lookAt(position, position + glm::vec3( 0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f));
}
// Возвращает количество источников
int Light::getCount()
{
return count;
}

View File

@ -139,11 +139,11 @@ int main(void)
// Источники света
Light& first = Light::getNew();
first.e_color() = {1.0f, 0.0f, 0.0f}; // цвет
first.e_position() = {0.3f, 0.0f, 0.6f}; // Позиция
first.e_angle() = 100.0f;
first.e_position() = {0.3f, 0.1f, 0.5f}; // Позиция
first.e_angle() = 70.0f;
Light& second = Light::getNew();
second.e_color() = {0.0f, 0.0f, 1.0f}; // цвет
second.e_position() = {-0.3f, 0.3f, 0.5f}; // Позиция
second.e_position() = {-0.3f, -0.1f, 0.5f}; // Позиция
// Uniform-буферы
UBO cameraUB(sizeof(CameraData), 0);
@ -180,7 +180,7 @@ int main(void)
lightShader.load(GL_VERTEX_SHADER, "shaders/quad.vert");
lightShader.load(GL_FRAGMENT_SHADER, "shaders/lighting.frag");
lightShader.link();
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth", "pointShadowDepth"};
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth"};
lightShader.bindTextures(gtextures_shader_names, sizeof(gtextures_shader_names)/sizeof(const char*));
// Загрузка данных о границах каскадов
glUniform1fv(lightShader.getUniformLoc("camera_cascade_distances"), CAMERA_CASCADE_COUNT, &camera_cascade_distances[1]);
@ -222,26 +222,6 @@ int main(void)
sunShadowShader.load(GL_FRAGMENT_SHADER, "shaders/empty.frag");
sunShadowShader.link();
// Размер одной стороны кубической карты
const GLuint pointShadow_resolution = 500;
// Создадим буфер кадра для рендера теней от источников света
FBO pointShadowBuffer;
// Создадим текстуры для буфера кадра
TextureCubeArray pointShadowDepth(MAX_LIGHTS, pointShadow_resolution, pointShadow_resolution, GL_DEPTH_ATTACHMENT, 5, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
// Отключим работу с цветом
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
// Активируем базовый буфер кадра
FBO::useDefault();
// Шейдер для расчета теней от точечных источников
ShaderProgram pointShadowShader;
// Загрузим шейдер
pointShadowShader.load(GL_VERTEX_SHADER, "shaders/sun_shadow.vert");
pointShadowShader.load(GL_GEOMETRY_SHADER, "shaders/point_shadow.geom");
pointShadowShader.load(GL_FRAGMENT_SHADER, "shaders/point_shadow.frag");
pointShadowShader.link();
// Модель прямоугольника
Model rectangle;
@ -274,8 +254,8 @@ int main(void)
rectangle.e_scale() = glm::vec3(4);
// Параметры материала
rectangle.material.ka = {0.2, 0.2, 0.2};
rectangle.material.kd = {0.9, 0.9, 0.9};
rectangle.material.ka = {0.4, 0.4, 0.4};
rectangle.material.kd = {0.4, 0.4, 0.4};
// Шейдер для рисования отладочных лампочек
ShaderProgram bulbShader;
@ -383,23 +363,6 @@ int main(void)
scene.render(sunShadowShader, material_data);
rectangle.render(sunShadowShader, material_data);
// Изменим размер вывода для стороны кубической карты точечного источника
glViewport(0, 0, pointShadow_resolution, pointShadow_resolution);
// Активируем буфер кадра для теней от солнца
pointShadowBuffer.use();
// Подключим шейдер для расчета теней
pointShadowShader.use();
// Очистка буфера глубины
glClear(GL_DEPTH_BUFFER_BIT);
// Для каждого источника вызывается рендер сцены
for (int i = 0; i < Light::getCount(); i++)
{
glUniform1i(pointShadowShader.getUniformLoc("light_i"), i);
// Рендерим геометрию в буфер глубины
scene.render(pointShadowShader, material_data);
rectangle.render(pointShadowShader, material_data);
}
// Изменим размер вывода для окна
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
// Активируем базовый буфер кадра
@ -415,7 +378,6 @@ int main(void)
gAmbientSpecular.use();
// Подключаем текстуры теней
sunShadowDepth.use();
pointShadowDepth.use();
// Рендерим прямоугольник с расчетом освещения
quadModel.render();