OpenGL ES20 - 点亮一个立方体,如何获得法线?

时间:2014-02-06 12:55:29

标签: android matrix 3d opengl-es-2.0 normals

要为我的OpenGL ES20立方体添加一些闪电,我需要计算每个平面的法线。我在闪电上找到了一个“教程”,但他们只是将法线硬编码到立方体中,这在我看来不是最好的选择,因为它似乎有限?

所以我对立方体的处理方法如下:

private float[] mVertices = {
        -1, -1, -1, // bottom left
        1, -1, -1, // bottom right   back
        1, 1, -1, // top right
        -1, 1, -1, // top left
        -1, -1, 1, // bottom left
        1, -1, 1, // bottom right   front
        1, 1, 1, // top right
        -1, 1, 1 // top left
};

private float[] mColors = {
        0.6f, 0f, 0.6f,
        0.6f, 0f, 0.6f,
        0.6f, 0f, 0.6f,
        0.6f, 0f, 0.6f,

        0.8f, 0f, 0.6f,
        0.8f, 0f, 0.6f,
        0.8f, 0f, 0.6f,
        0.8f, 0f, 0.6f
};

private float[] mNormal = new float[?]; ?

private short[] mIndices = {
        0, 4, 5,
        0, 5, 1,

        1, 5, 6,
        1, 6, 2,

        2, 6, 7,
        2, 7, 3,

        3, 7, 4,
        3, 4, 0,

        4, 7, 6,
        4, 6, 5,

        3, 0, 1,
        3, 1, 2
};

即。我定义了所有8个顶点以及索引,关于如何将它们组合成三角形。 为了获得正常矩阵,我已经读过我应该反转矩阵,然后转置它。所以我试过这个:

    float[] mTempMatrix = new float[mVertices.length];
    Matrix.invertM(mTempMatrix, 0, mVertices, 0);
    Matrix.transposeM(mNormal, 0, mTempMatrix, 0);

但是这总是用零填充,而我的立方体保持黑色。我应该如何计算正常矩阵?它应该是模型矩阵的东西吗?如果是的话,我应该在哪里这样做,因为他们真正合并的唯一地方是着色器?有没有其他方法可以做到这一点更合适?

1 个答案:

答案 0 :(得分:1)

您面临的问题是您在立方体面之间共享顶点。法线是指向与表面平面正交的矢量。

以顶部/右侧/前顶点为例(与前面,右面和顶面共享)。

在正面使用时,法线需要指向0,0,1 当在右脸上使用时,法线需要指向右边为1,0,0 在顶面使用时,法线需要指向0,1,0

那么如何调和呢? 您可以将顶点的法线设置为从角落指出,例如为0.707,0.707,0.707。这很可能会给角落带来有趣的灯光效果,但可能不是你想要的。

另一种解决方案是不要重复使用面之间的顶点。所以你需要24(每边4个)而不是8个。然后你将拥有每个顶点的3个版本,但每个顶点中的每一个现在只属于一个面,因此你可以将法线向量设置为垂直于那个面。您还可以为该面设置颜色,因为您将不再与其他面共享顶点。