# How to connect perlin noise seamlessly?

I’m making procedural terrain generation with perlin noise
My problem here is that when I put a few chunks generated by perlin noise next together, they dont connect, how do I make them connect seamlessly?

I do not think it is meant to tile unfortunately.

Maybe @Evgeni_Popov has a trick ?

1 Like

Well other games do it so I assume there must be a way
Maybe I should be using another type of noise? Idk

A trick I used was to generate 3d perlin noise and sample a tube. as the tube would loop, so is the 2D perlin.

2 Likes

Sorry i don’t understand that
Can u explain it more?

let me do it with pseudo code:

``````for(let y = 0;y < 256;y++)
{
for(let x = 0;x < 256;x++)
{
const rotationAngle = (x / 256) * 2 * Math.PI; // full circle from x
coordinate.x = Math.cos(rotationAngle);
coordinate.y = y / 256;
coordinate.z = Math.sin(rotationAngle);
const perlinValue = perlin3D(coordinate);
}
}
``````

This will sample a tube in a perlin 3D. produced values will tile on 1 dimension.
Sample a torus to have tile in 2 dimensions.

3 Likes

Sorry but I dont know how to implement this in my code

This is what I currently have:

``````function chunkPosition({ x, y }) {
const resultX = Math.floor(x / 32);
const resultY = Math.floor(y / 32);

return { x: resultX, y: resultY };
};

function chunk({ px, py }, seed) {
let n = new perlinNoise3d();
n.noiseSeed(seed);

let size = 16;
let output = [];
for (let x = 0; x < size; x++) {
for (let y = 0; y < size; y++) {
output.push({ x: x+px, y: y+py, value: n.get(x / 12, y / 12) });
};
};
return output;
};

``````
``````let chunks = [];

async function loadChunk({ posX, posY }) {
let b1;
let first = false;
let chunkData = [];

for (const block of chunk({ px: posX*16, py: posY*16 }, (Math.random() * 6000))) {
if (first == false) {
b1 = block;
first = true;
};

createBlock('grass', { x: block.x-8, y: Math.round((block.value*10)/2)-2, z: block.y-8 });
chunkData.push({ type: 'grass', position: { x: block.x-8, y: Math.round((block.value*10)/2)-2, z: block.y-8 }});

for (let i = 1; i < 6; i++) {
//createBlock('dirt', { x: block.x-8, y: Math.round((block.value*10)/2)-2-i, z: block.y-8 });
//chunkData.push({ type: 'grass', position: { x: block.x-8, y: Math.round((block.value*10)/2)-2-i, z: block.y-8 }});
};
}; scene.blockMaterialDirtyMechanism = false;

let chunkPos = chunkPosition({ x: b1.x , y: b1.y });
chunks.push({ position: chunkPos, data: chunkData });
};

loadChunk({ posX: 0, posY: 0 });
loadChunk({ posX: 1, posY: 0 });
loadChunk({ posX: 0, posY: 1 });
loadChunk({ posX: 1, posY: 1 });
``````

And i’m using this module to generate noise (thats why I couldnt create a playground)

Could you try to ask them if you rely on their package ? Maybe they have a trick for it ?

but you are providing a new random seed for each of your chucks , this wont tile.

you need to use the same seed and “scroll” the noise function in a manner that makes sense for the position of the chuck

looking at the module sample code , you would use this

` noise.get(x,y,z)`

you do not need to create a new instance of the perline noise or apply the seed more than once , so do that outside the code that generates the chucks , then just use this function to get the tile from the function you need

4 Likes

I tried using the same seed but it just loaded the same copy 4 times

Do you have a playground?

I didn’t only say use the same seed, read my response properly and do your research into how to use the offsets of the noise function 1 Like