Perlin Gürültüsünü Anlamak


31

Diamond Square ile yaptığım çalışmalardan sonra Perlin Noise ile oynuyorum. Uygulamayı Hugo Elias tarafından takip ettim ; temel olarak, her koordinat değerini atmak için girdi olarak x, y ile bir dizi fonksiyon yapan.

PHP kodum burada :

İki sorum var:

Bir dizide bir yükseklik haritası oluşturmak için algoritmayı nasıl kullanırım? Onu tam olarak anlamadım ve PHP'ye sadece sahte kodu aktardım, ancak bir yerde okuduktan sonra son işlevi (map_perlined) yapıyorum, "sihirli bir şekilde" algoritmasının size verilen her x, y noktası (görünüşe göre, okumak zorunda kalmadan) size geçiş değerleri verdiği komşu değerler), bunu sadece rastgele işlev olarak kullanırken elde ederimmt_rand(-100,100)/100;

görüntü tanımını buraya girin

Ve bu kriptografik kullanılırken: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;(BTW, PHP'de "olduğu gibi" uygulanabilir?):

görüntü tanımını buraya girin

Yani, özetle, üç soru:

  1. Kodum doğru mu?
  2. Rastgele işlev, kodda açıklandığı şekilde PHP'ye taşınabilir mi? Hata atmaz, ancak sonuç yoktur.
  3. Algoritmayı gerçekte nasıl kullanırım?

GÜNCELLEŞTİRME

Tamam, Gustavson gazetesinde gösterilen kodun bir PHP portunu yaptı ve diğer kodlayıcıların söylediği gibi sadece bir oktav üretti. Gürültü fonksiyonunu kontrol etmek için bunun çoklu oktav, genlik, frekans vb. Kavramları ile nasıl kullanılacağı hakkında başka yararlı bir site / kağıt / rehberiniz var mı? Gustavson'un makalesinde sadece algoritmanın gerçek uygulamasını değil, belki bir şeyleri özlüyorum, sonuçları gösteriyor?

GÜNCELLEME 2
@NATHAN

Gibi bir şey yaptım:

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

Ve değerleri 0,1 olarak normalleştirdikten sonra, aşağıdaki gibi oldukça donuk bir yükseklik haritası alıyorum:

görüntü tanımını buraya girin

Haritayı nasıl ekerim? Belki de uygulamam gereken şey, üçüncü değeri rastgele bir yüksekliğe sahip olan 3d versiyonudur. Ama eğer öyleyse, tam olarak yapmak istemediklerimi, elmas kare algoritması gibi bir şeyle sonlandırdığım komşu değerleri göz önünde bulundurmalıyım.

GÜNCELLEME 3

Daha fazla Perlin çalışması. Sonuçlarıma göre gürültüyü yönlendirecek bir yol bulamadım. Bu oktavları ve nihai sonucu kontrol edin:

Octave I ile IV

octave1Octave2Octave3Octave4

Özetlenmiş

1-4 arası Toplamlar

Her oktav hemen hemen aynıdır. Kodu kontrol et:

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

Sonuçlar normalleştirildi. Gürültünün gelişiminde ne kullanırsınız? Genliği değiştirmenin yumuşak veya pürüzlü yüzeyler verdiği örnekleri görüyorum, ancak çok büyük bir genlik versem bile, çok az fark görüyorum.


Sadece birden çok örneği ekleyin, frekansı artırın ve her seferinde genliği azaltın, örneğin: perlin (x) + 0.5 * perlin (2 * x) + 0.25 * perlin (4 * x) + ... (en çok oktav için İstediğiniz). Farklı görünümler elde etmek için faktörleri değiştirmeyi deneyebilirsiniz; 2 güç olmaları gerekmez
Nathan Reed

1
Güncelleme Sonrası, Y'yi doğru şekilde ölçeklemediğiniz görülüyor - PHP'yi grok yapmak için çok yorgunum (PHP'yi bilmediğim için); fakat ilk defa perlin uygularken, anadilimde de benzer bir konuya değindim. Ayrıca, oktavları öldürün ve sadece bir seviye perlin hata ayıklayın.
Jonathan Dickinson

III güncellememden isteyen var mı?
Gabriel A. Zorrilla 24:11

Yanıtlar:


28

Yaptığın şey Perlin sesi değil. Hugo Elias'ın neden söylediğinden emin değilim, ama kafası karışık. İşte Ken Perlin'in referans uygulaması. Aslında herhangi bir harici rasgele sayı üreteci olarak adlandırılmaz, ancak sözde rasgele degrade vektörlerini üretmek için yerleşik bir karma işlevi kullanır.

Ayrıca, Perlin gürültüsünün sadece bir oktavdan oluştuğunu unutmayın. Hugo Elias'ın öne sürdüğü gibi, çoklu oktavları (gürültü fonksiyonunun ölçeklenmiş örneklerini) özetlemek, Perlin gürültüsünün bir parçası değil, faydalı bir tekniktir. Bunu yaparak, fraktal gürültü, bazen de "fraktal Brownian gürültüsü" (Brownian hareketinin sözde benzerliği nedeniyle) denir.

Algoritmanın ne yaptığını geometrik olarak anlamak istiyorsanız, bu kağıdı deneyin . "Simpleks gürültü" olarak adlandırılan farklı bir tür gürültü hakkında, ancak klasik Perlin gürültüsünün bir açıklamasını da içerir. Bu arada, simpleks gürültü de Perlin tarafından icat edildi ve onun klasik gürültüsünde bir gelişme olması gerekiyordu, bu nedenle gürültü işlevleriyle oynamak istiyorsanız, onu da uygulamayı deneyebilirsiniz.


2
Gustavson'un makalesi için +1. Şimdiye kadar gördüğüm en net şekilde hem perlin hem de simpleks gürültüyü açıklıyor. Açıkçası simpleks gürültü kuralları!
FxIII

Bir süre önce bu makaleyi de buldum ama Hugo daha basit görünüyordu. Onu okuyacağım ve bir şans vereceğim! Teşekkürler!
Gabriel A. Zorrilla 10:11

2
simpleks gürültü indirirken dikkatli olun, virüs olabilir;)
bobobobo 12:11

Bunun eski bir konu olduğunu biliyorum, ancak başvuru uygulamasının rasgele bir sayı kullanmadığını söylemek yanlış. Kitaplık başlatıldığında (veya ilk kez bir gürültü fonksiyonu çağırıldığında) 256 rastgele degrade oluşturulur. Bahsettiğiniz karmaşa yalnızca sonsuz tam sayı kümesini önbelleğe alınan [0, 255] aralığına zorlamaktır. Temel olarak bu sadece bir arama tablosu optimizasyonu ve algoritma, örneğin bir ızgara koordinatına sahip bir PRNG ekleyip degradesini oluşturmak için kullanırsanız, bu yöntem sadece (çok) bu kadar yavaşsa da iyi çalışır.
bcrist

@bcrist Bence Perlin gürültüsünün eski bir versiyonundan bahsediyorsunuz. Perlin'in bağlandığım "gelişmiş gürültü", 256 rastgele değil, sabit bir 12 degrade vektör kümesi kullanıyor. Izgara koordinatlarını bu 12 degrade vektörden birine eşlemek için karma işlevi olarak permütasyon tablosu kullanır.
Nathan Reed

11

Bu yaygın bir yanılgıdır. Hugo Elias'ın “Perlin” gürültüsü dediği şey aslında fraktal veya pembe gürültüdir. Perlin gürültüsünün ne olduğunu daha iyi anlamak için, Nathan Reed'in cevabındaki Perlin'in makalesini okuyabilir veya dokümanları serbest bırakabilirsiniz (aynı hata var: Perlin gürültüsü Gradient gürültü dedikleri şeydir) veya CoherentNoise docs .

Şimdi, sorunuzu gerçekten cevaplamak için: Beklenen sonucu alamadım, çünkü gürültü frekansı çok yüksek. Frekanslarınız 1 ile başlar ve artar, bu da sonuçtaki haritadaki her pikselin rastgele bir değere sahip olduğu anlamına gelir. Haritanın daha ince yapısını görmek için gürültüyü "yakınlaştırmanız" gerekir. PHP'yi gerçekten konuşmuyorum ama kodun şöyle görünmesi gerektiğini düşünüyorum:

$arrayMap[$i][$j] = PerlinNoise_2D($i/$width, $j/$height, $p, $octaves);

Yani, haritanızın tamamı boyunca bir dönem gürültü "uzatıyorsunuz". Elbette, diğer katsayıları kullanabilirsiniz - sadece farklı olanları deneyin, neler olduğunu görün.


Tutarlı gürültü belgeleri için teşekkürler! Yazdığını görüyorum :) Libnoise belgelerinde hata nedir? Perlin gürültüsü bir çeşit degrade gürültüsü değil mi?
legends2k
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.