ทำไม pixel shaders ไม่ให้เราอ่านโดยตรงจาก framebuffer หรือ buffer ความลึก?


18

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

ทำไมทั้ง OpenGL และ DirectX ไม่ให้ฉันทำเช่นนี้? ฉันคาดหวังว่าจะมีข้อ จำกัด ด้านฮาร์ดแวร์บางอย่าง แต่การผสมสีด้วยอัลฟาใช้สีใน framebuffer สำหรับการคำนวณแบบผสมผสานและการทดสอบ Z จะทดสอบบัฟเฟอร์ความลึกที่ตำแหน่งปัจจุบัน ทำไมไม่เพียงแค่เปิดเผยค่าเหล่านี้กับเราโดยตรง ฉันหวังว่าจะเห็นสิ่งนี้ในอนาคตหรือไม่

คำตอบ:


20

มันเป็นข้อ จำกัด ของฮาร์ดแวร์ Fragment Shader เป็นส่วนหนึ่งของไพพ์ไลน์ที่สามารถตั้งโปรแกรมได้ แต่การผสมสีสุดท้ายกับบัฟเฟอร์เป้าหมายนั้นไม่สามารถตั้งโปรแกรมได้ในฮาร์ดแวร์ / ชุดสินค้าที่มีวางจำหน่ายอย่างแพร่หลาย ณ จุดนี้ (มันสามารถกำหนดได้ผ่านทางสถานะการผสม แต่คุณไม่สามารถเขียนเอง รหัสที่มาแทนที่การผสมผสานของ GPU ในตัว)

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

เพียงเพราะพิกเซล A จะอยู่ด้านหลังพิกเซล B ในเฟรมสุดท้ายไม่ได้หมายความว่าพิกเซล A จะเสร็จสิ้นการประมวลผลส่วนและเขียนไปยังปลายทางก่อน B โดยเฉพาะอย่างยิ่งในหลาย ๆ เฟรมของการเรนเดอร์ ดังนั้นค่าที่อ่านจากบัฟเฟอร์ปลายทางในระหว่างการประมวลผลพิกเซล B จะไม่ใช่พิกเซล A เสมอไป - บางครั้งมันจะเป็นค่าที่ชัดเจน

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

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


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

4

ถึงแม้จะน่ารำคาญ แต่ก็ช่วยให้ผู้ผลิตฮาร์ดแวร์มีความยืดหยุ่นในการปรับกระบวนการแสดงผลให้เหมาะสมและหลากหลาย

ตัวอย่างเช่นฮาร์ดแวร์ PowerVR (เคยใช้ในวันที่ไม่ได้ใช้มานาน) รอจนกว่าจะส่งภาพทั้งหมดที่แสดงแล้วทำการเรียงลำดับความลึกอัตโนมัติโดยใช้อัลกอริทึมจิตรกรและไม่จำเป็นต้องสร้าง บัฟเฟอร์ความลึก มันจะแบ่งหน้าจอเป็นกระเบื้องและทำให้แต่ละคนในทางกลับกัน


4

ตัวแบ่งพิกเซลไม่สามารถอ่านจากบัฟเฟอร์สีและความลึกได้เนื่องจาก:

พิกเซล A และ B อาจมีเงาในช่วงเวลาเดียวกันในฮาร์ดแวร์แม้ว่า B ในที่สุดจะแสดงผลที่ด้านบนของ ("หลัง") พิกเซล A

ถ้าคุณทำมันดังนั้นฮาร์ดแวร์รับประกันว่าจะแรเงา A ก่อน B ดังนั้นฮาร์ดแวร์บางส่วนจะนั่งทำอะไรขณะที่ A แรเงาแล้วส่วนของฮาร์ดแวร์จะนั่งทำอะไรขณะที่ B แรเงา

ในกรณีที่เลวร้ายที่สุดเท่าที่จะเป็นไปได้พิกเซลทั้งหมดที่คุณแรเงานั้นจะอยู่ด้านบนของกันและกันและเป็นพันในเธรด GPU หลายพัน - ทั้งหมดยกเว้นหนึ่ง - ไม่ได้ใช้งาน เธรดนี้มีความอดทนต่อการแรเงาพิกเซล A จากนั้น B และ C ...

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