4
votes

I have a number of spherical longitude/latitude coordinates for points on a sphere that I need to visualize. For that purpose, I transformed the points to cartesian coordinates and built a mesh of triangles that I can render with VTK. Works so far.

Now I want to use a texture for the sphere model. Therefore I transformed the spherical coordinates to texture coordinates and assigned these to each point. This works for the majority of the sphere's surface triangles and the result looks acceptable.

But, for the triangles on the opposite side of the prime meridian, where the texture wraps, the triangles are textured incorrectly: Instead of repeating the texture and mapping “over the texture boundary”, the whole texture gets squeezed onto the single triangle.

Here is a picture of how it looks like:

sphere-texture

The zick-zack line is obviously wrong, the blue line should be visible instead. The whole texture is mapped on the triangles, resulting in red and white stripes. This makes sense since, for the triangles in question, the texture coordinates span the whole texture space.

To illustrate this problem, which is not specific to spheres but all closed objects, I have created the following figure:

texture-seam

In the upper rectangle, we see a triangle that spans over the texture boundaries with computed texture coordinates A, B and C. Since the texture can be tiled, this is how I would like the triangle to be rendered.

The lower triangle shows how the texture coordinates are interpreted currently. The coordinates of the edges A, B and C are the same, but this time, the majority of the texture is used for the triangle, instead of tiling the texture at the borders.

I am sure there is quite a common mistake I made but I didn't find anything to help me yet. Have any hints for me?

3
I've been struggling with this for the past day or so, mostly in terms of detecting which faces have errors. Turns out that the erroneous faces have texture coordinates in counter-clock order.3Dave

3 Answers

5
votes

The answer is very simple you need to map your texture coordinates over the edge. The implementation depends on your data set but here is a stab at the problem.

In computer graphics texture coordinates are stored on the faces and not on the vertices and your problem shows the reason. When you map a texture around a sphere, let us say in 10 steps you start with 0.0 then continue in 0.1 increments. If you go with texture coordinates along the prime meridian you get faces with the texture coordinate 0.9 and 0.0. The graphic hardware does what it is told and interpolates the texture between 0.0 and 0.9.

To solve your problem you need to map the texture from 0.9 to 1.0.

If you can, create the polygons that way or duplicate the offending vertices with other texture coordinates.

2
votes

First off, you probably don't want to just map the spherical coordinates to a single rectangular texture that covers the sphere since the texel resolution becomes very non-uniform over the surface.

A better approach is to use an atlas. An "atlas" is a parameterization of the surface into multiple "charts", each of which is a connected region. For example, you could map the sphere onto roughly 6 charts that correspond to the sides of a cube, and each chart would preserve the shape of the portion of the sphere much better. You can google for multi-chart parameterization or something like that. DirectX has built in UVAtlas generation if you want to go that route. The issue of what to do at the seams between charts is simpler actually since triangles always sit within one chart, and is a different problem entirely.

That said, to deal with the seams in your case, you need to know which triangle edges of the (spherical) mesh intersect the boundaries (meridian or whatever). You will then have to break up the triangles incident on those edges into pieces that don't cross the boundary, and apply the texture coordinates properly.

1
votes

Replying to a very old question because I think there's an easier answer, using a built-in method of vtk's vtkSphereSource.

You want to "break" the sphere so that you don't get texture interpolation between 0.9 and 0.0 around the sphere. In python, call sphere.SetEndTheta(360 - 1.e-4), which will, in effect, take a tiny slice out of the sphere. That gives you that end set of vertices for the texture to map all the way to 1.0.