1 คะแนน โดย GN⁺ 2024-09-29 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • GodotOceanWaves เป็นการทดลองเรนเดอร์ใน Godot Engine ที่สร้างผิวน้ำทะเลเปิดด้วยการใช้ inverse Fourier transform ของ สเปกตรัมคลื่นทะเลแบบมีทิศทาง และจำลองสภาพแวดล้อมทางทะเลหลากหลายแบบด้วยพารามิเตอร์ที่ปรับผ่านสคริปต์ได้แบบเรียลไทม์
  • Gerstner waves เหมาะกับรายละเอียดความถี่ต่ำของน้ำที่สงบ แต่มีข้อจำกัดสำหรับผิวน้ำทะเลเปิดที่รุนแรง โปรเจกต์นี้จึงใช้สเปกตรัมที่อิงข้อมูลสมุทรศาสตร์เชิงประจักษ์และ FFT
  • การสร้างคลื่นทำตามแนวทางของ Tessendorf โดยสร้างสถานะสเปกตรัมเริ่มต้น จากนั้นแพร่กระจายตามเวลาด้วยความสัมพันธ์การกระจายตัว แล้วใช้ inverse Fourier transform เพื่อสร้าง displacement, normal และ foam map
  • การเรนเดอร์อิงตาม BSDF จากการนำเสนอ Atlas ที่ GDC แต่ใช้การแจกแจง GGX ส่วน foam จะสะสมและสลายตัวในบริเวณที่ Jacobian ของ displacement เป็นค่าลบ และ sea spray พัฒนาด้วย GPUParticles3D ของ Godot พร้อม shader แบบกำหนดเอง
  • รองรับ wave cascade หลายชุด การปรับรอบการอัปเดต และการกระจายโหลดแยกตาม cascade เพื่อจัดการ tiling และภาระงานของ GPU แต่ cascade ต้องใช้ความละเอียดของสเปกตรัมเท็กซ์เจอร์เดียวกัน และวิธีสร้างอนุภาค sea spray มีประสิทธิภาพต่ำเมื่อเพิ่มความหนาแน่น

GodotOceanWaves ทำอะไร

  • GodotOceanWaves เป็นโปรเจกต์ทดลองเรนเดอร์ทะเลเปิดใน Godot Engine
  • การสร้างคลื่นใช้ inverse Fourier transform ของสเปกตรัมคลื่นทะเลแบบมีทิศทาง
  • พารามิเตอร์ที่เปิดให้ปรับถูกจัดไว้อย่างกระชับ และสามารถแก้ไขแบบเรียลไทม์ผ่านสคริปต์เพื่อจำลองสภาพคลื่นทะเลหลายรูปแบบได้
  • มีวิดีโอเดโม ocean_demo.mp4 และ environment_demo.mp4 รวมอยู่ด้วย

เหตุผลที่ใช้คลื่นแบบ Fourier แทน Gerstner waves

  • วิธีทั่วไปในการทำอนิเมชันน้ำในเกมคือการเลื่อนตำแหน่งเวอร์เท็กซ์ด้วย Gerstner waves
  • Gerstner waves เหมาะกับการจำลองรายละเอียดความถี่ต่ำของน้ำที่สงบ แต่ยังไม่เพียงพอในการแสดงผิวน้ำทะเลเปิดที่ขรุขระอย่างแม่นยำ
  • เมื่อใช้สเปกตรัมคลื่นทะเลที่อิงข้อมูลเชิงประจักษ์ซึ่งนักสมุทรศาสตร์เก็บรวบรวมไว้ จะสามารถจัดการได้ตรงขึ้นว่าต้องเปลี่ยนคลื่นและพารามิเตอร์ใดเพื่อสร้างสภาพทะเลแบบหนึ่ง ๆ
  • FFT มีความซับซ้อน O(N log N) ซึ่งต่ำกว่า discrete Fourier transform แบบคลาสสิกที่เป็น O(N^2) และสามารถขยายไปยังระบบขนานได้ จึงเหมาะกับการรันบน GPU
  • ใน Gerstner waves แต่ละเธรดต้องคำนวณกับจำนวนคลื่น N ลูก แต่ในคลื่นแบบ FFT แต่ละเธรดทำการคำนวณเพียงระดับ log(N) เท่านั้น

Shading, foam และ sea spray

  • โมเดลแสงของทะเลโดยรวมอิงตาม BSDF จาก การนำเสนอ Atlas ที่ GDC
  • การแจกแจงไมโครแฟซิตใช้ GGX แทน Beckmann
    • เพราะไฮไลต์ของ GGX ที่แบนและนุ่มกว่าให้ภาพรวมที่สม่ำเสมอกว่าในสภาพคลื่นทะเลหลายแบบที่ทดสอบ
  • normal/foam map ถูกสุ่มตัวอย่างโดยผสมการกรองแบบ bicubic และ bilinear ตามความหนาแน่นพิกเซลใน world space
    • ช่วยลดอาร์ติแฟกต์ texture aliasing เมื่อความละเอียดพื้นผิวต่ำ และรักษารายละเอียดเมื่อความละเอียดพื้นผิวสูง
  • Sea foam ตัดสินใจว่าจะสร้างหรือไม่ตามวิธีของ Tessendorf ในตำแหน่งที่ยอดคลื่นม้วนเข้าด้านใน กล่าวคือบริเวณที่ Jacobian ของ displacement เป็นค่าลบ
    • foam จะสะสมแบบเชิงเส้นลงในเท็กซ์เจอร์ตลอดการอัปเดตคลื่นหลายครั้ง
    • พารามิเตอร์ "foam grow rate" และ "foam decay rate" ควบคุมการสะสมและการสลายตัวแบบเอ็กซ์โปเนนเชียลตามลำดับ
  • Sea spray พัฒนาด้วยโหนด GPUParticles3D ของ Godot และ particle shader แบบกำหนดเอง
    • อนุภาคกระจายอย่างสม่ำเสมอบนระนาบภายใน bounding box ของ GPUParticles3D
    • อนุภาคจะถูก culling ตามปริมาณ foam ณ ตำแหน่งนั้น และอนุภาคที่ไม่ถูก culling จะเริ่มวงจรชีวิตจากออฟเซ็ตแบบสุ่ม
    • อนุภาคแต่ละตัวใช้ billboard sprite ที่ใช้เท็กซ์เจอร์คงที่หนึ่งภาพ
    • ระหว่างวงจรชีวิต จะเปลี่ยน scale และ displacement เพื่อจำลองรูปลักษณ์ของ splash และใช้เอฟเฟกต์ dissolve ใน mesh shader เพื่อให้เกิดความรู้สึกว่าน้ำกระเซ็นแตกเป็นละอองกลางอากาศ
  • ข้อเสียใหญ่ของวิธี sea spray นี้คือ ต่อให้เพิ่มจำนวนอนุภาคมาก ความหนาแน่นก็เพิ่มขึ้นเพียงเล็กน้อย
    • เพราะอนุภาคกระจายสม่ำเสมอใน bounding box ทำให้อนุภาคที่เพิ่มมาส่วนใหญ่ถูก culling

Pipeline การจำลองคลื่น

  • วิธีสร้างคลื่นผิวน้ำทำตาม Tessendorf อย่างใกล้ชิด
  • สร้างสถานะทะเลในสเปกตรัมเริ่มต้นโดยนำฟังก์ชันสเปกตรัมคลื่นทะเลแบบมีทิศทางมาคูณกับตัวเลขสุ่มที่มีการแจกแจง Gaussian
  • สถานะเริ่มต้นจะถูกแพร่กระจายตามเวลาโดยใช้ ความสัมพันธ์การกระจายตัว ที่เชื่อมความถี่ของคลื่นกับความเร็วการแพร่กระจาย
  • นำ inverse Fourier transform ไปใช้กับสถานะที่แพร่กระจายแล้วเพื่อสร้าง displacement map และ normal map
  • การพัฒนาประกอบเป็น compute shader pipeline ที่ใช้ abstraction RenderingDevice ของ Godot

องค์ประกอบของสเปกตรัมคลื่นทะเล

  • ฟังก์ชันสเปกตรัมคลื่นทะเลแบบมีทิศทาง S(ω, θ) คืนค่าพลังงานของคลื่นเมื่อกำหนดความถี่ ω และทิศทาง θ
  • ฟังก์ชันนี้ประกอบด้วยฟังก์ชันสเปกตรัมแบบไม่มีทิศทาง S(ω) และฟังก์ชันการกระจายทิศทาง D(ω, θ) โดยตัวเลือกทั้งสองเป็นอิสระต่อกัน
  • สำหรับสเปกตรัมแบบไม่มีทิศทาง ใช้สเปกตรัม Texel-Marsen-Arsloe(TMA) ที่ Horvath อธิบายไว้
    • TMA ใช้ความเร็วลม U, ความลึกน้ำ D และ fetch length F
    • TMA ผสานสเปกตรัม JONSWAP ก่อนหน้าเข้ากับฟังก์ชันลดทอนตามความลึกน้ำ
  • สำหรับฟังก์ชันการกระจายทิศทาง ใช้วิธีผสมการกระจายทิศทางแบบ flat และ Hasselmann ของ Horvath ด้วยพารามิเตอร์ spread คือ μ
    • รวมพารามิเตอร์ swell คือ ξ ที่ Horvath เสนอไว้ด้วย เพื่อจำลอง elongation ของคลื่นทะเล
    • เลือกการกระจายทิศทางแบบ Hasselmann เพราะให้คำตอบเชิงวิเคราะห์แบบประมาณสำหรับค่าสัมประสิทธิ์ normalization Q(σ)
  • ตามข้อเสนอของ Tessendorf ฟังก์ชันสเปกตรัมผลลัพธ์ยังคูณด้วยเทอมกดทอนคลื่นขนาดเล็กด้วย
    • เทอมนี้ใช้ขนาดของเวกเตอร์ wave number k และพารามิเตอร์ detail คือ δ
  • สเปกตรัมคลื่นทะเลแบบมีทิศทางขั้นสุดท้ายผสาน TMA, mixed directional spread และ small-wave suppression เข้าด้วยกัน

การพัฒนา GPU FFT

  • FFT ใช้ การพัฒนา GPU แบบกำหนดเอง ที่เขียนด้วย compute shader
  • ใช้อัลกอริทึม Stockham FFT แทน Cooley-Tukey เพื่อหลีกเลี่ยง bit-reversal permutation ตอนเริ่มต้น
  • ตาม Flügge จะคำนวณเท็กซ์เจอร์ "butterfly" ที่เข้ารหัสการไหลของข้อมูลของ FFT
    • เท็กซ์เจอร์นี้จะถูกคำนวณหนึ่งครั้งทุกครั้งที่ความละเอียดของสเปกตรัมเท็กซ์เจอร์เปลี่ยน
  • 2D FFT เริ่มจากใช้เคอร์เนล FFT ในทิศทางแถวของสเปกตรัมเท็กซ์เจอร์
  • จากนั้น transpose เท็กซ์เจอร์ด้วย compute shader เพื่อใช้เคอร์เนล FFT ทิศทางแถวเดิมซ้ำในลักษณะ FFT ทิศทางคอลัมน์
  • การ transpose ไม่เพียงช่วยให้ใช้ pipeline ซ้ำได้ แต่ยังปรับปรุงรูปแบบการเข้าถึงหน่วยความจำด้วย

Wave cascade และการรับมือ tiling

  • ในระยะไกล โดยเฉพาะเมื่อมี sea foam อาร์ติแฟกต์แบบ tiling จะเห็นได้ชัดมาก
  • ระบบสร้างคลื่นจัดการปัญหานี้ด้วยการเลเยอร์ wave cascade หลายชุดพร้อมกัน
  • แต่ละ cascade มีขนาด tiling และชุดพารามิเตอร์ของตัวเอง
  • สามารถเพิ่มหรือลบ cascade แบบไดนามิกได้แบบเรียลไทม์
  • เนื่องจาก cascade ทั้งหมดใช้ compute pipeline เดียวกัน จึงต้องมี ความละเอียดของสเปกตรัมเท็กซ์เจอร์ เท่ากัน
  • อีกทางเลือกหนึ่งคือ blend wave displacement และ normal กับ noise เพื่อลดอาร์ติแฟกต์แบบ tiling ด้วยต้นทุนประสิทธิภาพที่ต่ำกว่า
  • เมื่อนำ cascade มาซ้อนกัน ต้องเลือกพารามิเตอร์และขนาดของแต่ละ cascade อย่างระมัดระวังเพื่อหลีกเลี่ยงการแทรกสอดกันของคลื่น
  • phase ของคลื่นในแต่ละ cascade ก็ควรถูก offset เพื่อไม่ให้แทรกสอดกัน
    • ระบบพยายามทำสิ่งนี้โดยอัตโนมัติด้วยการ offset เวลาเริ่มต้นของแต่ละ cascade ให้ต่างกัน
    • มี caveat ระบุว่าไม่แน่ชัดว่าวิธีนี้ใช้งานได้จริงหรือไม่

การกระจายโหลดการอัปเดต

  • เนื่องจากการเคลื่อนที่ของคลื่นไม่สม่ำเสมอ แม้ไม่อัปเดต displacement ทุกเฟรม ก็ยังอาจดูราบรื่นในเชิงการรับรู้ได้
  • พารามิเตอร์ "update rate" ควบคุมว่าจะอัปเดต wave cascade บ่อยแค่ไหนต่อวินาที
  • การข้ามเฟรมช่วยลดเวลา GPU ที่ใช้กับ FFT แต่ในเฟรมที่ pipeline สร้างคลื่นทำงาน ก็ยังเกิด stutter ได้
  • การทดลองคำนวณการอัปเดต cascade แบบอะซิงโครนัสด้วย local RenderingDevice ของ Godot ทำให้เกิด overhead ด้านประสิทธิภาพสูงจากการส่งต่อเท็กซ์เจอร์ระหว่าง CPU และ GPU
  • ดังนั้นระบบจึงพยายามทำ การกระจายโหลด ของ cascade แทน
    • ถ้าเวลาเฟรมสั้นกว่า update rate จะอัปเดต cascade เพียงหนึ่งชุดต่อเฟรม
    • วิธีนี้ลด stutter พร้อมรักษาประโยชน์ของภาระงาน GPU ที่ต่ำลงจากการข้ามเฟรมไว้ได้

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

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

 
GN⁺ 2024-09-29
ความคิดเห็นบน Hacker News
  • รีโพซิทอรี Godot อีกสองอันที่คนนี้ทำก็น่าสนใจมากเหมือนกัน ชอบตรงที่ใส่รายละเอียดไว้เยอะเวลาอธิบายรีโพซิทอรี โดยเฉพาะอันนี้ที่สะดุดตา: https://github.com/2Retr0/GodotGaussianSplatting
    สงสัยว่าเป็นนักศึกษาหรือเปล่า เขาอ้างอิงงานอื่นอยู่บ่อย ๆ และดูเหมือนเข้าใจเอกสารที่เพิ่งเผยแพร่ล่าสุดได้ค่อนข้างดี

    • ดูมีความเป็นไปได้ว่าเป็นนักศึกษา ชื่อกับคำอธิบายของรีโพซิทอรีหนึ่งคือ ENGR96A-coursework, Relevant coursework for ENGR 96A Introduction to Engineering Design F23 และดูจากวันที่ commit แล้ว F23 น่าจะหมายถึงเทอมฤดูใบไม้ร่วงปี 2023
      แน่นอนว่า คอร์สของ UCLA ที่กล่าวถึงในรีโพซิทอรีอาจเปิดให้ทุกคนเข้าถึงได้ก็ได้ ดังนั้นอาจไม่จำเป็นต้องเป็นนักศึกษาที่ลงทะเบียนกับ UCLA ในความหมายแบบดั้งเดิมถึงจะเรียนได้
  • เมื่อ 20 ปีก่อน ต่อให้ปรับ ผิวน้ำทะเล ในงานเรนเดอร์กันเป็นเดือน ๆ ก็คงยังไปไม่ถึงใกล้ระดับนี้เลย ผลงานทำออกมาได้ดีจริง ๆ
    แต่คลิปเดโมดูเหมือนจะโอเวอร์ไปนิด จากมุมมองของคนที่มีบันทึกการเดินเรือทะเลเปิดมากกว่า 50,000 ไมล์ทะเล ถ้าคลื่นแหลมและสูงแบบนั้น ลมน่าจะต้องพัดแรงกว่านี้มาก ถึงอย่างนั้นก็น่าจะเป็นส่วนที่ปรับพารามิเตอร์ได้
    ถ้าทำด้วย Godot แบบนี้ถือว่าเป็นการเรนเดอร์แบบเรียลไทม์ได้ไหม? ก็สงสัยเหมือนกันว่าต้องใช้ GPU ระดับสัตว์ประหลาดหรือเปล่า

    • ไม่ได้วิจารณ์ แค่สังเกตนะ แต่นี่ดูเหมือนภาพที่นึกออกถ้าจินตนาการถึง ทะเลของคอร์นไซรัปร้อนที่ย้อมเป็นสีน้ำเงิน ความหนืดดูเหมือนจะใช่ แต่แรงตึงผิวอาจต่างจากน้ำทะเลจริง น้ำทะเลจริงเป็นคอลลอยด์ของน้ำเกลือ H2O กับสสารชีวภาพ ซึ่งในโลกจริงพบได้ทั่วไป แต่สำหรับพลศาสตร์ของไหลเชิงคำนวณแล้วเป็นวัตถุที่ค่อนข้างยุ่งยาก
      อีกอย่าง ละอองน้ำทะเลในนี้ดูเหมือนเป็นเอฟเฟกต์หลังการประมวลผล แต่ในทะเลจริง ละอองน้ำจะทำให้ความคมของคลื่นดูทู่ลง และเผยให้เห็นได้ราง ๆ ทางสายตาด้วย
      แน่นอนว่าโมเดลที่สง่างาม เรียบง่าย และได้ผลนี้แทบไม่มี ฟิสิกส์ อยู่เลย ดังนั้นขอให้มองเรื่องพวกนี้ไม่ใช่การยืนกอดอกวิจารณ์ แต่เป็นการลองจิ้ม ๆ สำรวจ และเสนอทิศทางที่น่าลองมากกว่า
    • เดี๋ยวนี้มีวิดีโอที่พูดถึงเรื่องแบบนี้เยอะ ทำให้กระบวนการโดยรวมเข้าถึงได้พอสมควร แต่ก็ยังมีกับดักอยู่มาก
      หนึ่งในวิดีโอที่ชอบในหัวข้อนี้: https://m.youtube.com/watch?v=yPfagLeUa7k
      อันนี้ก็ใช้ได้: https://m.youtube.com/watch?v=kGEqaX4Y4bQ
    • ผมมีโปรเจกต์เกมอยู่ แต่พอเห็นเทคโนโลยีเกมเจ๋ง ๆ ทีไร ก็มักโดน nerd sniping จนอยากลงมือทำเองทุกที ถ้าใช้หรือซื้อ asset สำเร็จรูป ความคืบหน้าที่ทำมาจนถึงตอนนี้คงทำได้แม้ในเกมแจม 48 ชั่วโมง
      แต่กลับใช้เวลาทุกสุดสัปดาห์ไปกับการปรับ water shader เล่นจนกว่าจะได้ภาพที่ต้องการ ทั้งที่เกมของผมเป็นเกมปริศนา ไม่ต้องมีน้ำเลย ตอนนี้ก็แค่ได้หน้าจอเริ่มต้นเท่ ๆ มาเท่านั้นเอง
    • ตอนผมเรียนจบใหม่ ๆ การทำ particle engine หรือ marching cubes ยังเป็นโปรเจกต์วิทยานิพนธ์จบการศึกษาอยู่เลย
      เดี๋ยวนี้มันเป็นแค่ช่องติ๊กหนึ่งใน game engine และยังมีฟีเจอร์แบบนั้นอีกนับไม่ถ้วน ผู้คนคงจินตนาการไม่ออกว่าเราอยู่ในสภาพแวดล้อมที่ดีแค่ไหนเพราะเอนจินสมัยใหม่
      ไม่ได้ตั้งใจจะลดคุณค่าของงานนี้นะ มันเป็นความสำเร็จที่ยอดเยี่ยมจริง ๆ และขอชื่นชมผู้สร้าง แค่อยากบอกว่าเรากำลังอยู่ในยุคที่ดีมากแค่ไหน
    • เห็นด้วยว่าถ้าดูจากวิดีโออย่างเดียว มันดูสุ่ม ๆ ไปหน่อย
      ถึงอย่างนั้นก็ดูดีมาก และจากที่ลองค้นคร่าว ๆ เมื่อเร็ว ๆ นี้ น่าจะเป็นระดับที่ดีที่สุดในบรรดาสิ่งที่ทำได้
      ส่วนตัวอยากเห็นคลื่นทะเลเปิดที่โดยปกติดูมี จังหวะ มากกว่านี้ สงสัยว่าการจำลองลม 15 นอตที่พัดเหนือผิวน้ำระยะ 1 กม. เป็นเวลาหลายชั่วโมง จะตรงกับสิ่งที่สังเกตได้จริงไหม นั่นคือภาพที่รอยแตกของคลื่นค่อนข้างเป็นระเบียบก่อตัวขึ้นแล้วกระจายตัวไป
  • สิ่งแบบนี้แหละที่ดึงผมเข้าสู่โลกคอมพิวเตอร์ แต่ไม่รู้ตัวเลยว่าชีวิตกลับไหลไปสู่ความง่ายและน่าเบื่อของการเอาไลบรารี endpoint และเรื่องไร้สาระแบบองค์กรมาเชื่อมต่อกัน จนพาไปสู่ burnout
    หวังว่าสักวันจะกลับไปได้อีกครั้ง

    • ผมว่าค่อย ๆ ย้ายไปก็ได้ หาแขนงที่ตอนแรกคุณสนใจ อยากเรียนรู้เพิ่ม และสุดท้ายอยากลงมือทำจริง ๆ แล้วใช้เวลาสัปดาห์ละไม่กี่ชั่วโมงขุดลงไป จากนั้นค่อย ๆ เพิ่มขึ้นและค่อย ๆ ถอยห่างจากงานปัจจุบัน
      ลองทำดูเถอะ ทุกคนเอาใจช่วยอยู่
    • ผมเห็นเพื่อนหลายคนที่ทำงานแบบนั้นแล้วได้เงินมากกว่าผม แต่ผมตามความสนใจของตัวเองและกระโดดไป โรโบติกส์ ทันทีที่มีโอกาส แล้วก็ไม่เสียใจเลย อย่างน้อยสำหรับผม ไม่มีอะไรเทียบความรู้สึกที่ได้เห็นโค้ดของตัวเองโต้ตอบกับโลกจริงได้
  • แม้แนวทางจะต่างกัน แต่ถ้าสนใจ การจำลองคลื่น/มหาสมุทร Acerola ก็ทำวิดีโอเรื่องนี้ไว้อย่างยอดเยี่ยมตามสไตล์เขา https://youtu.be/PH9q0HNBjT4 และ https://youtu.be/yPfagLeUa7k
    แก้ไข: หนึ่งในนั้นถูกลิงก์ไว้ในเอกสารอ้างอิงแล้ว แต่ใช้ชื่อจริงแทนนิกเนม เลยเพิ่งสังเกตเห็นตอนนี้

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

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

    • ตอนนี้ผมอยู่ริมทะเล และมีวิวจากความสูงประมาณชั้น 14 เหนือผิวน้ำด้วย แต่น่าแปลกที่อันนี้ดูออกชัดเจนว่าเป็นของปลอม ไม่มี ปื้นมืดที่เกิดจากลมกระโชก และส่วนสีขาวก็พุ่งตรงขึ้นด้านบนโดยไม่ม้วนเข้าแม้แต่นิดเดียว นอกนั้นก็ดูค่อนข้างจริง
    • เคยเห็นคลื่นและการเคลื่อนไหวของมันจริง ๆ ไหม? ถ้าเคยอยู่ริมทะเลมาหลายปี น่าจะสังเกตได้ทันทีว่า การก่อตัวของฟอง และการเคลื่อนไหวของคลื่นไม่เป็นธรรมชาติ
  • ใน Shadertoy ก็มีตัวอย่างที่ดีอยู่: https://www.shadertoy.com/view/Ms2SD1

  • Fourier เกิดไอเดียเรื่องการแปลงความถี่ของคลื่นระหว่างวัด คลื่นน้ำขึ้นน้ำลง ดังนั้นในแง่หนึ่งก็เหมือนวนกลับมาครบรอบพอดี
    น่าประทับใจมาก

  • ยอดเยี่ยม แต่แนวทางนี้น่าจะพังลงในระดับหนึ่งเมื่อเจอกับคลื่นใหญ่มาก ๆ เพราะ ความไม่เชิงเส้น ระลอกน้ำไม่ใช่คลื่นไซน์ แต่สำหรับคลื่นเล็กและคลื่นสูงระดับกลาง มันใกล้เคียงพอให้วิธีแบบนี้ทำงานได้ดีมาก
    คลื่นใหญ่มาก ๆ ไม่เพียงแต่ห่างจากคลื่นไซน์มากขึ้นเท่านั้น แต่คลื่นยังเริ่มมีปฏิสัมพันธ์กันแบบไม่เชิงเส้น ซึ่งจับด้วยวิธีซ้อนทับเชิงเส้นที่ใช้ที่นี่ไม่ได้
    ดังนั้นสำหรับสภาพทะเลส่วนใหญ่ มันยอดเยี่ยมมาก แต่ถ้าอยากทำคลื่นแบบใน ‘The Perfect Storm’ ให้สมจริง ก็ต้องใช้แนวทางอื่น

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