Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于地形高度图的奇异法线生成_C++_Opengl_Terrain_Normals_Heightmap - Fatal编程技术网

C++ 基于地形高度图的奇异法线生成

C++ 基于地形高度图的奇异法线生成,c++,opengl,terrain,normals,heightmap,C++,Opengl,Terrain,Normals,Heightmap,我正在使用libnoise和OpenGL进行地形生成。我做了一个看起来有点复杂的正常生成算法: list = glGenLists(1); glNewList(list, GL_COMPILE); glPushAttrib(GL_ENABLE_BIT); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDisable(GL_TEXTURE_2D); glPushMatrix(); int h = 256; int w = 256; float

我正在使用libnoise和OpenGL进行地形生成。我做了一个看起来有点复杂的正常生成算法:

list = glGenLists(1);
glNewList(list, GL_COMPILE);


glPushAttrib(GL_ENABLE_BIT);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDisable(GL_TEXTURE_2D);

glPushMatrix();

int h = 256;
int w = 256;
float h1 = 0.0f;
float h2 = 0.0f;
float h3 = 0.0f;

float div = 7.0f;

float lPos[] = { 128, image.GetHeight() + 15.0f, 128, 1.0f };

for (int x = 1; x < h; x++)
{
    glColor3ub(139, 69, 19);
    glLightfv(GL_LIGHT0, GL_POSITION, lPos);
    glBegin(GL_TRIANGLE_STRIP);
    for (int z = 1; z < w; z++)
    {
        h1 = image.GetValue(x, z).red / 7.0f;
        h2 = image.GetValue(x + 1, z).red / 7.0f;


        Vector3 t1, t2, t3;
        Vector3 v1, v2, v3, v4, v5, v6;


        t1 = Vector3(x, h1, z);


        t2 = Vector3(x - 1, image.GetValue(x - 1, z).red / div, z);
        t3 = Vector3(x, image.GetValue(x, z - 1).red / div, z - 1);
        v1 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1, image.GetValue(x + 1, z).red / div, z);
        t3 = Vector3(x, image.GetValue(x, z + 1).red / div, z + 1);
        v2 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1, image.GetValue(x + 1, z).red / div, z);
        t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
        v3 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, - 1);
        t3 = Vector3(x , image.GetValue(x, z - 1).red / div, z - 1);
        v4 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x - 1, image.GetValue(x - 1, z + 1).red / div, z + 1);
        t3 = Vector3(x - 1, image.GetValue(x - 1, z).red / div, z);
        v5 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x - 1, image.GetValue(x - 1, z + 1).red / div, z + 1);
        t3 = Vector3(x, image.GetValue(x, z + 1).red / div, z + 1);
        v6 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));


        Vector3 normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);

        glNormal3f(normal1.X, normal1.Y, normal1.Z);
        glVertex3f(x, h1, z);


        t1 = Vector3(x + 1, h2, z);


        t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z).red / div, z);
        t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
        v1 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z).red / div, z);
        t3 = Vector3(x + 1, image.GetValue(x + 1, z + 1).red / div, z + 1);
        v2 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z).red / div, z);
        t3 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z - 1).red / div, z - 1);
        v3 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1 + 1, image.GetValue(x + 1 + 1, z - 1).red / div, -1);
        t3 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, z - 1);
        v4 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z + 1).red / div, z + 1);
        t3 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z).red / div, z);
        v5 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));

        t2 = Vector3(x + 1 - 1, image.GetValue(x + 1 - 1, z + 1).red / div, z + 1);
        t3 = Vector3(x + 1, image.GetValue(x + 1, z + 1).red / div, z + 1);
        v6 = Vector3::Normalize(Vector3::Cross(t3 - t1, t2 - t1));


        normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);

        glNormal3f(normal1.X, normal1.Y, normal1.Z);
        glVertex3f(x + 1, h2, z);
    }
    glEnd();
}

glPopMatrix();
glPopAttrib();
glEndList();
list=glgenlist(1);
glNewList(列表,总账汇编);
glPushAttrib(GLU启用位);
glEnable(德国劳埃德大学照明);
glEnable(GL_LIGHT0);
glDisable(GL_纹理_2D);
glPushMatrix();
int h=256;
int w=256;
浮动h1=0.0f;
浮子h2=0.0f;
浮球h3=0.0f;
浮动div=7.0f;
浮点LPO[]={128,image.GetHeight()+15.0f,128,1.0f};
对于(int x=1;x
如你所见,我通过平均六个周围面的法线来生成法线,从而实现平滑着色。问题是,在某些地方(特别是地势较低的地方),比特仍然是黑色的,有着奇怪的阴影。 这是一张照片:

我的正常一代是如何工作的: 笔记我画的是Y,我的意思是Z,对不起! 这是一张图片:

绿色是第一个顶点
红色是第二个顶点(x轴上的第一个+1)
黄色是相邻三角形的点

X是外环
Z是内部循环

因为我使用的是
GL\u TRIANGLE\u STRIP
,所以在下一次迭代中,我只需要两个顶点就可以构建一个三角形

所以。。。每个三角形的构造:
p1=(x,图像高度,z)
p2=(x+1,图像高度,z)

在下一次迭代中(z++)

p3=(x,图像高度,z+1)
p4=(x+1,图像高度,z+1)


…等等。

我还没有彻底检查所有代码,但我注意到您在这行末尾附近缺少一个“z”:

t2 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, - 1);
Vector3 normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);
计算
v4
(两次)

此外,在这方面:

t2 = Vector3(x + 1, image.GetValue(x + 1, z - 1).red / div, - 1);
Vector3 normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);

在标准化之前,不需要除以6。事实上,在求和之前,您可以尝试不规范化单个叉积。这将使法线朝向中心更靠近顶点的三角形加权

尝试过,变得更糟。就像用小三角形做的跳棋。我在某个地方读到,由于
\u条
存在双向排序,我需要翻转法线。然而,我不知道反向法线的确切生成位置,也不知道如何测试它。@Arctic:对于每个奇数三角形,你翻转生成的法线。当按带状排列时,每个三角形交替缠绕。如果按照条带顺序计算三角形的法线,但未能对此进行补偿,则如果平均每个三角形的法线,则其中一半的法线将朝向错误的方向。这是一种因为这个而发生的事情。