这些顶点的法线应该是这样的吗?

时间:2011-11-12 17:02:58

标签: c++ opengl

我正在使用四边形绘制一个球体。我绘制了一个额外的顶点,只是将四边形划分为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;


             }
        }
   }

3 个答案:

答案 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)

看起来你应该画的是一个由正方形组成的球体,想象一个橙色,上面画着一堆正方形。

由于他想要顶点法线,每个四边形将在其每个顶点绘制四个法线,每个法线垂直于四边形曲面

请注意,每个顶点都有四个不同的顶点法线,因为每个顶点由四个四边形共享。

编辑:在光照环境中,他可能想要每个顶点有一个法线,所以只需取平均值即可。这可能就是他的意思,但不是说明书所说的。