OpenGL ES20 - Зажгите куб, как получить нормали?

Чтобы добавить молнии в мой куб 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);

Но это всегда заполнено нулями, и мой куб остается черным. Как, например, я должен вычислить нормальную матрицу? Должно быть что-то с матрицей модели? Если да, то где я должен это сделать, поскольку единственное место, где они действительно объединяются, находится в шейдере? Есть ли другой способ сделать это, который был бы более подходящим?


person damian    schedule 06.02.2014    source источник
comment
Ваши вершины жестко закодированы, поэтому имеет смысл также жестко закодировать нормали (они не будут изменяться больше, чем вершины). Каким образом вы видите в этом какое-то ограничение?   -  person NigelK    schedule 06.02.2014
comment
М-да, это правда, я думал иначе, так как я меняю вершины в конструкторе - но я только сдвигаю их в соответствии с шириной, высотой и глубиной куба. Я больше думал о будущем, о более детализированных и сложных объектах, таких как полигоны и т. д. Также я немного запутался, как добавить нормали, жестко запрограммированные так, как они есть прямо сейчас, особенно с индексами, сколько мне нужно и где они должны быть основаны? РЕДАКТИРОВАТЬ: В примерах, которые я видел, было определено гораздо больше вершин без индексов, поэтому я не могу понять, как мне адаптировать эту часть.   -  person damian    schedule 06.02.2014
comment
Хорошо, я пробовал кое-что. Я думаю, чтобы жестко закодировать в нем нормали, я должен изменить способ отрисовки куба. Я изменил цвета, чтобы определить, какой индекс является какой стороной куба, но изменение всех цветов на белый, кроме одного, привело к цветному углу, поскольку вершина используется более одного раза. Поэтому я действительно не знаю, как я должен добавить нормаль плоскости в реализацию моего куба.   -  person damian    schedule 06.02.2014


Ответы (1)


Проблема, с которой вы столкнулись, заключается в том, что вы делите вершины между гранями куба. Нормаль — это вектор, направленный ортогонально плоскости поверхности.

В качестве примера рассмотрим верхнюю/правую/переднюю вершину (которую вы разделяете с передней, правой и верхней гранями).

При использовании на лицевой стороне нормаль должна указывать на вас как 0, 0, 1 При использовании на правой стороне нормаль должна указывать вправо как 1, 0, 0 При использовании на верхней грани нормаль должен указывать вверх как 0, 1, 0

Так как же это примирить? Вы можете установить нормаль для вершины, чтобы она указывала из угла, например. как 0,707, 0,707, 0,707. Это, скорее всего, даст вам интересный световой эффект в углу, но, вероятно, это не то, что вам нужно.

Другое решение — не использовать повторно вершины между гранями. Таким образом, вам понадобится 24 (по 4 на сторону) вместо 8. Тогда у вас будет 3 версии каждой вершины, но каждая из них теперь принадлежит только одной грани, поэтому вы можете установить вектор нормали перпендикулярно этой грани. Вы также сможете установить цвет только для этой грани, так как вы больше не будете делить вершину с другими гранями.

person NigelK    schedule 06.02.2014
comment
Спасибо за ваше объяснение. Думал, будет удобное решение с индексами и не так часто переписывать вершины, но теперь я переключился на более частое использование одних и тех же вершин, и теперь я, наконец, вижу свет. - person damian; 06.02.2014