c++ - OpenGL .obj 加载程序 : Model only lit correctly with incorrect normal vectors?

标签 c++ qt opengl

我正在尝试编写一个加载 .obj 文件的程序。出于某种原因,我的模型只在计算错误的法 vector 时亮起。我无法在网上找到任何解释此异常的信息。

这就是我计算法线的方式,我认为这是正确的方式。

vector<float> Vertex::findNormal(Vertex v2, Vertex v3)
{
    float va[3], vb[3], vr[3], val;
    /* Calculate 1st Vector */
    va[0] = v2.getX() - x;
    va[1] = v2.getY() - y;
    va[2] = v2.getZ() - z;
    /* Calculate 2nd Vector */
    vb[0] = v3.getX() - v2.getX();
    vb[1] = v3.getY() - v2.getY();
    vb[2] = v3.getZ() - v2.getZ();

    /* 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]);

    normal.push_back(vr[0]/val);
    normal.push_back(vr[1]/val);
    normal.push_back(vr[2]/val);

   return normal;
}

但这是结果: Correct Normals

Angel 数据集由 U.C. 提供伯克利计算机动画和建模小组。

(不允许我发布图片,因为 <10 声望)

如果我切换其中一个 vector 的方向,例如:

 /* Calculate 1st Vector */
    va[0] = x - v2.getX();
    va[1] = y - v2.getY();
    va[2] = z - v2.getZ();

然后它正确呈现:

Incorrect Normals

但它不应该,因为顶点的方向是逆时针的。所以根据右手法则,第一次计算应该产生正确的、向外的法 vector 。

我试过通过,反转绕组,

glFrontFace(GL_CW);

我对我的代码进行了单元测试,以确保从文件中按逆时针顺序读取顶点,我对照明设置进行了无数次修改,但都无济于事。

谁能解释为什么会这样?我的顶点计算中是否存在我遗漏的错误?或者关于可能出错的任何其他想法?

最佳答案

问题在于您如何计算 a 和 b vector 。看看这张显示右手定则的图片:

enter image description here

vector a 和 b 都起源于同一点并指向不同的方向。 vector b不是从 vector a的尖端开始的。

但是在您的代码中,就好像中指的根部( vector b)从食指的指尖( vector a)开始,因为您要绕三角形而不是选择从同一三角形发出的两个 vector 顶点。这相当于使用 vector a 的尖端作为公共(public)顶点,但是 vector a 指向错误的方向

用顺时针编号的顶点画一个覆盖在图像上的三角形:

enter image description here

(您可以用 3 种不同的方式对顶点进行编号,但我选择了与您的代码的工作版本相匹配的编号。)

要获得从顶点 2 到顶点 1 的 vector a,从顶点 1 减去顶点 2:

/* Calculate 1st Vector */
va[0] = x - v2.getX();
va[1] = y - v2.getY();
va[2] = z - v2.getZ();

要获得从顶点 2 到顶点 3 的 vector b,从顶点 3 减去顶点 2:

/* Calculate 2nd Vector */
vb[0] = v3.getX() - v2.getX();
vb[1] = v3.getY() - v2.getY();
vb[2] = v3.getZ() - v2.getZ();

关于c++ - OpenGL .obj 加载程序 : Model only lit correctly with incorrect normal vectors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31397662/

相关文章:

c++ - std::thread 在 vc++ 的析构函数中获取中止异常

c++ - 错误打印 posix_time

c++ - 为什么继承值打印了两次?

java - 如何绘制球体的中半部分(在代码中)

c++ - GLSL 将指示法线传递给着色器

c++ - 在运行时更改纹理参数

c++ - 如何传递 ostream 对象?

html - QTextDocument HTML 表格宽度

c++ - 如何使用 Qt5 编译 Qt FTP webkit 示例?

mysql - 无法使用 qt 4.8.5 和 Ubuntu 12.04 连接到 mariadb 数据库服务器