การแสดงผลที่มีประสิทธิภาพพร้อมแหล่งกำเนิดแสงจำนวนมาก


10

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

สิ่งนี้สามารถขยายได้อย่างง่ายดายเพื่อรองรับแหล่งกำเนิดแสงหลายแห่งด้วยการเพิ่มผลลัพธ์ของการใช้แหล่งกำเนิดแสงแต่ละแหล่งบนชิ้นส่วนเช่น:

final_color = (0, 0, 0, 1)
for each light:
    final_color += apply_light(material, light)
final_color = clamp(final_color, (0,0,0,1), (1,1,1,1))

อย่างไรก็ตามด้วยแหล่งกำเนิดแสงจำนวนมากกระบวนการนี้ค่อนข้างช้า ด้วยNไฟวิธีนี้ต้องใช้การคำนวณสำหรับการแรเงาพองที่จะทำNครั้งต่อชิ้นส่วน

มีวิธีการที่ดีกว่าในการเรนเดอร์ฉากด้วยแหล่งแสงจำนวนมาก (หลายร้อยพัน ฯลฯ ) หรือไม่?

คำตอบ:


15

ใช่ แต่คุณต้องเปลี่ยนกระบวนทัศน์

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

แต่สิ่งต่าง ๆ มีวิวัฒนาการค่อนข้างมาก เข้าสู่: การแสดงผลที่เลื่อนออกไป

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

แนวคิดพื้นฐานคือเลื่อนการแรเงาไปตามหลังท่อ คุณมีสองขั้นตอนหลัก:

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

ภาพจากวิกิพีเดียแสดงสามบัฟเฟอร์ (สีความลึกและบรรทัดฐาน)

ป้อนคำอธิบายรูปภาพที่นี่

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

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

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

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

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

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

วิวัฒนาการเพิ่มเติมในด้านนี้คือการแรเงาแบบกลุ่มซึ่งมีแนวคิดคล้ายกับวิธีการปูกระเบื้องโดยแทนที่จะมีพื้นที่ว่างบนหน้าจอเป็นกระจุกที่มีขอบเขต 3 มิติ วิธีนี้จะจัดการกับปัญหาความไม่ต่อเนื่องเชิงลึกได้ดีกว่าและโดยทั่วไปจะทำงานได้ดีกว่าวิธีการเรียงต่อกัน

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


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