阴影卷-查找轮廓 [英] Shadow volumes - finding a silhouette

查看:93
本文介绍了阴影卷-查找轮廓的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im working on my OpenGL task, and next stage is loading models and producing shadows using shadow volumes algorithm. I do it in 3 stages -

  1. setConnectivity-查找 每个三角形的邻居和 将其索引存储在neigh中 每个三角形的参数

  1. setConnectivity - finding neighbours of each triangle and storing their indices in neigh parameter of each triangle,

markVisible(float* lp)-如果为lp 代表光的向量 位置,将三角形标记为 visible = truevisible = false取决于点的产生 的法线向量和光 位置

markVisible(float* lp) - if lp represents vector of light's position, it marks triangles as visible = true or visible = false depending on dot production of its normal vector and light position,

markSilhoutte(float *lp)-标记轮廓边缘并构建体积本身,在与光相反的方向上将轮廓扩展到无穷大(足够100个单位).

markSilhoutte(float *lp) - marking silhouette edges and building the volume itself, extending silhouette to infinity(100 units is enough) in the direction opposite to light.

我检查了所有阶段,可以肯定地说前两个都可以,所以问题出在我的问题中的第三个功能上.我使用本教程中介绍的算法: http://www.3dcodingtutorial.com/Shadows/Shadow-Volumes.html

I checked all stages, and can definitely say that its all ok with first two, so the problem is in third function, which i included in my question. I use the algorithm introduced in this tutorial: http://www.3dcodingtutorial.com/Shadows/Shadow-Volumes.html

简而言之,如果边缘同时属于可见三角形和不可见三角形,则将其包括在轮廓中. 这是一对截图,向您显示出了什么问题: http://prntscr.com/17dmg http://prntscr.com/17dmq

Briefly, edge is included in silhouette if it belongs to the visible triangle and non-visible triangle at the same time. Here is a pair of screenshots to show you whats wrong: http://prntscr.com/17dmg , http://prntscr.com/17dmq

如您所见,绿色球形代表光线的位置,而这些难看的蓝绿色多边形代表阴影体积"的面.您还可以看到,即时消息将此功能应用于多维数据集模型,并且缺少体积的一侧(它没有闭合,但我应该是).有人可以建议我的代码有什么问题吗,我该如何解决?这是我答应包含的代码(我想,变量名是不言自明的,但是如果您不认为这样,我可以为它们中的每一个添加描述):

As you can see, green sphere represents light's position, and these ugly green-blue polygons are faces of "shadow volume". You can also see, that im applying this function to the model of cube, and one of volume's side is missing(its not closed, but i should be). Can someone suggest whats wrong with my code and how can i fix it? Here goes the code i promised to include(variables names are self-explanatory, i suppose, but if you dont think so i can add description for each of them):

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

推荐答案

我找到了它.看来,如果您几天都没有发现明显的算法错误,那么您就犯了一个愚蠢的愚蠢错误.

I've found it. It looks like if you dont see an obvious algorithm mistake for a few days, then you've made a f*cking stupid mistake.

我的三角形索引变量称为t.你猜怎么了?我扩展的矢量长度也称为t,它们在相同的范围内,我在第一个可见三角形之后设置t = 100:D现在,体积如下所示: 在 http://prntscr.com/17l3n 之外 内部 http://prntscr.com/17l40 它对于所有光线位置看起来都很不错(当然,阴影量算法可以接受).因此,用于绘制阴影体积的工作代码如下:

My triangle index variable is called t. Guess what? My extending vector length is also called t, and they are in the same scope, and i set t=100 after FIRST visible triangle :D So now volumes look like this: outside http://prntscr.com/17l3n inside http://prntscr.com/17l40 And it looks good for all light positions(acceptable by shadow volumes aglorithm, of course). So the working code for drawing a shadow volume is the following:

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

这篇关于阴影卷-查找轮廓的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆