Mengapa Objek Penyangga Vertex meningkatkan kinerja?

10

Dari pemahaman dasar saya, Objek Penyangga Vertex berfungsi seperti ini (kode semu):

Biasanya, jika seseorang ingin mengatakan, menggambar kotak, orang bisa mengeluarkan perintah menggambar garis.

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

Menggunakan VBO, jika saya mengerti dengan benar, akan memuat simpul ke VBO.

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

Kemudian Anda bisa mengeluarkan satu perintah menggambar.

draw VBO vertices

Sementara saya mengerti cara kerja VBO, saya tidak tahu mengapa mereka meningkatkan kinerja.

Bagaimana mereka meningkatkan kinerja?

Ethan Bierlein
sumber

Jawaban:

11

Secara umum, ketika Anda merender objek dalam mode langsung — mengeluarkan perintah menggambar garis misalnya — Anda membangun serangkaian perintah yang Anda kirim ke kartu grafis untuk menggambar. Jika Anda menggambar banyak data, atau menggambar sangat sering, Anda dapat membuang banyak waktu mengirimkan data ini berulang kali.

Buffer vertex memungkinkan Anda menghasilkan satu objek yang Anda kirimkan ke kartu grafis satu kali. Jika Anda tidak perlu mengubah geometri, Anda dapat membiarkannya di kartu grafis dan cukup mengirim kartu grafis permintaan untuk menggambar objek itu. Karena itu menghindari salinan setiap kali Anda menggambar, ada jauh lebih sedikit overhead untuk setiap undian.

Perhatikan bahwa menggunakan objek buffer verteks tidak selalu memberikan peningkatan yang sangat signifikan. Jika Anda hanya menggambar objek satu kali per frame, dan Anda mengganti geometri di antara setiap frame, maka Anda tidak mendapatkan manfaat dari menghindari menyalin setiap frame.

Sebagian besar pengalaman saya berasal dari menulis program menggunakan API grafik seperti OpenGL, jadi seseorang yang mengacaukan backend driver grafis mungkin dapat memberikan jawaban yang lebih terperinci, tapi saya harap ini membuat segalanya sedikit lebih jelas.

porglezomp
sumber
10

Ada dua langkah yang membuat VBO lebih efisien daripada mode langsung.

  1. Mode langsung ( glBegin / glEnd , glVertex * , dll.) Berarti bahwa pada setiap frame, Anda memberi makan simpul, atribut per atribut (posisi, normal, warna, dll.), Ke driver, yang kemudian memformat ulang mereka dan akhirnya mengirim seluruh paket sebagai perintah untuk GPU. Itu banyak panggilan fungsi per simpul pada setiap frame.
    (Perhatikan bahwa mode langsung sudah tidak digunakan lagi sejak OpenGL 3.0 , dan sepenuhnya dihapus dari 3.2 .)

  2. Dengan menggunakan array vertex (lihat glDrawArrays , glDrawElements , glVertexPointer , dll.), Anda dapat memberikan driver semuanya sekaligus dan menghemat beban untuk memformat ulang simpul. Anda secara efektif mengganti beberapa panggilan fungsi per simpul hanya dengan beberapa panggilan untuk seluruh jala. Tapi Anda masih perlu melakukan itu sekali bingkai.

  3. Vertex Buffer Object , atau VBO (lihat glGenBuffers , glBindBuffer , dll.) Selangkah lebih maju dan menyimpan data di sisi GPU: Anda mengirimnya hanya sekali, dan kemudian hanya merujuknya dengan pegangan. Anda menghemat bandwidth dengan tidak mengirim data yang sama berulang-ulang di setiap frame.

Julien Guertault
sumber
6

Dengan menggunakan antarmuka mode langsung (mis. OpenGL gaya lama glBegin () / glEnd () / glVertex ()) Anda secara efektif menitikkan data makan ke pengemudi satu per satu. Kemudian harus mengambil sepotong data, memformat ulang dan meneruskannya ke perangkat keras (yang hari ini berarti memasukkannya ke dalam buffer perintah).

Dengan menggunakan objek vertex buffer, Anda memberikan blok data yang besar (mudah-mudahan) kepada pengemudi terlebih dahulu ketika itu perlu digunakan. Itu dapat melakukan sejumlah optimasi (memformat ulang, menempatkan ke dalam memori video) serta tidak harus memberi makan sedikit demi sedikit GPU.

Dalam praktiknya jika Anda hanya menggambar sejumlah kecil primitif maka mungkin tidak akan banyak bedanya, namun jika Anda menggambar mesh segitiga multi-juta maka VBO dalam memori video adalah cara yang harus dilakukan.

Andrew Sidwell
sumber