how to do uv indexing like this procedurally?
i wanna make some shader that can pixelate image but with hexagonal.
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It only takes a minute to sign up.Sign up to join this community
Updated. See Edit at bottom of this answer..
You can't map the centers of tiled hexagons onto one rectangular grid, but you can map them onto two overlapping rectangular grids, and use a Voronoi-like distance-to-closest-point test to decide which grid a shading point belongs to.
Unfortunately, Blender's node implementation of modulo goes into the negative for negative bases, and we would like a plain regular sawtooth, not jumping as input crosses 0. So we can make a group implementing an alternative mod():
x - y * floor(x/y):
which, for convenience, we can use in a group 'Vector Modulus', applying it element-wise to a vector:
We can use the Vector Modulus group to divide a given UV space into rectangular cells, width 1, height sqrt(3). The centers of these rectangular cells are at the centers of successive tessellated hexagons in a column, and adjacent tessellated hexagons in a row.
We move (0,0) to the centers of the cells by subtracting (0.5, sqrt(3)/2) from (Cell U, Cell V):
.. and call it 'Grid A'.
We create another grid, 'Grid B', by offsetting Grid A by half its dimensions in both directions, so the corners of A at the centers of B, and vice-versa.
Now, by selecting the shorter of the Grid A UV and the Grid B UV vectors, i.e. the the UV in the space of the closest cell from either grid, the result falls into tessellated hexagons. (Surprising, until you think about it)
We haven't scaled or distorted the original Input UV in this conversion, just renumbered chunks of it. The rate of change in X and Y is the same, so if we subtract the Cell UV from the Input UV, the result will be constant in any cell, and different for each cell, so can be used to index the cells:
The 'Hexagonal Grid' group in the download has the outputs:
Since answering, and with newer nodes, Wannes Malfait has pointed out a much snappier way of constructing the offset grids, with just 9 nodes:
Adjacent hexagons will be translated by (+-1,+-SQRT(3)/2). I did not put in a scaling function (though I did attempt to tile it).
Here's the file I was working on. It's not very useful so far but you can move the hexagon by changing the center coordinates:
This has been especially challenging for me because hexagons do not tesselate on a square unless you are willing to crop 7 of them at once. I assumed making the unit based upon multiple hexagons would make it impossible (or more difficult) to link the color data to every hexagon's center.
At this stage though, I have not even succeeded at that yet.
Share your file with me and maybe I'll be inspired.