2017-02-14 6 views
1

Предположим, я создаю два буфера вершин для двух разных сеток.Использование индексных буферов в DirectX 11; как он узнает?

 (I'm assuming creating separate buffers for separate meshes is how it's usually done) 

Теперь предположим, что я хочу нарисовать одну из сеток с помощью индексного буфера. Глядя на книгу Практическая визуализация и вычисление с помощью Direct3D 11 не похоже, что создание индексного буфера каким-либо образом ссылается на буфер вершин, так как знает буфер индекса (во время сборки ввода), какой буфер вершин должен действовать ?

Я сделал несколько поисковых запросов без ответов, что заставляет меня предположить, что в этом есть что-то очевидное, что я отсутствую.

ответ

2

Вы правы, буферы индекса не ссылаются на конкретные буферы вершин. В течение DrawIndexed активный индексный буфер используется для подачи индексов в активные буферы вершин (те, которые вы устанавливаете с помощью SetIndexBuffer/SetVertexBuffers).

+0

Хорошо, я не знал об этом. Так скажите, было ли мое предположение правильным в том, что у вас есть отдельные буферы для отдельных сеток? Я понимаю, что один из них может быть полезен для определенных сеток, таких как статические реквизиты на сцене и т. Д., Но в целом это хорошая/плохая практика? Существуют ли какие-либо ограничения в отношении того, сколько можно/должно использовать? –

+1

Вы можете организовать свои VBs/IB по-разному. Ключевая проблема заключается в том, что вы должны иметь возможность подавать каждое «подмножество ячеек» как отдельную ничью, потому что параметры материала должны меняться между ничьей.Вы даже можете использовать один VB и один IB для целых уровней (в рамках [аппаратных ограничений] (https://blogs.msdn.microsoft.com/chuckw/2012/06/20/direct3d-feature-levels/)). Если вы новичок в DirectX, вы должны просто сделать то, что просто. BTW, посмотрите на [DirectX Tool Kit] (https://github.com/Microsoft/DirectXTK/wiki/Getting-Started). –

+1

@EliasFinoli. Лучшая практика (с точки зрения производительности) уменьшает количество вызовов DI, то есть пакетно-групповые сетки, которые разделяют вершинную компоновку, некоторые текстуры и некоторые шейдеры вместе, объединяя их VB/IB и отображая их в один вызов. Существует не общая стратегия выбора, она зависит от вашей сцены, целевых аппаратных возможностей и т. Д. Некоторые из этих методов упоминаются здесь (https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch28.html). – w1ck3dg0ph3r

1

Действительно, буферы индексов и буферы вершин полностью независимы.

индекс буфер будет знать о VertexBuffer во время ничьи (например: когда и как привязанные к трубопроводу)

Вы можете думать о индексном буфере, как «Lookup Table», где вы сохранить список или элементы индексы в привлечь.

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

Развязывающих и имеет много преимуществ, вот несколько примеров:

  • Вы можете повторно использовать буфер индексов (например, два разнесенных сетки с одинаковым разрешением могут разделить один индексный буфер). Это может быть приличный прирост памяти.
  • Вы можете нарисовать свой Vertex-буфер самостоятельно и выполнить некоторую обработку на вершину (например, нарисуйте список точек для спрайтов или примените скинирование/смещение в буфер потока потока, затем нарисуйте полученный вершинный буфер с помощью DrawIndexed)
  • Оба буфера Vertex/Index также могут быть привязаны как ByteAddressBuffer, поэтому вы также можете обрабатывать свою геометрию в Compute Shader и создавать другой оптимизированный индексный буфер, например, с отбракованными треугольниками, а затем обрабатывать Indexed Draw с оптимизированным буфером. Применение этих отбраков с индексами вместо вершин часто быстрее вершины, так как вы будете перемещать гораздо меньше памяти.
  • Это нишевый случай, но иногда мне нужно нарисовать сетку как набор треугольников, но затем нарисуйте как набор линий (в некоторой форме каркаса). Если в качестве примера вы берете один ящик, вам не нужно рисовать диагонали в виде строк, поэтому у меня есть общий Vertexbuffer с вершинами ящиков, затем один IndexBuffer, предназначенный для рисования списка треугольников, а другой для рисования списка линий. В случае больших моделей это также может быть эффективным усилением памяти.
Смежные вопросы