1 คะแนน โดย GN⁺ 2024-09-29 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

GodotOceanWaves

เป็นการทดลองเรนเดอร์ทะเลเปิดด้วย Godot Engine โดยสร้างคลื่นจากการแปลงฟูริเยร์ผกผันของสเปกตรัมคลื่นทะเลแบบมีทิศทาง มีพารามิเตอร์แบบเรียบง่ายที่สามารถปรับคุณสมบัติของคลื่นได้แบบเรียลไทม์ผ่านสคริปต์ เพื่อจำลองสภาพแวดล้อมคลื่นทะเลได้หลากหลายรูปแบบ

บทนำ

ทำไมต้องใช้การแปลงฟูริเยร์?
  • วิธีทั่วไปในการทำแอนิเมชันน้ำในวิดีโอเกมคือการใช้ Gerstner waves อย่างไรก็ตาม วิธีนี้เหมาะกับการจำลองรายละเอียดความถี่ต่ำของผิวน้ำที่สงบ แต่ยังไม่เพียงพอสำหรับการแสดงพื้นผิวทะเลเปิดที่ขรุขระได้อย่างแม่นยำ
  • เพื่อแก้ปัญหานี้ จึงจำลองคลื่นด้วย การแปลงฟูริเยร์ผกผัน ของสเปกตรัมคลื่นทะเลที่อิงจากข้อมูลเชิงประจักษ์ซึ่งนักสมุทรศาสตร์เก็บรวบรวมไว้
  • ข้อดีของการทำงานในโดเมนความถี่คือสามารถปรับคุณสมบัติของทะเลได้ง่าย เมื่อใช้ Gerstner waves จะไม่ชัดเจนว่าต้องปรับคลื่นและพารามิเตอร์อย่างไรเพื่อเลียนแบบสภาวะทะเลแบบใดแบบหนึ่ง
  • ใช้อัลกอริทึม Fast Fourier Transform (FFT) ในการคำนวณการแปลงฟูริเยร์ ซึ่งมีความซับซ้อนในการคำนวณต่ำกว่าอัลกอริทึมการแปลงฟูริเยร์แบบไม่ต่อเนื่องแบบดั้งเดิม และเหมาะกับการรันบน GPU

ผลลัพธ์

การเชดคลื่น
โมเดลแสง
  • โมเดลแสงของทะเลยึดตาม BSDF ที่อธิบายไว้ใน GDC talk ของ 'Atlas' เป็นหลัก แต่ใช้การกระจายแบบ GGX แทนการกระจายแบบ Beckmann สำหรับการกระจายของผิวจุลภาค
  • มีการสุ่มตัวอย่าง normal/form map โดยผสมการกรองแบบ bicubic และ bilinear ตามความหนาแน่นพิกเซลใน world space
ฟองทะเล
  • Tessendorf เสนอวิธีสร้างฟองเมื่อยอดคลื่นม้วนกลับเข้าหาตัวเอง
  • ฟองจะสะสมแบบเชิงเส้นและสลายแบบเอ็กซ์โปเนนเชียล โดยควบคุมด้วยพารามิเตอร์ "อัตราการเติบโตของฟอง" และ "อัตราการสลายของฟอง"
ละอองน้ำทะเล
  • ละอองน้ำทะเลถูกจำลองเป็นอนุภาคโดยใช้โหนด GPUParticles3D ของ Godot
  • อนุภาคถูกกระจายอย่างสม่ำเสมอภายใน bounding box ของโหนด GPUParticles3D
  • อนุภาคละอองน้ำทะเลแต่ละตัวใช้ billboard sprite ที่มีเท็กซ์เจอร์คงที่เพียงหนึ่งภาพ
การจำลองคลื่น
  • วิธีสร้างคลื่นผิวน้ำเป็นไปตามแนวทางของ Tessendorf
  • ฟังก์ชันสเปกตรัมคลื่นทะเลแบบมีทิศทางจะคืนค่าพลังงานของคลื่นตามความถี่และทิศทาง
สเปกตรัมคลื่นทะเล
  • เลือกใช้สเปกตรัม Texel-Marsen-Arsloe (TMA) เป็นฟังก์ชันสเปกตรัมแบบไม่มีทิศทาง
  • ใช้การผสมระหว่างฟังก์ชันการกระจายทิศทางแบบ flat และ Hasselmann
Fast Fourier Transform
  • เขียน FFT implementation แบบปรับแต่งเองสำหรับ GPU
  • ใช้อัลกอริทึม Stockham FFT เพื่อหลีกเลี่ยงการเรียงสับเปลี่ยนแบบ bit-reversal ในขั้นต้น
คลื่นแบบคาสเคด
  • เมื่ออยู่ในระยะไกล อาการ tile artifact จะเห็นได้ชัดมาก
  • ระบบสร้างคลื่นสามารถซ้อนหลาย wave cascade พร้อมกันได้
การกระจายภาระงาน
  • การเคลื่อนไหวของคลื่นยังสามารถดูนุ่มนวลได้แม้ไม่อัปเดต displacement ทุกเฟรม
  • มีการเพิ่มพารามิเตอร์ "อัตราการอัปเดต" เพื่อควบคุมความถี่ต่อวินาทีที่ wave cascade จะถูกอัปเดต

เอกสารอ้างอิง

  • 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).

การแสดงลิขสิทธิ์

  • 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.

สรุปโดย GN⁺

  • GodotOceanWaves เป็นการทดลองเรนเดอร์ทะเลเปิดด้วย Godot Engine โดยสร้างคลื่นจากการแปลงฟูริเยร์ผกผันของสเปกตรัมคลื่นทะเลแบบมีทิศทาง
  • ใช้ Fast Fourier Transform (FFT) เพื่อให้ทำงานได้อย่างมีประสิทธิภาพบน GPU และสามารถจำลองสภาพแวดล้อมคลื่นทะเลได้หลากหลายรูปแบบ
  • ครอบคลุมองค์ประกอบหลายด้าน เช่น การเชดคลื่น ฟองทะเล ละอองน้ำทะเล และการจำลองคลื่น เพื่อจำลองพื้นผิวทะเลที่สมจริง
  • โปรเจ็กต์นี้อาจเป็นประโยชน์ต่อการสร้างการเรนเดอร์ทะเลที่สมจริงในวิดีโอเกมและงานจำลองต่างๆ

1 ความคิดเห็น

 
GN⁺ 2024-09-29
ความคิดเห็นจาก Hacker News
  • ที่เก็บข้อมูล Godot อีกสองอันของคนนี้ก็น่าสนใจมากเช่นกัน

    • ชอบวิธีที่เขาเพิ่มรายละเอียดไว้ในคำอธิบายของรีโพซิทอรี
    • โดยเฉพาะอันนี้ที่น่าสนใจ: GodotGaussianSplatting
    • อาจจะยังเป็นนักศึกษาอยู่ มีการอ้างอิงงานวิจัยอื่นบ่อย และเข้าใจเอกสารที่เพิ่งตีพิมพ์ใหม่ได้ดี
  • เมื่อ 20 ปีก่อน ต่อให้ใช้เวลาหลายเดือนไปกับการเรนเดอร์พื้นผิวทะเล ก็ยังไปไม่ถึงระดับนี้

    • น่าทึ่งมากว่าเทคนิคนี้ยอดเยี่ยมขนาดไหน
  • คลิปเดโมให้ความรู้สึกโอเวอร์ไปนิดหน่อย

    • มีประสบการณ์เดินเรือมากกว่า 50,000 นอตไมล์
    • คลื่นที่คมและสูงขนาดนั้นต้องการลมที่แรงกว่านี้
    • น่าจะแก้ได้ด้วยการปรับพารามิเตอร์
  • คาดว่าการเรนเดอร์ใน Godot นี้ทำงานแบบเรียลไทม์

    • สงสัยว่าต้องใช้ GPU ที่แรงแค่ไหน
  • ของแบบนี้นี่แหละที่ทำให้เริ่มสนใจคอมพิวเตอร์ แต่ระหว่างทางก็หมดไฟเพราะต้องเจอกับไลบรารี, endpoint และงานบริษัท

    • สักวันหนึ่งก็อยากกลับไปลองอีกครั้ง
  • ถ้าสนใจการจำลองคลื่น/ทะเล Acerola เคยลงวิดีโอเจ๋ง ๆ เกี่ยวกับหัวข้อนี้ไว้

  • น่าสนใจว่าปัญหานี้มันยากขนาดไหน

    • พยายามกันมาหลายสิบปีแล้วแต่ก็ยังไม่สมบูรณ์
    • ถ้าหยุดเฟรมไว้ คลื่นจะดูเหมือนภูเขาหิมะ
    • ถ้าน้ำจะมีลักษณะคมแบบนั้นได้ ลมต้องแรงมาก
    • ตัวจำลองทำลักษณะความนุ่มของคลื่นออกมาได้ดี
  • เคยอาศัยอยู่ริมชายหาดมาหลายปี

    • พออยู่ริมชายหาดก็จะมองทะเลอยู่นาน ๆ
    • งานเรนเดอร์นี้ดูเหมือนทะเลจริง
  • วิธีนี้มีข้อจำกัดอยู่บ้างเมื่อเป็นคลื่นลูกใหญ่มาก

    • คลื่นน้ำไม่ใช่คลื่นไซน์ แต่สำหรับคลื่นเล็ก วิธีนี้ใช้ได้ดี
    • คลื่นใหญ่มีปฏิสัมพันธ์กันแบบไม่เชิงเส้น จึงต้องใช้วิธีอื่น
  • ใน Shadertoy ก็มีตัวอย่างเจ๋ง ๆ เหมือนกัน

  • Fourier คิดค้นการแปลงความถี่ของคลื่นขึ้นมาจากการวัดคลื่นน้ำขึ้นน้ำลง

    • แทบจะเป็นวงจรที่สมบูรณ์แบบ
    • น่าประทับใจมาก
  • น่าประทับใจมาก แต่ยังมีปัญหาเล็กน้อยเรื่องความนุ่มของคลื่น

    • วิธีที่คลื่นความถี่สูงเคลื่อนอยู่บนคลื่นความถี่ต่ำแตกต่างจากในวิดีโอ