Generowanie jaskiń z robakami Perlin

12

Obecnie próbuję wygenerować teren Minecraft, taki jak woksel, za pomocą 3D Simplex Noise, a także chcę wdrożyć jaskinie.

W tym wątku znalazłem metodę Perlin Worms , która generuje naprawdę fajne wyniki. Nie mam jednak pojęcia, jak wygenerować go na podstawie porcji. Czy jest to możliwe, czy są jakieś alternatywy, które wytwarzają podobną do robaka jaskinię w kawałkach po kawałku?

Edit: To jest problem, który nie wiem jak rozwiązać.

Edycja2: Jest to wynik połączenia wielopierścieniowego szumu 2D z mapą wysokości hałasu Simplex. Nadal wymaga drobnych poprawek, ale to prawie taki wynik, jaki chciałem. Dzięki Byte56.

user000user
źródło
Jeśli to możliwe, powinieneś używać bezpośrednich wzorów do generowania terenu. Jeśli możesz obliczyć woksel na podstawie jego współrzędnych i bez informacji o sąsiadujących, fragmenty nie stanowią już problemu. Jeśli chcesz używać robaków Perlin, które, jak sądzę, nie mogą być obliczane indywidualnie dla każdego woksela, spójrz na ostatni akapit w zaakceptowanej odpowiedzi na pytanie, które podłączyłeś.
danijar
1
Zasadniczo to moje pytanie. Podstawowy teren można łatwo obliczyć, podając tylko współrzędne, ale nie wiem, jak obliczyć, czy jest jaskinia, czy nie.
user000user

Odpowiedzi:

5

Większość algorytmów szumów Perlin pozwala na odzyskanie wartości hałasu w dowolnym miejscu, z czymś podobnym noise(x,y,z). To sprawia, że ​​generowanie hałasu na zasadzie fragmentu po kawałku jest dość proste. Wszystko, co musisz zrobić, to przekazać pozycję globalną zamiast pozycji fragmentu.

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);

Jak widać, generujemy teren dla fragmentu, wykonując iteracje ponad granicami fragmentu i sprawdzając, czy ta globalna pozycja jest stała, czy nie. Jest to prawdopodobnie ta sama metodologia, której używasz do generowania terenu w ogóle.

perlinNoise.getzajmuje pozycję globalną i zwraca swoją gęstość. Gdzie isSolidbyłby prosty test, aby sprawdzić, czy woksel jest „wystarczająco gęsty”, aby zakwalifikować się do substancji stałej.

perlinNoise.getmoże być bardziej złożony niż zwykły algorytm hałasu. Możesz mieć kontrole oparte na głębokości woksela w twoim świecie. Na przykład, jeśli woksel znajduje się poniżej poziomu absolutnego podstawowego podłoża, może użyć algorytmu perlin worms do zwrócenia gęstości, jeśli jest powyżej bezwzględnej podstawy, może użyć funkcji normalnej gęstości, aby uzyskać bardziej zróżnicowany teren. Poleciłbym jednak połączenie tych dwóch elementów.

Łączenie różnych funkcji hałasu Perlina to po prostu coś, z czym musisz się bawić i zobaczyć, co działa. Najlepiej jest skonfigurować środowisko, aby można było po prostu zmienić niektóre wartości i zamienić teren bez konieczności ponownego ładowania gry. Miłego eksperymentowania.

MichaelHouse
źródło
2
Dziękuję za odpowiedź. Nie wiem jednak, jak użyć „zwykłego” hałasu Perlin lub Simplex do stworzenia jaskiń robaków. Są albo kuliste, skalowane w jednym kierunku, albo niezbyt długie. W przypadku algorytmu Perlin Worms nie wiem, jak ustalić, czy bieżąca pozycja znajduje się wewnątrz robaka, nie znając pozycji głowy.
user000user
1
Algorytm robaków nie polega na znajomości „pozycji głowy”. Z tego, co mówisz, wygląda na to, że twoim problemem nie jest generowanie hałasu na podstawie fragmentu. Istnieją tutoriale dotyczące pytania, które połączyłeś w celu implementacji robaków Perlin. Jak wygenerować „zwykły” teren można znaleźć tutaj .
MichaelHouse
Podstawowe generowanie terenu za pomocą 3D Simplex Noise działa dobrze, ale nie wiem, jak określić pozycję / segment robaków wewnątrz fragmentu. Z tego, co zrozumiałem, dajesz robakowi pozycję głowy in n segmentów i obliczasz kąt między segmentami za pomocą funkcji szumu. Oto obraz, który może lepiej wyjaśnić, na czym polega mój problem: link .
user000user,
2
Istnieją różne rodzaje hałasu. Używanie pozycji głowy i podążanie za nią jest jedną metodą. Jeśli spojrzysz w dół na dole tej strony , znajdziesz trochę hałasu, który tworzy pożądany hałas bez potrzeby zajmowania pierwszej pozycji.
MichaelHouse
Dzięki za podpowiedź. Zaimplementowałem 3D Ridged Multifractal Noise, jednak wynik był raczej niezadowalający. Spróbuję połączyć go w 2D z mapą wysokości 2D, a następnie powtórzę raport. Może to stworzyć więcej jaskiń robaków.
user000user,
3

Myślę, że tak to działa w Minecraft. Każdy robak ma maksymalną długość (nazwijmy go M). Główki każdego robaka są obliczane na podstawie pozycji porcji. Kiedy renderujesz każdą porcję, musisz sprawdzić wszystkie porcje w Mpromieniu i podążać za wszystkimi robakami. Nie jest idealny pod względem wydajności, ale działa.

Tom Dalling
źródło