Jaki jest cel wskaźników w renderowaniu 3D?

11

Załóżmy, że tworzysz kostkę 3D w OpenGL. Implementujesz niezbędne dane wierzchołków dla obiektu (kostki). Po co używać indeksów?

v

 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);

W powyższym przykładzie tworzony jest sześcian z niezbędnymi wierzchołkami w przestrzeni świata. Jakie jest znaczenie dla indeksów?

Smutny programista CRUD
źródło
1
W wielu miejscach zobaczysz ludzi nazywających ich twarzami. I takie są. Każda twarz jest zwykle złożona z 3 wierzchołków, tworząc trójkąt. Dlatego każde 3 wskaźniki odpowiadają jednemu trójkątowi w końcowej siatce. Nazywa się je indeksami, ponieważ są głównie przesunięciami tego, gdzie rzeczywista informacja o wierzchołku znajduje się w tablicy wierzchołków. To chyba wszystko, co musisz wiedzieć o indeksach :)
Grimshaw

Odpowiedzi:

24

Istnieją wskaźniki, które zmniejszają powierzchnię pamięci wymaganą do przedstawienia modelu 3D, podobnie jak palety kolorów mogą być używane do zmniejszenia powierzchni pamięci obrazu 2D.

Indeksowanie pozwala uniknąć powtarzania pełnej definicji wierzchołka, jeśli trzeba zduplikować dane tego wierzchołka, jak zwykle w przypadku modelu złożonego.

Nowoczesne 3D API renderowane przy użyciu trójkątów; każda powierzchnia sześcianu wymaga dwóch trójkątów:

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

Aby określić tę powierzchnię bez indeksów, musisz określić wierzchołki A, B, D, A, D, C. Dwa wierzchołki ( Ai D) są powtarzane w buforze wierzchołków.

Jednak z indeksów, można mieć bufor wierzchołków zawierający wyłącznie wymaganych wierzchołki ( A, B, C, i D) oraz sześć indeksów: 0, 1, 3, 0, 3, 2. Ponieważ indeksy są na ogół znacznie mniejsze niż wierzchołki, a wiele wierzchołków zwykle powtarza się w praktycznych modelach, może to oznaczać znaczną oszczędność miejsca.

Zauważ, że niektóre wierzchołki będą miały tylko częściowe atrybuty. Na przykład podczas renderowania sześcianu z odwzorowaniem tekstury na ogół chce się uzyskać unikalne współrzędne tekstury na ścianę, więc będziesz mieć wiele wierzchołków o tej samej pozycji i różnych współrzędnych tekstury. Ta ilość powielania jest akceptowalna i konieczna; kiedy duplikujesz cały zestaw atrybutów wierzchołków, zaczniesz widzieć korzyści z indeksowania.

Jeśli rzeczywiście wszystkie wierzchołki siatki są w 100% odrębne, indeksy nie przynoszą korzyści (w rzeczywistości zajęłoby więcej miejsca w zużyciu zbędnego bufora indeksów). Jednak nie zawsze tak się dzieje.


źródło
1
Czy zamiast tego powinno być 0,1,3, 0,1,2?
Smutny programista CRUD,
0, 1, 3, 0, 3, 2 faktycznie, dzięki (na podstawie A = 0, B = 1, C = 2, D = 3). Zaktualizowałem odpowiedź.
może warto wspomnieć, że w siatce trójkątów średnia liczba trójkątów sąsiadujących z wierzchołkiem wynosi 6.
Arne
7

Korzystanie z indeksów służy trzem głównym celom:

  • Zmniejszenie wymagań dotyczących pamięci poprzez umożliwienie usuwania zduplikowanych wierzchołków z oryginalnej siatki.
  • Zmniejszenie obliczeń modułu cieniującego wierzchołków poprzez umożliwienie transformacji duplikatów wierzchołków tylko raz.
  • Łączenie prymitywów, umożliwiając w ten sposób redukcję wywołań losowania.

Pierwszy z nich jest oczywisty, ponieważ można go zmierzyć bezpośrednio we własnym kodzie: jeśli siatka miała, powiedzmy, 50 000 wierzchołków, ale jeśli 30 000 z nich było duplikatami, oznacza to oszczędność pamięci.

Drugi i trzeci nie są tak oczywiste - musisz już podjąć decyzję o użyciu indeksów i musisz profilować swój kod i izolować wydajność „przed” i „po”, aby uzyskać ich pomiar.

Po drugie, sprzęt jest w stanie buforować wynik ostatnio przekształconych wierzchołków. Jeśli pojawi się ten sam wierzchołek, który został niedawno przekształcony, można użyć wersji z pamięci podręcznej zamiast ponownie wykonywać obliczenia. Sprzęt korzysta z indeksu do ich identyfikacji, więc indeksy są absolutnie niezbędne, aby uzyskać takie zachowanie.

Po trzecie, każde wywołanie remisu ma narzut procesora, niezależnie od tego, ile pracy GPU musi wykonać. Jeśli wszystko inne jest równe, narysowanie siatki 50 tys. W 1 wywołaniu losowania będzie znacznie szybsze niż narysowanie w 10 tys. Ale jeśli twoja siatka składa się z wielu pasków lub (co gorsza) kombinacji pasków i fanów, nie możesz tego zrobić w jednym wywołaniu losowania bez (1) użycia indeksów lub (2) wprowadzenia zdegenerowanych trójkątów. Ponieważ jednak indeksy są znacznie mniejsze niż wierzchołki, w ogólnym przypadku preferowane jest stosowanie indeksów.

Maximus Minimus
źródło
0

Wskaźniki mówią, które grupy trzech wierzchołków tworzą razem ściany sześcianu. Nie każdy zestaw trzech wierzchołków trójkąta jest powierzchniami trójkąta.

Możesz użyć każdego wierzchołka dokładnie raz i powtórzyć wiele razy te, które są używane w więcej niż trójkącie, ale oznaczałoby to dodatkowe przekształcenia wierzchołków. Za pomocą indeksów przekształcasz wierzchołki tylko raz i używasz ich tyle razy, ile potrzebujesz.

ggambett
źródło
Kiedy masz na myśli trójkąt?
Smutny deweloper CRUD
Nowoczesny sprzęt graficzny renderuje wszystko jako trójkąty.
1
Jeśli naprawdę chcesz zrozumieć, co się dzieje, zdobądź papier milimetrowy, narysuj wierzchołki 3D i narysuj linie między wierzchołkami określonymi przez INDICES.
ggambett