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

标签 c++ opengl glut blender cg

我正在使用 OpenGL OBJ 加载器,可以下载 here!

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

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)。

有什么想法吗?

最佳答案

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

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

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

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 加载器,看看如何正确地从文件中获取包含在文件中的法线。

关于c++ - OpenGL 中用于 OBJ 导入的平滑着色器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33978189/

相关文章:

c++ - STL 容器的内存消耗

java - 奇怪的 glVertexAttrib 行为?

c++ - 变量的值根据 vector 值而变化

c++ - 使用 OpenGL 和 GLUT 创建 FPS 风格的运动系统

c++ - C++11 中无法识别的命令行

c++ - 如何在 CMake 中添加 "-l"(ell) 编译器标志

c++ - boost student_t 分布

java - 如何使用3.2或以上版本在LWJGL中显示文本

opengl - sRGB FBO 渲染到纹理

c++ - 将浮点值传递给 glutBitmapString()?