Какова цель индексов в 3D-рендеринге?


11

Предположим, вы создавали 3D-куб в OpenGL. Вы реализуете необходимые данные вершины для объекта (куба). Какой смысл использовать индексы?

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

В приведенном выше примере куб создается с необходимыми вершинами в мировом пространстве. Какое значение имеют индексы?


1
Во многих местах вы увидите людей, называющих их лицами. И это то, что они есть. Каждое лицо обычно состоит из 3 вершин, чтобы сформировать треугольник. Следовательно, каждые 3 индекса соответствуют одному треугольнику в конечной сетке. Их называют индексами, потому что они в основном смещены относительно того, где фактическая информация о вершине находится в массиве вершин. Это все, что вам нужно знать об индексах, я думаю :)
Grimshaw

Ответы:


24

Существуют индексы, чтобы уменьшить объем памяти, необходимый для представления трехмерной модели, во многом так же, как цветовые палитры можно использовать для уменьшения объема памяти двухмерного изображения.

Индексирование позволяет избежать повторения полного определения вершины, если вам необходимо дублировать данные этой вершины, как это обычно требуется для сложной модели.

Современные 3D API визуализируют с использованием треугольников; Каждое лицо куба требует двух треугольников:

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 вместо?
Грустный разработчик CRUD

0, 1, 3, 0, 3, 2 на самом деле, спасибо (на основе A = 0, B = 1, C = 2, D = 3). Я обновил ответ.

может быть, стоит упомянуть, что в сетке треугольников среднее число треугольников, смежных с вершиной, равно 6.
Арне

7

Использование индексов служит трем основным целям:

  • Снижение требований к памяти за счет удаления повторяющихся вершин из исходной сетки.
  • Сокращение вычислений вершинного шейдера, позволяя преобразовывать дублирующиеся вершины только один раз.
  • Объединяя примитивы, тем самым позволяя уменьшить количество вызовов отрисовки.

Первый из них очевиден, потому что вы можете измерить его непосредственно в своем собственном коде: если сетка имела, скажем, 50 тыс. Вершин, но если 30 тыс. Из них были дубликатами, то вы экономите память.

Второе и третье не так очевидно: вам нужно уже принять решение об использовании индексов, и вам нужно профилировать свой код и изолировать производительность «до» и «после», чтобы получить их измерение.

Во-вторых, аппаратное обеспечение способно кэшировать результат недавно преобразованных вершин. Если появляется та же самая вершина, что и недавно преобразованная, можно использовать кэшированную версию вместо того, чтобы выполнять вычисления заново. Аппаратное обеспечение использует индекс для их идентификации, поэтому индексы абсолютно необходимы для такого поведения.

В-третьих, каждый выполняемый вами вызов отрисовки имеет нагрузку на ЦП, независимо от того, сколько графической работы ему требуется. Если все остальное одинаково, то рисование 50-килобайтовой сетки в 1 вызове отрисовки будет намного быстрее, чем отрисовка 10k-вызовов. Но если ваша сетка состоит из нескольких полос или (что еще хуже) комбинации полос и вееров, вы не сможете сделать это за один вызов отрисовки без (1) использования индексов или (2) введения вырожденных треугольников. Но поскольку индексы намного меньше вершин, использование индексов является предпочтительным в общем случае.


0

Индексы говорят, какие группы из трех вершин вместе образуют грани куба. Не каждый набор из трех вершин треугольника является гранями треугольника.

Вы можете использовать каждую вершину ровно один раз и просто много раз повторять те, которые используются более чем в треугольнике, но это будет означать дополнительные преобразования вершин. С помощью индексов вы трансформируете вершины только один раз и используете их столько раз, сколько вам нужно.


Когда вы имеете в виду треугольник ??
Грустный разработчик CRUD

Современное графическое оборудование отображает все как треугольники.

1
Если вы действительно хотите понять, что происходит, возьмите диаграмму, нарисуйте трехмерные вершины и проведите линии между вершинами, указанными в INDICES.
ggambett
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.