Jump to content
  • Advertisement
Sign in to follow this  
tebriel

Making textures on a cube seamless

This topic is 408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need a fresh perspective or ideas to help make solving this problem a little easier.  Without going into overwhelming detail, basically I have 6 large textures, one for each side of a cube (let's say each is 2048 x 2048 pixels).  I want to build a utility which modifies the edges of the textures so that they're seamless, similar to how Gimp or any other image processor application would create a seamless tiling texture.  

This would be easy if I were just matching up the edges of two textures at a time, but the fact that this is a CUBE means that the corners make things tricky, since each edge needs to be matched up to two different textures, which also have their own bordering edges that need to be made seamless.  Another complication is determining the correct pixels on each texture to read and modify.  Due to the different ways the coordinates are oriented on each texture, it's not as easy as it sounds.  I could probably throw lots of code at the problem and "hard code" things for each edge/corner, but I'm hoping to find a less work intensive and error prone solution.  

Attachment is an effort to help visualize how the textures border one another.  The (x, y) in the corners contain texture pixel coordinates, mx is the maximum value (ex. index 2047).  The i & j can be read as x and y respectively (I also use i & j coordinates which range from -1 to 1 for some unrelated stuff, but we can ignore that bit here).  Red lines are just pointing out what sides are adjacent.  

[attachment=36186:Cube_map.png]

Is there some simple way to approach this problem that I'm failing to recognize? 

Not sure if this is the best place to drop this one, so if a mod wants to move it somewhere better, go for it.

Edited by Tebriel

Share this post


Link to post
Share on other sites
Advertisement

Is this for cubemapping, so that you can't see the edges during texture filtering?

If so, use D3D11 or in OpenGL enable GL_TEXTURE_CUBE_MAP_SEAMLESS (part of ARB_seamless_cube_map) :)

Otherwise if not-

I could probably throw lots of code at the problem and "hard code" things for each edge/corner, but I'm hoping to find a less work intensive and error prone solution.  
There's only 12 edges on a cube. I'd just hard-code those 12 edge definitions, and then make a loop that calls a function 12 times, passing the 12 different edge definitions. Edited by Hodgman

Share this post


Link to post
Share on other sites

I'll take a look at the paper, sometimes they can help spark ideas. 

I only wish it were that easy, Hodgman!  It's not a cube map in that sense.  What I'm doing is normalizing the surface coordinates of this cube around (0,0,0) to turn it into a sphere.  The textures are used for... texturing (duh) but even more importantly, height maps.  The vertices on the surface of the sphere get moved away from the center based on the value in the height map to create basic "terrain".  

Hard coding the edges... is my only current feasible idea, and probably the one I'll have to settle on. But the corners still seem to be problematic. If I crunch the numbers "by edge", will the edges being morphed later on screw up the previous iterations?  I'm not sure but it seems that way.  

So I believe I'll need to do all 12 edges, avoiding X number of pixels near the corners, and then do 8 more iterations to deal with the problem for each corner.  The 12 edges should be relatively easy to smooth out, we can think of those as just smaller rectangular textures.

But the corners seem a little mind bending, it's not a rectangular shape, so how in the heck am I going to iterate though that data?  Each corner will also have to respect the edge smoothing passes done before, otherwise I'll just be creating new seams between the corners and the edges. Hopefully I'm just making this more complicated than it is, but I'm not sure yet.

Edited by Tebriel

Share this post


Link to post
Share on other sites

assuming this is for heightmaps, and assuming these are generated by some kind of noise-function. treat the texture as if it actually were a cube or sphere in 3d space. use a 3d-noise-function to generate it. assign those corners their corresponding 3d-coordinate and go through the pixels based on that, feeding the interpolated 3d-coordinate to the noise-function. that way the texture is generated ready to be used. also you could use this to account for spherical distortion by interpolating coordinates between corners as if those were on a sphere.

Edited by ninnghazad

Share this post


Link to post
Share on other sites

I see i got the question wrong - you don't have a texture flitering seam problem, you have a coarse texture content mismatch problem.

You could fix it like this (if procedural generation is not what you want):

Generate a look at matrix from cube center to cube corner, render a unlit frame with orthographic projection using the matrix for the camera.

You sould get an image showing the corner at the center and 3 edges with 120 degrees in between.

Save the frame as an image, remove the seams with photoshop, figure out the mapping math to apply the edited image to the original textures masked around the corner by an automated tool.

 

The same could be done for the edges first, but it would be much easier to paint the textures directly on the sphere mesh with a 3D painting capable program.

Share this post


Link to post
Share on other sites

Whew, hard coding it and just doing the tedious work of manually mapping coordinates seems easier now! ha ha 
Seems like this is a little off the beaten path and I'm not going to find any magic bullet to make this easier. 

Maybe if I could map all the side's vertex coordinates (which match up with texture pixels) into some type of global coordinate system similar to a lat/long, that would make this easier - but that is probably easier said than done.

Edited by Tebriel

Share this post


Link to post
Share on other sites

The simplest way of making 2D textures seamless is shifting them by half along x and y and blending that with the unshifted version depending on distance from the edge (or manually stamping the edges away to maintain more detail). The cubemap version of that would, I believe, be to rotate by 45 degrees along all 3 dimensions, placing the corners in the centers of the faces.

Share this post


Link to post
Share on other sites

A single lat/long image is quite nice for human editing: You can shift the image horizontaly to fix the vertical seam, you can do a small gradient from top / bottom edges for the remaining seams at poles.

The only problem is a lot of horizontal stretch near the poles.

Converting the lat/long image to cube map should be easy, you could also use baking capability of Blender or another 3D package to automate it.

Share this post


Link to post
Share on other sites

The blending I'm not too worried about, I've done plenty of stuff like that before. The main trouble is figuring out a way to "iterate over the correct pixels in the correct order", if that makes sense. I'll have to iterate over two (possibly 3) differently oriented textures at the same time.

For example, the bottom side's upper right corner borders the front's bottom left corner (in that diagram). The bottom side coordinate is (0, 2047), and front side pixel coordinate is (0, 0). The direction to travel along the edge might vary, though. In this case for the front side I need to increment the x value until I get to (2047, 0), and those pixels blend with the bottom's (0, 2047) to (2047, 2047); the latter coordinate being the bottom's bottom-right corner.  

So that's one edge, but if you consider other edges you'll need to hit different coordinates. I'm not sure if in some cases I'll need to traverse backwards relative to one side due to the adjacent coordinates being inverted. It seems like that's not the case, so that'll make it much easier that I was thinking.

To start I'll see if I can hard code each edge's relationship - if I can flatten all the border pixels for all edges with a brute force algorithm maybe that will be a good enough starting point to build on. I'm thinking that if I just focus on the edge pixels only for the first phase and get those to match their adjacent sides, I can apply a simple blur filter to the internal neighboring pixels - which would be much easier since I'd only have to worry about a single texture image at a time at that point.

Edited by Tebriel

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!