C # Perlin noise - gerando "infinitos" pedaços de terreno?


7

Atualmente, estou escrevendo um pequeno scroller lateral em C #, para aprender C # e me divertir. No momento, tenho um gerador de números aleatórios simples gerando o mundo, mas não é exatamente tão bom - por isso, com algumas pesquisas, descobri que a geração de ruído Perlin pode me ajudar um pouco. O problema é que eu quero ter uma paisagem "interminável" composta de vários pedaços.

Basicamente, minhas perguntas / preocupações são:

  1. Usando minecraft como exemplo (Ignorando a 3ª dimensão), como o Notch está conseguindo que cada pedaço se conecte perfeitamente? Túneis, cavernas, veias de minério, montanhas, terrenos planos, biomas etc. estão todos conectados entre si, mesmo que cada pedaço seja gerado separadamente e, às vezes, muito mais tarde. Isso é fundamental para mim, quero que o jogador possa caminhar para a direita e, enquanto estiver caminhando, gere mais paisagem que se conecte à paisagem anterior, incluindo túneis subterrâneos e sistemas de cavernas.
  2. Partindo do ponto 1, como isso seria realizado sob a suposição de que cada pedaço é um quadrado e o mundo tem 10 quadrados de altura e infinitos quadrados de largura? Ou seja, cada "pedaço" tem 128 x 128 blocos e o mundo tem um total de 1.280 blocos. (Isso é para que eu possa fazer um mapa infinitamente profundo se eu escolher - e também mostrar que todos os quatro lados de um pedaço / quadrado precisam ser capazes de conectar e continuar o que o quadrado / pedaço anterior estava fazendo).

Respostas:


10

Encontre uma implementação C # do Simplex Noise, é como o Perlin, mas é melhor se comportar e mais rápido.

O problema das funções de ruído contínuo como Perlin e Simplex é que elas são determinísticas, o ruído não é aleatório . O que a maioria das implementações de ruído usa é um valor de Seed que compensa o ruído gerado, o que torna Seed = 1 diferente de Seed = 2.

Por causa da observação acima, você pode continuar reutilizando o Seed e todo o novo terreno gerado à medida que você avança na função de ruído será compatível, porque ele continua de onde parou.

Essa parte é bem simples e bastante agradável, o que você faz com o ruído gerado é onde a mágica acontece.

Para James, isso é possível, mas meu teste de velocidade pessoal com ruído 3D mostrou que simplex era mais rápido aos 3 anos, poderia haver vários fatores no meu teste pessoal, mas correspondia à idéia geral da literatura. Mesmo que fosse mais lento, eu recomendaria o simplex, porque não mostra os artefatos "quadrados" que o perlin mostra.

Para Jon, o Noise é uma função matemática e apenas mostra os resultados dos parâmetros e, dados os mesmos parâmetros, você receberá o mesmo número de volta. Eu vejo de onde a confusão pode vir.

Essa função de ruído é amostrada como: número = ruído (x, y, z); para ruído tridimensional. Por exemplo, seu primeiro mapa pode ter uma amostra de X = 0,0 a X = 1,9, o mapa à direita continua e amostras de X = 2,0 a 3,9

Parte da arte de usar o ruído é encontrar bons intervalos de amostra, decidir sobre quantas oitavas, filtragem e processamento etc ... Dê uma olhada em uma biblioteca de ruído útil para ver alguns exemplos e algum código fonte de Perlin em ação.


2
Eu pensei que o Simplex era apenas mais rápido em dimensões superiores a 3 ou 4 em relação ao ruído perlin? Que Perlin montou o Simplex especificamente para compensar a desaceleração da dimensão mais alta que seu algoritmo original encontrou.
11114 James

Então, basicamente, se eu gerar uma semente aleatória na criação de um mundo e continuar alimentando essa semente, se eu fizer um novo mapa de ruído a ser colocado à direita do primeiro mapa de ruído, ele continuará? Ou seja, se o mapa de ruído inicial tiver o que acabará por ser uma veia de ferro, essa veia de ferro continuará no novo mapa? Como, exatamente, isso funciona? Como o algoritmo sabe que precisa "continuar" o mapa de ruído no lado esquerdo, direito, superior ou inferior?
Jon

@ Jon Eu editei minha resposta para tentar descrever melhor o que as funções de ruído fazem, espero que faça mais sentido em termos de como o ruído pode ser usado para criar mapas contínuos uma peça de cada vez. A idéia mais importante ainda é que o ruído não seja aleatório.
Patrick Hughes

@PatrickHughes Wow sua edição esclareceu um pouco, obrigado. Agora só preciso encontrar uma classe C # / XNA simples para a geração de ruído simplex.
31412 Jon

2

uma tabela de ruído é pré-computada para integrar lado a lado, como em qualquer outro mapa de textura uniforme. é por isso que você pode ir para o ponto X e será sempre o mesmo, muito importante nas animações para que as texturas não mudem de quadro para quadro.

há um tópico sobre isso em answers.unity3d.com (geração de nível de rolagem do lado do procedimento)

também, o livro de 1994 "modelagem processual e texturização" discute ruído e multi-fractais (ruído em camadas com diferentes frequências e rotações).


Talvez eu esteja entendendo mal você ou não me expliquei muito bem - não quero colocá-los lado a lado, quero gerar um monte de 'pedaços' (mapas de ruído) que se conectam entre si - eu não ' não quero que nenhum deles seja o mesmo, só quero que percebam que "Ei, o cara ao meu lado tem um túnel no meio do caminho - devo continuar esse túnel"). Exatamente como o Minecraft faz, mas em 2D.
Jon
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.