Определение угла и рисование части отладочной сферы

This commit is contained in:
Ковалев Роман Евгеньевич 2022-12-20 15:58:42 +03:00 committed by R.E. Kovalev
parent f115505a06
commit 891014a79c
6 changed files with 55 additions and 16 deletions

View File

@ -13,13 +13,15 @@
class Bulb
{
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); // Конструктор с координатами, цветом и радиусом
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); // Отрисовка отладочной лампы и сферы
alignas(16) glm::vec3 position; // Позиция
alignas(16) glm::vec3 color; // Цвет
void setRadius(float radius); // Задание радиуса и расчет коэф. угасания
float angle; // Угол освещенности
alignas(16) glm::vec3 direction; // Направление для прожектора
private:
float radius; // Радиус действия источника
glm::vec2 K; // линейный и квадратичный компоненты затухания

View File

@ -8,9 +8,18 @@ layout(std140, binding = 1) uniform Material
float p;
};
in vec3 pos_local;
out vec4 color;
uniform float angle;
uniform vec3 direction;
void main()
{
float cosA = dot(normalize(pos_local), normalize(direction));
if (degrees(acos(cosA)) <= angle)
color = vec4(ka, 1);
else
discard;
}

View File

@ -11,7 +11,10 @@ layout(std140, binding = 0) uniform Camera
uniform mat4 model;
out vec3 pos_local;
void main()
{
pos_local = pos;
gl_Position = camera.projection * camera.view * model * vec4(pos, 1.0);
}

View File

@ -13,6 +13,8 @@ struct LightData
{
vec3 position;
vec3 color;
float angle;
vec3 direction;
float radius;
vec2 K;
};
@ -50,6 +52,7 @@ void main()
vec3 H; // Вектор половины пути
float specular; // Зеркальная составляющая
float attenuation; // Угасание с учетом расстояния
float acosA; // Косинус между вектором от поверхности к источнику и обратным направлением источника
// Фоновая освещенность
@ -69,7 +72,11 @@ void main()
{
// Нормирование вектора
L_vertex = normalize(L_vertex);
// арккосинус между вектором от поверхности к источнику и обратным направлением источника
acosA = degrees(acos(dot(-L_vertex, normalize(light_f.data[i].direction))));
// Если угол меньше угла источника или угол источника минимален, то считаем освещенность
if(acosA <= light_f.data[i].angle)
{
// Диффузная составляющая
diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0
@ -86,3 +93,4 @@ void main()
}
}
}
}

View File

@ -6,7 +6,7 @@ void genShpere(Model& model, float radius, int sectorsCount); // Model.cpp
GrouptedModel Bulb::bulb_model;
// Конструктор с координатами, цветом и радиусом
Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r)
Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r, float a, const glm::vec3 &dir)
{
// Если отладочная модель не загружена - загрузим
if (!bulb_model.parts.size())
@ -25,21 +25,37 @@ Bulb::Bulb(const glm::vec3 &pos, const glm::vec3 &c, float r)
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)
{
// Расположение uniform-переменных
GLuint model_uniform = shaderProgram.getUniformLoc("model");
GLuint angle_uniform = shaderProgram.getUniformLoc("angle");
GLuint direction_uniform = shaderProgram.getUniformLoc("direction");
// Загрузим направление
glUniform3fv(direction_uniform, 1, &direction[0]);
// Зададим параметры материала сфере действия
bulb_model.parts[0].material.ka = color;
bulb_model.parts[0].position = position;
bulb_model.parts[0].scale = {radius, radius, radius};
// Угол для сферы (рисуем направленный конус)
glUniform1f(angle_uniform, angle);
// Рисование сферы покрытия источника в режиме линий
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
bulb_model.parts[0].render(shaderProgram, material_buffer);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Угол для лампочки = 180 (рисуем целую модель)
glUniform1f(angle_uniform, 180); // Зададим параметры материала сфере действия
// Зададим цвет для колбы (первая в составе модели)
bulb_model.parts[1].material.ka = color;

View File

@ -121,7 +121,8 @@ int main(void)
GLint lights_count = 0;
lights[lights_count].position = {0.3f, 0.1f, 0.5f}; // позиция
lights[lights_count++].color = {1.0f, 0.0f, 0.0f}; // цвет
lights[lights_count].color = {1.0f, 0.0f, 0.0f}; // цвет
lights[lights_count++].angle = 35;
lights[lights_count].position = {-0.3f, -0.1f, 0.5f}; // позиция
lights[lights_count++].color = {0.0f, 0.0f, 1.0f}; // цвет