Instancja poprawia wydajność (znacznie) podczas renderowania wielu (setki tysięcy?) Kopii tej samej siatki jednocześnie. Ale ile to narzutu podczas renderowania dokładnie jednej kopii za pomocą jednego wywołania losowania? Czy dobrym pomysłem byłoby użycie instancji dla całej geometrii renderowanej przez silnik?
Edycja: Załóżmy, że tworzymy grę FPS. Większość obiektów ma tylko jedną instancję: nóż, pistolet, karabin maszynowy, budynek i wieżę radiową. Ale są też obiekty z wieloma instancjami: drzewa (np. 3 rodzaje drzew z setkami instancji), trawa i tak dalej ... Mam na myśli: zamiast renderować obiekty z jedną instancją w „tradycyjny” sposób i drzewa i trawy za pomocą instancji, renderujemy je wszystkie za pomocą instancji. Tak więc nasza wieża radiowa ma tylko jedną instancję (której informacje przechowujemy w buforze danych instancji) i renderujemy tę wieżę za pomocą pewnego rodzaju DrawInstanced()
wywołania z liczbą instancji równą 1
. To samo dotyczy wszystkich innych obiektów (oczywiście drzewa i trawa mają wiele wystąpień).
Moje pytanie brzmi: czy złym pomysłem jest narysowanie pojedynczej instancji obiektu za pomocą instancji? Czy wystąpienie ma zbyt dużo narzutu (pod względem pamięci i wydajności), czy też jest w jakikolwiek sposób niepożądane w przypadku renderowania obiektów z jedną instancją?
źródło
(W moim systemie nie testowałem tego nigdzie indziej) W GL, wystąpienie pojedynczej siatki (rysunek z liczbą = 1) ma trochę nieprzyjemnego narzutu, ale nie wiem skąd pochodzi. Zdecydowanie odradzam to.
Testowałem to w praktycznym zastosowaniu kilka miesięcy temu. Zakodowałem niektóre algorytmy globalnego oświetlenia w scenie Crytek Sponza, która składa się z około 350 oczek (nie pamiętam dokładnie), z których kilka dzieli kilka przykładów. Na początku zrobiłem to tak, jak sugerujesz, po prostu wstaw wszystko i narysuj resztę z liczbą wystąpień 1, ponieważ nieco uprościło to renderowanie kodu.
Później podczas optymalizacji renderera, samo przejście z instancji count = 1 obiektów do przesłania ich w zwykły sposób pozwoliło mi zaoszczędzić około 3,5 milisekundy na klatkę na i7 3770k (i GTX 770). Przełączanie siatek z wieloma instancjami na zwykłe wykonywanie ich w tradycyjny sposób pozwoliło mi zaoszczędzić kolejne 0,5 ms. Ogólnie aplikacja wzrosła z ~ 120 FPS do około ~ 230 FPS.
Liczby te oczywiście zawsze zależą od tego, gdzie są wąskie gardła w twojej aplikacji, a ostatnie 0,5 ms może faktycznie stać się spowolnieniem w aplikacji, w której jesteś bardzo związany z drawem. Ale z drugiej strony, z mojego doświadczenia wynika, że instynkt ma paskudne koszty ogólne, jeśli nie rysujesz wielu rzeczy naraz.
źródło
Możesz być pewien, że rysowanie instancji pojedynczego obiektu jest droższe niż normalne rysowanie pojedynczego obiektu. Na przykład GPU przygotowuje się na dużą liczbę obiektów, a przygotowanie to będzie inne niż dla pojedynczego obiektu. Jednak, jak duża jest ta luka w wydajności, można znaleźć tylko poprzez eksperymenty i zależy ona w dużej mierze od rzeczywistej konfiguracji renderowania. Jedynym sposobem, aby się upewnić, jest przetestowanie go samemu. Benchmarking pojedynczego losowania jest trudny. Oto kilka pomysłów na dalsze kroki.
źródło
Minęły 4 lata ... i myślę, że można spokojnie powiedzieć, że wysyłanie „instancji” wywołań losowania za pomocą 1. Jak można zauważyć, nowe API DX12 i Vk mają liczbę instancji, która może wynosić od 0 do NUM_INSTANCES . Zauważ też, że nie ma DrawIndexed (...) .
EDYTOWAĆ
Uwaga: powyższe jest prawdopodobnie w porządku z tymi nowoczesnymi interfejsami API, być może użycie czegoś starego jak Gl <3.3 lub DX11 będzie wymagało pewnego profilowania, jak wspomniali inni użytkownicy.
źródło