Ray Marching นำไปใช้กับโลกที่มีชีวิตชีวาได้อย่างไร


10

ฉันคิดว่าฉันเข้าใจพื้นฐานของสนามเรย์มาร์ช คุณจำลองฉากของคุณด้วยฟิลด์ระยะไกล (เช่น: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm ) จากนั้นสำหรับแต่ละพิกเซลที่คุณฉายรังสีให้เริ่มจากจุดเริ่มต้นของรังสี ค้นหาระยะทางไปยังวัตถุที่ใกล้ที่สุดที่จุดนั้นและเพิ่มจุดตามระยะทางที่ใกล้ที่สุดจนกว่าคุณจะตีอะไร ฉันจัดการที่จะทำ renderer ง่ายและนั่นคือที่ที่คำอธิบายส่วนใหญ่ของเทคนิคหยุด

นี่ทำให้ฉันมีคำถามบางอย่างเกี่ยวกับวิธีการใช้ SDF Ray Marching ในสถานการณ์จริง:

คำถามที่ 1: ในเกมจริงฉากมักจะซับซ้อนและโหลดบน CPU โดยมีวัตถุแบบไดนามิกมากมาย ฉันเข้าใจการบดเคี้ยวแบบพื้นฐาน (เช่น octrees) และด้วยการเรนเดอร์รูปหลายเหลี่ยมฉันจะสร้างรายการ (บน CPU) ของรายการในมุมมอง frustrum เพื่อเรนเดอร์

ดังนั้นจินตนาการว่าฉันมีฉากที่ซับซ้อนมากซึ่งมีตัวละครและวัตถุแบบไดนามิกเคลื่อนไปมาบนหน้าจอควบคุมโดยซีพียู ฉันจะสตรีมวัตถุที่ฉันต้องการให้แสดงกับ GPU ในแต่ละเฟรมได้อย่างไร ทุกตัวอย่างมีฉากฮาร์ดโค้ดใน GLSL บางคนสามารถแบ่งปันตัวอย่างของระดับที่ถูกส่งไปยัง shader แบบไดนามิกได้หรือไม่?

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

ขอบคุณ.

คำตอบ:


2

นี่เป็นคำตอบที่น้อยที่สุด แต่ต้องการแบ่งปันข้อมูลในกรณีที่คุณไม่ได้รับคำตอบที่ดีกว่า

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

สำหรับคำถามอื่นเกี่ยวกับสีและเช่นนั้นคนมักจะเชื่อมโยงวัสดุกับวัตถุและใช้ "พิกัดพื้นผิว" ของจุดที่รังสีชนกับวัตถุเพื่อหาคุณสมบัติของวัสดุที่จุดนั้นบนวัตถุ วัสดุทั่วไปรวมถึงสิ่งต่าง ๆ เช่นสีกระจายความเข้ม specular สี emissive และดัชนีความโปร่งใส / การหักเหของแสง

หวังว่าอย่างน้อยก็ช่วยคุณได้! คุณอาจได้รับคำตอบที่ดีจากไซต์แลกเปลี่ยนกราฟิกสแต็ก


2
"ไม่มีเกมที่ฉันตระหนักถึงการใช้รังสีเดินขบวนในแบบที่คุณอธิบาย" เกมที่กำลังจะมาถึงของ Media Molecule ใช้ฟิลด์ระยะทางที่เซ็นชื่อสำหรับการแกะสลักเนื้อหาที่ผู้ใช้สร้างขึ้นมา แต่ถ้าฉันเข้าใจอย่างถูกต้อง ถูก raymarched โดยตรง บทความนี้อาจมีความคิดบางอย่าง: dualshockers.com/2015/08/15/…
DMGregory

1
@ DMGregory Nice แต่ฉันคิดว่านี่ไม่ใช่เรย์มาร์ชนิ่ง ดังนั้นประเด็นก็ยังคงใช้ได้เกมมักไม่ใช้รังสีเดิน
concept3d

1
การอัพเดตเธรดนี้ - เกมClaybook ที่กำลังจะมีข่าวรายงานการแสดงฉากโดยใช้รังสีที่ยิงผ่านเขตข้อมูลระยะไกลโดยตรงแทนที่จะแปลงเป็นเรขาคณิตทั่วไปก่อน ดังนั้น "หรือยัง" ดูเหมือนว่าจะได้รับการแบกรับสองปี :)
DMGregory

1

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

เกี่ยวกับการสตรีมวิธีง่ายๆคือใช้บัฟเฟอร์ที่พิมพ์ไว้บางประเภทแล้วโยนมันลงบน GPU เมื่อคุณต้องการที่จะทำการเดิน องค์ประกอบของบัฟเฟอร์แต่ละชนิดเป็นชนิดที่ซับซ้อน (เช่นโครงสร้างใน C / C ++) และแต่ละประเภทมีองค์ประกอบที่กำหนดหน้าที่ที่คุณควรใช้เพื่อแสดงถึงตำแหน่งตำแหน่งการหมุนมาตราส่วน ฯลฯ และสีเฉลี่ย จากนั้นกระบวนการจะลดความซับซ้อนลงไปที่:

  1. คัดฉากของคุณให้เป็นเซตย่อยที่จัดการได้ (โปรดทราบว่าการคัดออกแบบ frustum และการบดเคี้ยวแบบบดเคี้ยวจะดำเนินการบางส่วนโดยอัตโนมัติโดยอัลกอริทึม ray-marching ต่อไป)
  2. ส่งชุดย่อยไปยังบัฟเฟอร์อินพุตการแสดงผลของคุณ
  3. ส่งผ่านบัฟเฟอร์ไปยัง GPU หากยังไม่มีอยู่จากนั้นแสดงฉากของคุณด้วยการเดินเรย์แบบดั้งเดิม คุณจะต้องทำการค้นหาต่อขั้นตอนบางอย่างเพื่อประเมินว่าไอเท็มใดในบัฟเฟอร์อินพุตใกล้กับเรย์แต่ละอันสำหรับการวนซ้ำของเรย์มาร์เชอร์แต่ละครั้งและคุณจะต้องใช้การแปลงกับเรย์ (ในกรณีนี้ คุณจะต้องสลับการหมุนของภาพก่อนที่พวกเขาจะไปถึง GPU) หรือฟังก์ชั่นระยะทาง (ย้ายที่มาของฟังก์ชั่นสำหรับการเปลี่ยนตำแหน่งการปรับเช่นความยาวด้านลูกบาศก์สำหรับการเปลี่ยนสเกล ฯลฯ ) วิธีที่ง่ายที่สุดคือ คุณส่งผ่านมันไปยังฟังก์ชั่นระยะทางแกนกลางจริง

เกี่ยวกับสีรูปโปรดจำไว้ว่าเฉดสีช่วยให้คุณสามารถกำหนดประเภทที่ซับซ้อนเช่นเดียวกับดั้งเดิม;) ที่ช่วยให้คุณสามารถโยนทุกอย่างลงในโครงสร้าง C จากนั้นส่งผ่านโครงสร้างเหล่านั้นกลับจากฟังก์ชันระยะทางของคุณ

ในเอ็นจิ้นของฉันแต่ละโครงสร้างมีระยะทางสีและ ID ที่เชื่อมโยงกับนิยามรูปที่สอดคล้องกันในบัฟเฟอร์อินพุต แต่ละ ID ถูกอนุมานจากบริบทโดยรอบของฟังก์ชันระยะทางที่เกี่ยวข้อง (เนื่องจากฟังก์ชั่นการทำแผนที่ของฉันวนซ้ำผ่านอินพุตบัฟเฟอร์เพื่อค้นหาตัวเลขที่ใกล้เคียงที่สุดสำหรับแต่ละเรย์ในแต่ละขั้นตอนฉันสามารถรักษาค่าของตัวนับลูปได้อย่างปลอดภัย เป็นรหัสรูปสำหรับฟังก์ชั่นนั้น) ในขณะที่ค่าระยะทางถูกกำหนดโดยใช้ SDF หลักตามอำเภอใจ (เช่นpoint - figure.pos สำหรับทรงกลม) และสีจะถูกกำหนดจากสีเฉลี่ยขององค์ประกอบที่เหมาะสมในบัฟเฟอร์รูป (ดังนั้นทำไมจึงมีประโยชน์ในการรักษารูป ID ของมันไว้รอบ ๆ ) หรือผ่านสีขั้นตอนที่ถ่วงน้ำหนักไปสู่ค่าเฉลี่ยที่เก็บไว้ (ตัวอย่างหนึ่งอาจ การนับซ้ำสำหรับบางจุดบน Mandelbulb การแมป "สีเฉลี่ย" ของคุณจากพื้นที่สี FP ไปยังพื้นที่สีจำนวนเต็มจากนั้นใช้สีที่แมปเป็นจานสีโดย XOR โดยเทียบกับจำนวนการทำซ้ำ)

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

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

ฉันไม่รู้ว่าข้างต้นชัดเจนเพียงพอหรือไม่ดังนั้นไม่ต้องกังวลกับการถามว่ามีอะไรไม่เข้าท่า ฉันไม่สามารถให้ตัวอย่างรหัส GLSL / การแรเงาพิกเซลใด ๆ ได้จริง ๆ เนื่องจากฉันทำงานกับ HLSL และการคำนวณการแรเงา แต่ฉันดีใจที่ได้ลองทำทุกสิ่งที่ฉันไม่ได้เขียนอย่างถูกต้องตั้งแต่แรก :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.