จุดประสงค์ของดัชนีในการเรนเดอร์ 3D คืออะไร?


11

สมมติว่าคุณกำลังสร้างลูกบาศก์ 3D ใน OpenGL คุณใช้ข้อมูลจุดสุดยอดที่จำเป็นสำหรับวัตถุ (คิวบ์) จุดประสงค์ของการใช้ดัชนีคืออะไร

โวลต์

 void CreateCube()
        {
            const Vertex VERTICES[8] =
            {
                { { -.5f, -.5f,  .5f, 1 }, { 0, 0, 1, 1 } },
                { { -.5f,  .5f,  .5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f,  .5f, 1 }, { 0, 1, 0, 1 } },
                { {  .5f, -.5f,  .5f, 1 }, { 1, 1, 0, 1 } },
                { { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
                { { -.5f,  .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
                { {  .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
            };

            const GLuint INDICES[36] =
            {
                0,2,1,  0,3,2,
                4,3,0,  4,7,3,
                4,1,5,  4,0,1,
                3,6,2,  3,7,6,
                1,6,5,  1,2,6,
                7,5,6,  7,4,5
            };

    //....

    glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);

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


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

คำตอบ:


24

มีดัชนีเพื่อลดขนาดหน่วยความจำที่ต้องใช้ในการแสดงโมเดล 3 มิติในลักษณะเดียวกับที่จานสีสามารถใช้เพื่อลดขนาดหน่วยความจำของภาพ 2D

การจัดทำดัชนีช่วยให้คุณหลีกเลี่ยงการทำซ้ำคำจำกัดความของจุดสุดยอดได้อย่างสมบูรณ์ถ้าคุณต้องทำซ้ำข้อมูลของจุดสุดยอดเนื่องจากคุณจำเป็นต้องทำแบบจำลองที่ซับซ้อน

API 3 มิติที่ทันสมัยแสดงผลโดยใช้รูปสามเหลี่ยม แต่ละหน้าของลูกบาศก์ต้องการสองสามเหลี่ยม

A--B 
|\ |   This cube face has two triangles:
| \|   ABD and ADC.
C--D

A, B, D, A, D, Cเพื่อระบุว่าไม่มีใบหน้าดัชนีคุณต้องระบุจุด จุดยอดสองจุด ( AและD) ถูกทำซ้ำในบัฟเฟอร์จุดสุดยอด

แต่ด้วยดัชนีคุณสามารถมีบัฟเฟอร์จุดสุดยอดที่มีเฉพาะจุดที่ต้องการ ( A, B, CและD) 0, 1, 3, 0, 3, 2และหกดัชนี: เนื่องจากดัชนีโดยทั่วไปมีขนาดเล็กกว่าจุดยอดมากและจุดยอดนิยมจำนวนมากมักทำซ้ำในแบบจำลองที่ใช้งานได้จริงจึงสามารถประหยัดพื้นที่ได้อย่างมาก

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

หากแน่นอนจุดยอดตาข่ายทั้งหมดของคุณแตกต่างกัน 100% ไม่มีประโยชน์ต่อดัชนี (อันที่จริงคุณต้องใช้พื้นที่มากขึ้นในการใช้บัฟเฟอร์ดัชนีซ้ำซ้อน) อย่างไรก็ตามสิ่งนี้ไม่ได้เกิดขึ้นเสมอไป


1
ควรเป็น 0,1,3, 0,1,2 แทนไหม
Sad CRUD Developer

0, 1, 3, 0, 3, 2 จริง ๆ ขอบคุณ (จาก A = 0, B = 1, C = 2, D = 3) ฉันอัพเดตคำตอบแล้ว

อาจเป็นสิ่งที่ควรค่าแก่การกล่าวถึงว่าบนสามเหลี่ยมตาข่ายจำนวนสามเหลี่ยมเฉลี่ยที่อยู่ติดกับจุดยอดนั้นคือ 6
Arne

7

การใช้ดัชนีมีจุดประสงค์หลักสามประการ:

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

สิ่งแรกคือสิ่งเหล่านี้ชัดเจนเพราะคุณสามารถวัดได้โดยตรงในรหัสของคุณ: ถ้ามี mesh, บอกว่าจุดยอด 50k แต่ถ้า 30k ของจุดนั้นซ้ำกันคุณก็ประหยัดหน่วยความจำได้

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

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

สำหรับการจับรางวัลครั้งที่สามแต่ละครั้งจะมีโอเวอร์เฮดของ CPU โดยไม่คำนึงว่าจะต้องใช้ GPU มากแค่ไหน หากทุกอย่างอื่นเท่ากันการวาด 50k mesh ใน 1 draw call จะเร็วกว่าการวาดใน 10k draw call แต่ถ้าตาข่ายของคุณประกอบด้วยหลายแถบหรือ (ยิ่งแย่กว่า) การรวมกันของแถบและแฟน ๆ คุณไม่สามารถทำได้ด้วยการดึงสายเดี่ยวโดยไม่ต้อง (1) โดยใช้ดัชนีหรือ (2) แนะนำสามเหลี่ยมที่เสื่อม แต่เนื่องจากดัชนีมีขนาดเล็กกว่าจุดยอดนิยมมากการใช้ดัชนีจึงเป็นที่ต้องการในกรณีทั่วไป


0

ดัชนีบอกว่ากลุ่มสามจุดยอดใดรวมกันเป็นรูปหน้าของคิวบ์ ไม่ใช่ว่าจุดยอดสามจุดของสามเหลี่ยมทุกชุดจะเป็นใบหน้าของรูปสามเหลี่ยม

คุณสามารถใช้จุดสุดยอดแต่ละจุดเพียงครั้งเดียวและเพียงทำซ้ำหลาย ๆ ครั้งที่ใช้ในรูปสามเหลี่ยมมากกว่า แต่จะหมายถึงการแปลงจุดสุดยอดพิเศษ ด้วยดัชนีที่คุณเปลี่ยนจุดยอดเพียงครั้งเดียวและใช้พวกเขาหลายครั้งเท่าที่คุณต้องการ


เมื่อคุณหมายถึงรูปสามเหลี่ยม ??
Sad CRUD Developer

ฮาร์ดแวร์กราฟิกสมัยใหม่ทำให้ทุกอย่างเป็นรูปสามเหลี่ยม

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