OpenGL计算法线(四边形)
OpenGL Calculating Normals (Quads)
我的问题是关于OpenGL和Normals,我了解它们背后的数学原理,并且我取得了一些成功。
我在下面附加的函数接受一个交错的顶点阵列,并计算每4个顶点的法线。这些表示具有相同方向的四边形。根据我的理解,这4个顶点应该共享相同的法线。只要他们面对同样的方式。
我遇到的问题是,我的QUADS是用对角线渐变渲染的,很像这样:灯光效果-除了阴影在中间,灯光在角落。
我以一贯的方式画我的QUADS。TopLeft、TopRight、BottomRight、BotomLeft和用于计算法线的顶点分别为TopRight-TopLeft和BottomRight-TopLeft。
希望有人能看到我犯了错误的东西,但我已经在这方面坚持了几个小时,但没有获胜。
作为记录,我渲染了一个立方体,并在我的对象旁边渲染一个茶壶,以检查我的照明是否正常工作,所以我很确定灯光位置没有问题。
void CalculateNormals(point8 toCalc[], int toCalcLength)
{
GLfloat N[3], U[3], V[3];//N will be our final calculated normal, U and V will be the subjects of cross-product
float length;
for (int i = 0; i < toCalcLength; i+=4) //Starting with every first corner QUAD vertice
{
U[0] = toCalc[i+1][5] - toCalc[i][5]; U[1] = toCalc[i+1][6] - toCalc[i][6]; U[2] = toCalc[i+1][7] - toCalc[i][7]; //Calculate Ux Uy Uz
V[0] = toCalc[i+3][5] - toCalc[i][5]; V[1] = toCalc[i+3][6] - toCalc[i][6]; V[2] = toCalc[i+3][7] - toCalc[i][7]; //Calculate Vx Vy Vz
N[0] = (U[1]*V[2]) - (U[2] * V[1]);
N[1] = (U[2]*V[0]) - (U[0] * V[2]);
N[2] = (U[0]*V[1]) - (U[1] * V[0]);
//Calculate length for normalising
length = (float)sqrt((pow(N[0],2)) + (pow(N[1],2)) + (pow(N[2],2)));
for (int a = 0; a < 3; a++)
{
N[a]/=length;
}
for (int j = 0; i < 4; i++)
{
//Apply normals to QUAD vertices (3,4,5 index position of normals in interleaved array)
toCalc[i+j][3] = N[0]; toCalc[i+j][4] = N[1]; toCalc[i+j][5] = N[2];
}
}
}
似乎是从索引5、6和7中获取用于计算的顶点位置值,然后写出索引3、4和5处的法线。请注意索引5是如何在两者上使用的。我想其中一个是不对的。
看起来你的for-loops
正在咬你。
for (int i = 0; i < toCalcLength; i+=4) //Starting with every first corner QUAD vertice
{
...
for (int j = 0; i < 4; i++)
{ // ^ ^
// Should you be using 'j' instead of 'i' here?
// j will never increment
// This loop won't be called at all after the first time through the outer loop
...
}
}
使用索引3、4和5存储正常:
toCalc[i+j][3] = N[0]; toCalc[i+j][4] = N[1]; toCalc[i+j][5] = N[2];
AND您使用索引5、6和7来获得点坐标:
U[0] = toCalc[i+1][5] - toCalc[i][5]; U[1] = toCalc[i+1][6] - toCalc[i][6]; U[2] = toCalc[i+1][7] - toCalc[i][7];
这些索引重叠(normal.x和position.z共享相同的索引),这不应该发生。
建议:
- 把一切都安排好
- 两者之一:
- 使用数学库
- 或者将矢量算法放入单独的、命名恰当的子程序中
- 使用命名变量而不是索引
通过这样做,您将减少代码中的错误数量。a.position.x
比quad[0][5]
更容易读取,并且当代码没有被复制粘贴时,它更容易修复矢量运算中的拼写错误。
您可以使用并集通过索引和名称访问矢量分量:
struct Vector3{
union{
struct{
float x, y, z;
};
float v[3];
};
};
用于计算四边形中的法线ABCD
A--B
| |
C--D
使用公式:
normal=归一化((B.位置-A.位置)X(C.位置-A.职位))。
或
normal=归一化((D.位置-A.位置)X(C.位置-B.位置))。
其中"X"表示"叉积"。
无论哪种方式都可以。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 计算缩放多边形的比例,得到给定的多边形面积
- 计算三角形与四边形的TBN矩阵的差异?
- 计算两个四边形的交点的方法
- OpenGL计算法线(四边形)