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 ?
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.
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.
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
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