Compare commits
No commits in common. "master" and "v0.1" have entirely different histories.
|
@ -10,8 +10,6 @@
|
||||||
#define MAX_LIGHTS 64
|
#define MAX_LIGHTS 64
|
||||||
// Стандартное направление источника без поворота
|
// Стандартное направление источника без поворота
|
||||||
#define DEFAULT_LIGHT_DIRECTION glm::vec4(0.0f, 0.0f, 1.0f, 0.0f)
|
#define DEFAULT_LIGHT_DIRECTION glm::vec4(0.0f, 0.0f, 1.0f, 0.0f)
|
||||||
// Максимальное число образцов для SSAO
|
|
||||||
#define MAX_SSAO 64
|
|
||||||
|
|
||||||
// Точечный источник света
|
// Точечный источник света
|
||||||
struct LightData
|
struct LightData
|
||||||
|
@ -95,14 +93,4 @@ class Sun
|
||||||
static bool uploadReq; // Необходимость загрузки в следствии изменений
|
static bool uploadReq; // Необходимость загрузки в следствии изменений
|
||||||
};
|
};
|
||||||
|
|
||||||
// Данные для SSAO
|
|
||||||
struct SSAO_data
|
|
||||||
{
|
|
||||||
float radius = 0.05f;
|
|
||||||
float bias = 0.025f;
|
|
||||||
int size = MAX_SSAO;
|
|
||||||
alignas(16) glm::vec2 scale;
|
|
||||||
glm::vec3 samples[MAX_SSAO];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LIGHTS_H
|
#endif // LIGHTS_H
|
||||||
|
|
|
@ -39,7 +39,6 @@ uniform sampler2D gDiffuseP;
|
||||||
uniform sampler2D gAmbientSpecular;
|
uniform sampler2D gAmbientSpecular;
|
||||||
uniform sampler2DArray sunShadowDepth;
|
uniform sampler2DArray sunShadowDepth;
|
||||||
uniform samplerCubeArray pointShadowDepth;
|
uniform samplerCubeArray pointShadowDepth;
|
||||||
uniform sampler2D ssao;
|
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
@ -52,7 +51,6 @@ void main()
|
||||||
vec3 ka = texture(gAmbientSpecular, texCoord).rgb;
|
vec3 ka = texture(gAmbientSpecular, texCoord).rgb;
|
||||||
float ks = texture(gAmbientSpecular, texCoord).a;
|
float ks = texture(gAmbientSpecular, texCoord).a;
|
||||||
float p = texture(gDiffuseP, texCoord).a;
|
float p = texture(gDiffuseP, texCoord).a;
|
||||||
float ssao_value = texture(ssao, texCoord).r;
|
|
||||||
|
|
||||||
// Переменные используемые в цикле:
|
// Переменные используемые в цикле:
|
||||||
vec3 L_vertex; // Данные об источнике относительно фрагмента
|
vec3 L_vertex; // Данные об источнике относительно фрагмента
|
||||||
|
@ -81,7 +79,7 @@ void main()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Фоновая освещенность
|
// Фоновая освещенность
|
||||||
color = vec4(ka, 1) * ssao_value;
|
color = vec4(ka, 1);
|
||||||
|
|
||||||
// Расчет солнца, если его цвет не черный
|
// Расчет солнца, если его цвет не черный
|
||||||
if (length(sun.color) > 0)
|
if (length(sun.color) > 0)
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
#version 420 core
|
|
||||||
|
|
||||||
in vec2 texCoord;
|
|
||||||
|
|
||||||
out float occlusion;
|
|
||||||
|
|
||||||
uniform sampler2D gPosition;
|
|
||||||
uniform sampler2D gNormal;
|
|
||||||
uniform sampler2D noise;
|
|
||||||
|
|
||||||
layout(std140, binding = 0) uniform Camera
|
|
||||||
{
|
|
||||||
mat4 projection;
|
|
||||||
mat4 view;
|
|
||||||
vec3 position;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
layout(std140, binding = 3) uniform SSAO
|
|
||||||
{
|
|
||||||
float radius;
|
|
||||||
float bias;
|
|
||||||
int size;
|
|
||||||
vec2 scale;
|
|
||||||
vec3 samples[64];
|
|
||||||
} ssao;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// Получим информацию из текстур для данного фрагмента по текстурным координатам
|
|
||||||
vec3 fragPos = (camera.view * vec4(texture(gPosition, texCoord).xyz, 1)).xyz;
|
|
||||||
vec3 normal = normalize(texture(gNormal, texCoord).rgb);
|
|
||||||
vec3 randomVec = normalize(texture(noise, texCoord * ssao.scale).xyz);
|
|
||||||
// Расчет TBN матрицы
|
|
||||||
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
|
||||||
vec3 bitangent = cross(normal, tangent);
|
|
||||||
mat3 TBN = mat3(tangent, bitangent, normal);
|
|
||||||
|
|
||||||
float sampleDepth; // Значение глубины образца выборки
|
|
||||||
vec3 samplePos; // Выборка, ориентированная в пространстве вида камеры
|
|
||||||
vec4 sampleCoord; // Выборка, преобразованная к текстурным координатам
|
|
||||||
float rangeCheck; // Проверка диапазона
|
|
||||||
|
|
||||||
// Проинициализируем значение счетчика и запустим цикл по выборкам
|
|
||||||
occlusion = 0;
|
|
||||||
for(int i = 0; i < ssao.size; i++)
|
|
||||||
{
|
|
||||||
samplePos = TBN * ssao.samples[i]; // в TBN-пространстве
|
|
||||||
samplePos = fragPos + samplePos * ssao.radius; // в пространстве вида камеры
|
|
||||||
|
|
||||||
sampleCoord = camera.projection * vec4(samplePos, 1.0);
|
|
||||||
sampleCoord.xyz /= sampleCoord.w; // Деление на значение перспективы
|
|
||||||
sampleCoord.xyz = sampleCoord.xyz * 0.5 + 0.5; // Трансформация в диапазон [0.0; 1.0]
|
|
||||||
|
|
||||||
// Получаем значение глубины по образцу выборки
|
|
||||||
sampleDepth = (camera.view * vec4(texture(gPosition, sampleCoord.xy).rgb, 1)).z;
|
|
||||||
|
|
||||||
rangeCheck = smoothstep(0.0, 1.0, ssao.radius / abs(fragPos.z - sampleDepth));
|
|
||||||
occlusion += (sampleDepth >= samplePos.z + ssao.bias ? 1.0 : 0.0) * rangeCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
occlusion = 1 - (occlusion / ssao.size);
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec2 texCoord;
|
|
||||||
|
|
||||||
out float occlusion;
|
|
||||||
|
|
||||||
uniform sampler2D ssao;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 texelSize = 1.0 / vec2(textureSize(ssao, 0));
|
|
||||||
vec2 offset;
|
|
||||||
occlusion = 0.0;
|
|
||||||
for (int x = -2; x < 2; x++)
|
|
||||||
{
|
|
||||||
for (int y = -2; y < 2; y++)
|
|
||||||
{
|
|
||||||
offset = vec2(x, y) * texelSize;
|
|
||||||
occlusion += texture(ssao, texCoord + offset).r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
occlusion = occlusion / (4.0 * 4.0);
|
|
||||||
}
|
|
105
src/main.cpp
105
src/main.cpp
|
@ -4,7 +4,6 @@
|
||||||
#include <GLM/glm.hpp>
|
#include <GLM/glm.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
|
@ -18,8 +17,6 @@ Texture* pgNormal = NULL;
|
||||||
Texture* pgDiffuseP = NULL;
|
Texture* pgDiffuseP = NULL;
|
||||||
Texture* pgAmbientSpecular = NULL;
|
Texture* pgAmbientSpecular = NULL;
|
||||||
RBO* pgrbo = NULL;
|
RBO* pgrbo = NULL;
|
||||||
Texture* pssaoTexture = NULL;
|
|
||||||
Texture* pssaoTexture_raw = NULL;
|
|
||||||
// Размеры окна
|
// Размеры окна
|
||||||
int WINDOW_WIDTH = 800;
|
int WINDOW_WIDTH = 800;
|
||||||
int WINDOW_HEIGHT = 600;
|
int WINDOW_HEIGHT = 600;
|
||||||
|
@ -41,11 +38,6 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
// И буфера глубины
|
// И буфера глубины
|
||||||
if (pgrbo)
|
if (pgrbo)
|
||||||
pgrbo->reallocate(width, height);
|
pgrbo->reallocate(width, height);
|
||||||
// SSAO
|
|
||||||
if (pssaoTexture)
|
|
||||||
pssaoTexture->reallocate(width, height, 6, GL_RED, GL_RED);
|
|
||||||
if (pssaoTexture_raw)
|
|
||||||
pssaoTexture_raw->reallocate(width, height, 0, GL_RED, GL_RED);
|
|
||||||
|
|
||||||
// Запомним новые размеры окна
|
// Запомним новые размеры окна
|
||||||
WINDOW_WIDTH = width;
|
WINDOW_WIDTH = width;
|
||||||
|
@ -188,8 +180,7 @@ int main(void)
|
||||||
lightShader.load(GL_VERTEX_SHADER, "shaders/quad.vert");
|
lightShader.load(GL_VERTEX_SHADER, "shaders/quad.vert");
|
||||||
lightShader.load(GL_FRAGMENT_SHADER, "shaders/lighting.frag");
|
lightShader.load(GL_FRAGMENT_SHADER, "shaders/lighting.frag");
|
||||||
lightShader.link();
|
lightShader.link();
|
||||||
// Привязка текстур
|
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth", "pointShadowDepth"};
|
||||||
const char* gtextures_shader_names[] = {"gPosition", "gNormal", "gDiffuseP", "gAmbientSpecular", "sunShadowDepth", "pointShadowDepth", "ssao"};
|
|
||||||
lightShader.bindTextures(gtextures_shader_names, sizeof(gtextures_shader_names)/sizeof(const char*));
|
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]);
|
glUniform1fv(lightShader.getUniformLoc("camera_cascade_distances"), CAMERA_CASCADE_COUNT, &camera_cascade_distances[1]);
|
||||||
|
@ -251,73 +242,6 @@ int main(void)
|
||||||
pointShadowShader.load(GL_FRAGMENT_SHADER, "shaders/point_shadow.frag");
|
pointShadowShader.load(GL_FRAGMENT_SHADER, "shaders/point_shadow.frag");
|
||||||
pointShadowShader.link();
|
pointShadowShader.link();
|
||||||
|
|
||||||
// Создадим буфер для вычисления SSAO
|
|
||||||
GLuint attachments_ssao[] = { GL_COLOR_ATTACHMENT0 };
|
|
||||||
FBO ssaoBuffer(attachments_ssao, sizeof(attachments_ssao) / sizeof(GLuint));
|
|
||||||
// Создадим текстуры для буфера кадра
|
|
||||||
Texture ssaoTexture_raw(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT0, 0, GL_RED, GL_RED);
|
|
||||||
pssaoTexture_raw = &ssaoTexture_raw;
|
|
||||||
// Активируем базовый буфер кадра
|
|
||||||
FBO::useDefault();
|
|
||||||
|
|
||||||
// Стандартные параметры SSAO
|
|
||||||
SSAO_data ssao_data;
|
|
||||||
// Расчет масштабирования текстуры шума
|
|
||||||
ssao_data.scale = {WINDOW_WIDTH/4,WINDOW_HEIGHT/4};
|
|
||||||
// Генерируем случайные векторы
|
|
||||||
std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0); // Генерирует случайные вещественные числа в заданном диапазоне
|
|
||||||
std::default_random_engine generator;
|
|
||||||
glm::vec3 sample; // Выборка
|
|
||||||
for (int i = 0; i < ssao_data.size; i++)
|
|
||||||
{
|
|
||||||
sample = { randomFloats(generator) * 2.0 - 1.0
|
|
||||||
, randomFloats(generator) * 2.0 - 1.0
|
|
||||||
, randomFloats(generator)
|
|
||||||
};
|
|
||||||
sample = glm::normalize(sample);
|
|
||||||
sample *= randomFloats(generator);
|
|
||||||
|
|
||||||
// Отмасштабируем выборку
|
|
||||||
sample *= 0.1 + 0.9 * (i / (float)ssao_data.size) * (i / (float)ssao_data.size);
|
|
||||||
ssao_data.samples[i] = sample;
|
|
||||||
}
|
|
||||||
// Загрузка данных в uniform-буфер
|
|
||||||
UBO ssaoUB(&ssao_data, sizeof(SSAO_data), 4);
|
|
||||||
|
|
||||||
// Текстура шума
|
|
||||||
glm::vec3 noise_vecs[16];
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
noise_vecs[i] = { randomFloats(generator) * 2.0 - 1.0
|
|
||||||
, randomFloats(generator) * 2.0 - 1.0
|
|
||||||
, 0.0f
|
|
||||||
};
|
|
||||||
Texture noiseTexture(4,4, noise_vecs, 2, GL_RGBA32F, GL_RGB);
|
|
||||||
|
|
||||||
// Шейдер для расчета SSAO
|
|
||||||
ShaderProgram ssaoShader;
|
|
||||||
// Загрузим шейдер
|
|
||||||
ssaoShader.load(GL_VERTEX_SHADER, "shaders/quad.vert");
|
|
||||||
ssaoShader.load(GL_FRAGMENT_SHADER, "shaders/ssao.frag");
|
|
||||||
ssaoShader.link();
|
|
||||||
// Текстуры, используемые в шейдере
|
|
||||||
const char* ssaoShader_names[] = {"gPosition", "gNormal", "noise"};
|
|
||||||
ssaoShader.bindTextures(ssaoShader_names, sizeof(ssaoShader_names)/sizeof(const char*));
|
|
||||||
|
|
||||||
// Создадим буфер для размытия SSAO
|
|
||||||
FBO ssaoBlurBuffer(attachments_ssao, sizeof(attachments_ssao) / sizeof(GLuint));
|
|
||||||
// Создадим текстуры для буфера кадра
|
|
||||||
Texture ssaoTexture(WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_ATTACHMENT0, 6, GL_RED, GL_RED);
|
|
||||||
pssaoTexture = &ssaoTexture;
|
|
||||||
// Активируем базовый буфер кадра
|
|
||||||
FBO::useDefault();
|
|
||||||
|
|
||||||
// Шейдер для размытия SSAO
|
|
||||||
ShaderProgram ssaoBlurShader;
|
|
||||||
// Загрузим шейдер
|
|
||||||
ssaoBlurShader.load(GL_VERTEX_SHADER, "shaders/quad.vert");
|
|
||||||
ssaoBlurShader.load(GL_FRAGMENT_SHADER, "shaders/ssaoBlur.frag");
|
|
||||||
ssaoBlurShader.link();
|
|
||||||
|
|
||||||
// Модель прямоугольника
|
// Модель прямоугольника
|
||||||
Model rectangle;
|
Model rectangle;
|
||||||
|
|
||||||
|
@ -447,31 +371,6 @@ int main(void)
|
||||||
scene.render(gShader, material_data);
|
scene.render(gShader, material_data);
|
||||||
rectangle.render(gShader, material_data);
|
rectangle.render(gShader, material_data);
|
||||||
|
|
||||||
// Активируем буфер SSAO
|
|
||||||
ssaoBuffer.use();
|
|
||||||
// Используем шейдер для расчета SSAO
|
|
||||||
ssaoShader.use();
|
|
||||||
// Очистка буфера цвета
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
// Подключаем текстуры G-буфера
|
|
||||||
gPosition.use();
|
|
||||||
gNormal.use();
|
|
||||||
// Подключаем текстуру шума для SSAO
|
|
||||||
noiseTexture.use();
|
|
||||||
// Рендерим прямоугольник
|
|
||||||
quadModel.render();
|
|
||||||
|
|
||||||
// Активируем буфер размытия SSAO
|
|
||||||
ssaoBlurBuffer.use();
|
|
||||||
// Используем шейдер для размытия SSAO
|
|
||||||
ssaoBlurShader.use();
|
|
||||||
// Очистка буфера цвета
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
// Подключаем текстуру сырого SSAO
|
|
||||||
ssaoTexture_raw.use();
|
|
||||||
// Рендерим прямоугольник
|
|
||||||
quadModel.render();
|
|
||||||
|
|
||||||
// Изменим размер вывода для тени
|
// Изменим размер вывода для тени
|
||||||
glViewport(0, 0, sunShadow_resolution, sunShadow_resolution);
|
glViewport(0, 0, sunShadow_resolution, sunShadow_resolution);
|
||||||
// Активируем буфер кадра для теней от солнца
|
// Активируем буфер кадра для теней от солнца
|
||||||
|
@ -517,8 +416,6 @@ int main(void)
|
||||||
// Подключаем текстуры теней
|
// Подключаем текстуры теней
|
||||||
sunShadowDepth.use();
|
sunShadowDepth.use();
|
||||||
pointShadowDepth.use();
|
pointShadowDepth.use();
|
||||||
// Подключим текстуру SSAO
|
|
||||||
ssaoTexture.use();
|
|
||||||
// Рендерим прямоугольник с расчетом освещения
|
// Рендерим прямоугольник с расчетом освещения
|
||||||
quadModel.render();
|
quadModel.render();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue