Я знаю, что эта ветка устарела, и я не умею объяснять, но я поделюсь своим подходом.
Так, например, деревья 5x5x5. Вы хотите, чтобы ваша функция шума возвращала одно и то же значение для области размером 5x5 блоков, так что даже за пределами блока вы все равно можете проверить, следует ли вам сгенерировать дерево или нет.
// Here the returned value is different for every block
float value = simplexNoise(x * frequency, z * frequency) * amplitude;
// Here it will return the same value for an area of blocks (you should use floorDiv instead of dividing, or you it will get negative coordinates wrong (-3 / 5 should be -1, not 0 like in normal division))
float value = simplexNoise(Math.floorDiv(x, 5) * frequency, Math.floorDiv(z, 5) * frequency) * amplitude;
А теперь посадим дерево. Для этого нам нужно проверить, в какой позиции x y z находится этот текущий блок относительно начальной позиции дерева, чтобы мы могли знать, в какой части дерева находится этот блок.
if(value > 0.8) { // A certain threshold (checking if tree should be generated at this area)
int startX = Math.floorDiv(x, 5) * 5; // flooring the x value to every 5 units to get the start position
int startZ = Math.floorDiv(z, 5) * 5; // flooring the z value to every 5 units to get the start position
// Getting the starting height of the trunk (middle of the tree , that's why I'm adding 2 to the starting x and starting z), which is 1 block over the grass surface
int startY = height(startX + 2, startZ + 2) + 1;
int relx = x - startX; // block pos relative to starting position
int relz = z - startZ;
for(int j = startY; j < startY + 5; j++) {
int rely = j - startY;
byte tile = tree[relx][rely][relz]; // Get the needing block at this part of the tree
tiles[i][j][k] = tile;
}
}
Трехмерный массив tree здесь почти как «префаб» дерева, который вы можете использовать, чтобы узнать, какой блок установить в позицию относительно начальной точки. (Боже, я не знаю, как это объяснить, и то, что мой пятый язык - английский, мне тоже не помогает; -; не стесняйтесь улучшить свой ответ или придумать новый). Я реализовал это в своем движке, и он полностью работает. Структуры могут быть сколь угодно большими без предварительной загрузки фрагментов. Единственная проблема с этим методом заключается в том, что деревья или структуры будут создаваться почти внутри сетки, но это можно легко решить с помощью нескольких октав с разными смещениями.
Итак, резюмируем
for (int i = 0; i < 64; i++) {
for (int k = 0; k < 64; k++) {
int x = chunkPosToWorldPosX(i); // Get world position
int z = chunkPosToWorldPosZ(k);
// Here the returned value is different for every block
// float value = simplexNoise(x * frequency, z * frequency) * amplitude;
// Here it will return the same value for an area of blocks (you should use floorDiv instead of dividing, or you it will get negative coordinates wrong (-3 / 5 should be -1, not 0 like in normal division))
float value = simplexNoise(Math.floorDiv(x, 5) * frequency, Math.floorDiv(z, 5) * frequency) * amplitude;
if(value > 0.8) { // A certain threshold (checking if tree should be generated at this area)
int startX = Math.floorDiv(x, 5) * 5; // flooring the x value to every 5 units to get the start position
int startZ = Math.floorDiv(z, 5) * 5; // flooring the z value to every 5 units to get the start position
// Getting the starting height of the trunk (middle of the tree , that's why I'm adding 2 to the starting x and starting z), which is 1 block over the grass surface
int startY = height(startX + 2, startZ + 2) + 1;
int relx = x - startX; // block pos relative to starting position
int relz = z - startZ;
for(int j = startY; j < startY + 5; j++) {
int rely = j - startY;
byte tile = tree[relx][rely][relz]; // Get the needing block at this part of the tree
tiles[i][j][k] = tile;
}
}
}
}
Итак, «i» и «k» зацикливаются внутри блока, а «j» зацикливается внутри структуры. Вот как это должно работать.
Что касается рек, я лично еще этого не делал, и я не уверен, почему вам нужно устанавливать блоки вокруг чанка при их генерации (вы можете просто использовать червей Perlin, и это решит проблему), но это довольно почти такая же идея, и для ваших городов тоже.
person
Adam
schedule
03.02.2020