1 poin oleh GN⁺ 2024-09-29 | 1 komentar | Bagikan ke WhatsApp
  • GodotOceanWaves adalah eksperimen rendering di Godot Engine yang menghasilkan permukaan laut terbuka menggunakan transformasi Fourier invers dari spektrum gelombang laut berarah, serta mensimulasikan berbagai lingkungan laut lewat parameter yang dapat disesuaikan secara real-time melalui skrip
  • Gerstner waves cocok untuk detail frekuensi rendah pada air tenang, tetapi memiliki keterbatasan untuk permukaan laut terbuka yang kasar, sehingga proyek ini menggunakan spektrum berbasis data oseanografi empiris dan FFT
  • Pembuatan gelombang mengikuti metode Tessendorf: membuat kondisi spektrum awal, mempropagasikannya seiring waktu dengan relasi dispersi, lalu menghasilkan peta displacement, normal, dan foam melalui transformasi Fourier invers
  • Rendering mengikuti BSDF dari presentasi Atlas GDC, tetapi menggunakan distribusi GGX; foam diakumulasi dan diredam pada area tempat Jacobian displacement bernilai negatif, sementara sea spray diimplementasikan dengan GPUParticles3D Godot dan shader kustom
  • Multi wave cascade, pengaturan siklus pembaruan, dan pembagian beban per cascade menangani tiling serta beban kerja GPU, tetapi cascade harus memakai resolusi tekstur spektrum yang sama dan pendekatan partikel sea spray kurang efisien untuk meningkatkan kepadatan

Apa yang dilakukan GodotOceanWaves

  • GodotOceanWaves adalah proyek untuk bereksperimen dengan rendering laut terbuka di Godot Engine
  • Pembuatan gelombang menggunakan transformasi Fourier invers dari spektrum gelombang laut berarah
  • Parameter yang diekspos disusun secara ringkas, dan dapat diubah secara real-time melalui skrip untuk mensimulasikan berbagai lingkungan gelombang laut
  • Video demo ocean_demo.mp4 dan environment_demo.mp4 disertakan

Mengapa memakai gelombang berbasis Fourier alih-alih Gerstner waves

  • Cara umum menganimasikan air di game adalah menggeser vertex dengan Gerstner waves
  • Gerstner waves cocok untuk memodelkan detail frekuensi rendah pada air tenang, tetapi kurang memadai untuk merepresentasikan permukaan kasar laut terbuka secara akurat
  • Dengan menggunakan spektrum gelombang laut berbasis data empiris yang dikumpulkan oseanografer, pengembang dapat menangani secara lebih langsung gelombang dan parameter apa yang perlu diubah untuk membuat kondisi laut tertentu
  • FFT memiliki kompleksitas O(N log N), lebih rendah daripada transformasi Fourier diskret klasik yang O(N^2), dan dapat diskalakan ke sistem paralel sehingga cocok dijalankan di GPU
  • Pada Gerstner waves, setiap thread harus menghitung untuk N gelombang, sedangkan pada gelombang berbasis FFT setiap thread hanya melakukan komputasi setara log(N)

Shading, foam, dan sea spray

  • Model pencahayaan laut secara umum mengikuti BSDF dari presentasi Atlas GDC
  • Distribusi microfacet menggunakan GGX, bukan Beckmann
    • Alasannya, highlight GGX yang lebih datar dan halus memberikan tampilan yang lebih konsisten di berbagai lingkungan gelombang laut yang diuji
  • Peta normal/foam disampling dengan campuran filtering bicubic dan bilinear sesuai kepadatan piksel di ruang dunia
    • Pada resolusi permukaan rendah, ini mengurangi artefak texture aliasing; pada resolusi permukaan tinggi, detail tetap dipertahankan
  • Sea foam menentukan apakah foam dibuat mengikuti metode Tessendorf, yaitu pada lokasi puncak gelombang menggulung ke dalam, atau saat Jacobian displacement bernilai negatif
    • Foam diakumulasikan secara linear ke tekstur selama beberapa pembaruan gelombang
    • Parameter "foam grow rate" dan "foam decay rate" masing-masing mengendalikan akumulasi dan peluruhan eksponensial
  • Sea spray diimplementasikan dengan node GPUParticles3D Godot dan shader partikel kustom
    • Partikel didistribusikan merata pada bidang di dalam bounding box GPUParticles3D
    • Partikel di-culling berdasarkan jumlah foam di lokasi tersebut, dan partikel yang tidak di-culling memulai siklus hidupnya dari offset acak
    • Setiap partikel menggunakan billboard sprite dengan satu tekstur statis
    • Selama siklus hidupnya, scale dan displacement diubah untuk meniru tampilan splash, sementara efek dissolve pada mesh shader memberi kesan percikan air teratomisasi di udara
  • Kelemahan besar pendekatan sea spray ini adalah peningkatan jumlah partikel yang besar hanya menghasilkan kenaikan kepadatan yang kecil
    • Sebab partikel didistribusikan merata di bounding box, sehingga sebagian besar partikel tambahan akan di-culling

Pipeline simulasi gelombang

  • Metode pembuatan gelombang permukaan mengikuti Tessendorf secara erat
  • Kondisi laut spektrum awal dibuat dengan mengalikan fungsi spektrum gelombang laut berarah dengan bilangan acak berdistribusi Gaussian
  • Kondisi awal dipropagasikan seiring waktu menggunakan relasi dispersi yang menghubungkan frekuensi gelombang dan kecepatan propagasinya
  • Transformasi Fourier invers diterapkan pada kondisi yang telah dipropagasikan untuk menghasilkan peta displacement dan peta normal
  • Implementasinya disusun sebagai compute shader pipeline yang menggunakan abstraksi RenderingDevice milik Godot

Komposisi spektrum gelombang laut

  • Fungsi spektrum gelombang laut berarah S(ω, θ) mengembalikan energi gelombang untuk frekuensi ω dan arah θ tertentu
  • Fungsi ini terdiri dari fungsi spektrum non-arah S(ω) dan fungsi directional spreading D(ω, θ), dan kedua pilihannya saling independen
  • Untuk spektrum non-arah digunakan spektrum Texel-Marsen-Arsloe(TMA) yang dijelaskan Horvath
    • TMA menggunakan kecepatan angin U, kedalaman air D, dan fetch length F
    • TMA menggabungkan spektrum JONSWAP pendahulunya dengan fungsi atenuasi kedalaman air
  • Untuk fungsi directional spreading digunakan metode yang mencampur directional spreading flat dan Hasselmann dari Horvath dengan parameter spread μ
    • Parameter swell ξ yang diusulkan Horvath juga disertakan untuk memodelkan elongation gelombang laut
    • Directional spreading Hasselmann dipilih karena menyediakan solusi analitik hampiran untuk koefisien normalisasi Q(σ)
  • Sesuai usulan Tessendorf, fungsi spektrum hasil juga dikalikan dengan suku penekan gelombang kecil
    • Suku ini menggunakan magnitudo vektor bilangan gelombang k dan parameter detail δ
  • Spektrum gelombang laut berarah akhir menggabungkan TMA, mixed directional spread, dan small-wave suppression

Implementasi GPU FFT

  • FFT menggunakan implementasi GPU kustom yang ditulis sebagai compute shader
  • Alih-alih Cooley-Tukey, digunakan algoritma Stockham FFT untuk menghindari initial bit-reversal permutation
  • Mengikuti Flügge, tekstur "butterfly" yang mengenkode aliran data FFT dihitung
    • Tekstur ini dihitung satu kali setiap resolusi tekstur spektrum berubah
  • FFT 2D pertama-tama menerapkan kernel FFT ke arah baris pada tekstur spektrum
  • Setelah itu, tekstur di-transpose dengan compute shader agar kernel FFT arah baris yang sama dapat digunakan kembali seperti FFT arah kolom
  • Transpose tidak hanya memungkinkan reuse pipeline, tetapi juga memperbaiki pola akses memori

Wave cascade dan penanganan tiling

  • Pada jarak jauh, terutama saat ada sea foam, artefak tiling menjadi sangat jelas
  • Sistem pembuatan gelombang menangani masalah ini dengan memungkinkan beberapa wave cascade di-layer secara bersamaan
  • Setiap cascade memiliki ukuran tiling dan set parameternya sendiri
  • Cascade dapat ditambahkan dan dihapus secara dinamis saat runtime
  • Karena semua cascade menggunakan compute pipeline yang sama, semuanya harus memiliki resolusi tekstur spektrum yang sama
  • Sebagai alternatif, displacement dan normal gelombang juga dapat dibaurkan dengan noise untuk mengurangi artefak tiling dengan biaya performa lebih rendah
  • Saat menumpuk cascade, parameter dan ukuran setiap cascade harus dipilih dengan hati-hati agar interferensi antar-gelombang dihindari
  • Phase gelombang tiap cascade juga harus diberi offset agar tidak saling menginterferensi
    • Sistem secara otomatis mencoba melakukannya dengan memberi offset berbeda pada waktu mulai tiap cascade
    • Terdapat caveat bahwa belum pasti apakah pendekatan ini benar-benar bekerja

Pembagian beban pembaruan

  • Karena gerakan gelombang tidak beraturan, displacement tidak harus diperbarui setiap frame agar tetap terlihat halus secara perseptual
  • Parameter "update rate" mengendalikan seberapa sering wave cascade diperbarui per detik
  • Melewati frame mengurangi waktu GPU yang dipakai FFT, tetapi stutter tetap terjadi pada frame ketika pipeline pembuatan gelombang dijalankan
  • Eksperimen melakukan komputasi pembaruan cascade secara asinkron dengan local RenderingDevice milik Godot menghasilkan overhead performa besar akibat transfer tekstur antara CPU dan GPU
  • Sebagai gantinya, sistem mencoba pembagian beban cascade
    • Jika waktu frame lebih pendek daripada update rate, hanya satu cascade diperbarui per frame
    • Cara ini mengurangi stutter sambil mempertahankan manfaat beban kerja GPU yang lebih rendah dari frame skipping

Referensi yang digunakan

1 komentar

 
GN⁺ 2024-09-29
Komentar Hacker News
  • Dua repositori Godot lain yang dibuat orang ini juga sangat menarik. Saya suka karena dia memasukkan banyak detail saat menjelaskan repositorinya, dan yang ini khususnya menonjol: https://github.com/2Retr0/GodotGaussianSplatting
    Penasaran apakah dia seorang mahasiswa. Dia sering mengutip karya lain, dan tampaknya memahami materi yang baru dipublikasikan dengan cukup baik

    • Sepertinya memang mungkin mahasiswa. Judul dan deskripsi salah satu repositorinya adalah ENGR96A-coursework, Relevant coursework for ENGR 96A Introduction to Engineering Design F23, dan dari tanggal commit, F23 tampaknya berarti semester gugur 2023
      Tentu saja, kelas UCLA yang disebut di repositori itu mungkin terbuka untuk umum, jadi belum tentu harus mahasiswa UCLA yang terdaftar dalam arti tradisional untuk bisa mengikutinya
  • Dua puluh tahun lalu, rasanya bahkan setelah menyetel permukaan laut selama berbulan-bulan dalam rendering, hasilnya tetap tidak akan mendekati level ini. Hasilnya benar-benar sangat bagus
    Meski begitu, video demonya terasa sedikit berlebihan. Dari sudut pandang seseorang yang punya lebih dari 50 ribu mil laut pelayaran lepas pantai di catatan pelayaran, ombak setinggi dan setajam itu harusnya membutuhkan angin yang jauh lebih kencang. Tapi sepertinya ini hal yang bisa disesuaikan hanya dengan mengubah parameternya
    Karena ini dibuat di Godot, apakah aman menganggapnya sebagai rendering real-time? Saya juga penasaran apakah butuh GPU monster

    • Ini bukan kritik, cuma pengamatan, tapi kalau membayangkan lautan sirup jagung panas yang diwarnai biru, rasanya akan terlihat seperti ini. Viskositasnya terasa pas, tapi tegangan permukaannya mungkin berbeda dari air laut sungguhan. Air laut nyata adalah H2O air asin dengan koloid bahan biologis, jadi sesuatu yang umum di dunia nyata tetapi cukup berantakan dalam komputasi fluida
      Selain itu, percikan laut di sini tampak seperti efek pascaproses, padahal di laut nyata percikan akan menumpulkan ketajaman ombak dan juga membuatnya tampak lebih samar secara visual
      Tentu saja, model yang elegan, sederhana, dan efektif ini hampir tidak memiliki fisika, jadi anggap saja ini bukan kritik sok tahu, melainkan usulan arah untuk dicoba dan diutak-atik
    • Sekarang sudah ada banyak video yang membahas hal seperti ini, jadi keseluruhan prosesnya sampai taraf tertentu jadi lebih mudah diakses, tapi jebakannya masih banyak
      Salah satu video favorit saya tentang topik ini: https://m.youtube.com/watch?v=yPfagLeUa7k
      Yang ini juga bagus: https://m.youtube.com/watch?v=kGEqaX4Y4bQ
    • Saya punya proyek game, dan setiap kali melihat teknologi game yang keren saya selalu kena nerd sniping dan ingin mengimplementasikannya sendiri. Kalau saya memakai atau membeli aset yang sudah ada, progres yang saya punya sekarang mungkin bahkan bisa dicapai dalam game jam 48 jam
      Sebagai gantinya, saya malah menghabiskan akhir pekan mengutak-atik shader air sampai tampilannya sesuai keinginan. Padahal game saya game puzzle dan tidak butuh air. Sekarang saya cuma punya layar pembuka yang keren
    • Saat saya lulus, hal-hal seperti particle engine atau marching cubes itu adalah proyek tesis kelulusan
      Sekarang cuma jadi satu checkbox di game engine, dan ada tak terhitung banyaknya fitur seperti itu. Sulit membayangkan betapa bagusnya lingkungan yang disediakan engine modern sekarang
      Bukan untuk mengurangi nilai karya ini, ini benar-benar pencapaian yang luar biasa dan pembuatnya layak dipuji. Saya cuma ingin mengatakan betapa beruntungnya zaman kita sekarang
    • Saya setuju kalau dari videonya saja ini terlihat agak acak
      Meski begitu, tampilannya sangat bagus, dan dari pencarian singkat saya belakangan ini, mungkin ini yang terbaik di antara yang memungkinkan saat ini
      Secara pribadi saya ingin melihat ombak lepas pantai punya lebih banyak ritme. Saya penasaran apakah simulasi angin 15 knot yang bertiup selama beberapa jam di atas permukaan air sejauh 1 km akan cocok dengan apa yang benar-benar diamati, yaitu pecah gelombang yang relatif teratur terbentuk lalu menyebar
  • Hal-hal seperti inilah yang dulu menarik saya ke dunia komputer, tapi entah bagaimana saya malah terjebak dalam hidup yang mudah namun membosankan, merangkai library, endpoint, dan omong kosong korporat, yang berujung pada burnout
    Semoga suatu hari saya bisa kembali ke sana

    • Menurut saya, cukup pindah sedikit demi sedikit. Cari bidang yang awalnya membuatmu tertarik, yang ingin kamu pelajari lebih jauh dan akhirnya ingin kamu kerjakan, lalu dalami beberapa jam setiap minggu, tingkatkan secara bertahap, dan perlahan menjauh dari pekerjaanmu sekarang
      Semoga berhasil. Semua orang mendukungmu
    • Saya punya banyak teman yang menghasilkan lebih banyak uang daripada saya dengan pekerjaan seperti itu, tapi saya mengikuti minat saya dan masuk ke robotika pada kesempatan pertama, dan saya tidak menyesal. Setidaknya bagi saya, tidak ada yang menandingi perasaan melihat kode saya berinteraksi dengan dunia nyata
  • Pendekatannya berbeda, tapi kalau tertarik pada simulasi ombak/lautan, Acerola mengunggah video yang seperti biasa sangat bagus tentang topik ini. https://youtu.be/PH9q0HNBjT4 dan https://youtu.be/yPfagLeUa7k
    Sunting: salah satunya ternyata sudah ditautkan di referensi, tapi karena ditulis dengan nama asli, bukan nama panggilan, saya baru sadar sekarang

  • Menarik betapa sulitnya masalah ini. Sudah dicoba selama puluhan tahun, tapi masih berada di uncanny valley
    Kalau adegan ini dijeda, ombak yang menjulang tampak seperti gunung bersalju. Agar air memiliki bentuk setajam itu, anginnya harus cukup kuat, tetapi angin tidak akan bertiup lurus ke atas, jadi terasa tidak realistis. Ciri-ciri tajam seperti ini seharusnya punya arah
    Meski begitu, sifat ombak swell-nya tertangkap cukup baik. Gerakan naik-turunnya lebih besar daripada perpindahan horizontalnya, yang memang sesuai dengan yang diharapkan di laut lepas

    • Saya pernah memainkan Nightingale, dan air laut di sana benar-benar istimewa. Sejujurnya, sepertinya mereka menjaga ombaknya tetap tenang sehingga tidak perlu menangani masalah seperti percikan, dan sebagai gantinya bisa fokus pada bagian lain
      Saya tidak tahu bagaimana mereka mensimulasikan transmisi cahaya, tapi itu bekerja dengan baik. Cahaya yang menembus di antara ombak saat matahari terbit atau terbenam sangat bagus, dan benar-benar membuat efeknya terasa meyakinkan
      Bisa dibilang agak painterly, tapi tidak terasa salah
  • Saya tinggal di pantai selama beberapa tahun. Kalau tinggal di pantai, laut itu begitu memikat dan menyenangkan secara inderawi sampai-sampai bisa ditatap berjam-jam. Melihat ini, saya rasa saya tidak akan pernah mengira ini rendering

    • Saya tinggal di pantai sekarang dan punya pemandangan dari sekitar lantai 14 di atas permukaan air, dan anehnya justru sangat jelas bahwa ini palsu. Tidak ada bercak gelap akibat hembusan angin, dan bagian putihnya tidak sedikit pun melipat ke dalam, melainkan langsung naik ke atas. Selain itu, cukup mirip dengan aslinya
    • Apakah kamu benar-benar pernah melihat ombak dan gerakannya? Kalau pernah tinggal di pantai selama beberapa tahun, kamu pasti langsung sadar bahwa pembentukan buih dan gerakan ombaknya tidak terlihat alami
  • Ada juga contoh yang lumayan bagus di Shadertoy: https://www.shadertoy.com/view/Ms2SD1

  • Fourier mendapat ide transformasi frekuensi gelombang saat mengukur gelombang pasang, jadi dalam arti tertentu ini seperti hampir kembali ke titik awal
    Sangat mengesankan

  • Sangat bagus, tetapi pendekatan ini kemungkinan akan agak runtuh pada ombak yang benar-benar besar karena nonlinearitas. Riak bukan gelombang sinus, tetapi untuk ombak kecil dan sedang bentuknya cukup mirip sehingga metode seperti ini bekerja sangat baik
    Ombak yang sangat besar bukan hanya jauh lebih berbeda dari gelombang sinus, tapi juga mulai saling berinteraksi secara nonlinier, sehingga tidak bisa ditangkap dengan pendekatan superposisi linear yang dipakai di sini
    Jadi untuk sebagian besar kondisi laut, ini fantastis. Tapi kalau ingin membuat ombak seperti di ‘The Perfect Storm’ secara realistis, dibutuhkan pendekatan lain

  • Sangat mengesankan dan lebih baik dari yang pernah saya lihat sejauh ini, tetapi swell-nya terasa sedikit meleset. Kalau harus menjelaskan, saya rasa ombak berfrekuensi tinggi tidak bergerak menumpang di atas ombak berfrekuensi rendah seperti yang terlihat di video