As you all probably know, seamless tileable textures are often needed. They can be easily obtained with the help of Photoshop or Gimp. But how do the algorithms these programs use work? Does anyone know? I need an algorithm with an arbitrary image as input and a tileable seamless image as output.
This is not an OpenGL question, although it is of course relevant to 3D graphics programming. It is a question on image processing, and you are unlikely to find good help here.
All algorithms in Gimp are open and free because the software is GPL licensed, and Gimp can be scripted to process images in batches for you. If Gimp solves the problem, you may be able to use code from the Gimp source tree for your own purposes.
I have no experience with the automatic algorithms in Photoshop.
Why should I not find good help in this forum? As you say the question is relevant to 3D programming and most of experienced people have probably bumped into this issue sometime.
The image processing plays AFAIK a huge role in post-processing (bloom, AA, glow, blur, …) and there have been many discussions about these topics.
ugluk, this type of questions is best asked on this dedicated section of the GL forums :
Math and Algorithms
ZBuffer, it shouldn’t be a difficult algorithm, that’s why I asked here. If no one knows, it does not matter where I ask.
Generally, it is not the graphics programmer’s responsibility to prepare textures; that’s on the job of texture artists. Most of whom use tools like Photoshop and the like, and they generally work by hand, as tiling algorithms tend to, well, suck.
However, assuming you have no texture artists to tell what to do, there are a number of ways you could work. One would be to flip the texture over in the X and Y axes, but I imagine that’s probably not what you had in mind. You could also use GL_MIRRORED_REPEAT to do the same thing, but again that’s probably not what you had in mind.
If you don’t want to parse through the GIMP codebase to find something (and quite frankly, I don’t blame you), one possibility is fairly obvious. To handle the left and right sides, take the left-most column of values, then blend it on-top of the right-most column. And do the same for the right-most on top of the left-most (obviously making sure to source from the original values).
Then, repeat the process for the next columns, one away from the edge. Of course, you blend with a smaller weight, so that it doesn’t affect the final color as much. You keep doing this for several columns until you have made the weight negligible; how you define this is up to you.
You can do the same for the top and bottom as well. How you combine the overlapping pixels… well, try stuff and see what works best.
Note that you’ll get better results if the texture is really close to being perfectly mirrored and you just need to clean up the edges a bit.
Well, you have covered almost all the standard tricks, I’ve tried them all and none give satisfactory results.
You’ve forgotten one:
nonlinearly interpolate pixel colors towards a constant color as a function of distance from the closest edge. This is what I did and it was closest to what I liked. Still, I’ve grown dissatisfied with it. Here’s an example:
Mirroring in any way gives truly unnatural results.
EDIT: I’ll try the blending approach on the edges again. As you mentioned, the corners often give trouble. As you can see, I am trying to make noise textures tileable.
Little bit off topic, but it’s worth reading. You can see how the tiles can be prepared and rendered.
Not sure how your noise textures are generated, but sometimes noise generation can be periodic (ie perlin noise, fractal noise). It may be easier that to re-synthetize later.
ZBuffer, that’s true, they are periodic, if you optimize them, but almost every noise texture is composed of several noise functions, how can I make them all tile?
Sorry I do not understand what could be the problem. Just make sure the periodicity is exactly the same size as texture.
… and if having noises with the exact period the texture size is isn’t satisfactory, you can use any periodicity that is a divider of the size of the texture (e.g. if texture width is 1024 you can use a periodicity of 512 or 256), and you can use whatever bias to achieve the look and feel you want. I think this should result in enough freedom of what types of textures you can generate.
Not really, say my starting frequency is 0.015 and I want to generate a 256 x 256 texture, the frequency is doubled every iteration:
0.015 * 256 = 3.840
this means I’d need to set the period of my noise functions to about 4. This obviously gives bad results.
BUT, if the period of my noise functions is, say 512, I could set 512 = x * 0.015 => x = 34133.3333333333
an unbelievably large image, that I’d have to scale down, which would require filtering, I’m sure.
EDIT: I really don’t understand you two. Yes, the noise function has some period, after which it repeats, but the argument to the noise function is usually multiplied by some frequency.