【问题标题】:Shadow volumes - finding a silhouette阴影体积 - 寻找轮廓
【发布时间】:2010-11-21 22:44:13
【问题描述】:

我正在处理我的 OpenGL 任务,下一阶段是加载模型并使用阴影体积算法生成阴影。我分三个阶段进行 -

  1. setConnectivity - 发现 每个三角形的邻居和 将他们的索引存储在neigh 每个三角形的参数,

  2. markVisible(float* lp) - 如果 lp 表示光的向量 位置,它将三角形标记为 visible = truevisible = 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();
    }

【问题讨论】:

    标签: c++ opengl shadow


    【解决方案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();
    }
    

    【讨论】:

      【解决方案2】:

      我认为一切都很好,你只是在没有深度测试的情况下渲染体积 =)

      【讨论】:

      • 添加了 glEnable(GL_DEPTH_TEST),结果相同。根据图片,我认为顶点索引错误/顺序错误,我随机交换了所有 glVertex.. 行,结果各不相同,但总是不好:D
      • 只启用深度测试是不够的 =) 你应该多做几个步骤,比如这里gpwiki.org/index.php/…
      • 从这个链接添加了所有设置:glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE);我完全不知道它们会改变什么,但即使是这些丑陋的多边形也消失了>_
      • 你能给我你的来源吗?我现在正在运行 linux,但如果您愿意,可以尝试在 win7 下运行它。
      猜你喜欢
      • 2011-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 2012-01-16
      相关资源
      最近更新 更多