2011-09-24 9 views
17

Co jest preferowane, z punktu widzenia efektywności (lub innego punktu widzenia, jeśli jest to ważne)?OpenGL jest lepszy do grupowego rysowania lub do statycznych VBO

Sytuacja zastosowanie
OpenGL, który czerpie wiele linii w różnych pozycjach co rama (60 klatek na sekundę). Powiedzmy, że jest 10 linii. Lub 100 000 linii. Czy odpowiedź byłaby inna?

  • # 1 mieć statyczny VBO, że nigdy się nie zmienia, zawierający 2 wierzchołki linii

Każda rama miałaby jeden glDrawArrays zadzwonić na linię rysować, a pomiędzy nimi nie byłoby transformacje matrix aby ustawić nasz jedna linia

  • # 2 Aktualizacja VBO z danymi dla wszystkich linii każda ramka

Każda klatka ma jedno wywołanie losowania

Odpowiedz

27

Druga jest niesamowicie wydajniejsza.

Zmiana stanów, szczególnie transformacja i macierze, może powodować ponowne obliczanie innych stanów i generalnie więcej matematyki.

Aktualizacja geometrii polega jednak po prostu na zastąpieniu bufora.

Dzięki nowoczesnemu sprzętowi wideo na dość masowych magistralach szerokopasmowych wysyłanie kilku elementów pływających jest banalne. Są zaprojektowane do szybkiego przenoszenia ton danych, jest to efekt uboczny pracy. Aktualizowanie buforów wierzchołków jest dokładnie tym, co robią często i szybko. Jeśli przyjmiemy 32-bajtowe punkty (pozycja i kolor float4), 100000 segmentów linii ma mniej niż 6 MB, a PCIe 2.0 x16 to około 8 GB/s, jak sądzę.

W niektórych przypadkach, w zależności od tego, jak zmienia się uchwyt sterownika lub karta, zmiana może powodować pewne mnożenie macierzy i ponowne obliczanie innych wartości, w tym transformacji, wycinania i wycinania płaszczyzn itp. Nie stanowi to problemu, jeśli zmienisz państwo, narysuj kilka tysięcy polys i powtórz, ale kiedy zmiany stanu są często, będą miały znaczny koszt.

Dobrym przykładem tego, co zostało wcześniej rozwiązane, jest koncepcja grupowania, minimalizująca zmiany stanu, co pozwala na większą geometrię między nimi. Służy do wydajniejszego rysowania dużych ilości geometrii.

Jako bardzo wyraźny przykład, rozważ najlepszy przypadek dla # 1: zestaw transformatorów wyzwala bez dodatkowych obliczeń, a sterownik buforuje gorliwie i idealnie.Aby narysować 100000 linie, trzeba:

  • 100000 zestawów macierzy (w systemowej pamięci RAM)
  • 100000 matrix zestaw połączeń z napowietrznej wywołania funkcji (do sterownika wideo, kopiowanie matrycy do bufora tam)
  • 100000 macierze skopiowane do pamięci wideo, wykonywane w jednej bryle
  • 100000 linia remis zwraca

funkcja połączeń napowietrznych sam zamierza zabić wydajność.

Z drugiej strony, Składowanie obejmuje:

  • 100000 obliczenia punktów i zestawów w pamięci systemowej RAM
  • 1 VBO kopię wideo RAM. Będzie to duża porcja, ale pojedynczy ciągły kawałek i obie strony wiedzą, czego się spodziewać. Można go dobrze obsługiwać.
  • 1 matryca zestaw wezwanie
  • 1 kopia matryca do pamięci wideo
  • 1 wywołanie remis

Robisz skopiować więcej danych, ale istnieje duża szansa zawartość VBO nadal nie są tak drogie jak kopiowanie dane matrycy. Co więcej, oszczędzasz ogromną ilość czasu procesora w wywołaniach funkcji (od 200000 do 2). To upraszcza życie kierowcy, który musi buforować wszystko i sprawdzać nadmiarowe połączenia oraz optymalizować i obsługiwać pobieranie, a także prawdopodobnie kartę graficzną (która mogła zostać ponownie obliczona). Aby uczynić go naprawdę jasne, wizualizację prostego kodu dla niego:

1:

for (i = 0; i < 100000; ++i) 
{ 
    matrix = calcMatrix(i); 
    setMatrix(matrix); 
    drawLines(1, vbo); 
} 

(teraz rozpakować to)

2:

matrix = calcMatrix(); 
setMatrix(matrix); 
for (i = 0; i < 100000; ++i) 
{ 
    localVBO[i] = point[i]; 
} 
setVBO(localVBO); 
drawLines(100000, vbo); 
+3

Ok, więc to znaczy, że jest zawsze lepiej piec na VBO, a następnie rysować, w przeciwieństwie do używania macierzy do transformacji? Co jeśli powiem kilka, może 10, poruszających się teksturowanych quadów. Czy byłoby naprawdę lepiej obliczyć współrzędne obiektów, odtworzyć VBO, załadować i narysować? W przeciwieństwie do korzystania z translacji macierzy (którą optymalizuję, aby była po prostu 2 dodatkami zamiast 64 multiplikacjami i 48 dodatkami) dla każdego obiektu, a następnie dla każdego z nich. – mk12

+1

"Jeśli przyjmiemy 32-bajtowe punkty każdy (pozycja i kolor float4)" I nie byłoby praktycznie żadnego wysiłku, aby przeciąć to na pół: vec3 pozycji i vec4 niepodpisanych kolorów bajtów. Należy również zbadać [streaming obiektu bufora] (http://www.opengl.org/wiki/Buffer_Object_Streaming), aby poprawić wydajność tego. –

+1

@ Mk12 Zadałeś o wiele bardziej skomplikowane pytanie. Odpowiedź na pytanie była prosta, ponieważ każdy obiekt był bardzo mały, a nawet gdy było ich dużo, dane werteksów były niewielkie. Po uzyskaniu większej liczby obiektów koszt obliczania ich pozycji staje się znacznie większy, podobnie jak koszty przesyłania. –