【发布时间】:2021-12-05 02:04:45
【问题描述】:
我正在尝试通过将 3 个向量相乘以沿这些法线挤出顶点来计算法线,它仅适用于对象的一半,请参阅this 图像作为参考(粉红色线代表挤出的顶点)
以下是计算法线的方法:
for (Vertex& v : vertices)
{
glm::vec3 normal = { 0,0,0 };
for (int i = 0; i < vertices.size(); i++)
{
const glm::vec3& a = vertices[i].position;
const glm::vec3& b = vertices[i + 1].position;
const glm::vec3& c = vertices[i + 2].position;
glm::vec3 n = (b - a) * (c - a);
normal += glm::normalize(n);
}
v.normal = glm::normalize(normal);
}
编辑1: 我尝试使用 glm::cross(b-a, c-a),但输出始终为零,对象现在看起来像 this
这是代码:
for (Vertex& v : vertices)
{
glm::vec3 normal = { 0,0,0 };
for (int i = 0; i < vertices.size(); i++)
{
const glm::vec3& a = vertices[i].position;
const glm::vec3& b = vertices[i + 1].position;
const glm::vec3& c = vertices[i + 2].position;
glm::vec3 n = glm::cross( (b - a), (c - a) );
normal += glm::normalize(n);
}
v.normal = glm::normalize(normal);
}
另外,每个向量中的 Y 分量总是等于 0
编辑 2: 基本形状是二维的,它只使用 x,z 分量,然后沿 y 轴拉伸,this 是顶点处理的工作原理
-- 更新--
我设法通过首先计算顶点切线然后使用该切线计算法线来解决问题,但这会导致一个小问题,当我更改对象的位置时,切线/法线计算会使对象变形并且我想这是与规范化有关的问题,我可能会为此创建一个单独的帖子,我会在创建它时包含指向该帖子的链接。
glm::vec3 GetUnitNormal(const glm::vec2& p1, const glm::vec2& p2, const float s)
{
const glm::vec2 p3 = p1 + ( (p2 - p1) * s );
const float m = (p3.y - p1.y) / (p3.x - p1.x);
const float c = p1.y - m * p1.x;
const float y = (m * p1.x) + c;
const glm::vec2 tangent = glm::normalize(glm::vec2(p1.x, y));
glm::vec3 normal = glm::vec3(-tangent.y, 0, tangent.x);
return glm::normalize(normal);
}
编辑 4: here is帖子链接
【问题讨论】:
-
你的形状是二维的吗?
-
@n.1.8e9-where's-my-sharem。基础顶点是 2d 的,它们只使用 x、z 分量,在挤压之后,新对象会沿 y 轴挤压
-
我不明白你在做什么。法线是否应该沿 y 轴延伸?那么无论顶点如何,它总是(0,1,0)。
-
@n.1.8e9-where's-my-sharem。抱歉混淆,我正在尝试计算每个顶点的法线,以便我可以沿着它们的法线挤出这些顶点,这将使形状具有厚度,在第三张图像中,这表示为第二步,我已经知道如何挤出它们沿 y 轴,这是第三张图像的最后一步(位于第二个编辑处)
-
您正在计算一个法线向量。法线向量在表面上的某个点垂直于某个表面。它是什么表面?
标签: c++ opengl glm-math normals