I'm currently using marching cubes to generate a mesh, and have encountered this incredibly weird problem.
Looking from below the terrain, these weird fully lit lines appear between every triangle. And from above, these are black. Moving closer does not remove these lines.
What could be causing these artifacts?
Marching Cubes
std::vector<glm::vec3> triangles;
glm::vec3 pos(0, 0, 0);
for (int x = 0; x < t_width - 1; x++)
for (int y = 0; y < t_height - 1; y++)
for (int z = 0; z < t_depth - 1; z++)
{
glm::float4 cubeCorners[8] = {
m_scalar_field[x][y][z],
m_scalar_field[x + 1][y][z],
m_scalar_field[x + 1][y][z + 1],
m_scalar_field[x][y][z + 1],
m_scalar_field[x][y + 1][z],
m_scalar_field[x + 1][y + 1][z],
m_scalar_field[x + 1][y + 1][z + 1],
m_scalar_field[x][y + 1][z + 1]
};
int cubeindex = 0;
for (int i = 0; i < 8; i++)
{
if (cubeCorners[i].w <= m_scalar_median)
{
cubeindex |= 1 << i;
}
}
if (m_edge_table[cubeindex] != 0)
{
glm::float3 vertexList[12];
if (m_edge_table[cubeindex] & 1)
vertexList[0] =
linearInterp(m_scalar_median, cubeCorners[0], cubeCorners[1]);
if (m_edge_table[cubeindex] & 2)
vertexList[1] =
linearInterp(m_scalar_median, cubeCorners[1], cubeCorners[2]);
if (m_edge_table[cubeindex] & 4)
vertexList[2] =
linearInterp(m_scalar_median, cubeCorners[2], cubeCorners[3]);
if (m_edge_table[cubeindex] & 8)
vertexList[3] =
linearInterp(m_scalar_median, cubeCorners[3], cubeCorners[0]);
if (m_edge_table[cubeindex] & 16)
vertexList[4] =
linearInterp(m_scalar_median, cubeCorners[4], cubeCorners[5]);
if (m_edge_table[cubeindex] & 32)
vertexList[5] =
linearInterp(m_scalar_median, cubeCorners[5], cubeCorners[6]);
if (m_edge_table[cubeindex] & 64)
vertexList[6] =
linearInterp(m_scalar_median, cubeCorners[6], cubeCorners[7]);
if (m_edge_table[cubeindex] & 128)
vertexList[7] =
linearInterp(m_scalar_median, cubeCorners[7], cubeCorners[4]);
if (m_edge_table[cubeindex] & 256)
vertexList[8] =
linearInterp(m_scalar_median, cubeCorners[0], cubeCorners[4]);
if (m_edge_table[cubeindex] & 512)
vertexList[9] =
linearInterp(m_scalar_median, cubeCorners[1], cubeCorners[5]);
if (m_edge_table[cubeindex] & 1024)
vertexList[10] =
linearInterp(m_scalar_median, cubeCorners[2], cubeCorners[6]);
if (m_edge_table[cubeindex] & 2048)
vertexList[11] =
linearInterp(m_scalar_median, cubeCorners[3], cubeCorners[7]);
for (int i = 0; m_tri_table[cubeindex][i] != -1; i += 3) {
triangles.push_back(vertexList[m_tri_table[cubeindex][i]]);
triangles.push_back(vertexList[m_tri_table[cubeindex][i + 1]]);
triangles.push_back(vertexList[m_tri_table[cubeindex][i + 2]]);
}
}
}
return triangles;
Calculate Normals
std::vector<GLfloat> CubeMarcher::calculateNormals(const std::vector<glm::vec3> t_triangles)
{
std::vector<GLfloat> normals;
normals.resize(t_triangles.size() * 3);
for(int i = 0; i < t_triangles.size(); i+= 3)
{
glm::vec3 normal = calulateNormal(
t_triangles[i],
t_triangles[i + 1],
t_triangles[i + 2]
);
normals[i * 3] = normal.x;
normals[i * 3 + 1] = normal.y;
normals[i * 3 + 2] = normal.z;
}
return normals;
}
glm::vec3 CubeMarcher::calulateNormal(const glm::vec3 t_vertex1, const glm::vec3 t_vertex2, const glm::vec3 t_vertex3)
{
glm::vec3 normal;
glm::vec3 u = t_vertex2 - t_vertex1;
glm::vec3 v = t_vertex3 - t_vertex1;
normal = glm::cross(u, v);
return normal;
}
Vertex Shader
#version 400 core
in vec3 position;
in vec3 normal;
out vec3 pass_Color;
out vec3 surface_normal;
out vec3 to_light;
uniform mat4 projectionMatrix;
uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;
uniform vec3 color;
void main()
{
vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_Color = color;
surface_normal = (transformationMatrix * vec4(normal, 0.0)).xyz;
to_light = lightPosition - worldPosition.xyz;
}
Fragment Shader
#version 400 core
in vec3 pass_Color;
in vec3 surface_normal;
in vec3 to_light;
out vec4 out_Color;
void main(void){
vec3 ambient = vec3(0.1, 0.1, 0.1);
vec3 normal = normalize(surface_normal);
vec3 light = normalize(to_light);
float dotP = dot(normal, light);
float brightness = max(dotP, 0.0);
vec3 diffuse = (brightness + ambient) * pass_Color;
out_Color = vec4(diffuse, 1.0);
}
Above
Below
EDIT I decided to render to a flat color as recommended in the comments. But neither looking from above or below the mesh shows any seams.