ฉันต้องเขียนซอฟต์แวร์ 3d rasterizer ของตัวเองและจนถึงตอนนี้ฉันสามารถฉายโมเดล 3 มิติของฉันที่สร้างจากรูปสามเหลี่ยมลงในพื้นที่ 2d:
ฉันหมุนแปลและฉายจุดเพื่อให้ได้พื้นที่ 2 มิติของสามเหลี่ยมแต่ละอัน จากนั้นฉันใช้จุดสามเหลี่ยม 3 จุดและใช้อัลกอริธึม scanline (โดยใช้การแก้ไขเชิงเส้น) เพื่อค้นหาทุกจุด [x] [y] ตามขอบ (ซ้ายและขวา) ของรูปสามเหลี่ยมเพื่อให้ฉันสามารถสแกนสามเหลี่ยมในแนวนอนได้ เรียงต่อกันแล้วเติมด้วยพิกเซล
วิธีนี้ใช้ได้ผล ยกเว้นฉันต้องใช้ z-buffering ด้วย ซึ่งหมายความว่าการรู้พิกัด z ที่หมุนและแปลของจุดยอด 3 จุดของรูปสามเหลี่ยมฉันต้องแก้ไขพิกัด z สำหรับจุดอื่น ๆ ทั้งหมดที่ฉันพบด้วยอัลกอริทึมสแกนไลน์ของฉัน
แนวคิดดูเหมือนชัดเจนพอแรกพบ Za และ Zb ด้วยการคำนวณเหล่านี้:
var Z_Slope = (bottom_point_z - top_point_z) / (bottom_point_y - top_point_y);
var Za = top_point_z + ((current_point_y - top_point_y) * Z_Slope);
จากนั้นสำหรับ Zp แต่ละอันฉันทำการแก้ไขแบบเดียวกันในแนวนอน:
var Z_Slope = (right_z - left_z) / (right_x - left_x);
var Zp = left_z + ((current_point_x - left_x) * Z_Slope);
และถ้า z ปัจจุบันใกล้ชิดกับวิวเวอร์มากกว่า z ก่อนหน้านี้ที่ดัชนีนั้นจากนั้นเขียนสีไปยังบัฟเฟอร์สีและเขียน z ใหม่ไปยังบัฟเฟอร์ z (ระบบพิกัดของฉันคือ x: left -> right; y: top -> bottom; z: หน้าคุณ -> หน้าจอคอมพิวเตอร์;)
ปัญหาคือมันไปยุ่งเหยิง โครงการอยู่ที่นี่และหากคุณเลือกปุ่มตัวเลือก "Z-Buffered" คุณจะเห็นผลลัพธ์ ... (โปรดทราบว่าฉันใช้อัลกอริทึมของจิตรกร (- เพียงเพื่อวาดโครงลวด) ในโหมด "Z-Buffered" สำหรับการแก้ไขจุดบกพร่อง )
PS: ฉันได้อ่านที่นี่ว่าคุณจะต้องเปลี่ยน z เป็นส่วนกลับ (ความหมายz = 1/z
) ของพวกเขาก่อนที่คุณจะแก้ไข ฉันลองมันและดูเหมือนว่าจะไม่มีการเปลี่ยนแปลง ฉันกำลังคิดถึงอะไร (ทุกคนสามารถชี้แจงได้อย่างแม่นยำว่าคุณต้องเปลี่ยน z เป็น 1 / z และที่ไหน (ถ้า) เพื่อเปลี่ยนกลับได้หรือไม่)
[แก้ไข]นี่คือข้อมูลบางส่วนเกี่ยวกับค่า z และค่าต่ำสุดที่ฉันได้รับ:
max z: 1; min z: -1; //<-- obvious, original z of the vertices of the triangles
max z: 7.197753398761272; min z: 3.791703256899924; //<-- z of the points that were drawn to screen (you know, after rotation, translation), by the scanline with zbuffer, gotten with interpolation but not 1/z.
max z: 0.2649908532179404; min z: 0.13849507306889008;//<-- same as above except I interpolated 1/z instead of z.
//yes, I am aware that changing z to 1/z means flipping the comparison in the zBuffer check. otherwise nothing gets drawn.
ก่อนที่ฉันจะทำการดีบักอย่างระมัดระวังใครบางคนสามารถยืนยันได้ว่าแนวคิดของฉันถูกต้องแล้วหรือยัง?
[EDIT2]
ฉันแก้ไข z-buffering แล้ว ตามที่ปรากฎคำสั่งวาดไม่ได้ยุ่งเลย คำนวณพิกัด z อย่างถูกต้อง
ปัญหาคือในความพยายามที่จะเพิ่มอัตราเฟรมของฉันฉันกำลังวาดกล่อง 4px / 4px ทุกพิกเซลที่ 4 แทนพิกเซลจริงบนหน้าจอ ดังนั้นฉันกำลังวาด 16px ต่อพิกเซล แต่ตรวจสอบบัฟเฟอร์ z สำหรับหนึ่งในนั้น ฉันเป็นคนโง่
TL / DR:คำถามยังคงอยู่: คุณจะต้องใช้ส่วนกลับของ Z (ดังใน 1 / z) เป็นอย่างไร / ทำไม / เมื่อใดจึงต้องใช้แทน Z เพราะตอนนี้ทุกอย่างทำงานเหมือนกัน (ไม่มีความแตกต่างที่เห็นได้ชัดเจน)