Я новичок в изучении opengl, и после изучения некоторых руководств (спасибо Learnopengl!) эта зеркальная проблема начала становиться проблемой. Кажется, что центр зеркального прожектора на лице объекта остается в центре объекта и выходит наружу, что верно, но только для лица, обращенного непосредственно к источнику света. Размещение источника света в другом месте вызывает это «растяжение», которое выглядит как строчная буква «i» с точкой в новом положении источника света и прямой, соединяющей точку и центр фазы. Кроме того, когда источник света помещен на сторону объекта, не обращенную к началу координат, зеркальное отражение не появится, если я не помещу лицо на путь прямой секции, о которой я упоминал ранее.
первая половина демонстрации показывает растяжение зеркального света на земле
вторая половина демонстрации показывает неправильное освещение на сторонах граней объекта, не обращенных к началу координат
В идеале , зеркало должно выглядеть одинаково на всех гранях, когда перед ним находится источник света, но этого не происходит. Я проверял и перепроверял код освещения на предмет того, что есть в opengl, а также то, как все передается в шейдер, но неясно, в чем причина. Я включил свой вершинный шейдер, фрагментный шейдер, класс сетки и класс освещения, а также функцию отправки единых форм из моего основного класса Game. Также, пожалуйста, дайте мне знать, если я испортил какую-то часть этого вопроса, я не отправлял вопрос здесь. Давно скрываюсь, звоню впервые...
vert.glsl
#version 440
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec2 vertex_texcoord;
layout (location = 2) in vec3 vertex_normal;
out vec3 vs_position;
out vec2 vs_texcoord;
out vec3 vs_normal;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjMatrix;
void main()
{
vs_position = vec3(ModelMatrix * vec4(vertex_position, 1.0));
vs_texcoord = vec2(vertex_texcoord.x, vertex_texcoord.y * -1.0);
vs_normal = mat3(transpose(inverse(ModelMatrix))) * vertex_normal;
//vs_normal = vec3(ModelMatrix * vec4(vertex_normal, 1.0));
gl_Position = ProjMatrix * ViewMatrix * ModelMatrix * vec4(vertex_position, 1.0);
}
frag.glsl
#version 440
struct Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
struct PointLight
{
vec3 pos;
vec3 color;
float intensity;
float attenConstant;
float attenLinear;
float attenQuadratic;
};
in vec3 vs_position;
in vec2 vs_texcoord;
in vec3 vs_normal;
out vec4 fs_color;
uniform Material material;
uniform PointLight pointLight;
uniform vec3 camPos;
void main()
{
// Ambient
vec3 ambientFinal = pointLight.color * material.ambient;
vec3 norm = normalize(vs_normal);
vec3 lightDir = normalize(pointLight.pos - vs_position);
float ndotl = dot(norm, lightDir);
float diffuse = max(ndotl, 0.0);
vec3 diffuseFinal = pointLight.color * (material.diffuse * diffuse);
vec3 specularFinal;
if(ndotl > 0.0)
{
vec3 reflectDir = reflect(-lightDir, norm);
vec3 viewDir = normalize(camPos - vs_position);
float specular = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
specularFinal = pointLight.color * (material.specular * specular);
}
float distance = length(pointLight.pos - vs_position);
float attenuation = 1.0 / (pointLight.attenConstant + pointLight.attenLinear * distance + pointLight.attenQuadratic * (distance * distance));
fs_color = vec4((ambientFinal + diffuseFinal + specularFinal), 1.0);
//fs_color = (vec4(ambientFinal, 1.0) + vec4(diffuseFinal, 1.0) + vec4(specularFinal, 1.0));
}
Mesh.h
#pragma once
#include "Primitives.h"
class Mesh
{
private:
std::vector vertices;
std::vector indices;
GLuint VAO;
GLuint VBO;
GLuint EBO;
glm::vec3 org;
glm::vec3 pos;
glm::vec3 rot;
glm::vec3 scl;
glm::mat4 ModelMatrix;
void initVAO()
{
// Vertex Buffer Object
glGenBuffers(1, &this->VBO);
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), this->vertices.data(), GL_STATIC_DRAW);
// Vertex Array Object
glCreateVertexArrays(1, &this->VAO);
glBindVertexArray(this->VAO);
// Element Buffer Object
if (this->indices.size() > 0)
{
glGenBuffers(1, &this->EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), this->indices.data(), GL_STATIC_DRAW);
}
// Vertex Attribs
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, normal));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
}
const void updateUniforms(Shader* shader)
{
shader->setMat4fv("ModelMatrix", this->ModelMatrix);
}
void updateModelMatrix()
{
this->ModelMatrix = glm::mat4(1.f);
this->ModelMatrix = glm::translate(this->ModelMatrix, this->org);
this->ModelMatrix = glm::rotate(this->ModelMatrix, glm::radians(this->rot.x), glm::vec3(1.0f, 0.0f, 0.f));
this->ModelMatrix = glm::rotate(this->ModelMatrix, glm::radians(this->rot.y), glm::vec3(0.0f, 1.0f, 0.f));
this->ModelMatrix = glm::rotate(this->ModelMatrix, glm::radians(this->rot.z), glm::vec3(0.0f, 0.0f, 1.f));
this->ModelMatrix = glm::translate(this->ModelMatrix, this->pos - this->org);
this->ModelMatrix = glm::scale(this->ModelMatrix, this->scl);
}
public:
Mesh(Primitive* primitive, glm::vec3 org = glm::vec3(0.f), glm::vec3 pos = glm::vec3(0.f), glm::vec3 rot = glm::vec3(0.f), glm::vec3 scl = glm::vec3(1.f))
{
this->org = org;
this->pos = pos;
this->rot = rot;
this->scl = scl;
Vertex* tempV = primitive->getVertices();
int count = primitive->getVertexCount();
for (int i = 0; i < count; ++i)
this->vertices.push_back(tempV);
GLuint* tempI = primitive->getIndices();
count = primitive->getIndexCount();
for (int i = 0; i < count; ++i)
this->indices.push_back(tempI);
this->initVAO();
this->updateModelMatrix();
}
Mesh(std::vector vertexArray, GLuint* indexArray, const unsigned& indexNum, glm::vec3 org = glm::vec3(0.f), glm::vec3 pos = glm::vec3(0.f), glm::vec3 rot = glm::vec3(0.f), glm::vec3 scl = glm::vec3(1.f))
{
this->org = org;
this->pos = pos;
this->rot = rot;
this->scl = scl;
for (int i = 0; i < vertexArray.size(); ++i)
this->vertices.push_back(vertexArray);
for (int i = 0; i < indexNum; ++i)
this->indices.push_back(indexArray);
this->initVAO();
this->updateModelMatrix();
}
Mesh(Mesh& obj)
{
this->org = obj.org;
this->pos = obj.pos;
this->rot = obj.rot;
this->scl = obj.scl;
for (int i = 0; i < obj.vertices.size(); ++i)
this->vertices.push_back(obj.vertices);
for (int i = 0; i < obj.indices.size(); ++i)
this->indices.push_back(obj.indices);
this->initVAO();
this->updateModelMatrix();
}
~Mesh()
{
glDeleteVertexArrays(1, &this->VAO);
glDeleteBuffers(1, &this->VBO);
if(this->indices.size() > 0)
glDeleteBuffers(1, &this->EBO);
}
void setOrigin(const glm::vec3& org)
{
this->org = org;
}
void setPosition(const glm::vec3& pos)
{
this->pos = pos;
}
void setRotation(const glm::vec3& rot)
{
this->rot = rot;
}
void setScale(const glm::vec3& scl)
{
this->scl = scl;
}
void move(const glm::vec3 pos)
{
this->pos += pos;
}
void rotate(const glm::vec3& rot)
{
this->rot += rot;
}
void scale(const glm::vec3& scl)
{
this->scl += scl;
}
void update()
{
}
void render(Shader* shader)
{
this->updateModelMatrix();
this->updateUniforms(shader);
glBindVertexArray(this->VAO);
shader->use();
if (this->indices.size() == 0)
glDrawArrays(GL_TRIANGLES, 0, this->vertices.size());
else
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
};
Light.h
#pragma once
#include "Camera.h"
class Light
{
protected:
glm::vec3 color;
float intensity;
public:
Light(glm::vec3 color, float intensity)
{
this->color = color;
this->intensity = intensity;
}
~Light()
{
}
virtual void sendToShader(Shader& prog) = 0;
};
class PointLight : public Light
{
protected:
glm::vec3 pos;
float attenConstant;
float attenLinear;
float attenQuadratic;
public:
PointLight(glm::vec3 pos, glm::vec3 color = glm::vec3(1.f), float intensity = 1.f,
float attenConstant = 1.f, float attenLinear = 0.045f, float attenQuadratic = 0.0075f) : Light(color, intensity)
{
this->pos = pos;
this->attenConstant = attenConstant;
this->attenLinear = attenLinear;
this->attenQuadratic = attenQuadratic;
}
~PointLight()
{
}
void setPos(const glm::vec3 pos)
{
this->pos = pos;
}
void sendToShader(Shader& prog)
{
prog.setVec3f("pointLight.pos", this->pos);
prog.setVec3f("pointLight.color", this->color);
prog.setFloat("pointLight.intensity", this->intensity);
prog.setFloat("pointLight.attenConstant", this->attenConstant);
prog.setFloat("pointLight.attenLinear", this->attenLinear);
prog.setFloat("pointLight.attenQuadratic", this->attenQuadratic);
}
};
Отрывок из Game.cpp
void Game::updateUniforms()
{
glfwGetFramebufferSize(this->window, &this->fbWidth, &this->fbHeight);
this->ProjMatrix = glm::perspective(glm::radians(this->fov), static_cast(this->fbWidth) / this->fbHeight, this->nearPlane, this->farPlane);
this->ViewMatrix = this->camera.getViewMatrix();
this->shaders[SHADER_CORE]->setMat4fv("ProjMatrix", this->ProjMatrix);
this->shaders[SHADER_CORE]->setMat4fv("ViewMatrix", this->ViewMatrix);
this->shaders[SHADER_CORE]->setVec3f("cameraPos", this->camera.getPos());
//for (auto*& pointLight : pointLights)
pointLights[0]->sendToShader(*this->shaders[SHADER_CORE]);
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... stretching
Зеркальное растяжение OpenGL ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Зеркальное отображение на виртуальном мониторе с помощью xrandr [закрыто]
Anonymous » » в форуме Linux - 0 Ответы
- 30 Просмотры
-
Последнее сообщение Anonymous
-