Tại sao các đối tượng đệm của Vertex cải thiện hiệu suất?


10

Theo hiểu biết cơ bản của tôi, Đối tượng đệm của Vertex hoạt động tương tự như thế này (mã giả):

Thông thường, nếu muốn nói, vẽ hình vuông, người ta có thể ra lệnh vẽ đường thẳng.

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

Sử dụng VBO, nếu tôi hiểu chính xác, sẽ tải các đỉnh vào VBO.

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

Sau đó, bạn có thể ban hành một lệnh vẽ.

draw VBO vertices

Trong khi tôi hiểu cách VBO hoạt động, tôi không biết tại sao họ cải thiện hiệu suất.

Làm thế nào để họ cải thiện hiệu suất?

Câu trả lời:


11

Nói chung, khi bạn kết xuất một đối tượng ở chế độ ngay lập tức, ban hành các lệnh vẽ đường thẳng, ví dụ, bạn xây dựng một loạt các lệnh mà bạn gửi đến card đồ họa để vẽ. Nếu bạn đang vẽ nhiều dữ liệu hoặc vẽ rất thường xuyên, bạn có thể lãng phí rất nhiều thời gian để gửi dữ liệu này nhiều lần.

Một bộ đệm đỉnh cho phép bạn tạo một đối tượng mà bạn gửi đến card đồ họa một lần. Nếu bạn không cần thay đổi hình học của mình, bạn có thể để nó trên card đồ họa và chỉ cần gửi cho card đồ họa một yêu cầu để vẽ đối tượng đó. Vì nó tránh được bản sao mỗi lần bạn vẽ, nên sẽ có ít chi phí hơn cho mỗi lần vẽ.

Lưu ý rằng việc sử dụng một đối tượng bộ đệm đỉnh không phải lúc nào cũng cung cấp một tốc độ rất đáng kể. Nếu bạn chỉ vẽ đối tượng một lần trên mỗi khung và bạn đang thay thế hình học ở giữa mỗi khung, thì bạn không nhận được lợi ích của việc tránh sao chép từng khung.

Hầu hết kinh nghiệm của tôi đến từ việc viết chương trình sử dụng API đồ họa như OpenGL, vì vậy ai đó đã nhầm lẫn với phần phụ trợ của trình điều khiển đồ họa có thể cung cấp câu trả lời chi tiết hơn, nhưng tôi hy vọng điều này làm cho mọi thứ rõ ràng hơn một chút.


10

Có hai bước giúp VBO hiệu quả hơn chế độ ngay lập tức.

  1. Chế độ ngay lập tức ( glBegin / glEnd , glVertex * , v.v.) có nghĩa là tại mỗi khung hình, bạn đưa thìa cho các đỉnh, thuộc tính trên mỗi thuộc tính (vị trí, bình thường, màu sắc, v.v.), cho trình điều khiển, sau đó định dạng lại chúng và cuối cùng gửi chúng toàn bộ gói như một lệnh cho GPU. Đó là rất nhiều hàm gọi cho mỗi đỉnh trên mỗi khung.
    (Lưu ý rằng chế độ ngay lập tức không được chấp nhận kể từ OpenGL 3.0bị xóa hoàn toàn khỏi 3.2 .)

  2. Bằng cách sử dụng các mảng đỉnh (xem glDrawArrays , glDrawElements , glVertexPulum , v.v.), bạn có thể cung cấp cho trình điều khiển toàn bộ mọi thứ cùng một lúc và tiết kiệm cho nó gánh nặng của việc định dạng lại các đỉnh. Bạn đang thay thế một cách hiệu quả một số cuộc gọi chức năng trên mỗi đỉnh chỉ bằng một số ít cuộc gọi cho toàn bộ lưới. Nhưng bạn vẫn cần phải làm điều đó một lần một khung.

  3. Đối tượng đệm của Vertex hoặc VBO (xem glGenBuffers , glBindBuffer , v.v.) tiến thêm một bước và lưu trữ dữ liệu ở phía GPU: bạn chỉ gửi nó một lần, và sau đó chỉ cần tham khảo nó bằng tay cầm. Bạn tiết kiệm băng thông bằng cách không gửi cùng một dữ liệu ở mỗi khung.


6

Bằng cách sử dụng giao diện chế độ ngay lập tức (ví dụ: OpenGL glBegin () / glEnd () / glVertex ()), bạn sẽ truyền dữ liệu cho từng trình điều khiển một cách hiệu quả. Sau đó, nó phải lấy một phần dữ liệu đó, định dạng lại nó và chuyển nó vào phần cứng (ngày nay có nghĩa là đưa nó vào bộ đệm lệnh).

Bằng cách sử dụng một đối tượng bộ đệm đỉnh, bạn đang cung cấp một khối dữ liệu lớn (hy vọng) cho trình điều khiển trước khi cần sử dụng. Nó có thể thực hiện một số tối ưu hóa (định dạng lại, đặt vào bộ nhớ video) cũng như không phải cung cấp cho GPU từng phần.

Trong thực tế nếu bạn chỉ vẽ một số lượng nhỏ nguyên thủy thì có lẽ điều đó sẽ không có nhiều khác biệt, tuy nhiên nếu bạn đang vẽ một lưới tam giác nhiều triệu thì VBO trong bộ nhớ video là cách để đi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.