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

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

View File

@ -8,9 +8,18 @@ layout(std140, binding = 1) uniform Material
float p; float p;
}; };
in vec3 pos_local;
out vec4 color; out vec4 color;
uniform float angle;
uniform vec3 direction;
void main() void main()
{ {
color = vec4(ka, 1); 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; uniform mat4 model;
out vec3 pos_local;
void main() void main()
{ {
pos_local = pos;
gl_Position = camera.projection * camera.view * model * vec4(pos, 1.0); gl_Position = camera.projection * camera.view * model * vec4(pos, 1.0);
} }

View File

@ -13,6 +13,8 @@ struct LightData
{ {
vec3 position; vec3 position;
vec3 color; vec3 color;
float angle;
vec3 direction;
float radius; float radius;
vec2 K; vec2 K;
}; };
@ -50,6 +52,7 @@ void main()
vec3 H; // Вектор половины пути vec3 H; // Вектор половины пути
float specular; // Зеркальная составляющая float specular; // Зеркальная составляющая
float attenuation; // Угасание с учетом расстояния float attenuation; // Угасание с учетом расстояния
float acosA; // Косинус между вектором от поверхности к источнику и обратным направлением источника
// Фоновая освещенность // Фоновая освещенность
@ -69,20 +72,25 @@ void main()
{ {
// Нормирование вектора // Нормирование вектора
L_vertex = normalize(L_vertex); 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
// Вектор половины пути
H = normalize(L_vertex + Cam_vertex);
// Зеркальная составляющая
specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p
// Диффузная составляющая // Угасание с учетом расстояния
diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0 attenuation = 1 / (1 + light_f.data[i].K[0] * L_distance + light_f.data[i].K[1] * L_distance * L_distance);
// Вектор половины пути
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 * attenuation, 1)
attenuation = 1 / (1 + light_f.data[i].K[0] * L_distance + light_f.data[i].K[1] * L_distance * L_distance); + vec4(light_f.data[i].color*ks*specular * attenuation, 1);
}
color += vec4(light_f.data[i].color*kd*diffuse * attenuation, 1)
+ vec4(light_f.data[i].color*ks*specular * attenuation, 1);
} }
} }
} }

View File

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

View File

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