Procedural Tiles with Shader Graph
Tags: unity3d, tutorial, beginners, gamedev
Published: 2022-08-14 18:13:54

### Disclaimer

I am a beginner myself when it comes to game dev. This may not be the best way to do this, but I failed to find another method online, so this might help a fellow newbie. 

If you notice any mistakes or have better solutions, please point them out in the comments.


### The goal
So, what I wanted to create is a shader, I mean, a material with a repeating texture I could just assign to a cube and then resize it however I want. It had to look the same on every side, and the tile size had to be constant.

Just to be clear from the beginning, as far as I know, this will work correctly only if you are using a cube.


### Creating a texture
For this example, I decided to create a simple texture with a black border and a small circle in the center using the _Rectangle_ and _Eclipse_ node.

I am going to assume you already know how to create a shader graph shader, assign it to a material, and assign that material to an object.


![Tile texture created in shader graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbfyreiswxbhrwpiylf7.png)

I am also going to assume that this part doesn't require any explaining.

Here is the texture on a resized cube.

![Tile texture on a cube](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fyeguqjoza1f9picqvlk.png)


### Tiling effect
Creating a tiling effect is pretty straightforward; all we need is a _Tiling And Offset_ node, connected to the _Fraction_ node, which we then connect to our texture nodes, in this case, _Rectangle_ and _Eclipse_.

We can then mess with tiling Vector2 to choose the number of tiles. There is also an offset Vector2, but I won't be using that one here.

![Applying tilling to our texture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hibo5w5p05d16gipa9fg.png)

We can see that the effect works, but this is still not what we want.

![Cube with tiling applied](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvmigr7ku68hrqg1jx6o.png)


### Making tile size constant
This is, of course, the most difficult part. However, since we are using a resized cube as our object, we can make use of the object's scale to determine the number of tiles.

Getting an object's scale in shader graph is pretty easy. It's one of two properties we get from the _Object_ node.

So, to get the number of tiles on a face, we can divide the scale by the tile size.

To define the tile size I created a Vector2 property. In this example, I set it to .8.

You might have noticed that there is one small problem, scale is a Vector3 property, and tiling is a Vector2 property, so how will we pick which two axis we need?

To solve this issue we need the normal vector, which we can access with the _Normal Vector_ node. The normal vector is perpendicular to the texture face. That means that if we invert and then multiply the normal vector with the scale, we will get a Vector3 with the irrelevant axis as zero.

Make sure you use the _Absolute_ node somewhere in this process to avoid negative values. Also, set the normal vector space to _Object_. Otherwise, rotating the cube will ruin your tiles.

The last thing to do is just removing the 0 from our Vector3, thus turning it into a Vector2 we can connect to tiling.

I wasn't sure how to approach this problem so I just reused a custom node I created for something else which takes three inputs and returns the two largest ones.

If you want to use the same method I did, create a custom node, give it three float inputs (A, B, C) and two float outputs (X, Y). Set the type to _String_ and put this code in _Body_.


```c#
bool a = A < B;

if (a) {
bool c=C<A;
Y=B;
X=c?A:C;
}

else {
bool b=C>B;
X=A;
Y=b?C:B;
}
```

And that's it! Our cube is now covered with equally large tiles. And we can use this shader to create walls, floors, and whatnot.

Here is my implementation of that last part.

![Getting number or tiles](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nozku5bxw2h5ql6019ji.png)

And this is our cube. :D


![Final cube](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71vb28kdcaiqh4m4jh9w.png)

If you want the tiles to perfectly fit the surface, so, no cut tiles (like in the picture), make sure the cube size is divisible by the tile size.

#### Thank you for reading!