OpenGL中奇怪的方形照明人工制品

sig*_*ill 7 c opengl lighting

我有一个生成高度图的程序,然后将其显示为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]);
}
Run Code Online (Sandbox Code Playgroud)

虽然这不是我用过的唯一代码,但我怀疑这是问题的原因.

我绘制网格:

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);
Run Code Online (Sandbox Code Playgroud)

我目前没有使用任何着色器.

可能是什么导致了这个?

编辑:一套更全面的截图:

对于最后一个,着色器代码是

顶点:

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();
}
Run Code Online (Sandbox Code Playgroud)

分段:

varying vec3 lightvec, normal;

void main(void) {
    float l = dot(lightvec, normal);
    gl_FragColor = vec4(l, l, l, 1);
} 
Run Code Online (Sandbox Code Playgroud)

Tim*_*Tim 1

对于非着色器版本,我没有明确的答案,但我想补充一点,如果您在片段着色器中进行逐像素照明,则可能应该对片段着色器内的法线和 lightvec 进行标准化。

如果不这样做,它们就不是单位长度(两个归一化向量之间的线性插值不一定是归一化的)。这可以解释您在着色器版本中看到的一些伪像,因为点积的大小会随着距顶点的距离而变化,这看起来就像您所看到的那样。

编辑:另一个想法是,在渲染非着色器版本时,您是否对网格进行任何非均匀缩放(不同的 x、y、z)?如果缩放它,则需要通过反比例因子修改法线,或设置glEnable(GL_NORMALIZE)。请参阅此处了解更多信息: http://www.lighthouse3d.com/tutorials/glsl-tutorial/normalization-issues/