I’ve looked into the code for this myself and one thing struck me a while back when I tried to do the classic skin/cracked mud type effect. In nature the basis is not square as is used by most voronoi implementations but more hexagonal. So I duly made an attempt at a hexagonal based voronoi. It’s not perfect, definitely a work in progress and could do with some optimisation but some critique may help. Or alternatively rip it off
Fac by the way controls the amount of distortion from a hexagon.
Apologies for the formatting. I’m somewhat new to this forum and posting isn’t my strongpoint.
#define H 0.86602540378443864676372317075294 // sqrt(3)/2
#define H2 (2 * H)
#define H3 (3 * H)
#define H4 (4 * H)
#define H5 (5 * H)
#define H6 (6 * H)
#define HY (1 / H)
#define HY8 (.5 / H4)
#define HL 7
void genHexPoints(vector pp, vector h[]) {
int i;
vector hh[HL] = {
vector(1.5, H2, 0), // Center Point
vector(0, H, 0),
vector(1.5, 0, 0),
vector(0, H3, 0),
vector(1.5, H4, 0),
vector(3, H, 0),
vector(3, H3, 0)
};
for (i = 0; i < HL; i++) {
h[i] = pp + hh[i];
}
}
shader hexapoints(
vector Pos = 0,
float Scale = 5,
float Fac = 1,
output float Dist = 0,
output float Bord = 0,
output float BordNm = 0,
output color Col = color(0,0,0))
{
// This centers 1 hexagon in the range 0 - 1 x, y
vector p = vector(abs(Pos[0]) * 2 * Scale + 2, abs(Pos[1]) * 2 * Scale - HY8 + H2, 0);
// calculate the origin point of the hexagon array
// float sx = mod(p[0], 3); float sy = mod(p[1], H4); float sz = mod(p[2], H4);
vector pp = vector(p[0] - mod(p[0], 3), p[1] - mod(p[1], H4), 0);
float d, cd = 1000, bd = 1000;
color c, cl;
vector cn, bp, cp, h[HL], f = vector(Fac * .75, Fac * H, 1);
int i, j = 0, k = 3;
do {
genHexPoints(pp , h);
for (i = 0; i < HL; i++) {
cn = vector(cellnoise(h[i][0], h[i][1]), cellnoise(h[i][1], h[i][0]), .5);
d = distance(p, (cn - .5) * f + h[i]);
if (d <= cd) {
cp = h[i];
j = i;
cd = d;
} else if (d <= bd) {
bp = h[i];
bd = d;
}
}
if (j) {
pp = h[j] - vector(1.5, H2, 0);
//bd = 1000;
}
} while(j && --k);
c = color(cellnoise(cp[0], cp[1]), cellnoise(cp[1], cp[0]), cellnoise(cellnoise(cp[0], cp[1]) * 1000, cellnoise(cp[1], cp[0]) * 1000));
Dist = cd;
Bord = bd - cd;
BordNm = 1 - (2 * cd) / (bd + cd);
Col = c;
}
enjoy…