อะไรทำให้พื้นผิวซ้อนทับกันอย่างแน่นอน


10

ฉันไม่สามารถเข้าใจได้ว่าอะไรทำให้พื้นผิวด้านหนึ่งทับซ้อนกัน ในเครื่องมือ 3 มิติที่ฉันสร้างขึ้นเทคนิคของฉันล้มเหลวในกรณีแบบขอบ

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

สี่เหลี่ยมสีม่วงขนาดใหญ่ที่มีส่วนสีแดงอยู่ด้านข้าง

สิ่งที่เราจะเห็นคือพื้นผิวด้านหน้าสีม่วงของลูกบาศก์เท่านั้นในขณะที่พื้นผิวด้านสีแดงถูกทาสีทับสีม่วง ค่าเฉลี่ย z ของพื้นผิวสีม่วงสูงกว่าดังนั้นจึง 'ไกลออกไป' ดังนั้นฉันสงสัยว่าเทคนิคนี้ถูกต้องหรือไม่

สิ่งที่ฉันพยายามก็คือการหาระยะทางจากกล้อง (เช่นที่มา) ไปยังพื้นผิว แต่แล้วฉันก็ต้องการจุด ฉันเลือกตรงกลางของแต่ละพื้นผิว แต่มันก็ไม่ได้ผลเสมอไปเพราะทุกพื้นผิวไม่ใหญ่เท่ากัน

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

คำตอบ:


11

ดูเหมือนว่าคุณจะพยายามที่จะใช้ช่างทาสีขั้นตอนวิธี ฉันเดาว่าคุณกำลังพยายามเขียน rasteriser ตั้งแต่เริ่มต้นเป็นแบบฝึกหัดการเรียนรู้เนื่องจากฮาร์ดแวร์ 3 มิติที่ทันสมัยที่สุดใช้สิ่งที่ Bart ได้กล่าวถึง (บัฟเฟอร์ Z / Depth) เพื่อให้อัลกอริทึมของจิตรกรทำงานได้ในทุกกรณีคุณจะต้องเตรียมแบ่งพื้นผิวเนื่องจากพวกมันถูกสร้างขึ้นเพื่อแก้ไขสถานการณ์ที่เป็นไปได้ (เช่นปัญหารูปหลายเหลี่ยมซ้อนทับกันที่แสดงในหน้า Wikipedia)

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

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


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

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

Roger Perkins พูดถูก คุณจะไม่สามารถบรรลุการจัดเรียง z อย่างถูกต้อง (หมายความว่าคุณจะมีกรณีขอบบางส่วน) เว้นแต่คุณจะตัดรูปหลายเหลี่ยม ที่สามารถกลายเป็นค่อนข้างช้าแม้ว่า
bummzack

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

1
นั่นจะใช้ได้กับรูปร่างนูนง่ายเช่นลูกบาศก์เท่านั้น ฉันดีใจที่มันทำงานให้คุณ แต่ก็ไม่ใช่วิธีแก้ปัญหาทั่วไป
Richard Fabian

3

สิ่งที่คุณต้องเป็นปัญหาการมองเห็น ทางออกหนึ่งคือการใช้Z-บัฟเฟอร์


ขอบคุณ แต่ z-buffering ต้องการการเรนเดอร์พิกเซลหากฉันไม่ผิดพลาด ฉันไม่ได้ทำอย่างนั้น - ฉันวาดเส้นตรงระหว่างจุดที่ฉายของคิวบ์ z-buffering ยังคงเป็นไปได้หรือไม่?
pimvdb

แม้ว่าคุณจะวาดเส้นตรงในบางจุดก่อนที่ภาพจะเข้าสู่หน้าจอ (หรือไฟล์บิตแมป) มันจะอยู่ในรูปแบบพิกเซล
Bart van Heukelom

ถูกต้อง แต่ไลบรารี่รูปวาดของฉันช้าเกินกว่าที่จะแสดงผลพิกเซลด้วย 20fps ขอบคุณแม้ว่า
pimvdb

2

การจัดเรียงใบหน้าตามค่าเฉลี่ย z ของพวกเขาใช้งานไม่ได้เนื่องจากค่าเฉลี่ย z ไม่ได้ให้ข้อมูลเกี่ยวกับค่า z จริงของจุดยอดหรือพิกเซลผิว

ตัวอย่าง (คำเตือน, ASCII art ล่วงหน้า):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

มีสองใบหน้า A และ B จากมุมมองของกล้อง A อยู่ด้านหน้า B แต่ค่า z เฉลี่ยของ B นั้นเล็กกว่า ลองดูค่า z อื่น ๆ :

  • ค่า z ต่ำสุดของ A คือ 4
  • ค่า z สูงสุดของ A คือ 11
  • ดังนั้นค่าเฉลี่ย z ของ A คือ 7.5
  • ค่า z ต่ำสุดของ B คือ 6
  • ค่า z สูงสุดของ B คือ 8
  • ดังนั้นค่าเฉลี่ย z ของ B คือ 7

คุณสามารถลองเรียงมันด้วยค่า z ที่น้อยที่สุด แต่มีบางกรณีที่มันไม่ทำงานเช่นกัน ไม่มีวิธีการเรียงลำดับใบหน้าอย่างถูกต้องโดยใช้ค่า z เพียงค่าเดียว

ในอัลกอริทึมของ Newell http://en.wikipedia.org/wiki/Newell 's_algorithm สิ่งที่คุณทำคือจัดเรียงค่า min / max-range ของค่า z หากช่วงของใบหน้าทั้งสองไม่ซ้อนทับกันคุณสามารถรู้ได้อย่างชัดเจนว่าใบหน้าใดที่อยู่ด้านหน้า หากพวกเขาทำบางครั้งคุณต้องแยกหน้า บางครั้งมันก็เพียงพอที่จะ raytrace ทุกจุดสุดยอดสำหรับการบดเคี้ยวหรือเทคนิคอื่น ๆ


แผนภาพนั้นเป็นภาพค่าใช้จ่ายของสิ่งที่ฉันคาดเดาว่าจะเกิดขึ้นในสกรีนช็อตของเขา
jhocking

1

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

การคัดลอก Backfaceกำลังตรวจสอบพื้นผิวปกติในพื้นที่หน้าจอสำหรับทิศทางของมัน (เพิ่งได้รับสัญญาณขององค์ประกอบความลึกจากพื้นที่หน้าจอเปลี่ยนเป็นปกติ (ในกรณีของเรามันคือ z ของปกติ) หรือผลิตภัณฑ์ครอสของเวกเตอร์สองตัว สามเหลี่ยมคือไขว้ (v1-v0, v2-v0))

หากคุณใช้การคัดแบบ Backface คุณจะลดจำนวนการแรสเตอร์ที่คุณทำ .. ชนะสองเท่า


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

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