OpenGL平面着色光照着色器问题

OpenGL flat shading lighting shader problem

我正在尝试渲染具有平坦阴影的基于网格的地形,但我的输出看起来非常错误:

地形数据如下:

0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0

因此中间的正方形高度为 1,平坦(即共面三角形)并平行于地面,4 个 NSEW 正方形一半高度为 0 一半高度为 1(或更具体地说是 1/3),平坦和侧面,4 个角正方形与您想象的差不多——不用担心角,我没有正确旋转接缝。

我的顶点着色器是:

#version 460

layout(location = 0) uniform mat4 projection;
layout(location = 4) uniform mat4 world;

layout(location = 0) in vec3 vPosition;
layout(location = 0) in vec3 fNormal;
layout(location = 2) in vec4 vColor;

flat out vec4 fColor;

const vec3 sunDirection = vec3(0, 0, 1);

void main(void)
{
    gl_Position = projection * world * vec4(vPosition, 1);
    fColor = (1 - max(0, dot(sunDirection, fNormal))) * vColor;
}

太阳方向硬编码为沿 Z 轴垂直。片段着色器只是复制给定的颜色,没什么特别的。

下面你可以看到一些生成的顶点数据。 Index 24是中间正方形(4 * 6)的起点,在它之前是左中正方形,根据计算的法线可以看到它是共面的。

所以我的问题:

  1. 为什么我需要减去太阳方向和法向量之间的点积才能看到任何东西?没有它,我会得到一张完全“浅”(即亮绿色)的图片。在我读过的任何教程中,我都没有看到需要做那个减法。

  2. 为什么中左和中右单元格看起来一半暗一半亮?它们是共面的,它们应该共享一种颜色。

  3. 为什么我中间的扁平单元格不是亮绿色?同样,它与垂直向上的法向量共面。

  4. 为什么上面的3个格子全亮了?假设顶点计算正确,但如果需要我也可以提供它们。

layout(location = 0) in vec3 vPosition;
layout(location = 0) in vec3 fNormal;

那是行不通的。这是位置别名,两个输入变量将从属性槽 0 接收相同的数据。