Geração de cavernas com vermes Perlin

12

Atualmente, estou tentando gerar um Minecraft como voxel terreno com 3D Simplex Noise e também quero implementar cavernas.

Eu encontrei o método de Perlin Worms neste tópico, que gera resultados muito bons. No entanto, não tenho idéia de como gerá-lo em um pedaço por pedaço. Isso é possível ou existem alternativas que produzam um sem-fim semelhante, como uma caverna em pedaços por pedaços?

Edit: Este é o problema que eu não sei como resolver.

Edit2: Este é o resultado da combinação de Ruído Multifractal 2D Ridged com um mapa de altura do Simplex Noise Ainda precisa de alguns ajustes, mas esse é praticamente o resultado que eu queria. Graças a Byte56.

user000user
fonte
Você deve usar fórmulas diretas para geração de terreno, se possível. Se você pode calcular um voxel apenas com base em suas coordenadas e sem informações sobre as adjacentes, os blocos não são mais um problema. Se você quiser usar worms perlin, que acho que não podem ser calculados para cada voxel individualmente, dê uma olhada no último parágrafo da resposta aceita da pergunta que você vinculou.
Danijar 06/04
1
Basicamente, essa é a minha pergunta. O terreno básico é fácil de calcular com apenas as coordenadas fornecidas, mas não sei como calcular, se há uma caverna ou não.
user000user

Respostas:

5

A maioria dos algoritmos de ruído perlin permitirá recuperar o valor do ruído em qualquer local, com algo parecido noise(x,y,z). Isso faz com que seja bastante trivial gerar ruído em partes por partes. Tudo que você precisa fazer é passar a posição global, em vez da posição do bloco.

for(int i = 0; i < CHUNKMAX_X; i++)
    for(int j = 0; j < CHUNKMAX_Y; j++)
        for(int k = 0; k < CHUNKMAX_Z; k++)
            if(isSolid(perlinNoise.get(chunkPosition.x + i,
                                         chunkPosition.y + j,
                                         chunkPosition.z + k))
                thisChunk[i,j,k] = new Voxel(solid);
            else
                thisChunk[i,j,k] = new Voxel(air);

Como você pode ver, estamos gerando terreno para o bloco, iterando sobre os limites do bloco e verificando se essa posição global é sólida ou não. Essa é provavelmente a mesma metodologia usada para gerar o terreno em geral.

perlinNoise.getassume uma posição global e retorna sua densidade. Onde isSolidseria apenas um teste simples para ver se o voxel é "denso o suficiente" para se qualificar para sólido.

perlinNoise.getpode ser mais complexo do que apenas um simples algoritmo de ruído. Você pode ter verificações com base na profundidade do voxel em seu mundo. Por exemplo, se o voxel estiver abaixo do que você decidiu como "nível absoluto da base", ele poderá usar o algoritmo perlin worms para retornar uma densidade; se estiver acima da base absoluta, poderá usar uma função de densidade normal para fornecer terreno mais variado. Eu recomendaria algumas misturas entre os dois.

Combinar diferentes funções de ruído Perlin é apenas algo com o qual você precisa brincar e ver o que funciona. É melhor configurar seu ambiente para que você possa alterar alguns valores e trocar de terreno a quente sem precisar recarregar o jogo. Feliz experimentando.

MichaelHouse
fonte
2
Obrigado pela resposta. No entanto, não sei como usar Perlin ou Simplex Noise "regular" para criar cavernas semelhantes a vermes. Eles são esféricos, redimensionados em uma direção ou não são muito longos. E para o algoritmo Perlin Worms, não sei como determinar se a posição atual está dentro de um worm, sem saber a posição da cabeça.
User000user
1
O algoritmo de worms não depende de conhecer a "posição da cabeça". Pelo o que você está dizendo, parece que seu problema não é gerar ruído em pedaços. Existem tutoriais sobre a questão que você vinculou para implementar worms perlin. Como gerar terrenos "regulares" pode ser encontrado aqui .
Michaelhouse
A geração básica de terreno com o 3D Simplex Noise funciona bem, mas não sei como determinar uma posição / segmento de worms dentro de um pedaço. Pelo que entendi, você dá ao verme uma posição de cabeça en segmentos e calcula o ângulo entre os segmentos com a função de ruído. Aqui está uma imagem que pode explicar melhor qual é o meu problema: link .
user000user
2
Existem diferentes tipos de ruído. Usando uma posição da cabeça e seguindo a partir de há um método. Se você olhar perto da parte inferior desta página , encontrará algum ruído que cria o tipo de ruído desejado, sem precisar primeiro de uma posição de cabeça.
Michaelhouse
Obrigado pela dica sobre isso. Eu implementei o 3D Ridged Multifractal Noise, porém, o resultado com ele foi bastante insatisfatório. Vou tentar combiná-lo em 2D com um mapa de altura 2D e depois reportar novamente. Isso pode criar mais cavernas semelhantes a vermes.
user000user
3

Eu acho que é assim que funciona no Minecraft. Cada worm tem um comprimento máximo (vamos chamá-lo M). As cabeças de cada verme são calculadas com base na posição do pedaço. Ao renderizar cada pedaço, você deve verificar todos os pedaços dentro de um Mraio e seguir todos os seus worms. Não é ideal em termos de desempenho, mas funciona.

Tom Dalling
fonte