我正在使用四边形绘制一个球体。我绘制了一个额外的顶点,只是将四边形划分为2个三角形。所以它是这样的:
1 ----> 2
| |
| |
4 ----> 3
但在3之后我再次绘制1。所以想象一下3 - > 1的额外一行。
我现在正在尝试计算每个顶点的正常值。 这是我的代码:
//calculate normals
for (no_vertice=0; no_vertice<12887; no_vertice+=1)
{
//getting the sphere's vertices
x=sphere_vertices[no_vertice].position[0];
y=sphere_vertices[no_vertice].position[1];
z=sphere_vertices[no_vertice].position[2];
//normalising vector "norm(Vertex - Center)"
magnitude = sqrt((x*x) + (y*y) + (z*z));
sphere_vertices[no_vertice].normal[0] = (x/magnitude);
sphere_vertices[no_vertice].normal[1] = (y/magnitude);
sphere_vertices[no_vertice].normal[2] = (z/magnitude);
printf("Normal at vertice %d = X:%f, Y:%f, Z:%f. \n", no_vertice, sphere_vertices[no_vertice].normal[0], sphere_vertices[no_vertice].normal[1], sphere_vertices[no_vertice].normal[2]);
}
我正在计算每个顶点的幅度,然后将该顶点的每个分量除以幅度,以便得到单位矢量。问题是我得到了很多零向量。那是x = 0,y = 0,z = 0的顶点... 当我将法线传递给顶点着色器时,
//my vertex structure
struct Vertex {
GLdouble position[3];
GLfloat color[3];
GLdouble normal[3];
};
....
..
.
/* Enable attribute index 2 as being used */
glEnableVertexAttribArray ( 2 );
glVertexAttribPointer ( ( GLuint ) 2, 3, GL_FLOAT, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* )
offsetof(struct Vertex, normal) );
...
..
.
//pass the normal to vertex shader
glBindAttribLocation(shaderprogram, 2, "in_Normal");
做我的光计算我得到了所有奇怪的效果。
我做错了吗?
最令人困惑的部分是我被要求这样做:
“对于球体,计算表面法线方向并增加线框 用短线绘制表示每个顶点的法线方向球体 现在看来应该是对冲猪。“
“注意:表面法线是与表面贴片成直角的单位矢量,假设它是平的。”
它基本上是顶点的法线,还是我必须绘制的四边形表面? 我很困惑,因为它说,
“计算表面法线方向”
然后
“用表示每个顶点法线方向的短线绘图”
那么应该绘制线条???在顶点?还是在四边形的中间?感谢
编辑:顶点计算
for (theta=-90;theta<=90-dtheta;theta+=dtheta) {
for (phi=0;phi<=360-dphi;phi+=dphi) {
//calculating Vertex 1
x = cos(theta*DTOR) * cos(phi*DTOR);
y = cos(theta*DTOR) * sin(phi*DTOR);
z = sin(theta*DTOR);
no_vertice+=1;
sphere_vertices[no_vertice].position[0] = x;
sphere_vertices[no_vertice].position[1] = y;
sphere_vertices[no_vertice].position[2] = z;
//calculating Vertex 2
x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR);
y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR);
z = sin((theta+dtheta)*DTOR);
no_vertice+=1;
sphere_vertices[no_vertice].position[0] = x;
sphere_vertices[no_vertice].position[1] = y;
sphere_vertices[no_vertice].position[2] = z;
//calculating Vertex 3
x = cos((theta+dtheta)*DTOR) * cos((phi+dphi)*DTOR);
y = cos((theta+dtheta)*DTOR) * sin((phi+dphi)*DTOR);
z = sin((theta+dtheta)*DTOR);
no_vertice+=1;
sphere_vertices[no_vertice].position[0] = x;
sphere_vertices[no_vertice].position[1] = y;
sphere_vertices[no_vertice].position[2] = z;
//adding Vertex_1 again to divide the Quad into 2 triangles
//calculating Vertex 1
x = cos(theta*DTOR) * cos(phi*DTOR);
y = cos(theta*DTOR) * sin(phi*DTOR);
z = sin(theta*DTOR);
no_vertice+=1;
sphere_vertices[no_vertice].position[0] = x;
sphere_vertices[no_vertice].position[1] = y;
sphere_vertices[no_vertice].position[2] = z;
if (theta > -90 && theta < 90) {
//calculating Vertex 4
x = cos(theta*DTOR) * cos((phi+dphi)*DTOR);
y = cos(theta*DTOR) * sin((phi+dphi)*DTOR);
z = sin(theta*DTOR);
no_vertice+=1;
sphere_vertices[no_vertice].position[0] = x;
sphere_vertices[no_vertice].position[1] = y;
sphere_vertices[no_vertice].position[2] = z;
}
}
}
答案 0 :(得分:2)
你的问题,正如我所看到的那样,你并没有抓住实际发生的事情。不要查看某些教程中的代码,而应该掌握数学概念(尝试从代码中过滤掉这些代码会产生反作用,因为代码不会告诉完整的故事,也可能省略或简化事情以获得足够的近似值)
首先,你得到了顶点的顺序,没有错,但是不开心。 OpenGL假定向量计算中的右手(除非您在转换管道的末尾交换一个轴)。这意味着,顶点应逆时针计数。你可以顺时针方向做,但事情变得更容易了。接下来你应该从0开始计数,至少如果你是一个C语言,通过偏移索引解决数组,即第一个元素在索引0。
3--2
| /|
|/ |
0--1
以原点为中心的球体的法线是特殊的,因为标准化(不要将“正常”与正常的正常混淆,它们是不同的东西!)顶点位置向量是所讨论的顶点的法线。
在一般情况下,可以通过取顶点的切线空间的叉积来评估法线,即三角形是拐角处边缘矢量的叉积。在你的四边形情况下,[0]处的法线将是
normalize( ([1]-[0]) × ([2]-[0]) )
表示三角形0,1,2和
normalize( ([2]-[0]) × ([3]-[0]) )
注意,这是表面分析表示的偏导数的叉积。您已经知道球体表面的分析表示(参见Paul Bourke的教程)。我建议将其作为练习进行测试,即证明对于原点周围的单位半径球体,表面点的位置等于该点处表面的法线。
答案 1 :(得分:0)
冒repeating myself的风险:
对于中心为C的球体上的给定矢量位置P,法线为范数(P - C),其中范数使矢量归一化。
我没有看到你的代码这样做。除非你知道这些职位以原点为中心,这不是你所说的假设。
答案 2 :(得分:0)
看起来你应该画的是一个由正方形组成的球体,想象一个橙色,上面画着一堆正方形。
由于他想要顶点法线,每个四边形将在其每个顶点绘制四个法线,每个法线垂直于四边形曲面
请注意,每个顶点都有四个不同的顶点法线,因为每个顶点由四个四边形共享。
编辑:在光照环境中,他可能想要每个顶点有一个法线,所以只需取平均值即可。这可能就是他的意思,但不是说明书所说的。