Perlin gürültüsü - Perlin noise

Z = 0'da 3D Perlin gürültüsü aracılığıyla iki boyutlu dilim

Perlin gürültüsü bir tür gradyan gürültüsü tarafından geliştirilmiş Ken Perlin.

Tarih

Ken Perlin 1983'te "makine benzeri" görünümden duyduğu hayal kırıklığının bir sonucu olarak perlin gürültüsü geliştirdi. bilgisayar tarafından oluşturulan görüntüler (CGI) o sırada.[1] Bulgularını resmen bir SIGGRAPH 1985'te kağıt aradı Görüntü Sentezleyici.[2] O geliştirdi Matematiksel Uygulamalar Grubu, Inc. (MAGI) için Disney 's Bilgisayar animasyonlu bilim kurgu sinema filmi Tron (1982). 1997'de Perlin, Teknik Başarı Akademi Ödülü algoritmayı oluşturmak için.[3] 1997'de bir kazandı Teknik Başarı Akademi Ödülü -den Sinema Sanatları ve Bilimleri Akademisi CGI'ye bu katkı için.[4][5][6]

Doğal görünüm elde etmek için kullanılan bir teknik olan Perlin Noise'un geliştirilmesi için Ken Perlin'e dokular Perlin Noise'un gelişimi, bilgisayar grafik sanatçılarının sinema endüstrisi için görsel efektlerdeki doğal fenomenlerin karmaşıklığını daha iyi temsil etmesine izin verdi.

Perlin, algoritma ile ilgili herhangi bir patent başvurusunda bulunmadı, ancak 2001'de 3D + uygulamalarının kullanımı için bir patent aldı. tek yönlü gürültü için doku sentezi. Tek yönlü gürültü aynı amaca sahiptir, ancak daha basit bir boşluk doldurma ızgarası kullanır. Tek yönlü gürültü, Perlin'in "klasik gürültüsü" ile ilgili, hesaplama karmaşıklığı ve görsel olarak önemli yönsel eserler gibi bazı sorunları hafifletir.[7]





Kullanımlar

Perlin gürültüsü kullanılarak oluşturulan sanal bir manzara

Perlin gürültüsü bir prosedürel doku ilkel, bir tür gradyan gürültüsü görsel efekt sanatçıları tarafından gerçekçiliğin görünümünü artırmak için kullanılır. bilgisayar grafikleri. Fonksiyonun bir sözde rastgele görünüm, ancak tüm görsel detayları aynı boyuttadır. Bu özellik, kolayca kontrol edilebilir olmasına izin verir; Perlin gürültüsünün birden çok ölçekli kopyası, çok çeşitli prosedürel dokular oluşturmak için matematiksel ifadelere eklenebilir. Perlin gürültüsünü kullanan sentetik dokular, genellikle CGI'da, bilgisayar tarafından üretilen görsel unsurların - nesne yüzeyleri, ateş, duman veya bulutlar gibi - doğadaki dokuların kontrollü rastgele görünümünü taklit ederek daha doğal görünmesini sağlamak için kullanılır.

Perlin gürültüsü ile oluşturulan organik bir yüzey

Ayrıca, bellek aşırı derecede sınırlı olduğunda, doku oluşturmak için de sıklıkla kullanılır. demolar. Gibi halefleri fraktal gürültü ve tek yönlü gürültü, neredeyse her yerde grafik işleme birimleri ikisi için gerçek zamanlı grafikler ve her türlü bilgisayar grafiğindeki gerçek zamanlı olmayan prosedürel dokular için.


Algoritma ayrıntısı

Perlin gürültüsü yeniden ölçeklendirildi ve oluşturmak için kendi içine eklendi fraktal gürültü.

Perlin Noise, N boyutlarında belirli bir koordinat için 0,0 ile 1,0 arasında bir sayı döndüren bir işlevdir. [8]


Perlin gürültüsü en yaygın olarak iki, üç veya dört boyutlu olarak uygulanır. işlevi, ancak herhangi bir sayıda boyut için tanımlanabilir. Bir uygulama tipik olarak üç adımı içerir: rastgele gradyan vektörlerinden oluşan bir ızgara tanımlama, nokta ürün gradyan vektörleri ve ofsetleri arasında ve bu değerler arasındaki enterpolasyon. [9]

Izgara tanımı

Gradyan vektörlerinden oluşan 2 boyutlu bir ızgara

Tanımla nher ızgara kesişiminin kendisiyle ilişkilendirildiği boyutsal ızgara sabit bir rastgele ngradyanların -1 ile 1 arasında rasgele skaler olduğu tek boyutlu durum dışında, boyutlu birim uzunluk gradyan vektörü.

Nokta ürün

En yakın ızgara düğümü gradyan değerine sahip her noktanın iç çarpımı. Hücredeki diğer üç düğüme sahip iç çarpım gösterilmez.

Herhangi bir aday noktanın değerini hesaplamak için, önce noktanın bulunduğu benzersiz ızgara hücresi bulunur. Sonra bu hücrenin köşeleri ve bunlarla ilişkili gradyan vektörleri tanımlanır. Daha sonra, her köşe için, aday noktadan o köşeye yer değiştirme vektörü olan bir ofset vektörü hesaplanır.

Her köşe için, nokta ürün gradyan vektörü ve ofset vektörü arasında aday noktaya. Aday nokta tam olarak ızgara köşesindeyse, bu iç çarpım sıfır olacaktır.

İki boyutlu bir ızgaradaki bir nokta için, bu 4 ofset vektörünün ve nokta ürünlerinin hesaplanmasını gerektirirken, üç boyutta 8 ofset vektörü ve 8 nokta çarpımı gerektirecektir. Genel olarak, algoritmanın bir karmaşıklık ölçeklendirme.

İnterpolasyon

Son enterpolasyonlu sonuç

Son adım, nokta ürünleri. Enterpolasyon, önce sıfır olan bir fonksiyon kullanılarak gerçekleştirilir türev (ve muhtemelen ikinci türev) ızgara düğümleri. Bu nedenle, ızgara düğümlerine yakın noktalarda çıktı, düğümün gradyan vektörünün nokta ürününü ve ofset vektörünü düğüme yaklaştıracaktır. Bu, gürültü işlevinin her düğümde sıfırdan geçeceği ve Perlin gürültüsüne karakteristik görünümünü vereceği anlamına gelir.

Eğer değer arasında enterpolasyon yapan bir işlev örneği ızgara düğümünde 0 ve değer ızgara düğümünde 1

nerede pürüzsüz adım işlevi kullanıldı.

Bilgisayar grafiklerinde kullanım için gürültü fonksiyonları tipik olarak [-1.0,1.0] aralığında değerler üretir ve buna göre ölçeklenebilir.

Uygulama

Aşağıdaki, C ile yazılmış Klasik Perlin Gürültüsünün iki boyutlu bir uygulamasıdır.

Perlin'in orijinal referans uygulaması, büyük farklarla Java'da yazılmıştır:

  • aşağıdaki karenin 4 köşesi yerine bir küpün 8 köşesi arasında enterpolasyon yaparak üç boyutlu bir yaklaşım kullanıyor.
  • rastgele gradyan yönü, köşelerin tamsayı koordinatlarının bitlerini karıştırır; bu, köşelerin tamsayı koordinatlarının yüksek dönme frekansındaki paraziti kullanarak karıştırmadan çok daha hızlıdır, bir ürün tarafından yüksek frekansta birleştirilir ve tekrar döndürülür: dönmeler tekdüze değildir dağıtıldı.
  • Perlin'in yöntemi, tamsayı alanını 256x256x256 küplere böler ve daha sonra bunları karıştırmak için bu küplerin rastgele bir permütasyonunu kullanır ve ardından her bir küp konumu köşesine, 4x4x4'lük bir asfaltlama alanında komşu permütasyonsuz küplere on iki yönden biri atanır: bu sadece gerektirir tamsayı işlemleri, ancak tekdüze bir yön dağılımını korur.
  • enterpolasyon işlevi (adlandırılmış solmak) daha pürüzsüz 4 derecedir Daha düzgün adım (kenetleme sınırlarında ilk üç türev sıfıra eşittir) ve temel doğrusal adım değil. Bu, özellikle örnekleme köşelerini birleştiren köşeler veya köşegenler boyunca, sonuçların gözle görülür şekilde anizotropik olacağı (istenen beyaz gürültü içine pembe gürültü; gürültü katı bir kristal oluşturmak için kullanılmış olsaydı, tamamen siyah ve ışığa opak olmazdı, ancak kısmen saydam ve bazı farklı gözlem yönlerinde renkli olurdu).

Bu nedenle, aşağıdaki kod çok basittir a yalnızca gösterim amaçlıdır, yavaş olacaktır ve uygulamalarda kullanılamaz.

#Dahil etmek <math.h>/ * A0 ve a1 arasında doğrusal olarak enterpolasyon yapma işlevi * Ağırlık w [0.0, 1.0] aralığında olmalıdır */yüzen interpolate(yüzen a0, yüzen a1, yüzen w) {    / * // Ekleyerek sıkıştırmak isteyebilirsiniz:     * eğer (0.0> w) a0 döndürür;     * eğer (1.0      */    dönüş (a1 - a0) * w + a0;    / * // Düzgün bir görünüm için bunun yerine bu kübik enterpolasyonu [[Smoothstep]] kullanın:     * dönüş (a1 - a0) * (3.0 - w * 2.0) * w * w + a0;     *     * // Sınırlarda sıfıra eşit ikinci bir türevle daha da yumuşak bir sonuç için [[Smootherstep]] kullanın:     * dönüş (a1 - a0) * (x * (w * 6.0 - 15.0) * w * w * w + 10.0) + a0;     */}typedef yapı {    yüzen x, y;} vektör2;/ * Rastgele yön vektörü oluştur */vektör2 randomGradient(int ix, int iy) {    // Rastgele kayan nokta. Önceden hesaplanmış gradyan olmaması, bunun herhangi bir sayıda ızgara koordinatı için çalıştığı anlamına gelir    yüzen rastgele = 2920.f * günah(ix * 21942.f + iy * 171324.f + 8912.f) * çünkü(ix * 23157.f * iy * 217832.f + 9758.f);    dönüş (vektör2) { .x = çünkü(rastgele), .y = günah(rastgele) };}// Uzaklık ve gradyan vektörlerinin iç çarpımını hesaplar.yüzen dotGridGradient(int ix, int iy, yüzen x, yüzen y) {    // Tamsayı koordinatlarından gradyan alın    vektör2 gradyan = randomGradient(ix, iy);    // Uzaklık vektörünü hesaplayın    yüzen dx = x - (yüzen)ix;    yüzen dy = y - (yüzen)iy;    // Nokta çarpımı hesaplayın    dönüş (dx*gradyan.x + dy*gradyan.y);}// x, y koordinatlarında Perlin gürültüsünü hesaplayüzen Perlin(yüzen x, yüzen y) {    // Izgara hücresi koordinatlarını belirle    int x0 = (int)x;    int x1 = x0 + 1;    int y0 = (int)y;    int y1 = y0 + 1;    // Enterpolasyon ağırlıklarını belirle    // Burada ayrıca daha yüksek dereceden polinom / s-eğrisi de kullanılabilir    yüzen sx = x - (yüzen)x0;    yüzen sy = y - (yüzen)y0;    // Izgara noktası gradyanları arasında enterpolate    yüzen n0, n1, ix0, ix1, değer;    n0 = dotGridGradient(x0, y0, x, y);    n1 = dotGridGradient(x1, y0, x, y);    ix0 = interpolate(n0, n1, sx);    n0 = dotGridGradient(x0, y1, x, y);    n1 = dotGridGradient(x1, y1, x, y);    ix1 = interpolate(n0, n1, sx);    değer = interpolate(ix0, ix1, sy);    dönüş değer;}

Permütasyon

Perlin gürültüsünün birçok uygulaması, Ken Perlin'in orijinal uygulamasında kullandığı aynı permütasyon kümesini kullanır.[10] Bu uygulama aşağıdaki gibidir:

int permütasyon[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36,                       103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0,                       26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56,                       87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,                       77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55,                       46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132,                       187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109,                       198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126,                       255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183,                       170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43,                       172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112,                       104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162,                       241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106,                       157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205,                       93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };

[0–255] (dahil) değerlerinin rastgele bir dizisini gerektirmesine rağmen, bu özel permütasyon kesinlikle gerekli değildir. Yeni bir permütasyon tablosu oluşturuyorsanız, değerlerin düzgün dağılımını sağlamak için özen gösterilmelidir.[11]

Karmaşıklık

Gürültü fonksiyonunun her bir değerlendirmesi için, konum ve gradyan vektörlerinin iç çarpımı, içeren grid hücresinin her bir düğümünde değerlendirilmelidir. Perlin gürültüsü bu nedenle karmaşıklıkla ölçeklenir için boyutlar. Gelişmiş karmaşıklık ölçeklendirmesi ile benzer sonuçlar üreten Perlin gürültüsüne alternatifler arasında tek yönlü gürültü ve OpenSimplex gürültü.

Ayrıca bakınız

Referanslar

  1. ^ Perlin, Ken. "Ses yapmak". noisemachine.com. Ken Perlin. Arşivlenen orijinal 8 Ekim 2007.
  2. ^ Perlin, Ken (Temmuz 1985). "Bir Görüntü Sentezleyici". SIGGRAPH Comput. Grafik. 19 (97–8930): 287–296. doi:10.1145/325165.325247.
  3. ^ Orijinal kaynak kodu
  4. ^ Kerman, Phillip. Macromedia Flash 8 @work: İşi Tamamlamak için Projeler ve Teknikler. Sams Yayıncılık. 2006. ISBN  9780672328282.
  5. ^ Arşivlendi 2018-05-01 de Wayback Makinesi Ken Perlin'in 'tutarlı gürültü işlevi'
  6. ^ Gustavson, Stefan. "Tek yönlü gürültü gizemi çözüldü" (PDF). Alındı 24 Nisan 2019.
  7. ^ ABD patenti 6867776 Kenneth Perlin, Kenneth Perlin ve Wsou Investments LLC'ye devredilen, 2005-03-15'te yayınlanan "Perlin gürültüsü için standart" 
  8. ^ Bryan McClain tarafından Perlin Gürültüsü
  9. ^ Gustavson, Stefan. "Tek yönlü gürültü gizemi çözüldü" (PDF). Alındı 24 Nisan 2019.
  10. ^ Perlin, Ken. "Perlin gürültüsü". Alındı 26 Ağustos 2020.
  11. ^ "Perlin Noise: 2. Bölüm". Alındı 26 Ağustos 2020.

Dış bağlantılar