Чому об’єкти буферних вершин покращують продуктивність?


10

З мого основного розуміння, буферний об’єкт Vertex працює приблизно так (псевдокод):

Зазвичай, якби хотіли сказати, намалювати квадрат, можна було б видавати команди для малювання рядків.

line (0, 0) -> (1, 0)
line (1, 0) -> (1, 1)
line (1, 1) -> (0, 1)
line (0, 1) -> (0, 0)

Якщо я правильно розумію, використовуючи VBO, ви завантажуєте вершини в VBO.

define VBO
load (0,0) -> VBO
load (1,0) -> VBO
load (1,1) -> VBO
load (0,1) -> VBO
load (0,0) -> VBO

Тоді ви можете надати одну команду малювання.

draw VBO vertices

Хоча я розумію, як працюють VBO, я не знаю, чому вони покращують продуктивність.

Як вони покращують продуктивність?

Відповіді:


11

Загалом, коли ви рендеруєте об'єкт у безпосередньому режимі (наприклад, видаючи команди для малювання рядків), ви створюєте ряд команд, які ви подаєте на відеокарту для малювання. Якщо ви малюєте багато даних або малюєте дуже часто, ви можете витрачати багато часу, надсилаючи ці дані знову і знову.

Вершинний буфер дозволяє виробляти один об'єкт, який ви один раз подаєте на відеокарту. Якщо вам не потрібно змінювати геометрію, ви можете залишити її на графічній карті та просто надіслати відеокарті прохання намалювати цей об’єкт. Оскільки це дозволяє уникати копії кожного разу, коли ви малюєте, для кожного малювання набагато менше накладних витрат.

Зауважте, що використання об'єкта вершинного буфера не завжди забезпечує дуже значну швидкість. Якщо ви малюєте об'єкт лише один раз на кадр, і ви замінюєте геометрію між кожен кадр, ви не отримаєте переваг уникнути копіювання кожного кадру.

Більшість мого досвіду надходить із написання програм із використанням графічних API, таких як OpenGL, тож хтось, хто заплутався із вихідним графічним драйвером, напевно, може дати більш детальну відповідь, але я сподіваюся, що це робить дещо зрозумілішими.


10

Два кроки роблять VBO більш ефективним, ніж безпосередній режим.

  1. Негайний режим ( glBegin / glEnd , glVertex * і т. Д.) Означає, що на кожен кадр ви ложкою подаєте вершини, атрибут на атрибут (положення, нормальний, колір тощо), драйверу, який потім переформатує їх і нарешті надсилає весь пакет як команда для GPU. Дуже багато функцій викликає вершину на кожному кадрі.
    (Зверніть увагу, що негайний режим застарілий з часу OpenGL 3.0 і повністю видалений з 3.2 .)

  2. Використовуючи вершинні масиви (див. GlDrawArrays , glDrawElements , glVertexPointer тощо), ви можете дати водієві всю справу відразу і зберегти її тягар переформатування вершин. Ви ефективно замінюєте кілька викликів функцій на вершину лише кількома дзвінками для всієї мережі. Але вам все одно потрібно зробити це один раз кадром.

  3. Об'єкт Vertex Buffer , або VBO (див. GlGenBuffers , glBindBuffer тощо), пройдіть ще один крок і збережіть дані на стороні GPU: ви надсилаєте їх лише один раз, а потім просто звертаєтесь до них за допомогою ручки. Ви економите пропускну здатність, не надсилаючи однакові дані знову і знову на кожен кадр.


6

Використовуючи інтерфейс негайного режиму (наприклад, старий стиль OpenGL glBegin () / glEnd () / glVertex ()), ви ефективно переносите дані про драйвер одночасно. Потім він повинен взяти цей єдиний фрагмент даних, переформатувати його і передати його на апаратне забезпечення (що в ці дні означає введення його в буфер команд).

Використовуючи об’єкт вершинного буфера, ви надаєте (сподіваємось) великий блок даних драйверу до того, коли його потрібно використовувати. Він може здійснити ряд оптимізацій (переформатування, розміщення у відеопам'яті), а також не потребує живлення графічного процесора.

На практиці, якщо ви малюєте лише невелику кількість примітивів, це, ймовірно, не матиме великої різниці, однак, якщо ви малюєте багатомільйонну сітку трикутника, то це VBO у відеопам'яті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.