Переделка света

This commit is contained in:
parent 1ea6390718
commit d1ce8718f6
4 changed files with 87 additions and 55 deletions

View File

@ -12,24 +12,35 @@
// Максимальное число образцов для SSAO // Максимальное число образцов для SSAO
#define MAX_SSAO 64 #define MAX_SSAO 64
// Класс лампочки (точечный источник с возможностью отладочного вывода)
class Bulb class Bulb
{ {
public: public:
Bulb(const glm::vec3 &pos = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec3 &color = glm::vec3(0.0f, 0.0f, 0.0f), float radius = 10.0f, float angle = 180, const glm::vec3 &direction = glm::vec3(0,0,1)); // Конструктор с координатами, цветом, радиусом и направлением Bulb(const glm::vec3 &pos = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec3 &color = glm::vec3(0.0f, 0.0f, 0.0f), float radius = 10.0f, float angle = 180, const glm::vec3 &direction = glm::vec3(0,0,1)); // Конструктор с координатами, цветом, радиусом и направлением
void render(ShaderProgram &shaderProgram, UBO &material_buffer); // Отрисовка отладочной лампы и сферы void setRadius(float radius); // Задание радиуса и расчет коэф. угасания
void recalc_pov(); // Пересчитывает матрицы проекции и трансформации в пространство источника
alignas(16) glm::vec3 position; // Позиция alignas(16) glm::vec3 position; // Позиция
alignas(16) glm::vec3 color; // Цвет alignas(16) glm::vec3 color; // Цвет
void setRadius(float radius); // Задание радиуса и расчет коэф. угасания
float angle; // Угол освещенности float angle; // Угол освещенности
alignas(16) glm::vec3 direction; // Направление для прожектора alignas(16) glm::vec3 direction; // Направление для прожектора
void recalc_pov(); // Пересчитывает матрицы проекции и трансформации в пространство источника
private: private:
float radius; // Радиус действия источника float radius; // Радиус действия источника
alignas(16) glm::vec2 K; // линейный и квадратичный компоненты затухания alignas(16) glm::vec2 K; // линейный и квадратичный компоненты затухания
alignas(16) glm::mat4 vp[6]; // Матрицы проекции и трансформации в пространство источника alignas(16) glm::mat4 vp[6]; // Матрицы проекции и трансформации в пространство источника
friend class BulbDebug;
};
// Класс лампочки (точечный источник с возможностью отладочного вывода)
class BulbDebug
{
public:
BulbDebug(Bulb* ref = NULL); // Конструктор с привязкой к источнику
void render(ShaderProgram &shaderProgram, UBO &material_buffer); // Отрисовка отладочной лампы и сферы
Bulb* data;
private:
static GrouptedModel bulb_model; static GrouptedModel bulb_model;
}; };

View File

@ -15,16 +15,25 @@ layout(std140, binding = 4) uniform gamma
float inv_gamma; float inv_gamma;
}; };
out vec4 color; layout (location = 1) out vec3 gNormal;
layout (location = 3) out vec4 gAmbientSpecular;
layout (location = 4) out uvec3 gID;
uniform float angle; uniform float angle;
uniform vec3 direction; uniform vec3 direction;
uniform uvec3 ID = uvec3(0);
void main() void main()
{ {
float cosA = dot(normalize(pos_local), normalize(direction)); float cosA = dot(normalize(pos_local), normalize(direction));
if (degrees(acos(cosA)) <= angle) if (degrees(acos(cosA)) <= angle)
color = vec4(pow(ka, vec3(inv_gamma)), 1); gAmbientSpecular.rgb = pow(ka, vec3(inv_gamma));
else else
discard; discard;
gNormal = vec3(0);
// Сохранение идентификатора объекта
gID = ID;
} }

View File

@ -6,10 +6,23 @@
void genShpere(Model& model, float radius, int sectorsCount); // Model.cpp void genShpere(Model& model, float radius, int sectorsCount); // Model.cpp
// Статическое поле для модели лампочки // Статическое поле для модели лампочки
GrouptedModel Bulb::bulb_model; GrouptedModel BulbDebug::bulb_model;
// Конструктор с координатами, цветом и радиусом // Конструктор с координатами, цветом и радиусом
Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm::vec3 &dir) Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm::vec3 &dir)
{
// Сохраним данные о параметрах источника:
position = pos;
color = c;
radius = r;
K[0] = 4.5/radius;
K[1] = 4 * K[0] * K[0];
angle = a;
direction = dir;
}
// Конструктор отладочной лампочки с координатами, цветом, радиусом и направлением
BulbDebug::BulbDebug(Bulb* ref) : data(ref)
{ {
// Если отладочная модель не загружена - загрузим // Если отладочная модель не загружена - загрузим
if (!bulb_model.parts.size()) if (!bulb_model.parts.size())
@ -21,19 +34,13 @@ Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm
genShpere(radius_sphere, 1, 16); genShpere(radius_sphere, 1, 16);
bulb_model.parts.insert(bulb_model.parts.begin(), radius_sphere); bulb_model.parts.insert(bulb_model.parts.begin(), radius_sphere);
} }
// Сохраним данные о параметрах источника:
position = pos;
color = c;
radius = r;
K[0] = 4.5/radius;
K[1] = 4 * K[0] * K[0];
angle = a;
direction = dir;
} }
// Отрисовка отладочной лампы и сферы // Отрисовка отладочной лампы и сферы
void Bulb::render(ShaderProgram &shaderProgram, UBO &material_buffer) void BulbDebug::render(ShaderProgram &shaderProgram, UBO &material_buffer)
{
bulb_model.set_group_id((GLuint64) this);
if (data)
{ {
// Расположение uniform-переменных // Расположение uniform-переменных
GLuint model_uniform = shaderProgram.getUniformLoc("model"); GLuint model_uniform = shaderProgram.getUniformLoc("model");
@ -41,15 +48,15 @@ void Bulb::render(ShaderProgram &shaderProgram, UBO &material_buffer)
GLuint direction_uniform = shaderProgram.getUniformLoc("direction"); GLuint direction_uniform = shaderProgram.getUniformLoc("direction");
// Загрузим направление // Загрузим направление
glUniform3fv(direction_uniform, 1, &direction[0]); glUniform3fv(direction_uniform, 1, &data->direction[0]);
// Зададим параметры материала сфере действия // Зададим параметры материала сфере действия
bulb_model.parts[0].material.ka = color; bulb_model.parts[0].material.ka = data->color;
bulb_model.parts[0].position = position; bulb_model.parts[0].position = data->position;
bulb_model.parts[0].scale = {radius, radius, radius}; bulb_model.parts[0].scale = glm::vec3(data->radius);
// Угол для сферы (рисуем направленный конус) // Угол для сферы (рисуем направленный конус)
glUniform1f(angle_uniform, angle); glUniform1f(angle_uniform, data->angle);
// Рисование сферы покрытия источника в режиме линий // Рисование сферы покрытия источника в режиме линий
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@ -60,15 +67,16 @@ void Bulb::render(ShaderProgram &shaderProgram, UBO &material_buffer)
glUniform1f(angle_uniform, 180); // Зададим параметры материала сфере действия glUniform1f(angle_uniform, 180); // Зададим параметры материала сфере действия
// Зададим цвет для колбы (первая в составе модели) // Зададим цвет для колбы (первая в составе модели)
bulb_model.parts[1].material.ka = color; bulb_model.parts[1].material.ka = data->color;
bulb_model.position = position; bulb_model.position = data->position;
glm::mat4 transform = bulb_model.getTransformMatrix(); glm::mat4 transform = bulb_model.getTransformMatrix();
for (int i = 1; i < bulb_model.parts.size(); i++) for (int i = 1; i < bulb_model.parts.size(); i++)
{ {
bulb_model.parts[i].render(shaderProgram, material_buffer, transform); bulb_model.parts[i].render(shaderProgram, material_buffer, transform);
} }
} }
}
// Задание радиуса и расчет коэф. угасания // Задание радиуса и расчет коэф. угасания
void Bulb::setRadius(float r) void Bulb::setRadius(float r)

View File

@ -150,6 +150,10 @@ int main(void)
lights[lights_count].position = {-0.3f, 0.3f, 0.5f}; // позиция lights[lights_count].position = {-0.3f, 0.3f, 0.5f}; // позиция
lights[lights_count++].color = {0.0f, 0.0f, 1.0f}; // цвет lights[lights_count++].color = {0.0f, 0.0f, 1.0f}; // цвет
BulbDebug lightsDebug[MAX_LIGHTS];
for (int i = 0; i < MAX_LIGHTS; i++)
lightsDebug[i].data = &lights[i];
// Uniform-буферы // Uniform-буферы
UBO cameraUB(sizeof(CameraData), 0); UBO cameraUB(sizeof(CameraData), 0);
UBO material_data(sizeof(Material), 1); UBO material_data(sizeof(Material), 1);
@ -430,6 +434,11 @@ int main(void)
scene.render(gShader, material_data); scene.render(gShader, material_data);
rectangle.render(gShader, material_data); rectangle.render(gShader, material_data);
// Отрисовка отладочных лампочек со специальным шейдером
bulbShader.use();
for (int i = 0; i < lights_count; i++)
lightsDebug[i].render(bulbShader, material_data);
// Используем шейдер для инструментов // Используем шейдер для инструментов
toolsShader.use(); toolsShader.use();
// Рендерим инструменты для выбранного объекта // Рендерим инструменты для выбранного объекта
@ -545,11 +554,6 @@ int main(void)
// Возвращаем запись глубины // Возвращаем запись глубины
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
// Отрисовка отладочных лампочек со специальным шейдером
bulbShader.use();
for (int i = 0; i < lights_count; i++)
lights[i].render(bulbShader, material_data);
// Дополнительная обработка мыши // Дополнительная обработка мыши
process_mouse_button(mouse.left); process_mouse_button(mouse.left);
process_mouse_button(mouse.right); process_mouse_button(mouse.right);