Seamless Perlin Noise
A seamless and tileable version of the Perlin Noise. Use this as is or as noise in the Fractal Brownian Motion function. cell_amount
and period
together sets how many times (and thus the appeared size) the noise will tile within the texture.
uniform int cell_amount = 20;
uniform vec2 period = vec2(5., 10.);
vec2 modulo(vec2 divident, vec2 divisor){
vec2 positiveDivident = mod(divident, divisor) + divisor;
return mod(positiveDivident, divisor);
}
vec2 random(vec2 value){
value = vec2( dot(value, vec2(127.1,311.7) ),
dot(value, vec2(269.5,183.3) ) );
return -1.0 + 2.0 * fract(sin(value) * 43758.5453123);
}
float seamless_noise(vec2 uv, vec2 _period) {
uv = uv * float(cell_amount);
vec2 cellsMinimum = floor(uv);
vec2 cellsMaximum = ceil(uv);
vec2 uv_fract = fract(uv);
cellsMinimum = modulo(cellsMinimum, _period);
cellsMaximum = modulo(cellsMaximum, _period);
vec2 blur = smoothstep(0.0, 1.0, uv_fract);
vec2 lowerLeftDirection = random(vec2(cellsMinimum.x, cellsMinimum.y));
vec2 lowerRightDirection = random(vec2(cellsMaximum.x, cellsMinimum.y));
vec2 upperLeftDirection = random(vec2(cellsMinimum.x, cellsMaximum.y));
vec2 upperRightDirection = random(vec2(cellsMaximum.x, cellsMaximum.y));
vec2 fraction = fract(uv);
return mix( mix( dot( lowerLeftDirection, fraction - vec2(0, 0) ),
dot( lowerRightDirection, fraction - vec2(1, 0) ), blur.x),
mix( dot( upperLeftDirection, fraction - vec2(0, 1) ),
dot( upperRightDirection, fraction - vec2(1, 1) ), blur.x), blur.y) * 0.8 + 0.5;
}
void fragment(){
float noise = seamless_noise(UV, period);
COLOR.rgb = vec3(noise);
}
This method of making a seamless noise is a modified version of Ronja’s tileable perlin noise.