Reputation: 67362
I'm trying to render a grid-based terrain with flat shading, and my output looks very wrong:
The terrain data is as follows:
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
So the square in the middle is at height 1, flat (ie coplanar triangles) and parallel to the ground, the 4 NSEW squares are half at height 0 half at 1 (or more specifically 1/3), flat and sideways, and the 4 corner squares are about as you'd imagine -- don't worry about the corners, I'm not rotating the seam correctly.
My vertex shader is:
#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;
}
The sun direction is hard coded as vertical along the Z axis. The fragment shader just copies the color as given, nothing fancy.
Below you can see the some of the generated vertex data. Index 24 is the start of the middle square (4 * 6), and before it is the middle-left square, and you can see it's coplanar based on the normals calculated.
So my questions:
Why do I need to subtract the dot product between the sun direction and the normal vector to see anything? Without it I get a completely "light" (ie bright green) picture. In no tutorial I've read have I seen the need to do that subtraction.
Why do the middle-left and middle-right cells look half shaded half bright? They're coplanar, they should share a color.
Why is my flat cell in the middle not colored bright green? Again, it's coplanar with a straight up normal vector.
Why are the top 3 cells completely bright? Assume the vertices are calculated correctly, but I can also provide them if needed.
Upvotes: 1
Views: 562
Reputation: 45322
layout(location = 0) in vec3 vPosition; layout(location = 0) in vec3 fNormal;
That's not going to work. This is location aliasing and both input variables will receive the same data from attribute slot 0.
Upvotes: 2