我有一个生成高度图的程序,然后将其显示为OpenGL的网格。当我尝试添加光照时,最终会形成覆盖网格的奇怪方形。它们在某些方面比其他方面更明显,但总是在那里。
我使用的是四边形网格,但切换到三角形网格后没有任何变化。我使用至少三种不同的方法来计算顶点法线,所有方法都具有相同的效果。我正在使用着色器手动进行照明,但使用内置时没有任何变化 OpenGL照明系统。
我最新的法线生成代码(faces是一个顶点索引数组,顶点数组):
int i;
for (i = 0; i < NINDEX; i += 3) {
vec v[3];
v[0] = verts[faces[i + 0]];
v[1] = verts[faces[i + 1]];
v[2] = verts[faces[i + 2]];
vec v1 = vec_sub(v[1], v[0]);
vec v2 = vec_sub(v[2], v[0]);
vec n = vec_norm(vec_cross(v2, v1));
norms[faces[i + 0]] = vec_add(norms[faces[i + 0]], n);
norms[faces[i + 1]] = vec_add(norms[faces[i + 1]], n);
norms[faces[i + 2]] = vec_add(norms[faces[i + 2]], n);
}
for (i = 0; i < NVERTS; i++) {
norms[i] = vec_norm(norms[i]);
}
虽然这不是我用过的唯一代码,但我怀疑这是问题的原因。
我用:
绘制网格glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, verts);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, norms);
glDrawElements(GL_TRIANGLES, NINDEX, GL_UNSIGNED_SHORT, faces);
我目前没有使用任何着色器。
导致这种情况的原因是什么?
编辑:一套更全面的截图:
对于最后一个,着色器代码是
顶点:
varying vec3 lightvec, normal;
void main() {
vec3 lightpos = vec3(0, 0, 100);
vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex);
normal = gl_NormalMatrix * gl_Normal;
lightvec = normalize(lightpos - v);
gl_Position = ftransform();
}
片段:
varying vec3 lightvec, normal;
void main(void) {
float l = dot(lightvec, normal);
gl_FragColor = vec4(l, l, l, 1);
}
答案 0 :(得分:2)
您需要在片段着色器中规范化法线,如下所示:
varying vec3 lightvec, normal;
void main(void) {
vec3 normalNormed = normalize(normal);
float l = dot(lightvec, normalNormed);
gl_FragColor = vec4(l, l, l, 1);
}
但这可能很昂贵。在这种情况下,使用定向灯也可以使用顶点照明。因此,计算顶点着色器中的光值
varying float lightItensity;
void main() {
vec3 lightpos = vec3(0, 0, 100);
vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex);
normal = gl_NormalMatrix * gl_Normal;
lightvec = normalize(lightpos - v);
lightItensity = dot(normal, lightvec);
gl_Position = ftransform();
}
并在片段着色器中使用它
varying float light;
void main(void) {
float l = light;
gl_FragColor = vec4(l, l, l, 1);
}
我希望这可以修复它,如果没有,请告诉我。
编辑:下面是一个解释最有可能发生的事情的小图
EDIT2:
如果这没有帮助,请添加更多三角形。插值高度图的值并在其间添加一些顶点。
或者,尝试更改您的细分方案。例如,像这样的等边三角形网格可能会使人工制品不那么突出。
你必须对你的身高图做一些插值。
否则我不知道..祝你好运!
答案 1 :(得分:1)
对于非着色器版本,我没有明确的答案,但我想补充一点,如果你在片段着色器中进行每像素照明,你应该将片段着色器内的法线和光线正常化
如果不这样做,则它们不是单位长度(两个归一化向量之间的线性插值不一定是标准化的)。这可以解释您在着色器版本中看到的一些工件,因为点积的大小会随着与顶点的距离而变化,这看起来就像您所看到的那样。
编辑:另一个想法是,在渲染非着色器版本时,您是否正在进行网格的任何非均匀缩放(不同的x,y,z)?如果缩放它,则需要通过反比例因子修改法线,或者设置glEnable(GL_NORMALIZE)
。请看这里了解更多:
http://www.lighthouse3d.com/tutorials/glsl-tutorial/normalization-issues/