As Voronoi uses a random location for each cell, it doesn't repeat (thought it has simetries).
For making a seamless loop with it, one must tweak the voronoi algorithm so that the random function loops after some vector. This is best done in OSL (with nodes it will become a monstruous setup).
Here's a variation of the original code, in order to loop in the Z coordinate after a fixed number of cells:
color cellnoise_color(point p)
{
float r = cellnoise(point(p[0], p[1], p[2]));
float g = cellnoise(point(p[1], p[0], p[2]));
float b = cellnoise(point(p[1], p[2], p[0]));
return color(r, g, b);
}
void voronoiLooped(point p, float e, int zloop, float da[4], point pa[4])
{
int xx, yy, zz, xi, yi, zi;
xi = (int)floor(p[0]);
yi = (int)floor(p[1]);
zi = (int)floor(p[2]);
da[0] = 1e10;
da[1] = 1e10;
da[2] = 1e10;
da[3] = 1e10;
for (xx = xi - 1; xx <= xi + 1; xx++) {
for (yy = yi - 1; yy <= yi + 1; yy++) {
for (zz = zi - 1; zz <= zi + 1; zz++) {
point ip = point(xx, yy, zz);
/*
In the next line, we set the Z coordinate to the Modulo of zloop.
This will make vp to repeat itself, because ip[2]+(n*zloop)=ip[2].
The original line is:
point vp = (point)cellnoise_color(ip);
*/
point vp = (point)cellnoise_color(point(ip[0], ip[1], mod(ip[2], zloop)));
point pd = p - (vp + ip);
float d = dot(pd, pd);
vp += point(xx, yy, zz);
if (d < da[0]) {
da[3] = da[2];
da[2] = da[1];
da[1] = da[0];
da[0] = d;
pa[3] = pa[2];
pa[2] = pa[1];
pa[1] = pa[0];
pa[0] = vp;
}
else if (d < da[1]) {
da[3] = da[2];
da[2] = da[1];
da[1] = d;
pa[3] = pa[2];
pa[2] = pa[1];
pa[1] = vp;
}
else if (d < da[2]) {
da[3] = da[2];
da[2] = d;
pa[3] = pa[2];
pa[2] = vp;
}
else if (d < da[3]) {
da[3] = d;
pa[3] = vp;
}
}
}
}
}
shader node_voronoi_texture(
float Scale = 5.0,
point Vector = P,
int ZLoop = 10,
output float Fac1 = 0.0)
{
point p = Vector;
float da[4];
point pa[4];
voronoiLooped(p * Scale, 1.0, ZLoop, da, pa);
Fac1 = fabs(da[0]);
}
Using the default ZLoop=10 means that the pattern will repeat when moving the coordinates in multiples of 10 units in the Z axis.