แนวคิดสำหรับการจำลองน้ำแบบ 2D


18

ฉันกำลังมองหาอินพุตใด ๆ เกี่ยวกับการจำลองน้ำในแบบ 2 มิติเทียบกับอาร์เรย์ที่มีขนาดใหญ่กว่า (เรียกว่า) ถูกบล็อก / ไม่ถูกบล็อก (ดูจากด้านข้าง) ฉันคิดตามแนวคิดต่อไปนี้:

Cell Automata

ทำแบบจำลอง parralel อย่างหนาแน่นบน CPU ที่ใช้ออโตเซลล์ ด้วยกฎที่ง่ายเหมือน:

  • หากมีเซลล์เปิดอยู่ให้เลื่อนไปด้านล่างสุดไปเลย
  • ตรวจสอบเซลล์ซ้ายและขวาเลือกสุ่มหนึ่งจากสองและย้ายไป

ข้อดี

  • ใช้งานง่าย
  • มีความหมาย / เสื่อมในระบบผู้เล่นหลายคน

จุดด้อย

  • อาจช้าจริง ๆ
  • ไม่น่าเชื่อ

Fluid Dynamics บน GPU

ทำการประมาณคร่าวๆของพลศาสตร์ของไหลบน GPU กับพื้นผิวดังนี้:

+------+-----+-----+-------+
|R     |G    |B    |A      |
+------+-----+-----+-------+
|vX    |vY   |NULL |Density|
+------+-----+-----+-------+

ข้อดี

  • น่าจะเร็วจริงๆ
  • อาจจะค่อนข้างน่าเชื่อ
  • Pixel Shader เพิ่มเติมสามารถแสดงผลได้โดยตรง

จุดด้อย

  • ใช้งานยาก
  • ปรับแต่งได้ยาก
  • ฉันไม่สามารถจัดสรรขนาดพื้นผิวในระดับเดียวได้
    • ฉันสามารถซ้อนพื้นที่กริดได้ แต่สิ่งนี้จะเพิ่มความซับซ้อนมากขึ้น

อนุภาค

ใช้อนุภาคเพื่อจำลองน้ำ ในระหว่างการเรนเดอร์โดยใช้การผสมแบบเติมแต่งแล้วใช้ฟังก์ชั่นการคูณกับช่องอัลฟาเพื่อให้ขอบน้ำมีความคมชัด

ข้อดี

  • อาจจะดูดี
  • ใช้งานง่าย
  • ง่ายต่อการแสดงผล
  • มีความหมายในระบบผู้เล่นหลายคนแม้ว่าจะต้องใช้แบนด์วิธค่อนข้างน้อยในการถ่ายโอน

จุดด้อย

  • ผลกระทบระหว่างอนุภาคอาจจะช้า (การค้นหาพื้นที่ใกล้เคียง)
  • อาจนำไปสู่การ 'รั่ว' ของน้ำผ่านช่องว่างที่เป็นของแข็ง (เพราะพื้นที่ของแข็งมีขนาดเล็กเช่น 1px)
  • อาจนำไปสู่หลุมแปลก ๆ ในน้ำขึ้นอยู่กับขนาดของอนุภาค
  • ทั้งสองข้อสามารถบรรเทาได้โดยอนุญาตให้อนุภาคเข้ามาใกล้กันมากกว่าขนาดจริงอย่างไรก็ตามจะทำให้เกิดปัญหากับประสิทธิภาพของอนุภาคและแนวนอน / แนวนอน

มีความคิดเพิ่มเติมหรือไม่

หมายเหตุ:นี่คือการประมาณฉันไม่ได้มองหาน้ำที่ถูกต้องทางร่างกายที่นี่ - สิ่งที่ 'ดีพอ' (คะแนนโบนัสสำหรับรวดเร็วและสกปรก) เกมนี้เป็นแบบผู้เล่นหลายคนดังนั้นน่าเสียดายที่ทั้งระดับต้องได้รับการจำลองอย่างต่อเนื่อง

คำตอบ:


12

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

ข้อดี:

  • ใช้งานง่าย
  • ผลลัพธ์ที่เป็นจริงในกรณีของน้ำนิ่ง
  • คำนวณอย่างรวดเร็วโดยใช้ GPU
  • ง่ายต่อการกำหนดระดับน้ำคงที่หรือแหล่งน้ำ

จุดด้อย:

  • ไม่สามารถจำลองคลื่น

สำหรับคลื่นน้ำฉันใช้วิธีคล้ายกับอัลกอริทึม Cell Automata ของคุณ แต่มีการเปลี่ยนแปลงเล็กน้อยที่จะให้ฉันใช้เฉดสีเพื่อคำนวณขั้นตอนต่อไปจากสถานการณ์ปัจจุบันนี่คือรหัส sudo อีกครั้งฉันมีพื้นผิวแสดงระดับน้ำในแต่ละ สีพิกเซล:

foreach (pixel p) in oldTexture
{
    newtexture.pixels[p.x,p.y]    += p.color / 5;
    newtexture.pixels[p.x+1,p.y]  += p.color / 5;
    newtexture.pixels[p.x-1,p.y]  += p.color / 5;
    newtexture.pixels[p.x,p.y+1]  += p.color / 5;
    newtexture.pixels[p.x,p.y-1]  += p.color / 5;
}

อัลกอริทึมนี้มีคุณสมบัติคล้ายกับก่อนหน้านี้ แต่มันทำงานได้ดีขึ้นในน่านน้ำคลื่นแทนที่จะสงบ มันเป็นทางเลือกของคุณขึ้นอยู่กับทะเลที่คุณกำลังจำลองให้ใช้อย่างใดอย่างหนึ่ง

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


ขอบคุณนั่นเป็นคำตอบที่ยอดเยี่ยม ฉันจะเปิดคำถามทิ้งไปอีกนาน แต่ดูเหมือนว่าฉันมีความสามารถพิเศษในการถามคำถามคำตอบเดียวที่นี่ :)
Jonathan Dickinson

คุณสามารถผสมอัลกอริทึมเหล่านี้เพื่อให้ได้ผลลัพธ์ที่ดีขึ้น
Ali1S232

ภาพหน้าจอเป็นอย่างไร
ashes999

@ ashes999 ฉันไม่มีภาพหน้าจอ แต่ที่นี่ใช้อัลกอริทึมแบบเดียวกัน! youtube.com/watch?v=avJPrL9UJ28
Ali1S232
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.