46
$\begingroup$

Most people's question in this area is how to reduce repeating patterns, however I want to create them.

I'm creating 2d rendered tiles for my game, and I want to create procedural materials for my tiles that will seamlessly match. For that I need the cycles procedural textures to repeat on a predictable interval.

I've looked at similar threads, and they only deal with simple gradients, or images, not things like voronoi, musgrave, noise.
I haven't been able to figure out how to scale/manupilate with math, the procedural nodes to any degree of repetition.

$\endgroup$
  • 1
    $\begingroup$ My dissatisfaction with the answers so far are that the textures are CLEARLY mirrored. It seems rather clumsy. $\endgroup$ – Mutant Bob Apr 9 '16 at 20:28
  • $\begingroup$ @MutantBob I agree, please check out my answer for an OSL based solution $\endgroup$ – SleepyMolecule Aug 23 at 7:44
  • 1
    $\begingroup$ @SleepyMolecule What you described sure sounds like what i was looking for, can you post screenshots of a shading thing and add it to your answer? i'll mark it as correct if it is what i'thinking. I wont have time to use blender to check your answer for a while. $\endgroup$ – Enetheru Aug 23 at 16:40
  • $\begingroup$ @Enetheru screen shot of node setup and output added, enjoy $\endgroup$ – SleepyMolecule Aug 23 at 18:47
  • $\begingroup$ nice questioning $\endgroup$ – Oliver WRIGHT Aug 24 at 5:05
2
$\begingroup$

To wrap a 2d texture seamlessly the 2d coordinates need to become circular in higher dimensional space. Think of it like painting a torus and then cutting it open and folding it flat, only without the distortion.

Fortunately the OSL noise functions support more than 3 dimensions.

By taking the X and Y components and remapping them we can sample 4D noise in to a 2D loop

shader noise(
 point Point = P,
    float Wrap = 1,
    float Scale = 1,
 output color Perlin2d = 0.8,
    )
{
    vector mx =0;
    vector my =0;

    point map(float c)
    {
        point z = 0;
        c = c / Wrap;
        z[0] = sin(c * M_2PI)*Scale;
        z[1] = cos(c * M_2PI)*Scale;
        return z;
    }

    color res2d(point _p)
    {
        point z1 = map( _p[0] );
        point z2 = map( _p[1] );
        z1[2] = z2[0];
        float z3 = z2[1];
        return noise("perlin", z1, z3);
    }

    Perlin2d = res2d(Point);

}

With the wrap and scale values we can change the area it covers and the detail of the texture. You may change the 'seed' by adding to the final coordinates (just before the noise function) effectively sliding the object through 4D space.

screen shot

$\endgroup$
  • $\begingroup$ Add a screenshot when you get a chance. $\endgroup$ – Mutant Bob Aug 23 at 14:15
  • 1
    $\begingroup$ Thanks @SleepyMolecule, this is exactly what I was thinking. repeated seamless texture without mirroring. Marked as correct answer. $\endgroup$ – Enetheru Aug 25 at 6:55
65
$\begingroup$

You can use the math Modulo node on mapping vectors to create tilling for procedural textures:

enter image description here

To tile them seamlessly you need to flip tiles in X and Y axis:

enter image description here

For the Tilling X and Y nodes use values between 0 and 1. And to tile them in 3D just copy the setup into Z channel.


Why Mapping node does not add tilling to procedural textures:

Mapping node does adjust tilling for Image textures. This is because image has finite dimensions and repeats itself - the tilling is already "build-in". The Mapping node only zooms, translates and rotates this tilled image.

Since procedural textures are infinite, they have no borders and are not tilled. The Mapping node will just transform them but not tile them.


How and why the math nodes work:

Texture mapping does transform texture space to object space - you can visualize it like this:

enter image description here

This is for Generated mapping, other types will be mapped differently. Generated mapping will map the <0,1> interval to object bounding box. Therefore it stretches with scaling the mesh, but it does not rotate with mesh rotating (edit mode). It does rotate with object since generated mapping will be always aligned with object's local coords. To bind the texture to mesh UV mapping must be chosen and mesh unwrapped to tangent space.

When we split the mapping vectors into XYZ channels, we get access to each axis and can manipulate it:

enter image description here

Lets focus only on single channel (all apply the same principles). Now we output what we get (in the marked rectangle). This can be visualized with a graph function:

enter image description here

What we need for tilling though is this graph:

enter image description here

This is a graph of a modulo function (precisely modulo 0.33..) and will create 3 tiles on each axis. It is mapping the output to the same input locations repeatedly.

To have it tile seamlessly and flip every odd tile lower the graph of half the curve height and make the values absolute:

enter image description here

You get double the tiles naturally.


There are many effects you can do with this:

Texture pixelation with rounding node: How to pixelate a texture in Cycles?

Image blurring with noising the vectors: Motion blur on texture

Staggered mapping with rounding and offsetting: Staggered Texture Mapping

Etc..

$\endgroup$
  • $\begingroup$ It would be cool if you could explain it a bit more... instead of showing what works, could you explain how $\endgroup$ – GiantCowFilms Mar 6 '15 at 15:50
  • $\begingroup$ By performing the same action on the z axis you can get it to tile around a cube $\endgroup$ – GiantCowFilms Mar 6 '15 at 15:53
  • 1
    $\begingroup$ @GiantCowFilms yep I can explain it a bit more but its for a long answer - has to do with constructing transforming functions with math nodes. Maybe best to ask it as a separate question? Something like How mapping vectors work and how to transform them with math nodes. I have a feeling it will be a popular question. $\endgroup$ – Jaroslav Jerryno Novotny Mar 6 '15 at 16:09
  • 7
    $\begingroup$ @Jerryno you are a texture wizard! $\endgroup$ – Chebhou Mar 6 '15 at 23:45
  • 3
    $\begingroup$ This is honestly one of the best answers I have ever seen on Blender.SE, an instant +1 $\endgroup$ – VRM Mar 7 '15 at 0:23
21
$\begingroup$

Jerryno answer is great but there is another way to achieve that with some simple trigonometry.

1) Use Cosine operation on coordinates multiplied by Pi (just type "pi" in node value slider). This will create sine wave that wraps on integer values.

2) Then use Arccosine operation to create Saw-like wave from it.

3) Complete setup. Quite simple as you see.

Bonus thing- Use Z value in Combine XYZ node as time input to modify your texture!

node setup

$\endgroup$
  • 3
    $\begingroup$ arccos(cos(theta)) is a lot of transcendental operations just to create a triangle wave. $\endgroup$ – Mutant Bob Apr 9 '16 at 20:30
1
$\begingroup$

Also tossing in a couple absolute nodes will do the mirrored tile trick, but sorry don't know of a solution for non-mirrored tiles besides photoshopping out the seams yourself.

Node Setup

$\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.