Zabawiam się Perlin Noise po pracy z Diamond Square. Śledziłem implementację Hugo Eliasa, która w zasadzie tworzy serię funkcji z x, y jako danymi wejściowymi, aby wyrzucić każdą wartość współrzędnej.
Mój kod PHP jest tutaj :
Mam dwa pytania:
Jak użyć algorytmu do wygenerowania mapy wysokości w tablicy? Nie w pełni go zrozumiałem i po prostu przeniosłem na PHP pseudokod, ale wykonuję ostatnią funkcję (map_perlined) po przeczytaniu gdzieś, że algorytm „magicznie” daje wartości przejściowe dla każdego podanego punktu x, y (najwyraźniej bez konieczności czytania jego sąsiednie wartości), po prostu otrzymuję to, gdy używam jako funkcji losowejmt_rand(-100,100)/100;
A to podczas korzystania z kryptografii: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(która, BTW, może być zaimplementowana w obecnej postaci w PHP?):
Podsumowując, trzy pytania:
- Czy mój kod jest poprawny?
- Funkcja losowa może być przeniesiona do PHP zgodnie z opisem w kodzie? Nie zgłasza błędów, ale wyników nie ma.
- Jak faktycznie korzystać z algorytmu?
AKTUALIZACJA
Ok, stworzyłem port PHP kodu pokazanego w artykule Gustavsona i, jak powiedział inny programista, generuje tylko jedną oktawę. Czy masz jakąkolwiek inną przydatną stronę / artykuł / przewodnik na temat tego, jak używać tego z pojęciami wielu oktaw, amplitudy, częstotliwości itp. W celu sterowania funkcją szumu? Na papierze Gustavsona pokazano tylko wyniki, a nie faktyczną implementację algorytmu, może coś mi brakuje?
AKTUALIZACJA 2
@NATHAN
Zrobiłem coś takiego:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;
}
//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);
Po normalizacji wartości do 0..1 otrzymuję raczej nudną mapę wysokości, taką jak:
Jak zaliczyć mapę? Być może muszę wdrożyć wersję 3d z trzecią wartością o losowej wysokości? Ale jeśli tak, musiałbym dowiedzieć się, aby wziąć pod uwagę wartości sąsiadów, które kończyłbym czymś w rodzaju algorytmu kwadratu diamentowego, dokładnie tego, czego nie chcę robić.
AKTUALIZACJA 3
Więcej pracy Perlina. Muszę jeszcze znaleźć sposób, aby kierować hałas do moich wyników. Sprawdź te oktawy i wynik końcowy:
Oktawa I do IV
Podsumował
Każda oktawa jest prawie taka sama. Sprawdź kod:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;
for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;
}
$this->map[$i][$j] = new Cell($value);
Wyniki są znormalizowane. Co byś zastosował, miałby silny wpływ na rozwój hałasu? Widzę przykłady, w których zmiana amplitudy daje miękkie lub szorstkie powierzchnie, ale nawet jeśli dam ogromną amplitudę, nie widzę różnicy.
Odpowiedzi:
To, co wdrożyłeś, nie jest hałasem Perlina. Nie jestem pewien, dlaczego Hugo Elias twierdzi, że tak, ale jest zdezorientowany. Oto referencyjna implementacja Kena Perlina. W rzeczywistości nie wywołuje żadnego zewnętrznego generatora liczb losowych, ale używa wbudowanej funkcji skrótu do tworzenia pseudolosowych wektorów gradientu.
Zauważ też, że hałas Perlina składa się tylko z jednej oktawy. Podsumowanie wielu oktaw (skalowane przypadki funkcji szumu), jak sugeruje Hugo Elias, jest użyteczną techniką, ale nie jest częścią szumu Perlina. To, co otrzymujesz, nazywa się hałasem fraktalnym, czasami „fraktalnym hałasem Browna” (z powodu rzekomej podobieństwa do ruchu Browna).
Jeśli chcesz zrozumieć geometrycznie, co robi algorytm, spróbuj tego artykułu . Chodzi o inny rodzaj hałasu zwany „hałasem jednostronnym”, ale zawiera także wyjaśnienie klasycznego hałasu Perlina. Nawiasem mówiąc, hałas simpleksowy został również wynaleziony przez Perlina i ma być poprawą w stosunku do jego klasycznego hałasu, więc możesz spróbować go wdrożyć, jeśli chcesz grać funkcjami szumu.
źródło
To powszechne nieporozumienie. To, co Hugo Elias nazywa hałasem „Perlina”, to tak naprawdę hałas fraktalny lub różowy. Aby lepiej zrozumieć, czym jest hałas Perlina, możesz przeczytać artykuł Perlina, do którego link znajduje się w odpowiedzi Nathana Reeda, lub libnoise docs (tam jest ten sam błąd: hałas Perlina to, co nazywają hałasem Gradientu) lub dokumenty CoherentNoise .
Teraz, aby odpowiedzieć na twoje pytanie: nie uzyskałeś oczekiwanego rezultatu, ponieważ częstotliwość hałasu jest zbyt wysoka. Częstotliwości zaczynają się od 1 i rosną, co oznacza, że każdy piksel na wynikowej mapie ma losową wartość. Aby zobaczyć dokładniejszą strukturę mapy, musisz „powiększyć” hałas. Tak naprawdę nie mówię w PHP, ale przypuszczam, że kod powinien wyglądać tak:
Oznacza to, że „rozciągasz” jeden okres hałasu na całej mapie. Oczywiście możesz użyć innych współczynników - po prostu wypróbuj inne, zobacz, co się stanie.
źródło