Объемы теней - нахождение силуэта - PullRequest
1 голос
/ 22 ноября 2010

Я работаю над своей задачей OpenGL, и следующий этап - загрузка моделей и создание теней с использованием алгоритма теневых объемов.Я делаю это в 3 этапа -

  1. setConnectivity - нахождение соседей каждого треугольника и сохранение их индексов в параметре neigh каждого треугольника,

  2. markVisible(float* lp) - если lp представляет вектор положения света, он помечает треугольники как visible = true или visible = false в зависимости от точечного производства его нормального вектора и положения света,

  3. markSilhoutte(float *lp) - разметка кромок силуэта и построение самого объема, расширение силуэта до бесконечности (достаточно 100 единиц) в направлении, противоположном свету.

Я проверил все этапы и определенно могуСкажите, что все нормально с первыми двумя, так что проблема в третьей функции, которую я включил в свой вопрос.Я использую алгоритм, представленный в этом уроке: http://www.3dcodingtutorial.com/Shadows/Shadow-Volumes.html

Вкратце, ребро включено в силуэт, если оно принадлежит одновременно видимому и невидимому треугольникам.Вот пара скриншотов, чтобы показать вам, что не так: http://prntscr.com/17dmg, http://prntscr.com/17dmq

Как вы можете видеть, зеленая сфера представляет положение света, а эти уродливые сине-зеленые многоугольники - это лица "теневой объем ".Вы также можете видеть, что я применяю эту функцию к модели куба, и одна из сторон тома отсутствует (она не закрыта, но я должен быть).Может кто-нибудь подсказать, что не так с моим кодом и как я могу это исправить?Вот код, который я обещал включить (я полагаю, что имена переменных говорят сами за себя, но если вы так не думаете, я могу добавить описание для каждого из них):

void Model::markSilhouette(float* lp){
        glBegin(GL_QUADS);
        for ( int i = 0; i < m_numMeshes; i++ )
        {
            for ( int t = 0; t < m_pMeshes[i].m_numTriangles; t++ )
            {
                int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t];
                Triangle* pTri = &m_pTriangles[triangleIndex];
                if (pTri->visible){

                    for(int j=0;j<3;j++){
                        int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1];
                        Triangle* pTrk = &m_pTriangles[triangleIndex];
                        if(!pTrk->visible){
                            int p1j=pTri->m_vertexIndices[j];
                            int p2j=pTri->m_vertexIndices[(j+1)%3];
                            float* v1=m_pVertices[p1j].m_location;
                            float* v2=m_pVertices[p2j].m_location;

                            float x1=m_pVertices[p1j].m_location[0];
                            float y1=m_pVertices[p1j].m_location[1];
                            float z1=m_pVertices[p1j].m_location[2];

                            float x2=m_pVertices[p2j].m_location[0];
                            float y2=m_pVertices[p2j].m_location[1];
                            float z2=m_pVertices[p2j].m_location[2];

                            t=100;

                            float xl1=(x1-lp[0])*t;
                            float yl1=(y1-lp[1])*t;
                            float zl1=(z1-lp[2])*t;

                            float xl2=(x2-lp[0])*t;
                            float yl2=(y2-lp[1])*t;
                            float zl2=(z2-lp[2])*t;
                            glColor3f(0,0,1);

                            glVertex3f(x1 + xl1,
                                y1 + yl1,
                                z1 + zl1);
                            glVertex3f(x1,
                                y1,
                                z1);
                            glColor3f(0,1,0);

                            glVertex3f(x2 + xl2,
                                y2 + yl2,
                                z2 + zl2);
                            glVertex3f(x2,
                                y2,
                                z2);
                        }
                    }

                }

            }
        }
        glEnd();
    }

Ответы [ 2 ]

1 голос
/ 23 ноября 2010

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

Моя переменная индекса треугольника называется t.Угадай, что?Моя длина вектора расширения также называется t, и они находятся в той же области видимости, и я установил t = 100 после первого видимого треугольника: D Так что теперь объемы выглядят так: снаружи http://prntscr.com/17l3n внутри http://prntscr.com/17l40И это выглядит хорошо для всех светлых положений (конечно, приемлемых для теневых объемов).Итак, рабочий код для рисования теневого объема следующий:

void Model::markSilouette(float* lp){
    glDisable(GL_LIGHTING);
    glPointSize(4.0);
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK,GL_FILL);
    glBegin(GL_QUADS);
    for ( int i = 0; i < m_numMeshes; i++ )
    {
        for ( int t = 0; t < m_pMeshes[i].m_numTriangles; t++ )
        {
            int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t];
            Triangle* pTri = &m_pTriangles[triangleIndex];

            if (pTri->visible){
                for(int j=0;j<3;j++){
                    Triangle* pTrk;
                    if(pTri->neigh[j]){
                        int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1];
                        pTrk = &m_pTriangles[triangleIndex];
                    }

                        if((!pTri->neigh[j]) || !pTrk->visible){

                            int p1j=pTri->m_vertexIndices[j];
                            int p2j=pTri->m_vertexIndices[(j+1)%3];
                            float* v1=m_pVertices[p1j].m_location;
                            float* v2=m_pVertices[p2j].m_location;

                            float x1=m_pVertices[p1j].m_location[0];
                            float y1=m_pVertices[p1j].m_location[1];
                            float z1=m_pVertices[p1j].m_location[2];

                            float x2=m_pVertices[p2j].m_location[0];
                            float y2=m_pVertices[p2j].m_location[1];
                            float z2=m_pVertices[p2j].m_location[2];

                            float f=100; // THE PROBLEM WAS HERE

                            float xl1=(x1-lp[0])*f;
                            float yl1=(y1-lp[1])*f;
                            float zl1=(z1-lp[2])*f;

                            float xl2=(x2-lp[0])*f;
                            float yl2=(y2-lp[1])*f;
                            float zl2=(z2-lp[2])*f;
                            glColor3f(0,0,0);
                            glVertex3f(x1 + xl1,
                                y1 + yl1,
                                z1 + zl1);
                            glVertex3f(x1,
                                y1,
                                z1);
                            glVertex3f(x2,
                                y2,
                                z2);
                            glVertex3f(x2 + xl2,
                                y2 + yl2,
                                z2 + zl2);
                        }
                    }
                }

        }
    }
    glEnd();
}
0 голосов
/ 22 ноября 2010

Я думаю, что все в порядке, вы просто визуализируете объем без проверки глубины =)

...