- 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.mp4danenvironment_demo.mp4disertakan
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 yangO(N^2), dan dapat diskalakan ke sistem paralel sehingga cocok dijalankan di GPU - Pada Gerstner waves, setiap thread harus menghitung untuk
Ngelombang, sedangkan pada gelombang berbasis FFT setiap thread hanya melakukan komputasi setaralog(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
GPUParticles3DGodot 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
- Partikel didistribusikan merata pada bidang di dalam bounding box
- 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
RenderingDevicemilik 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 spreadingD(ω, θ), dan kedua pilihannya saling independen - Untuk spektrum non-arah digunakan spektrum Texel-Marsen-Arsloe(TMA) yang dijelaskan Horvath
- TMA menggunakan kecepatan angin
U, kedalaman airD, dan fetch lengthF - TMA menggabungkan spektrum JONSWAP pendahulunya dengan fungsi atenuasi kedalaman air
- TMA menggunakan kecepatan angin
- 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(σ)
- Parameter
- Sesuai usulan Tessendorf, fungsi spektrum hasil juga dikalikan dengan suku penekan gelombang kecil
- Suku ini menggunakan magnitudo vektor bilangan gelombang
kdan parameterdetailδ
- Suku ini menggunakan magnitudo vektor bilangan gelombang
- 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
RenderingDevicemilik 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
- Realtime GPGPU FFT Ocean Water Simulation: Fynn-Jorin Flügge, Hamburg University of Technology, 2017
- I Tried Simulating The Entire Ocean: Garrett Gunnell, 2023
- Empirical Directional Wave Spectra for Computer Graphics: Christopher J. Horvath, DigiPro, 2015
- Simulating Ocean Water: Jerry Tessendorf, SIGGRAPH, 2004
- Implementing Fast Fourier Transform Algorithms of Real-Valued Sequences: Robert Matusiak, Texas Instruments, 2001
- Wakes, Explosions and Lighting: Interactive Water Simulation in 'Atlas': Mark Mihelich, GDC, 2019
- FFT-Ocean: Ivan Pensionerov, GitHub, 2020
1 komentar
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
ENGR96A-coursework,Relevant coursework for ENGR 96A Introduction to Engineering Design F23, dan dari tanggal commit, F23 tampaknya berarti semester gugur 2023Tentu 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
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
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
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
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
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
Semoga berhasil. Semua orang mendukungmu
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 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
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