Cách hiệu quả nhất để vẽ số lượng lớn các đối tượng giống nhau, nhưng với các biến đổi khác nhau


8

Tôi muốn vẽ một số lượng lớn (nhiều nghìn) lưới đơn giản (mỗi lưới có thể ... tối đa 50 hình tam giác, nhưng thậm chí đó là một giới hạn trên rất lớn), tất cả đều giống hệt nhau.

Như một cách đơn giản, ngay bây giờ tôi chỉ thực hiện hàng ngàn cuộc gọi rút thăm, trong đó tôi chỉ thay đổi ma trận biến đổi mà các shader cần và sau đó vẽ lại các đối tượng tương tự.

Tất nhiên điều này rất chậm, vì (tôi đoán) có quá nhiều cuộc gọi rút thăm để trình điều khiển và PC của tôi xử lý hiệu quả.

Tôi có thể làm gì để làm cho nó nhanh hơn?


4
Tôi không thể cung cấp cho bạn một câu trả lời hoàn chỉnh, nhưng câu trả lời cấp cao là sử dụng sự thay đổi hình học .
Seth Battin

Tìm kiếm trên google cho "Geometry Instance", có thể bạn có thể tìm thấy thứ gì đó giúp bạn theo cách đó
Luis W

Câu trả lời:


11

Giải pháp cho vấn đề này là sự ổn định. Hướng dẫn này giải thích một vài phương pháp của inst instance. Nếu bạn có ARB_draw_instancedARB_instanced_arrays, sử dụng chúng.

Ý tưởng chung là lưu trữ tất cả các biến đổi của các lưới của bạn trong một đối tượng bộ đệm riêng biệt và liên kết nó với một mảng thuộc tính sử dụng một "đỉnh" cho mỗi thể hiện thông qua glVertexAttribDivisor.

Nếu sau đó, bạn vẫn không chạy nhanh như bạn muốn, có lẽ bạn bị ràng buộc bộ xử lý đỉnh. Đừng nản lòng trên các mắt lưới, và tốt nhất là xây dựng một BVH để vượt qua thay vì thực hiện loại bỏ trên tất cả các mắt lưới một cách độc lập.


1
+1; với hàng ngàn đối tượng, bạn cũng có thể bị ràng buộc CPU trên các biến đổi (chỉ cần gửi vị trí và xoay trong bộ đệm theo trường hợp của bạn và tính toán ma trận cho từng đối tượng trên GPU có thể giúp đỡ ở đây) và đừng quên xem cách bạn cập nhật bộ đệm đỉnh động đó!
Maximus Minimus

@Robert Rouhani: Cảm ơn, tôi đã nghiên cứu và triển khai kịp thời. Bây giờ tôi có thể vẽ 5000 mắt lưới với 20 tris mỗi lưới ở 250 FPS. Nhân tiện, cách đề xuất của bạn có vẻ hơi lỗi thời. Vì OpenGL 3. một cái gì đó hình học hình học là một phần chính thức của đặc tả lõi OpenGL, không cần ARB_xxx nữa. Tôi sử dụng bộ đệm thống nhất để lưu trữ ma trận và sử dụng glDrawElementsInstified. Bên trong shader đỉnh, có một ma trận đồng nhất bố cục (std140) {mat4 mảng [5000]; } nơi tôi có thể truy cập phần tử có liên quan qua mảng [gl_InstanceID]
TravisG

1
@TravisG Tôi có xu hướng thử và hỗ trợ các phiên bản cũ hơn. Tôi hiểu cả hai tiện ích mở rộng này đã được quảng bá vào lõi trong một thời gian, tuy nhiên chuỗi tiện ích mở rộng vẫn sẽ có mặt :). Ngoài ra, sử dụng glVertexAttribDivisor(không bị phản đối hoặc lỗi thời bởi bất kỳ phương tiện nào) có lợi ích là không có giới hạn trên về số lượng cá thể. Hiệu suất đã được lịch sử tốt hơn so với bộ đệm đồng nhất, nhưng có lẽ là giống hoặc rất giống bây giờ, và cả hai cách đều hoàn thành công việc.
Robert Rouhani

@Robert Rouhani: Mhm ... tôi đoán đó là sự thật. Ai đó có trình điều khiển lỗi thời có thể hỗ trợ ARB_xxx nhưng không phải là tính năng OpenGl 3.x cốt lõi chính thức. Tôi sẽ xem glVertexAttribDivisor, cảm ơn.
TravisG

Tài khoản vs ~ 2000 với glVertexAttribDivisor, số 250 khung hình / giây chỉ dành cho phía CPU).
TravisG
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.