Myślę, że powszechnie przyjmuje się, że czas rzeczywisty to wszystko, co jest ponad interaktywne. Interaktywny jest definiowany jako „reaguje na dane wejściowe, ale nie jest płynny w tym, że animacja wydaje się postrzępiona”.
Czas rzeczywisty będzie więc zależeć od prędkości ruchów, które należy reprezentować. Projekcje kinowe odbywają się z prędkością 24 klatek na sekundę i w wielu przypadkach wystarcza na czas.
Zatem, z iloma wielokątami maszyna może sobie poradzić, można łatwo sprawdzić, sprawdzając sam. Po prostu stwórz małą łatkę VBO jako prosty test i licznik FPS, wiele próbek DirectX lub OpenGL da ci idealne podłoże testowe do tego testu porównawczego.
Przekonasz się, czy masz wysokiej klasy kartę graficzną, która może wyświetlać około 1 miliona wielokątów w czasie rzeczywistym. Jednak, jak powiedziałeś, silniki nie będą tak łatwo ubiegać się o wsparcie, ponieważ rzeczywiste dane ze sceny na świecie spowodują szereg błędów wydajności niezwiązanych z liczbą wielokątów.
Ty masz:
- wskaźnik wypełnienia
- próbkowanie tekstury
- Wyjście ROP
- rysować połączenia
- renderuj przełączniki docelowe
- aktualizacje buforów (jednolite lub inne)
- przejaskrawiać
- złożoność modułu cieniującego
- złożoność potoku (jakakolwiek informacja zwrotna? iteracyjne cieniowanie geometrii? okluzja?)
- punkty synchronizacji z procesorem (odczyt pikseli?)
- bogactwo wielokątów
W zależności od słabych i mocnych stron konkretnej karty graficznej, jeden lub drugi z tych punktów będzie wąskim gardłem. To nie tak, że można powiedzieć na pewno „tam, to jest to”.
EDYTOWAĆ:
Chciałem dodać, że nie można użyć wartości specyfikacji GFlops dla jednej konkretnej karty i odwzorować jej liniowo na zdolność wypychania wielokątów. Ze względu na fakt, że leczenie wielokątów musi przejść przez sekwencyjne wąskie gardło w potoku graficznym, jak wyjaśniono szczegółowo tutaj: https://fgiesen.wordpress.com/2011/07/03/a-trip-through-the-graphics -pipeline-2011-part-3 /
TLDR: wierzchołki muszą zmieścić się w małej pamięci podręcznej przed prymitywnym złożeniem, które jest natywnie sekwencyjne (kolejność buforów wierzchołków ma znaczenie).
Jeśli porównasz GeForce 7800 (9-letni?) Z tegorocznym 980, wydaje się, że liczba operacji na sekundę, jaką jest w stanie zwiększyć, wzrosła tysiąckrotnie. Ale możesz się założyć, że nie popchnie wielokątów tysiąc razy szybciej (co przy tej prostej metodzie byłoby około 200 miliardów na sekundę).
EDYCJA 2:
Aby odpowiedzieć na pytanie „co można zrobić, aby zoptymalizować silnik”, np. „Aby nie stracić zbyt dużej wydajności przełączników stanu i innych kosztów ogólnych”.
To pytanie tak stare jak same silniki. I staje się coraz bardziej złożony w miarę postępu historii.
Rzeczywiście w rzeczywistych sytuacjach typowe dane scen będą zawierać wiele materiałów, wiele tekstur, wiele różnych shaderów, wiele celów renderowania i przejść, wiele buforów wierzchołków i tak dalej. Jeden silnik, z którym pracowałem, działał z pojęciem pakietów:
Jeden pakiet jest renderowany za pomocą jednego wywołania losowania.
Zawiera identyfikatory do:
- bufor wierzchołków
- bufor indeksu
- kamera (podaje cel podania i renderowania)
- identyfikator materiału (podaje moduł cieniujący, tekstury i UBO)
- odległość do oka
- jest widoczny
Tak więc pierwszym krokiem każdej ramki jest szybkie sortowanie na liście pakietów za pomocą funkcji sortowania z operatorem, który daje pierwszeństwo widoczności, następnie przekazuje, następnie materiał, następnie geometrię i wreszcie odległość.
Rysowanie bliskich obiektów staje się priorytetem, aby zmaksymalizować wczesne ubijanie Z.
Karnety to stałe kroki, więc nie mamy wyboru, musimy je uszanować.
Materiał jest najdroższą rzeczą do zmiany stanu po renderowaniu celów.
Nawet pomiędzy różnymi identyfikatorami materiałów można dokonać podzlecenia przy użyciu kryterium heurystycznego w celu zmniejszenia liczby zmian modułu cieniującego (najdroższego w operacjach przełączania stanu materiału), a po drugie zmian wiązania tekstur.
Po tym całym zamówieniu można zastosować mega teksturowanie, wirtualne teksturowanie i renderowanie bez atrybutów ( link ), jeśli zostanie to uznane za konieczne.
W interfejsie API silnika jedną powszechną rzeczą jest odraczanie wydawania poleceń ustawiania stanu wymaganych przez klienta. Jeśli klient zażąda „ustaw kamerę 0”, najlepiej po prostu zapisać to żądanie, a jeśli później klient wywoła „ustaw kamerę 1”, ale bez innych poleceń pomiędzy nimi, silnik może wykryć bezużyteczność pierwszego polecenia i upuścić je . Jest to eliminacja redundancji, która jest możliwa dzięki zastosowaniu paradygmatu „w pełni zachowanego”. W przeciwieństwie do „natychmiastowego” paradygmatu, który byłby tylko opakowaniem nad natywnym API i wydawał polecenia zgodnie z kolejnością według kodu klienta. ( przykład: virtrev )
I wreszcie, przy nowoczesnym sprzęcie, bardzo kosztownym (do opracowania), ale potencjalnie bardzo satysfakcjonującym krokiem jest zmiana interfejsu API na metal / płaszcz / vulkan / DX12 i ręczne przygotowanie poleceń renderowania.
Mechanizm, który przygotowuje polecenia renderowania, tworzy bufor, który zawiera „listę poleceń”, która jest zastępowana w każdej ramce.
Zwykle istnieje pojęcie „budżetu” ramy, na które gra może sobie pozwolić. Musisz zrobić wszystko w ciągu 16 milisekund, więc wyraźnie dzielisz czas GPU na „2 ms dla lightpre pass”, „4 ms dla materiałów pass”, „6 ms dla oświetlenia pośredniego”, „4 ms dla postprocesów” ...