OpenGL - ขอบสีขาวบนก้อน


12

ในเกมที่คล้ายกับ Minecraft ที่ฉันกำลังสร้างฉันจะได้ขอบขาวบนลูกบาศก์ของฉัน:

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

มันชัดเจนมากขึ้นในพื้นผิวสีเข้ม พื้นผิวกำลังติดตั้งดังนี้: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

ความช่วยเหลือใด ๆ


3
คุณสามารถแสดงรหัสเกี่ยวกับวิธีที่คุณสร้างการแสดงผลแต่ละคิวบ์และวิธีการวางคิวบ์ได้อย่างไร
joncodo

1
การห่อพื้นผิวทำอะไรที่แตกต่างกันหรือไม่? พื้นผิวมีลักษณะ / ขนาดที่คุณผูกกับอะไร
Chuck D

ฉันแค่อยากจะชี้ให้เห็นว่าฉันเคยเห็นสิ่งนี้เกิดขึ้นในแผนที่ขนาดใหญ่ที่ใช้กระเบื้องขนาดเล็ก ตัวอย่างเช่นสมมติว่าคุณมีไทล์ 1024/1024 เซ็ต / แอตลาสและการใช้ไทล์ของคุณเป็น 32 * 32 คุณได้รับข้อผิดพลาดในการปัดเศษเนื่องจากจุดทศนิยมที่แมปที่จะกล่าวว่าไพ่นั้นมีขนาดเล็กมาก สิ่งนี้ทำให้ความแม่นยำใกล้เป็นไปไม่ได้ ทางออก? แยกแผนที่แผ่นกระเบื้องออกเป็นแผ่นย่อย ๆ นี่คือสิ่งที่ Minecraft ทำหรือเคยทำ พวกเขามีชุดไพ่ใบใหญ่หนึ่งใบและในตอนนั้นพวกเขาสับมันเป็นพื้นผิวแต่ละใบ
Krythic

คำตอบ:


19

มีสองสาเหตุที่เป็นไปได้สำหรับปัญหาประเภทนี้ขึ้นอยู่กับปัญหาที่แท้จริง ฉันจะแสดงรายการทั้งคู่:

1. คุณเห็นสีอื่น ๆ จากพื้นผิวของคุณตามขอบของแผ่นกระเบื้อง

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

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

มีหลายสิ่งที่คุณสามารถทำได้

  • ใช้พื้นผิวอาร์เรย์แทนแผนที่พื้นผิว พื้นผิวอาร์เรย์ประกอบด้วยภาพสองมิติที่มีขนาดเท่ากันและคุณระบุพิกัดที่สามเพื่อเลือกหนึ่งภาพ มันมีจุดมุ่งหมายเพื่อแทนที่แผนที่พื้นผิวโดยไม่มีปัญหาการกรอง อย่างไรก็ตามพื้นผิวของอาเรย์เป็นคุณสมบัติที่ใหม่กว่าอาจไม่สามารถใช้ได้ใน OpenGL เวอร์ชันที่คุณใช้งานอยู่
  • สร้างเส้นขอบ 1 พิกเซลในแต่ละแผ่นพื้นผิวของคุณซึ่งจำลองสีของพิกเซลปกติที่อยู่ติดกัน (นี่คือการปรับใช้ GL CLAMP[_TO_EDGE]ใหม่ แต่ในทางที่ตระหนักถึง atlases พื้นผิว - การใช้งานของคุณไม่มีผลเพราะขอบของกระเบื้องส่วนใหญ่ไม่ได้อยู่ที่ขอบของพื้นผิว) นี่เป็นวิธีแก้ปัญหาที่ฉันใช้ในรายการของฉันเอง ในประเภทก้อน ฉันรู้ว่าไม่มีข้อเสียโดยเฉพาะยกเว้นว่าจะใช้หน่วยความจำพื้นผิวมากขึ้น
  • แทรกพื้นผิวพิกัดของคุณเล็กน้อยเพื่อไม่ให้ไปจนถึงขอบของแผ่นพื้นผิว การทำเช่นนี้มากเกินไปจะนำไปสู่ความบางของขอบของพื้นผิวที่เห็นได้ชัดเจนเมื่อเปรียบเทียบกับพิกเซลที่อยู่ตรงกลาง
  • ใช้พื้นผิวเดียวต่อประเภทกระเบื้อง สิ่งนี้กำหนดต้นทุนการสลับพื้นผิว

2. คุณเห็นช่องว่างระหว่างกระเบื้อง

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

นี้สามารถเกิดขึ้นได้เมื่อคุณไม่ได้ให้ตรงพิกัดเหมือนกันสำหรับจุดของขอบประชุมของกระเบื้องที่อยู่ติดกันซึ่งมักจะเกิดขึ้นอันเนื่องมาจากข้อผิดพลาดจุดลอยตัว ตัวอย่างเช่นหากคุณมีไทล์ขนาด 0.6 และคำนวณขอบด้านขวาของไทล์x=100ด้วย(100*0.6) + 0.6และขอบด้านซ้ายของไทล์x=101ด้วย(100*0.6)คุณจะไม่ได้รับคำตอบเหมือนกันแน่นอนและความแตกต่างสามารถมองเห็นเป็นจุดเล็ก ๆ ของ ช่องว่าง

วิธีแก้ไขคือทำให้แน่ใจว่าเลขคณิตของคุณสอดคล้องกัน วิธีการทำเช่นนี้คือ:

  • ให้แน่ใจว่าคุณจะไม่ได้ (แม้ทางอ้อม) คอมพิวเตอร์แต่เพียงindex*size + size(index+1)*size
  • ตรวจสอบให้แน่ใจว่าเลขคณิตของคุณถูกต้อง; วิธีที่ง่ายที่สุดในการทำเช่นนี้คือทำให้ขนาดไทล์ 1.0 ของคุณตรงซึ่งจะส่งผลให้มีเลขคณิตเลขจำนวนเต็มถึงแม้ว่าคุณจะทำการคำนวณด้วยการลอยแบบ 32 บิต (มากถึง 16 ล้านบล็อกจากจุดเริ่มต้น)
  • ใช้จำนวนเต็มจริงสำหรับการคำนวณจุดสุดยอดพิกัด; สิ่งนี้ทำให้คุณมีช่วงที่มากยิ่งขึ้น

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

ขอขอบคุณการแทรกพิกัดพื้นผิวด้วยบิตดูเหมือนจะแก้ไขได้
Luis Cruz

@ มาริโอฉันคิดว่านี่คือกำลังขยายที่ใกล้เคียงที่สุด - ให้สังเกตเส้นขอบที่แหลมคมที่ด้านในของกระเบื้อง ดังนั้นสำหรับมุมมองนั้นมันเป็นพื้นผิวที่มีความละเอียดไม่สิ้นสุด
Kevin Reid

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