私はOpenGLタスクに取り組んでおり、次の段階はモデルをロードし、シャドウボリュームアルゴリズムを使用してシャドウを生成することです。私は3段階でそれを行います-
setConnectivity
-各三角形の近傍を見つけ、それらのインデックスneigh
を各三角形のパラメータに保存します。markVisible(float* lp)
visible = true
-lpが光の位置のベクトルを表す場合、法線ベクトルと光の位置のドット生成として、またはそれvisible = false
に応じて三角形をマークします 。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();
}