planet texturing

i dynamically create a texture for my planet, mixing different textures depending on slope, height etc.

now i got a 1024*1024 texture map, that i can stretch over this planet by converting the angles of every vertex into texcoords.
works well, except that it results in one line of triangles containing the whole texture. the reason is that every triange has, for example, the texcoords 0 to 0.1, the next one 0.1 to 0.2
do you see it coming ? the last one is 0.9 to 0.0, which means : nearly whole textur drawn. using multiple texcoords per vertex would kill my whole concept, so i looked for another solution - and stumbled over cubemapping/spheremapping.

can i use cube or spheremapping to wrap my image around the planet ? the texcoords would only depend on the angle of the vertices, not their length (= distance from the planet center)

if yes, how ?

What you do sounds to me like a spherical projection of the texture. The cubic and spherical mapping you are referring to, are probably the dynamic functions usually applied to environment mapping. You could use these, but it would mean re-calculating the texture-coordinates every frame, which would be a waste.

That being said, you might consider splitting the texture in 6, and doing a cubical projection instead of the spherical you currently do. It’s probably not going to be easy converting the texture (something like rendering to a sphere, and fixing the errors on the poles manually would probably work).

Text on the general problem of distributing points on a sphere:


i already got the correct texcoords per vertex. projecting the texture is no problem.
the problem is that i got only ONE texcoord per vertex, but i need 2 for the places where the beginning and end share the vertices.

assume y ist the beginning of my texture, z the next vertex, and x the previous, or the last one.

y is 0.0
z is 0.1
then we reach the end of our texture, which has the coordinates 0.9
now imagine a triangle that connects the beginning with the end - it would need the texcoords 0.9 and 1.0
but the y-point already has 0.0, so the result is 0.9 - 0.0 instead of 0.9 - 1.0, so the last triangle contains nearly the whole texture, instead of the little part it should contain.

i could copy the vertices and beginning/end for the 0.0 and 1.0-coords, but this feels like a noobish hack. isn’t there a more elegant way ?

[This message has been edited by HamsterofDeath (edited 02-06-2004).]

The two simplest options are a rectangular texture like you’ve been doing, or a cube map. A sphere map is more trouble than it’s worth, and makes poor use of your texture resolution; the area outside the outermost circle contains texels that’ll never be used (only pi/4, or 79%, are ever used), and that outermost circle gets mapped to only a single point on the sphere.

Using a rectangular texture, as you’ve pointed out, the last column of longitudinal triangles have texcoords that jump from something like 0.9 to 0, since you’re coming back to where you’ve started. For simplicity, let’s assume you’re mapping the texture onto a cylinder, which has the same problem without all the polar distortion of a sphere. Imagine taking a piece of paper and rolling it into a cylinder. There’s no getting around the fact that to form a closed cylinder, you’ve got to have two ends of the paper touching. In GL terms, that overlapping set of points must have two sets of vertices, one with s=0, the other with s=1, but otherwise identical. Theoretically, if you had an infinitely dense mesh, then your initial approach would work, since the last column of triangles would have texcoords ranging from 0.9999… to 0, but over an infintely thin span of space. The discontinuity only becomes apparent when you’re dealing with a discretized surface, like a triangular mesh. (Likewise, you could eliminate the extra vertices if you had control over the texcoord interpolation across a triangle; you’d have the s coord of that last column of triangles linearly march from 0.9 to 0.9999…, then abruptly jump down to 0, but even then you might get flickering of pixels at that edge that are pulled from arbitrary texels in the texture.)

Cube maps are a more elegant solution, since there’s no discontinuity in the mapping. There’s some distortion, but not nearly as bad as spherical or rectangular mapping onto a sphere. You can either define your own texcoords that at each vertex are identical to the normal (texcoord.s = normal.x, texcoord.t = normal.y, texcoord.r = normal.z), or you can just define the per-vertex normal and use a TEXTURE_GEN_MODE of NORMAL_MAP_ARB on S, T and R, which will establish the correspondence for you.

The only problem with cube mapping a sphere is actually producing the cube map; you have to come up with six square textures that meet smoothly at their edges. A smoothly wrapping rectangular texture is much easier to throw together, since only the left and right edges of the texture have to wrap. By comparison, cube maps have 12 edges where the texture must flow between faces.

Duplicating the verts at the seam isn’t noobish. It’s been done for decades.

With the cubemapping approach, the seam issue is harder, as maxuser points out. Think in terms of building your sphere planet geometry as a cube, subdividing each face and moving the verts along the radius vector to fit the shape of a sphere.