1

私はOpenGLタスクに取り組んでおり、次の段階はモデルをロードし、シャドウボリュームアルゴリズムを使用してシャドウを生成することです。私は3段階でそれを行います-

  1. setConnectivity-各三角形の近傍を見つけ、それらのインデックスneigh を各三角形のパラメータに保存します。

  2. markVisible(float* lp)visible = true-lpが光の位置のベクトルを表す場合、法線ベクトルと光​​の位置のドット生成として、またはそれvisible = falseに応じて三角形をマークします 。

  3. markSilhoutte(float *lp)-シルエットのエッジをマークし、ボリューム自体を構築し、光と反対の方向にシルエットを無限に拡張します(100ユニットで十分です)。

私はすべての段階をチェックしましたが、最初の2つですべて問題ないと断言できるので、問題は3番目の機能にあります。これを質問に含めました。このチュートリアルで紹介したアルゴリズムを使用します:http ://www.3dcodingtutorial.com/Shadows/Shadow-Volumes.html

簡単に言うと、エッジが表示されている三角形と表示されていない三角形に同時に属している場合、エッジはシルエットに含まれます。これが何が悪いのかを示すスクリーンショットのペアです: http ://prntscr.com/17dmg、http ://prntscr.com/17dmq

ご覧のとおり、緑色の球はライトの位置を表しており、これらの醜い緑と青のポリゴンは「シャドウボリューム」の面です。また、この関数を立方体のモデルに適用していて、ボリュームの側面の1つが欠落していることもわかります(閉じていませんが、閉じている必要があります)。誰かが私のコードの何が問題なのかを提案できますか?どうすれば修正できますか?これが私が含めると約束したコードです(変数名は自明だと思いますが、あなたが考えていない場合は、それぞれの説明を追加できます):

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();
    }
4

2 に答える 2

1

見つけました。明らかなアルゴリズムの間違いが数日間見られない場合は、ばかげた間違いを犯したようです。

私のトライアングル インデックス変数は 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();
}
于 2010-11-23T10:45:28.037 に答える
0

私はすべてが大丈夫だと思います、あなたは深さテストなしでボリュームをレンダリングしているだけです=)

于 2010-11-21T23:00:51.373 に答える