How can I get rid of zig zag artifact on sphere surface in vispy?

162 views Asked by At

I'm working on the 3D visualization of planets in the solar system. As I am going to apply texture, I have manually computed the texture coordinates (texcoords), however, I get zig-zag artefacts appeearing in the image.

I believe that my computation might be wrong. I have attached the texcoords computation below:

# Compute Texture Coordinates  
def get_texcoords(vertices):
    texcoords = []
    for v in vertices:
        #thresholding
        for i in range(3):
            if np.abs(v[i]) > 1e-6:
                v[i] = v[i]
            elif np.abs(v[i]) < 1e-6:
                v[i] = 0.0

        # Compute position in uv-space
        radius = np.sqrt(v[0]**2 + v[1]**2 + v[2]**2)
        
        latitude = np.arcsin(v[2]/radius)
        longitude = np.arctan2(v[1],v[0])
            
        # Convert to texture coordinates
        u = round(0.5 + longitude/(2*np.pi),5)
        v = round(0.5 + latitude/np.pi,5)

        texcoords.append([u,v])
            
    return np.array(texcoords)

Is there any way to remove the artefacts? Or is there a smarter way to obtain texture coordinates in vispy?

2

There are 2 answers

0
madmaxfzz On

maybe using "for v in vertices:" in conjunction with using texture cordinate variable names to be "u" and "v" ?? I'm not sure it would produce that artifact, but it is definitely not recommended to modify your iterator inside its loop without being extremely cautious. Not recommended in any manner, actually. That's my initial take. I'm using this same algorithm so once I get mine working I'll know if it's the cause of your issue.

I just found this link which explains the error lurking in the uv mapping algorithm: https://mft-dev.dk/uv-mapping-sphere/

In a nutshell, some of the mesh triangles cross the texture boundary, and some of those end up getting 'flipped' (i.e. their face normal points inward rather then outward). The article in the link shows how do find these rogue faces and fixes them.

I have been scratching my head over this one for a day or so.

0
Max WHiten On

Here is a code snippet that will generate a proper mesh without the zig-zag artefact:

Code sourced from from: https://www.songho.ca/opengl/index.html

colstep = 2 * pi / cols
    rowstep = pi / rows
    num_v = -1  # these counters are for logging/debuging
    num_f = -1
    num_e = -1
    num_eh = -1
    num_ev = -1

    for row in range(0, rows + 1):

        phi = pi / 2 - row * rowstep
        xy = radius[1] * cos(phi)
        z = radius[2] * sin(phi)

        for col in range(0, cols + 1):
            theta = col * colstep
            x = xy * cos(theta)
            y = xy * sin(theta)
            vert = np.array([x, y, z])
            # print(vert)
            self._verts.append(vert)
            self._norms.append(vert / np.sqrt(vert.dot(vert)))
            self._txcds.append(np.array([(col / cols), (row / rows)]))
            num_v += 1
    logging.info('----->>> Generated %r vertices...', num_v)

    for i in range(0, rows):

        k1 = i * (cols + 1)
        k2 = k1 + cols + 1

        for j in range(0, cols):

            if i != 0:
                self._faces.append(np.array([k1, k2, k1 + 1]))
                self._edges.append(np.array([k1, k2]))
                self._edges.append(np.array([k2, k1 + 1]))
                self._edges.append(np.array([k1 + 1, k1]))
                self._edge_colors.append((0, 0, 0, 1))
                self._edge_colors.append((0, 0, 0, 0))
                self._edge_colors.append((0, 0, 0, 1))
                num_f += 1
                num_e += 3
            if i != (rows - 1):
                self._faces.append(np.array([k1 + 1, k2, k2 + 1]))
                self._edges.append(np.array([k1 + 1, k2]))
                self._edges.append(np.array([k2, k2 + 1]))
                self._edges.append(np.array([k2 + 1, k1 + 1]))
                self._edge_colors.append((0, 0, 0, 0))
                self._edge_colors.append((0, 0, 0, 0))
                self._edge_colors.append((0, 0, 0, 0))
                num_f += 1
                num_e += 3

            k1 += 1
            k2 += 1

            self._v_edges.append(np.array([k1, k2]))
            num_ev += 1
            if i != 0:
                self._h_edges.append(np.array([k1, k1 + 1]))
                num_eh += 1