OpenGL 中用于 OBJ 导入的平滑着色器?

Smooth shader in OpenGL for OBJ import?

我使用的是 OpenGL OBJ 加载器,可以下载 here!

我从 Blender 导出了一个 OBJ 模型。 问题是我想实现平滑的着色。 As you can see, it is not smooth here. 我如何实现这一目标?也许是法向量计算器出了问题?

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
   /* calculate Vector1 and Vector2 */
   float va[3], vb[3], vr[3], val;
   va[0] = coord1[0] - coord2[0];
   va[1] = coord1[1] - coord2[1];
   va[2] = coord1[2] - coord2[2];

   vb[0] = coord1[0] - coord3[0];
   vb[1] = coord1[1] - coord3[1];
   vb[2] = coord1[2] - coord3[2];

   /* cross product */
   vr[0] = va[1] * vb[2] - vb[1] * va[2];
   vr[1] = vb[0] * va[2] - va[0] * vb[2];
   vr[2] = va[0] * vb[1] - vb[0] * va[1];

   /* normalization factor */
   val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );

    float norm[3];
    norm[0] = vr[0]/val;
    norm[1] = vr[1]/val;
    norm[2] = vr[2]/val;


    return norm;
}

并且设置了 glShadeModel(GL_SMOOTH)。

有什么想法吗?

如果要进行平滑着色,不能像现在这样简单地逐个三角形地计算每个三角形顶点的法线。这将产生平坦的阴影。

要进行平滑着色,您需要将为每个三角形计算的法线与关联的顶点相加,然后对每个顶点的结果进行归一化。这将产生一种指向平滑方向的平均向量。

基本上采用您正在做的事情,并将生成的三角形法线添加到它的所有顶点。然后对每个顶点的求和向量进行归一化。它看起来像这样(伪代码):

for each vertex, vert:
    vert.normal = vec3(0, 0, 0)

for each triangle, tri:
     tri_normal = calculate_normal(tri)
     for each vertex in tri, vert:
          vert.normal += tri_normal

for each vertex, vert:
    normalize(vert.normal)

但是,从像这样的 OBJ 文件加载时通常不需要这样做,并且像这样的硬表面模型通常需要其折痕和尖角的份额才能在法线不完全光滑和连续的地方看起来正确到处。 OBJ 文件通常存储每个顶点的法线,因为艺术家希望模型看起来如此。所以我会看看你的 OBJ 加载器,看看如何正确地从文件中获取包含在文件中的法线。

谢谢朋友!我在 Blender 中找到了导出法向量的选项,所以现在我已经完全重写了数据结构来管理法向量。现在看起来很光滑! image