微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

平均法线高度场

如何解决平均法线高度场

我正在创建高度场,我想创建其法线(面/顶点),我正在使用“三角形”创建网格。我已经计算了GL Quad法线,但是在这里对Triangles而不是Quads感到困惑。 我在互联网上搜索后发现,存在两种类型的法线,例如每个面和每个顶点,但是找不到与我的代码相关的任何帮助。 这是我现在正在创建的高度场。

int average_normal()

{ 
glPushmatrix();


GLfloat xdelta=xsize/xsteps;
GLfloat zdelta=zsize/zsteps;
   
glnormal3f(0,1,0);

for (int x=0; x<xsteps-1; x++)
    for (int z=0; z<zsteps-1; z++)
    {
    
    glBegin(GL_TRIANGLES);
    setMaterialHeight(map[x][z]);
    glnormal3f(0,1);
    glVertex3f(xdelta*x,map[x][z],zdelta*z);
    setMaterialHeight(map[x+1][z]);
    glnormal3f(0,1);
    glVertex3f(xdelta*x+xdelta,map[x+1][z],zdelta*z);
    setMaterialHeight(map[x][z+1]);
    glnormal3f(0,map[x][z+1],zdelta*z+zdelta);   
    glEnd();

    glBegin(GL_TRIANGLES);
    setMaterialHeight(map[x+1][z+1]);
    glnormal3f(0,map[x+1][z+1],zdelta*z+zdelta);  
    setMaterialHeight(map[x][z+1]);
    glnormal3f(0,zdelta*z+zdelta);       
    setMaterialHeight(map[x+1][z]);
    glnormal3f(0,zdelta*z);
    glEnd();
    }
glPopMatrix();
return true;
}

如何计算其正常值?

解决方法

法线向量可以由2个向量中的Cross product计算。创建一个函数,计算叉积并设置法线向量属性:

void set_normal_from_cross_product(
    float x1,float y1,float z1,float x2,float y2,float z2)
{
    float nx = y1*z2 - z1*y2;
    float ny = z1*x2 - x1*z2;
    float nz = x1*y2 - y1*x2;
    float len = sqrt(nx*nx + ny*ny + nz*nz);
    if (len != 0.0f)
        glNormal3f(nx/len,ny/len,nz/len);
}

在网格中,法线向量可以通过相邻顶点之间的向量来计算。写函数,用于计算相邻顶点之间的向量并调用set_normal_from_cross_product

void set_grid_normal(int x,int z)
{
    int prev_x = x > 0 ? x - 1 : x;
    int next_x = x < xsteps - 1 ? x + 1 : x;
    int prev_z = z > 0 ? z - 1 : z;
    int next_z = z < zsteps - 1 ? z + 1 : z;

    set_normal_from_cross_product(
        xdelta * 2,map[next_x][z]-map[prev_x][z],map[x][next_z]-map[x][prev_z],zdelta * 2);
}

使用该函数来设置法线向量:

void set_attributes(int x,int z)
{
    setMaterialHeight(map[x][z]);
    set_grid_normal(x,z);
    glVertex3f(xdelta*x,map[x][z],zdelta*z);
}
for (int x=0; x<xsteps-1; x++)
{
    for (int z=0; z<zsteps-1; z++)
    {
        glBegin(GL_TRIANGLES);
        set_attributes(x,z);
        set_attributes(x+1,z);
        set_attributes(x,z+1);
        glEnd();

        glBegin(GL_TRIANGLES);
        set_attributes(x+1,z+1);
        set_attributes(x,z+1);
        set_attributes(x+1,z);
        glEnd();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。