Уникальность OpenGL DirectX XNA Vertex При использовании Индексов или нет? - PullRequest
0 голосов
/ 26 февраля 2012

Это то, что я получаю при чтении файла FBX

Normals Count        = 6792
TextureCoords Count =  6792
Faces =                2264
Vertices =             3366

Чего я не понимаю, так это почему у меня меньше вершин, чем у Normals / TextCoords

Мне нужна ваша помощь, чтобы понять, когдаЯ должен использовать индексный буфер, и когда нет

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

Допустим, у меня есть модель с 1000 вершинами и 3000 гранями, сформированными из этих вершин, таким образом, индексный буфер состоит из 9000 элементов (3 индекса наface)

У меня есть 1000 уникальных массивов Positions, но 9000 уникальных TextCoords плюс массив Normals

Если вершины были только Position, это лучший сценарий для индексного буфера, без избыточных вершин

Но бывает, что у меня также есть TextureCoords и Normals, и для каждой грани они могут иметь разные значения для Позиции, другими словами, Положение, общее для граней, но с разными атрибутами для каждой грани

Так чтоуникальность вершины будет -Position И TextureCoord AND Normal-

Маловероятно, что я повторил вершины с этой полной комбинацией, тогда индексы бесполезны, верно?

Мне нужно будет повторитьПоложение для каждого TextureCoord AND Normal

В конце концов, кажется, я не могуПреимущество наличия только 1000 индексированных позиций

Тогда моя точка зрения, мне не нужны индексы, верно?или я неправильно понимаю концепции?

Ответы [ 2 ]

1 голос
/ 26 февраля 2012

Маловероятно, что я повторю вершины с этой полной комбинацией, тогда индексы бесполезны, верно?

Если у вас есть модель, в которой каждое лицо имеет свои совершенно уникальные текстурные координаты, да, индексы вам не очень помогут. Кроме того, у вас нет повторяющихся вершин; Вы повторили позиций . Позиции не вершины; они являются частью данных вершины, так же, как нормаль, текстовая координата и т. д.

Тем не менее, я не прошу вас показать мне такую ​​модель для любого разумного объекта (то есть: что-то явно не ограненное для эффекта, или что-то, что не было мозаичным образом, если говорить о его координатах текстуры). А для модели с 3000 отдельных граней, поэтому без кубиков.

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

0 голосов
/ 26 февраля 2012

Предполагая, что вы храните свои буферы на GPU, а не в памяти клиента, индексный буфер не будет ничего делать для уменьшения пропускной способности GPU после инициализации.Вместо этого он экономит пространство VRAM, не дублируя данные вершин.

Если ваши данные настроены таким образом, что вершины никогда не повторяются, использование индексов является избыточным и не экономит пространство.

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

Обычно при работе с 3d-моделями, состоящими из тысяч вершин,будет много совпадений вершин, и использование индексов очень поможет.Немного интересно, что у вас не так много дублированных вершин.

Вот два примера, где индексация полезна, а где нет:

Пример 1

Вы рисуете квадрат как два отдельных треугольника.

v0---v3
 |\  |
 | \ |
 |  \|
v1---v2

Так как этот пример находится в 2d, мы можем реально использовать только позиции и координаты текстуры.Без индексации ваш буфер вершин будет выглядеть так, если вы чередуете позиции и координаты текстуры вместе:

p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p0x, p0y, t0x, t0y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y

Когда вы используете индексы, ваш буфер вершин будет выглядеть так:

p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y

и у вас будет индексный буфер, который выглядит следующим образом:

0, 1, 2,
0, 2, 3

Предполагая, что все ваши данные вершин float с, а ваши индексы byte с, количество занятого неиндексированного пространства равно 96 байт , а индексированный - 70 байт .

Это не много, но это только для одного квадрата.Да, этот пример не самый оптимизированный способ рисования квадрата (вы можете избежать индексов во втором примере, рисуя в виде полос треугольника, а не треугольников), но это самый простой пример, который я могу придумать.

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

Пример 2

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

[

Изображение из статьи в Википедии для Треугольник веер .

Чтобы нарисовать кругиспользуя этот метод, вы начинаете с любой вершины и добавляете все остальные вершины в порядке, идущем либо по часовой стрелке, либо против часовой стрелки.(Вы могли бы лучше визуализировать это, представив, что A перемещено вниз, чтобы быть ниже F и B на диаграмме выше). Это работает так, что индексы последовательны и никогда не повторяются.

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

0, 1, 2, 3, 4, ..., n

Неиндексированная версия будет такой же, только без буфера индекса.


В 3d вы найдете это далекореже можно найти режим рисования, полностью соответствующий вашей индексации, как показано в примере с кружком.В 3d индексирование почти всегда полезно до некоторой степени.

...