OpenGL .obj Loader:模型只能正确点亮不正常的法向量?

时间:2015-07-14 04:28:50

标签: c++ qt opengl

我正在尝试编写一个加载.obj文件的程序。出于某种原因,我的模型只会用错误计算的法向量点亮。我无法在网上找到解释这种异常现象的任何内容。

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

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

天使数据集由联合国提供。伯克利计算机动画与建模组。

(不会让我发布图片,因为&lt; 10声誉)

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

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

然后它呈现正确:

Incorrect Normals

但它不应该,因为顶点的方向是逆时针的。因此,通过右手规则,第一次计算应产生正确的,面向外的法向量。

我试图扭转绕组,

glFrontFace(GL_CW);

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

任何人都可以解释为什么会这样吗?我遗漏的顶点计算中是否有错误?或者关于可能出现什么问题的任何其他想法?

1 个答案:

答案 0 :(得分:2)

问题在于你如何计算a和b向量。看一下显示右手规则的图像:

enter image description here

矢量a和b都来自同一个点并指向不同的方向。矢量b不是从矢量a的尖端开始的。

然而在你的代码中,好像中指的基部(矢量b)从食指的尖端(矢量a)开始,因为你绕着三角形而不是选择从它发出的两个矢量顶点。这相当于使用向量a的尖端作为您的公共顶点,但使用向量指向错误的方式

将图像上的三角形覆盖在顺时针编号的顶点上:

enter image description here

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

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

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

要获得从顶点2到顶点3的向量b,从顶点3中减去顶点2:

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