1 puan yazan GN⁺ 2024-09-29 | 1 yorum | WhatsApp'ta paylaş
  • GodotOceanWaves, Godot Engine’de yönlü okyanus dalgası spektrumunun ters Fourier dönüşümünü kullanarak açık deniz yüzeyi oluşturan bir render deneyi; gerçek zamanlı olarak betiklerle ayarlanabilen parametrelerle çeşitli okyanus ortamlarını simüle eder
  • Gerstner waves sakin suyun düşük frekanslı ayrıntıları için uygun olsa da dalgalı açık deniz yüzeylerinde sınırlı kalır; bu proje bu nedenle ampirik oşinografi verilerine dayalı spektrumlar ve FFT kullanır
  • Dalga üretimi Tessendorf yöntemini izleyerek başlangıç spektrum durumunu oluşturur, dağılım ilişkisiyle zaman içinde yayar ve ters Fourier dönüşümüyle displacement, normal ve foam map üretir
  • Render, Atlas GDC sunumundaki BSDF’yi izler ancak GGX dağılımını kullanır; foam, displacement’ın Jacobian’ının negatif olduğu bölgelerde biriktirilip sönümlenir, sea spray ise Godot’un GPUParticles3D ve özel shader’larıyla uygulanır
  • Çoklu wave cascade, güncelleme periyodu ayarı ve cascade bazında yük dağıtımıyla tiling ve GPU iş yükü yönetilir; ancak cascade’lerin aynı spektrum texture çözünürlüğünü kullanması gerekir ve sea spray parçacık yöntemi yoğunluk artışı açısından düşük verimlidir

GodotOceanWaves ne yapıyor

  • GodotOceanWaves, Godot Engine’de açık deniz render’ını deneyen bir projedir
  • Dalga üretiminde yönlü okyanus dalgası spektrumunun ters Fourier dönüşümü kullanılır
  • Dışa açılan parametreler sade tutulmuştur ve betiklerle gerçek zamanlı değiştirerek çeşitli okyanus dalgası ortamları simüle edilebilir
  • Demo video olarak ocean_demo.mp4 ve environment_demo.mp4 dahildir

Gerstner waves yerine neden Fourier tabanlı dalgalar kullanılıyor

  • Oyunlarda suyu canlandırmanın yaygın bir yolu, vertex’leri Gerstner waves ile displacement’a uğratmaktır
  • Gerstner waves sakin suyun düşük frekanslı ayrıntılarını modellemek için uygundur, ancak açık denizin dalgalı yüzeyini doğru ifade etmekte yetersiz kalır
  • Oşinografların topladığı ampirik verilere dayalı okyanus dalgası spektrumları kullanıldığında, belirli bir deniz durumu oluşturmak için hangi dalgaların ve parametrelerin değiştirileceği daha doğrudan ele alınabilir
  • FFT, klasik ayrık Fourier dönüşümünün O(N^2) karmaşıklığından daha düşük O(N log N) karmaşıklığa sahiptir; paralel sistemlere ölçeklenebildiği için GPU’da çalıştırmaya uygundur
  • Gerstner waves’te her thread’in N adet dalga için hesaplama yapması gerekirken, FFT tabanlı dalgalarda her thread yalnızca log(N) düzeyinde hesaplama yapar

Shading, foam ve sea spray

  • Okyanus aydınlatma modeli genel olarak Atlas GDC sunumundaki BSDF’yi izler
  • Mikrofacet dağılımı olarak Beckmann yerine GGX kullanılır
    • Çünkü GGX’in daha düz ve yumuşak highlight’ları, test edilen çeşitli okyanus dalgası ortamlarında daha tutarlı bir görünüm sağladı
  • Normal/foam map’ler, dünya uzayı piksel yoğunluğuna göre bicubic ve bilinear filtreleme karıştırılarak örneklenir
    • Düşük yüzey çözünürlüğünde texture aliasing artefaktlarını azaltır, yüksek yüzey çözünürlüğünde ise ayrıntıyı korur
  • Sea foam, Tessendorf yöntemine göre dalga tepelerinin içe kıvrıldığı yerlerde, yani displacement’ın Jacobian’ının negatif olduğu bölgelerde oluşturulup oluşturulmayacağına karar verir
    • Foam, birden fazla dalga güncellemesi boyunca texture içinde doğrusal olarak birikir
    • "foam grow rate" ve "foam decay rate" parametreleri sırasıyla birikimi ve üstel sönümlenmeyi kontrol eder
  • Sea spray, Godot’un GPUParticles3D node’u ve özel particle shader’ıyla uygulanır
    • Parçacıklar GPUParticles3D bounding box’ı içindeki bir düzleme eşit dağıtılır
    • İlgili konumdaki foam miktarına göre culling uygulanır; culling edilmeyen parçacıklar yaşam döngüsüne rastgele bir offset’ten başlar
    • Her parçacık, tek bir statik texture kullanan billboard sprite kullanır
    • Yaşam döngüsü boyunca scale ve displacement değiştirilerek splash görünümü simüle edilir; mesh shader’daki dissolve efektiyle havada su serpintisinin atomize olması hissi verilir
  • Bu sea spray yaklaşımının büyük dezavantajı, parçacık sayısı büyük ölçüde artırılsa bile yoğunluk artışının küçük olmasıdır
    • Çünkü parçacıklar bounding box’a eşit dağıtıldığından eklenen parçacıkların çoğu culling edilir

Dalga simülasyonu pipeline’ı

  • Yüzey dalgası üretim yöntemi Tessendorf’u yakından izler
  • Yönlü okyanus dalgası spektrum fonksiyonu, Gaussian dağılımlı rastgele sayılarla çarpılarak başlangıç spektrum deniz durumu oluşturulur
  • Başlangıç durumu, dalganın frekansı ile yayılma hızını ilişkilendiren dağılım ilişkisiyle zaman içinde yayılır
  • Yayılan duruma ters Fourier dönüşümü uygulanarak displacement map ve normal map oluşturulur
  • Uygulama, Godot’un RenderingDevice soyutlamasını kullanan bir compute shader pipeline olarak yapılandırılmıştır

Okyanus dalgası spektrumunun yapısı

  • Yönlü okyanus dalgası spektrum fonksiyonu S(ω, θ), frekans ω ve yön θ verildiğinde dalganın enerjisini döndürür
  • Bu fonksiyon, yönsüz spektrum fonksiyonu S(ω) ve yönlü yayılım fonksiyonu D(ω, θ) bileşenlerinden oluşur; iki seçim birbirinden bağımsızdır
  • Yönsüz spektrumda Horvath’ın açıkladığı Texel-Marsen-Arsloe(TMA) spektrumu kullanılır
    • TMA, rüzgâr hızı U, su derinliği D ve fetch length F kullanır
    • TMA, öncülü olan JONSWAP spektrumu ile su derinliği sönümleme fonksiyonunu birleştirir
  • Yönlü yayılım fonksiyonunda Horvath’ın flat ve Hasselmann yönlü yayılımlarını spread parametresi μ ile karıştıran yöntem kullanılır
    • Horvath’ın önerdiği swell parametresi ξ de okyanus dalgalarının elongation’ını modellemek için dahildir
    • Hasselmann yönlü yayılımı, normalizasyon katsayısı Q(σ) için yaklaşık analitik çözüm sunduğu için seçilmiştir
  • Tessendorf’un önerisine göre sonuç spektrum fonksiyonu küçük dalga bastırma terimiyle de çarpılır
    • Bu terim dalga sayısı vektörünün büyüklüğü k ve detail parametresi δ kullanır
  • Nihai yönlü okyanus dalgası spektrumu TMA, mixed directional spread ve small-wave suppression bileşenlerini birleştirir

GPU FFT uygulaması

  • FFT, compute shader ile yazılmış özel bir GPU uygulaması kullanır
  • Cooley-Tukey yerine, başlangıçtaki bit-reversal permutation’ı önlemek için Stockham FFT algoritması kullanılır
  • Flügge’yi izleyerek, FFT’nin veri akışını kodlayan "butterfly" texture’ı hesaplanır
    • Bu texture, spektrum texture çözünürlüğü her değiştiğinde bir kez hesaplanır
  • 2D FFT önce spektrum texture’ının satır yönünde FFT kernel’ini uygular
  • Ardından compute shader ile texture transpose edilir ve aynı satır yönlü FFT kernel’i sütun yönlü FFT gibi yeniden kullanılır
  • Transpose yalnızca pipeline’ın yeniden kullanımını mümkün kılmakla kalmaz, bellek erişim desenini de iyileştirir

Wave cascade ve tiling’e karşı önlemler

  • Uzak mesafelerde, özellikle sea foam olduğunda tiling artefaktları çok belirginleşir
  • Dalga üretim sistemi, bu sorunu ele almak için birden fazla wave cascade’in aynı anda katmanlanmasına izin verir
  • Her cascade’in kendi tiling boyutu ve parametre seti vardır
  • Cascade’ler gerçek zamanlı olarak dinamik biçimde eklenip çıkarılabilir
  • Tüm cascade’ler aynı compute pipeline’ını kullandığından aynı spektrum texture çözünürlüğüne sahip olmalıdır
  • Alternatif olarak, dalga displacement’ı ve normal’leri noise ile harmanlayarak daha düşük performans maliyetiyle tiling artefaktları azaltılabilir
  • Cascade’ler üst üste bindirilirken dalga girişimini önlemek için her cascade’in parametreleri ve boyutu dikkatle seçilmelidir
  • Cascade’lerin dalga phase’leri de birbirleriyle girişim yapmayacak şekilde offset edilmelidir
    • Sistem, her cascade’in başlangıç zamanını farklı offset’leyerek bunu otomatik olarak denemektedir
    • Bu yöntemin gerçekten işe yarayıp yaramadığına dair bir caveat bulunduğu belirtilir

Güncelleme yükünü dağıtma

  • Dalga hareketi düzensiz olduğu için displacement her frame güncellenmese bile algısal olarak akıcı görünebilir
  • "update rate" parametresi, wave cascade’in saniyede ne sıklıkla güncelleneceğini kontrol eder
  • Frame atlamak, FFT için kullanılan GPU süresini azaltır; ancak dalga üretim pipeline’ının çalıştığı frame’lerde yine de stutter oluşur
  • Godot’un yerel RenderingDevice’ı ile cascade güncellemelerini asenkron hesaplama olarak yürütme deneyi, CPU ile GPU arasındaki texture aktarımı nedeniyle büyük performans overhead’i oluşturmuştur
  • Bunun yerine sistem cascade’lerin yük dağıtımını dener
    • Frame süresi update rate’ten kısaysa frame başına yalnızca bir cascade güncellenir
    • Bu yöntem, stutter’ı azaltırken frame atlamayla elde edilen düşük GPU iş yükü avantajını korur

Yararlanılan kaynaklar

1 yorum

 
GN⁺ 2024-09-29
Hacker News yorumları
  • Bu kişinin yaptığı diğer iki Godot deposu da çok ilginç. Depoları açıklarken bol ayrıntı vermesini seviyorum; özellikle şu depo dikkat çekiyor: https://github.com/2Retr0/GodotGaussianSplatting
    Öğrenci mi merak ediyorum. Başka çalışmalara sık sık atıf yapıyor ve yakın zamanda yayımlanan materyalleri epey iyi anlamış görünüyor

    • Öğrenci olma ihtimali var gibi. Depolardan birinin başlığı ve açıklaması ENGR96A-coursework, Relevant coursework for ENGR 96A Introduction to Engineering Design F23; commit tarihlerine bakınca F23 muhtemelen 2023 güz dönemi demek
      Elbette depoda adı geçen UCLA dersleri herkese açık olabilir; bu yüzden geleneksel anlamda UCLA'ya kayıtlı bir öğrenci olmadan da alınabiliyor olabilir
  • 20 yıl önce render'da deniz yüzeyini aylarca ayarlasak bile bu seviyenin yakınına gelemezdik sanırım. Gerçekten çok iyi yapılmış bir sonuç
    Yine de demo videosu biraz abartılı görünüyor. Seyir kayıtlarında açık deniz seyri 50 bin deniz milini aşan biri olarak, bu kadar sivri ve yüksek dalgalar varsa rüzgârın çok daha sert esmesi gerekir. Yine de muhtemelen sadece parametre ayarıyla çözülecek bir kısım
    Godot ile yapıldıysa gerçek zamanlı render sayılır mı? Canavar gibi bir GPU gerektirip gerektirmediğini de merak ediyorum

    • Eleştiri değil, gözlem: maviye boyanmış sıcak mısır şurubundan bir deniz hayal etsem herhalde böyle görünürdü. Viskozite doğru gibi, ama yüzey gerilimi gerçek deniz suyundan farklı olabilir. Gerçek deniz suyu, tuzlu H2O ile biyolojik maddelerin kolloididir; gerçek dünyada yaygın, ama hesaplamalı akışkanlar dinamiği için epey dağınık bir nesne
      Ayrıca burada deniz serpintisi sonradan eklenmiş bir efekt gibi görünüyor; gerçek denizde ise serpinti dalgaların keskinliğini köreltir ve bu görsel olarak da belli belirsiz fark edilir
      Elbette bu zarif, basit ve etkili modelde neredeyse hiç fizik yok; o yüzden bunları kolları kavuşturup eleştirmekten çok, kurcalayıp denenebilecek yönler önermek olarak görün
    • Bugünlerde bu konuyu ele alan çok video var, bu yüzden tüm süreç bir ölçüde erişilebilir hâle geldi; ama hâlâ çok tuzak var
      Bu konuda sevdiğim videolardan biri: https://m.youtube.com/watch?v=yPfagLeUa7k
      Bu da fena değil: https://m.youtube.com/watch?v=kGEqaX4Y4bQ
    • Bir oyun projem var; havalı oyun teknolojileri görünce hep nerd-sniping'e uğrayıp kendim uygulamak istiyorum. Mevcut asset'leri kullansaydım ya da satın alsaydım, şimdiye kadar yaptığım ilerleme 48 saatlik bir game jam'de bile mümkün olurdu sanırım
      Onun yerine her hafta sonu su shader'ıyla oynayıp istediğim görüntüyü elde etmeye çalışıyorum. Ama oyunum bir bulmaca oyunu, suya ihtiyacı yok. Şimdi sadece havalı bir başlangıç ekranım var
    • Ben mezun olurken parçacık motoru, marching cubes gibi şeyler bitirme tezi projesiydi
      Bugünlerde oyun motorunda tek bir checkbox'tan ibaret ve buna benzer sayısız özellik var. Modern motorlar sayesinde ortamın ne kadar iyi olduğunu insanlar pek hayal edemiyor
      Bu çalışmanın değerini düşürmek istemiyorum; gerçekten harika bir başarı ve yapana şapka çıkarıyorum. Sadece şu anda ne kadar iyi bir dönemde olduğumuzu söylemek istedim
    • Sadece videoya bakınca biraz rastgele göründüğüne katılıyorum
      Yine de çok iyi görünüyor ve yakın zamanda üstünkörü baktıklarım arasında muhtemelen mümkün olanların en üst seviyesinde
      Kişisel olarak açık deniz dalgalarının genelde daha ritimli görünmesini isterdim. 15 knot rüzgârın 1 km'lik su yüzeyi üzerinde birkaç saat estiği bir simülasyonun gerçekten gözlenen şeye, yani nispeten düzenli kırılmaların oluşup dağıldığı görünüme uyup uymadığını merak ediyorum
  • Beni bilgisayar dünyasına çeken şeyler bunlardı; ama bir bakmışım kütüphaneleri, endpoint'leri ve kurumsal saçmalıkları birbirine bağlayan kolay ve sıkıcı bir hayata saplanmışım, bu da tükenmişliğe gidiyor
    Bir gün geri dönebilmeyi umuyorum

    • Bence adım adım geçebilirsin. Başta ilgini çeken, daha çok öğrenmek ve sonunda yapmak istediğin bir alan bulup her hafta birkaç saat derinleşerek, sonra bunu yavaş yavaş artırıp mevcut işinden uzaklaşabilirsin
      Denemeni isterim. Hepimiz destekliyoruz
    • Bu işleri yapıp benden daha çok para kazanan çok arkadaş görüyorum; ama ben ilgi alanımın peşinden gidip ilk fırsatta robotik alanına geçtim ve pişman değilim. En azından benim için, kodumun gerçek dünyayla etkileşime girdiğini görmek gibisi yok
  • Yaklaşımı farklı olsa da dalga/okyanus simülasyonu ile ilgileniyorsanız Acerola bu konuda her zamanki gibi harika bir video yayımladı. https://youtu.be/PH9q0HNBjT4 ve https://youtu.be/yPfagLeUa7k
    Düzenleme: Bunlardan biri kaynakçada zaten linklenmişti; kullanıcı adıyla değil gerçek adıyla yer aldığı için ancak şimdi fark ettim

  • Bu problemin ne kadar zor olduğu ilginç. On yıllardır deneniyor ama hâlâ tekinsiz vadide kalıyor
    Bu sahneyi durdurduğunuzda yükselen dalgalar karla kaplı dağlara benziyor. Suyun böyle keskin şekiller alması için rüzgârın epey güçlü olması gerekir; rüzgârın da doğrudan yukarı esmesi mümkün olmadığından gerçek dışı geliyor. Böyle keskin özelliklerin bir yönlülüğü olmalı
    Yine de solugan dalgaların karakterini epey iyi yakalamış. Yatay hareketten çok yukarı-aşağı hareket daha büyük; açık denizde beklenebilecek görünüm de bu

    • Nightingale oynadım; oradaki deniz suyu gerçekten özel. Açıkçası dalgaları sakin tutarak serpinti gibi sorunlarla uğraşmamışlar, bunun yerine başka kısımlara odaklanabilmişler gibi
      Işık geçirgenliğini nasıl simüle ettiklerini bilmiyorum ama iyi çalışıyor. Gün doğumu ya da gün batımında dalgaların arasından süzülen ışık harika ve efekti gerçekten inandırıcı kılıyor
      Biraz resimsel denebilir, ama yanlış görünmüyor
  • Yıllarca sahilde yaşadım. Sahilde yaşayınca deniz büyüleyici ve duyusal olarak hoş olduğu için saatlerce bakıyorsunuz. Bunu görsem bir an bile render olduğunu düşünmezdim

    • Şu anda sahilde yaşıyorum ve su seviyesinden yaklaşık 14 kat yüksekte bir manzaram da var; garip bir şekilde bunun sahte olduğu açıkça belli oluyor. Rüzgâr hamlelerinin oluşturduğu koyu lekeler yok ve beyaz kısımlar birazcık bile kıvrılıp içeri girmeden dümdüz yukarı çıkıyor. Onun dışında oldukça gerçekçi
    • Gerçekten dalgaları ve hareketlerini hiç gördün mü? Yıllarca sahilde yaşadıysan köpük oluşumunun ve dalga hareketinin doğal olmadığını hemen fark edebilmen gerekir
  • Shadertoy'da da iyi bir örnek var: https://www.shadertoy.com/view/Ms2SD1

  • Fourier gelgit dalgalarını ölçerken dalga frekansı dönüşümünü düşündüğüne göre, bir anlamda neredeyse başa dönmüş sayılırız
    Çok etkileyici

  • Harika, ama bu yaklaşım gerçekten büyük dalgalarda doğrusal olmama nedeniyle bir noktada bozulacaktır. Su dalgaları sinüs dalgası değildir; ama küçük ve orta yükseklikteki dalgalarda yeterince benzer oldukları için bu yöntem çok iyi çalışır
    Çok büyük dalgalar sinüs dalgasından çok daha fazla uzaklaşmakla kalmaz, dalgalar birbirleriyle doğrusal olmayan biçimde etkileşmeye başlar; burada kullanılan doğrusal süperpozisyon yöntemi bunu yakalayamaz
    Bu yüzden çoğu deniz durumu için şahane. Ama “Kusursuz Fırtına” türü dalgaları gerçekçi yapmak istiyorsanız başka bir yaklaşım gerekir

  • Çok etkileyici ve şimdiye kadar gördüklerimden iyi, ama solugan biraz yanlış hissettiriyor. Açıklamaya çalışırsam, yüksek frekanslı dalgaların videodaki gibi düşük frekanslı dalgaların üzerinde ilerlediğini sanmıyorum