简体   繁体   English

在Open GL中计算表面的法线

[英]Calculating Normals for Surface in Open GL

I am trying to add shading/lighting to my terrain generator. 我正在尝试向地形生成器添加阴影/照明。 But for some reason my output still looks blocky even after I calculate surface normals. 但是由于某种原因,即使在计算表面法线之后,我的输出仍然看起来很块状。

set<pair<int,int> >::const_iterator it;

for ( it = mRandomPoints.begin(); it != mRandomPoints.end(); ++it )
{
    for ( int i = 0; i < GetXSize(); ++i )
    {
        for ( int j = 0; j < GetZSize(); ++j )
        {
            float pd = sqrt(pow((*it).first - i,2) + pow((*it).second - j,2))*2 / mCircleSize;
            if(fabs(pd) <= 1.0)
            {
                mMap[i][j][2] += mCircleHeight/2 + cos(pd*3.14)*mCircleHeight/2; ;
            }

        }
    }
}

/*
    The three points being considered to compute normals are 
    (i,j)
    (i+1,j)
    (i, j+1)
*/

for ( int i = 0; i < GetXSize() -1 ; ++i )
{
    for ( int j = 0; j < GetZSize() - 1; ++j )
    {
        float b[] = {mMap[i+1][j][0]-mMap[i][j][0], mMap[i+1][j][1]-mMap[i][j][1], mMap[i+1][j][2]-mMap[i][j][2] };
        float c[] = {mMap[i][j+1][0]-mMap[i][j][0], mMap[i][j+1][1]-mMap[i][j][1], mMap[i][j+1][2]-mMap[i][j][2] };
        float a[] = {b[1]*c[2] - b[2]*c[1], b[2]*c[0]-b[0]*c[2], b[0]*c[1]-b[1]*c[0]};

        float Vnorm = sqrt(pow(a[0],2) + pow(a[1],2) + pow(a[2],2));

        mNormalMap[i][j][0] = a[0]/Vnorm;
        mNormalMap[i][j][1] = a[1]/Vnorm;
        mNormalMap[i][j][2] = a[2]/Vnorm;

    }
}

Then when drawing this I use the following 然后在绘制时我使用以下

float*** normal = map->GetNormalMap();

for (int i = 0 ; i < map->GetXSize() - 1; ++i)
{
    glBegin(GL_TRIANGLE_STRIP);

    for (int j = 0; j < map->GetZSize() - 1; ++j)
    {

        glNormal3fv(normal[i][j]);


        float color = 1 - (terrain[i][j][2]/height);
        glColor3f(color,color, color);
        glVertex3f(terrain[i][j][0], terrain[i][j][2], terrain[i][j][1]);
        glVertex3f(terrain[i+1][j][0], terrain[i+1][j][2], terrain[i+1][j][1]);
        glVertex3f(terrain[i][j+1][0], terrain[i][j+1][2], terrain[i][j+1][1]);
        glVertex3f(terrain[i+1][j+1][0], terrain[i+1][j+1][2], terrain[i+1][j+1][1]);
    }

    glEnd();
}

EDIT: Initialization Code 编辑:初始化代码

glFrontFace(GL_CCW);
glCullFace(GL_FRONT); // glCullFace(GL_BACK); 
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glMatrixMode(GL_PROJECTION);

Am I calculating the Normals Properly? 我是否可以正确计算法线?

In addition to what Bovinedragon suggested, namely glShadeModel(GL_SMOOTH); 除了Bovinedragon建议的内容外,还包括glShadeModel(GL_SMOOTH); , you should probably use per-vertex normals. ,您可能应该使用每个顶点的法线。 This means that each glVertex3f would be preceded by a glNormal3fv call, which would define the average normal of all adjacent faces. 这意味着每个glVertex3f之前都会有一个glNormal3fv调用,该调用将定义所有相邻面的平均法线。 To obtain it, you can simply add up these neighbouring normal vectors and normalize the result. 要获得它,您可以简单地将这些相邻的法线向量相加并标准化结果。

在此处输入图片说明

Reference this question: Techniques to smooth face edges in OpenGL 引用此问题: 在OpenGL中平滑脸部边缘的技术

Have you set glShadeModel to GL_SMOOTH? 您是否已将glShadeModel设置为GL_SMOOTH?

See: http://www.khronos.org/opengles/documentation/opengles1_0/html/glShadeModel.html 请参阅: http : //www.khronos.org/opengles/documentation/opengles1_0/html/glShadeModel.html

This settings also effects vertex colors in addition to lighting. 除照明外,此设置还影响顶点颜色。 You seem to say it was blocky even before lighting which makes me think this is the issue. 您似乎说,即使在点灯之前它还是很块状的,这让我认为这是问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM