#Seams in generated "cube-sphere"

3 messages · Page 1 of 1 (latest)

civic ferry
#

This is the code I am using:

//
// Generate unit quad-sphere vertices and indices.
//
// res is vertex resolution.
// face_n, face_t, and face_b are basis vectors of cube faces.
//
for (s32 face_index = 0; face_index < 6; face_index++) {
    s32 face_offset = face_index * SQUARE(res);
    for (s32 row = 0; row < res; row++) {
        for (s32 column = 0; column < res; column++) {
            // Convert from range 0..1 to -1..1
            f32 x = (((f32)column / (f32)(res - 1)) - 0.5f) * 2.0f;
            f32 y = (((f32)row    / (f32)(res - 1)) - 0.5f) * 2.0f;
            V3 p  = face_n[face_index] + face_t[face_index]*x + face_b[face_index]*y;
            p     = normalize(p);
            array_add(&sphere_mesh_vertices, Vertex_XN{p, p});
            // Indices.
            if (row != res-1 && column!=res-1) {
                u32 bottom_left  = face_offset + (row * res + column);
                u32 bottom_right = face_offset + (row * res + (column + 1));
                u32 top_right    = face_offset + ((row + 1) * res + (column + 1));
                u32 top_left     = face_offset + ((row + 1) * res + column);
                // Triangle 1 (CCW).
                array_add(&sphere_mesh_indices, bottom_left);
                array_add(&sphere_mesh_indices, bottom_right);
                array_add(&sphere_mesh_indices, top_right);
                // Triangle 2 (CCW).
                array_add(&sphere_mesh_indices, bottom_left);
                array_add(&sphere_mesh_indices, top_right);
                array_add(&sphere_mesh_indices, top_left);
            }
        }
    }
}
#

//
// Calculate vertex normals.
//
s32 num_faces = body->num_indices / 3;
for (s32 i = 0; i < num_faces; i++) {
    s32 vid0 = sphere_mesh_indices[i * 3 + 0];
    s32 vid1 = sphere_mesh_indices[i * 3 + 1];
    s32 vid2 = sphere_mesh_indices[i * 3 + 2];
    
    V3 vert0 = sphere_mesh_vertices[vid0].position;
    V3 vert1 = sphere_mesh_vertices[vid1].position;
    V3 vert2 = sphere_mesh_vertices[vid2].position;
    
    V3 edge0 = vert1 - vert0;
    V3 edge1 = vert2 - vert0;
    V3 face_normal = normalize(cross(edge0, edge1));
    
    sphere_mesh_vertices[vid0].normal += face_normal;
    sphere_mesh_vertices[vid1].normal += face_normal;
    sphere_mesh_vertices[vid2].normal += face_normal;
}
for (s32 i = 0; i < sphere_mesh_vertices.count; i++) {
    sphere_mesh_vertices[i].normal = normalize(sphere_mesh_vertices[i].normal);
}
#

I think this is happening because vertices on the edges need to be accumulated with ones on neighboring cube-faces as well and they're not. So I tried solving the issue by removing vertex duplicates that have almost same position. Result was improved but there were still visible seams.