Внешний вид треугольной полосы. Нормали поверхности? Или обмотки?

Ниже на фото мой результат.

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

Я предоставил часть своего кода ниже всем, кто хочет просмотреть его и лучше понять, в чем может быть проблема.

Полоса треугольника с

Triangle currentTri = new Triangle();
int triPointIndex = 0;
List<Triangle> triList = new ArrayList<Triangle>()                               

GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
        int counter1 = 0;               
        float stripZ = 1.0f;
        float randY;
        for (float x=0.0f; x<20.0f; x+=2.0f) {
            if (stripZ == 1.0f) {
                stripZ = -1.0f;
            } else { stripZ = 1.0f; }

            randY = (Float) randYList.get(counter1);
            counter1 += 1;

            GL11.glVertex3f(x, randY, stripZ);

            Vert currentVert = currentTri.triVerts[triPointIndex];
            currentVert.x = x;
            currentVert.y = randY;
            currentVert.z = stripZ;

            triPointIndex++;

            System.out.println(triList);

            Vector3f normal = new Vector3f();
            float Ux = currentTri.triVerts[1].x - currentTri.triVerts[0].x;
            float Uy = currentTri.triVerts[1].y - currentTri.triVerts[0].y;
            float Uz = currentTri.triVerts[1].z - currentTri.triVerts[0].z;

            float Vx = currentTri.triVerts[2].x - currentTri.triVerts[0].x;
            float Vy = currentTri.triVerts[2].y - currentTri.triVerts[0].y;
            float Vz = currentTri.triVerts[2].z - currentTri.triVerts[0].z;

            normal.x = (Uy * Vz) - (Uz * Vy);
            normal.y = (Uz * Vx) - (Ux * Vz);
            normal.z = (Ux * Vy) - (Uy * Vx);

            GL11.glNormal3f(normal.x, normal.y, normal.z);

            if (triPointIndex == 3) {
                triList.add(currentTri);
                Triangle nextTri = new Triangle();

                nextTri.triVerts[0] = currentTri.triVerts[1];
                nextTri.triVerts[1] = currentTri.triVerts[2];
                currentTri = nextTri;
                triPointIndex = 2;
            }           

        }
 GL11.glEnd();

person Alpha Centauri A B    schedule 04.12.2013    source источник


Ответы (2)


Вы должны установить обычный перед вызовом glVertex3f (...). Вызов glVertex* в основном завершает вершину, он связывает текущий цвет, нормаль, координаты текстуры и т. д. с вершиной в позиции, которую вы проходите, и создает новую вершину.


glVertex — указать вершину

Описание

Команды glVertex используются в парах glBegin / glEnd для указания точек, линий и вершин многоугольников. Текущий цвет, нормаль, координаты текстуры и координаты тумана связаны с вершиной при вызове glVertex.

Если указаны только x и y, по умолчанию z равно 0,0, а w по умолчанию равно 1,0. Когда указаны x, y и z, w по умолчанию равно 1.0.


Скорее всего, это является большой частью вашей проблемы. Треугольные полоски предназначены для решения проблем неявной намотки. Вы должны изменить намотку каждого треугольника, когда используете полосу, но растеризатор компенсирует это, изменяя порядок намотки, используемый для передней/задней части, внутри каждого чередующегося треугольника.

Обновлять:

Поймите, конечно, что растеризатор достаточно умен, чтобы переворачивать переднюю/заднюю обмотку для каждого альтернативного треугольника при использовании полосы, но ваш код этого не делает (по крайней мере, в настоящее время). Компенсировать попеременно перевернутую обмотку нужно при самостоятельном расчете нормалей на стороне ЦП.

person Andon M. Coleman    schedule 04.12.2013
comment
Проблема с ОП, вероятно, вызвана тем, что его обычный расчет заменяется местами для каждого нечетного индексированного треугольника. Вы можете видеть тусклые треугольники на его изображении, так что это не проблема намотки/выбраковки (как вы указали, не может быть в полосе). - person datenwolf; 05.12.2013
comment
@datenwolf: А, я перечитал вопрос и снова посмотрел на диаграмму. Да, отсутствующие (на ЖК-дисплее ноутбука их было трудно увидеть, когда я впервые посмотрел на вопрос) темные треугольники определенно связаны с тем, что нормали вычисляются на стороне ЦП после изменения порядка намотки. Растеризатор выполняет свою работу, как описано, но фактический код Java, вычисляющий нормали, ведет себя не так, как описано; он также должен переворачивать их для каждого альтернативного треугольника. Но вдобавок к этому нормали назначаются каждой вершине поздно, поэтому они всегда расходятся на единицу. - person Andon M. Coleman; 05.12.2013
comment
Спасибо! Это действительно помогло мне понять, что происходит, и многое прояснило. В конце концов у меня это заработало. :) - person Alpha Centauri A B; 05.12.2013

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

Обмотка также важна для OpenGL, но вы ничего не можете изменить в полосатом примитиве.

person datenwolf    schedule 04.12.2013
comment
Итак, вы говорите, что нет способа обойти это и что я должен перейти от использования GL_TRIANGLE_STRIP к использованию GL_TRIANGLES? - person Alpha Centauri A B; 05.12.2013
comment
Или я мог бы сделать что-то другое с моими вычислениями нормалей к поверхности, чтобы они компенсировали и перевернули все остальные треугольники? - person Alpha Centauri A B; 05.12.2013
comment
@AlphaCentauriAB: Вы должны исправить расчет нормалей. Для каждого треугольника с нечетным индексом вы должны либо поменять местами векторы в векторное произведение, либо масштабировать результирующую нормаль на -1. Также вы должны вызвать glNormal перед вызовом glVertex. - person datenwolf; 05.12.2013
comment
Спасибо! Второе предложение в этом комментарии действительно помогло мне понять это. Хотя это было намного проще, чем мне. - person Alpha Centauri A B; 05.12.2013