基于高度图的地形上奇怪的正常世代
我正在使用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();
所以,正如你所看到的,我通过平均来自六个周围脸部的法线来生成法线,从而实现平滑的阴影。 问题在于,在某些地方(特别是地形的下部),位仍然是黑色的,奇怪的是阴影。 这是一张图片:
我的正常代人如何工作:
注意!!!! 我画了Y,我的意思是Z,对不起!
这是一张图片:
绿色是第一个顶点。
红色是第二个顶点(x轴上的第一个+1)
黄色是相邻三角形的点。
X是外部循环。
Z是内部循环。
由于我使用的是GL_TRIANGLE_STRIP
,我只需要2个顶点用于下一次迭代来构造一个三角形。
所以......每个三角形都被构造出来
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);
在计算v4
(两次)中。
另外,在这一行中:
Vector3 normal1 = Vector3::Normalize((v1 + v2 + v3 + v4 + v5 + v6) / 6);
正常化之前,你不需要除以6。 事实上,你可以尝试在统计各个交叉产品之前对它们进行归一化。 这将使法线朝着中心更靠近顶点的三角形加权。
链接地址: http://www.djcxy.com/p/37179.html上一篇: Weird normal generation on height map based terrain
下一篇: Fractal noise terrain generating strange artefact lines