1
\$\begingroup\$

I'm trying to develop a procedural tile generator for a game, mostly for the ground tiles, instead of using "hand-drawn" tiles.

To achieve this I'm using Perlin noise and a sine wave with multiple parameters, which already gives me pretty nice results. I don't want to generate 1 tile and repeat that one forever for one ground type, but I want to avoid recurrences, so I'm generating n different tiles.

The problem I'm having now is that I want to tile the generated textures (smooth transitions).

At the moment I have this:

enter image description here

4 256x256 textures.

I thought a simple method would be to just add the positions of the different tiles to the noise generation algorithm, so that, when creating the 4 256x256 textures, it would behave like it would create a 512x512 texture, but that somehow didn't work as intented.

So how can I tile those textures?

\$\endgroup\$
  • \$\begingroup\$ Possible duplicate: gamedev.stackexchange.com/questions/23625/… \$\endgroup\$ – MichaelHouse Aug 17 '13 at 16:33
  • \$\begingroup\$ @Byte56 Already saw that post, but the question asked there is to tile the same generated texture, not multiple different ones, as it is the case here. So I don't know if the solutions from there would work in this case. \$\endgroup\$ – Burhuc Aug 17 '13 at 16:46
  • \$\begingroup\$ I have seen this done by using the one tiling texture everywhere and then overlaying a variety of alpha blended textures randomly, to give detail and break up the pattern. The real problem is that it may not be possible to create 2..N textures that all tile against any other texture's sides and still not look tiled. \$\endgroup\$ – Patrick Hughes Aug 17 '13 at 22:21
0
\$\begingroup\$

There is a really good answer to another question about tileable Perlin noise here:

How do you generate tileable Perlin noise?

The basic idea is to get the gradient vectors at the gridpoints on the edges of each tile to 'match up' - so the gradient at the bottom left gridpoint should be the same as that at the top right, for example. N.B. To do this, you'll need to make sure that the edges of each tile are on gridlines.

If this doesn't make sense, check out the linked answer, which probably explains it better.

EDIT: I just noticed that you said that you'd already seen this answer. I know that you aren't trying to tile a single texture, but the same idea will work - you just need to make sure that the gradients on the edges of all the tiles in your set match up. More specifically, generate a single set of random gradient vectors for the tile edges, and use these for all textures. Then you can randomly generate the gradient vectors for gridpoints interior to the tiles separately for each of the n tiles.

I am not quite sure how you are using sine waves, but would imagine that you will want to make sure that the period of your sine functions matches up with the tile edges. So for example, if your tiles are 256x256, you could add sine functions like

sin(2 * PI * N * x / 256)

Where x is the pixel coordinate, and N is some natural number (i.e. 1,2,3,...). This function will match up at the edges of the grid, unlike for example sin(x / 256) which will be equal to zero on the left edge, and something close to 0.8 on the right.

You'll have to think carefully, and make up sine functions which always match at the edges of tiles. You could try to make sure that the functions are always zero at the edges of tiles, for example using functions of the form:

sin(2 * PI * N * x / 256) * sin(2 * PI * M * y / 256)

Where N and M are both natural numbers.

Wolfram alpha can be good for visualising functions like this (e.g. http://www.wolframalpha.com/input/?i=sin+x+sin+y)

I hope this helps!

\$\endgroup\$
  • \$\begingroup\$ Yes, I saw that answer already but wasn't entirely sure if it'll work in this case. But I'll definitely try it out now \$\endgroup\$ – Burhuc Aug 17 '13 at 16:56
0
\$\begingroup\$

if you make the texture from scratch, it's 3d, non repeating, tileable...

              //MARBLE BLUE formula code 
              // float ht = sin((pos.y*.2+1*perlin(float3(pos.x, pos.y, pos.z),4))*3.1415);
              // ht = sqrt(ht+1)*.7071;
               //return float4(.3,.3 + .6*ht,.6 + .4*ht,1)*(2*i.color);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.