Kết xuất sóng biển dựa trên FFT được triển khai trong Godot
(github.com/2Retr0)GodotOceanWaves
Đây là một thử nghiệm kết xuất biển khơi bằng Godot Engine, tạo sóng bằng cách dùng biến đổi Fourier ngược của phổ sóng biển có hướng. Dự án cung cấp các tham số đơn giản có thể chỉnh bằng script theo thời gian thực để mô phỏng nhiều môi trường sóng biển khác nhau.
Giới thiệu
Vì sao lại là biến đổi Fourier?
- Cách phổ biến để tạo hoạt ảnh nước trong game là dùng Gerstner waves. Tuy nhiên, cách này phù hợp để mô hình hóa các chi tiết tần số thấp của mặt nước yên ả, nhưng chưa đủ để biểu diễn chính xác bề mặt gồ ghề của biển khơi.
- Để giải quyết điều này, dự án mô phỏng sóng bằng biến đổi Fourier ngược của phổ sóng biển dựa trên dữ liệu thực nghiệm do các nhà hải dương học thu thập.
- Lợi thế của việc làm việc trong không gian tần số là có thể dễ dàng chỉnh sửa các thuộc tính của biển. Khi dùng Gerstner waves, không rõ cần thay đổi sóng và các tham số của chúng như thế nào để mô phỏng một trạng thái biển cụ thể.
- Để tính biến đổi Fourier, dự án dùng thuật toán biến đổi Fourier nhanh (FFT). Thuật toán này có độ phức tạp tính toán thấp hơn thuật toán biến đổi Fourier rời rạc cổ điển và phù hợp để chạy trên GPU.
Kết quả
Đổ bóng sóng
Mô hình chiếu sáng
- Mô hình chiếu sáng của biển chủ yếu theo BSDF được mô tả trong bài nói chuyện GDC của 'Atlas'. Tuy nhiên, dự án dùng phân bố GGX thay cho phân bố Beckmann cho phân bố vi bề mặt.
- Các bản đồ normal/foam được lấy mẫu bằng cách trộn lọc bicubic và bilinear theo mật độ pixel trong không gian thế giới.
Bọt biển
- Tessendorf đề xuất tạo bọt khi đỉnh sóng cuộn ngược vào chính nó.
- Bọt được tích lũy tuyến tính và tiêu biến theo hàm mũ, được điều khiển bằng các tham số "tốc độ tăng trưởng bọt" và "tốc độ tiêu biến bọt".
Tia nước biển
- Tia nước biển được mô hình hóa bằng hạt sử dụng node GPUParticles3D của Godot.
- Các hạt được phân bố đồng đều bên trong hộp giới hạn của node GPUParticles3D.
- Mỗi hạt tia nước biển dùng billboard sprite với một texture tĩnh duy nhất.
Mô phỏng sóng
- Phương pháp tạo sóng bề mặt tuân theo Tessendorf.
- Hàm phổ sóng biển có hướng trả về năng lượng của sóng theo tần số và hướng.
Phổ sóng biển
- Chọn phổ Texel-Marsen-Arsloe (TMA) làm hàm phổ không hướng.
- Dùng hỗn hợp giữa hàm lan truyền flat và Hasselmann làm hàm khuếch tán có hướng.
Biến đổi Fourier nhanh
- Dự án tự viết một triển khai FFT tùy chỉnh cho GPU.
- Sử dụng thuật toán FFT Stockham để tránh hoán vị đảo bit ban đầu.
Cascade sóng
- Ở khoảng cách xa, các lỗi tạo lát lặp lại trở nên rất rõ ràng.
- Hệ thống tạo sóng có thể xếp chồng nhiều cascade sóng cùng lúc.
Cân bằng tải
- Chuyển động của sóng vẫn có thể trông mượt mà ngay cả khi không cập nhật độ dịch chuyển ở mỗi khung hình.
- Dự án đưa vào tham số "tốc độ cập nhật" để điều khiển tần suất cập nhật các cascade sóng mỗi giây.
Tài liệu tham khảo
- Flügge, Fynn-Jorin. Realtime GPGPU FFT Ocean Water Simulation. Hamburg University of Technology. (2017).
- Gunnell, Garrett. I Tried Simulating The Entire Ocean. (2023).
- Horvath, Christopher J. Empirical Directional Wave Spectra for Computer Graphics. DigiPro. (2015).
- Tessendorf, Jerry. Simulating Ocean Water. SIGGRAPH. (2004).
- Matusiak, Robert. Implementing Fast Fourier Transform Algorithms of Real-Valued Sequences. Texas Instruments. (2001).
- Mihelich, Mark. Wakes, Explosions and Lighting: Interactive Water Simulation in 'Atlas'. GDC. (2019).
- Pensionerov, Ivan. FFT-Ocean. GitHub. (2020).
Ghi công bản quyền
- Evening Road 01 (Pure Sky) by Jarod Guest is used under the CC0 1.0 license.
- OTFFT DIT Stockham Algorithm by Takuya Okahisa is used and modified under the MIT license.
Tóm tắt của GN⁺
- GodotOceanWaves là một thử nghiệm kết xuất biển khơi bằng Godot Engine, tạo sóng bằng cách dùng biến đổi Fourier ngược của phổ sóng biển có hướng.
- Dự án dùng biến đổi Fourier nhanh (FFT) để chạy hiệu quả trên GPU và có thể mô phỏng nhiều môi trường sóng biển khác nhau.
- Dự án bao gồm nhiều yếu tố như đổ bóng sóng, bọt biển, tia nước biển và mô phỏng sóng để tái hiện bề mặt biển chân thực.
- Dự án này có thể hữu ích để triển khai kết xuất biển chân thực trong game và các mô phỏng.
1 bình luận
Ý kiến Hacker News
Hai kho lưu trữ Godot khác của người này cũng rất thú vị
20 năm trước, dù có bỏ ra vài tháng để kết xuất bề mặt biển cũng không thể đạt đến mức này
Đoạn clip demo có cảm giác hơi cường điệu
Có vẻ như việc kết xuất trong Godot diễn ra theo thời gian thực
Những thứ như thế này từng khiến tôi quan tâm đến máy tính, nhưng rồi dần mệt mỏi vì thư viện, endpoint và công việc ở công ty
Nếu bạn quan tâm đến mô phỏng sóng/biển, Acerola đã đăng một video rất hay về chủ đề này
Thật thú vị khi vấn đề này khó đến mức nào
Tôi đã sống vài năm ở bãi biển
Cách tiếp cận này có một chút giới hạn với sóng rất lớn
Shadertoy cũng có một ví dụ hay
Fourier đã đo sóng thủy triều khi nghĩ ra phép biến đổi tần số cho sóng
Rất ấn tượng, nhưng có một chút vấn đề với độ mềm mại của sóng