Shader stutter, czyli skąd biorą się irytujące przycięcia w grach na PC?

Shader stutter, czyli skąd biorą się irytujące przycięcia w grach na PC?

Maciej Zabłocki | Dzisiaj, 22:00
Google Chcesz częściej widzieć nasze treści w Google? Dodaj do źródeł

Licznik pokazuje 120 klatek na sekundę, karta graficzna nie jest w pełni obciążona, procesor kosztował małą fortunę, a mimo to obraz nagle zamiera na ułamek sekundy. Po chwili wszystko wraca do normy, tylko po wejściu do kolejnego pomieszczenia sytuacja się powtarza. Można zmniejszyć rozdzielczość, wyłączyć ray-tracing i uruchomić DLSS, ale przycięcie nadal pojawi się dokładnie wtedy, gdy gra po raz pierwszy wyświetli określony efekt. To właśnie jeden z najbardziej irytujących problemów współczesnych wersji PC - tzw. shader stutter.

Niestety, tutaj nie chodzi wcale o wydajność. Jeśli GPU nie nadąża z renderowaniem, liczba klatek spada na dłużej, a obniżenie ustawień zazwyczaj pomaga. Shader stutter przychodzi nagle i znika równie szybko, ponieważ nie wynika bezpośrednio z obciążenia podzespołów. Komputer na chwilkę zamiera, bo zanim wyświetli następną klatkę, musi przygotować brakujący program dla karty graficznej. Nawet jeśli później będzie wykonywał go tysiące razy bez najmniejszego problemu.

Dalsza część tekstu pod wideo

Shadery są niewielkimi programami określającymi, w jaki sposób karta graficzna ma przetwarzać obraz. Vertex shader może odpowiadać za pozycję wierzchołków modelu, pixel shader za końcowy kolor pikseli, compute shader za efekty, symulacje lub przetwarzanie danych, a shadery ray-tracingowe za obsługę promieni, trafień i oświetlenia. Woda, mgła, skóra postaci, włosy, refleksy, cienie, cząsteczki i postprocesing nie są więc dla GPU gotowymi obrazkami. To zestaw instrukcji, które trzeba wcześniej przetłumaczyć na język konkretnego układu. Twórcy piszą shadery między innymi w HLSL lub GLSL, ale karta graficzna nie wykonuje takiego kodu bezpośrednio. Gra przekazuje sterownikowi jego pośrednią reprezentację, a sterownik przygotowuje kod maszynowy dopasowany do architektury GPU. Microsoft tłumaczył niegdyś, że wynik kompilacji jest zależny od konkretnej gry, układu graficznego i wersji sterownika. Dlatego plik przygotowany dla wybranego Radeona albo GeForce’a nie musi nadawać się do wykorzystania na innym sprzęcie.

Czym to dokładnie jest i jak to działa?

Redfall
resize icon

Same shadery również nie wystarczają. W DirectX 12 są częścią tak zwanego Pipeline State Object, czyli PSO. Taki obiekt łączy używane shadery ze stanem rasteryzacji, formatem wierzchołków, sposobem mieszania kolorów, buforem głębokości i formatami celów renderowania. Dokumentacja Direct3D 12 opisuje PSO jako gotowy, niezmienny zestaw stanu, który sterownik może przełożyć na instrukcje sprzętowe. Kiedy wszystko jest przygotowane wcześniej, przełączanie pipeline’ów jest bardzo szybkie. Kiedy brakuje odpowiedniego PSO, trzeba go utworzyć.

Liczba możliwych kombinacji potrafi rosnąć w absurdalnym tempie. Ten sam materiał może występować ze światłem dynamicznym albo statycznym, z cieniami i bez nich, na postaci animowanej lub nieruchomym obiekcie, podczas deszczu, we mgle, z ray-tracingiem, przezroczystością albo konkretnym typem antyaliasingu. Już dziesięć ustawień mających po dwa warianty daje teoretycznie 1024 kombinacje. Rozbudowana gra może potrzebować dziesiątek tysięcy PSO, a stworzenie wszystkich w ciemno wydłużyłoby uruchamianie, zwiększyło pamięć podręczną i przygotowało masę wariantów, których gracz nigdy nie zobaczy.

Tu dochodzimy do DirectX 12 i Vulkana. Starsze interfejsy pokroju DirectX 11 ukrywały więcej elementów w samym sterowniku. DX12 i Vulkan dają deweloperom większą kontrolę, ograniczają narzut procesora i pozwalają lepiej wykorzystać współczesne GPU, ale przenoszą też większą odpowiedzialność na silnik. Khronos ostrzega wprost, że tworzenie pipeline’u może wiązać się z wielomilisekundową, blokującą kompilacją, a uruchamianie jej bezpośrednio przed użyciem grozi przycięciami i chwilowym brakiem responsywności. Problemem nie jest więc samo istnienie nowoczesnego API, lecz nieprzygotowanie potrzebnych pipeline’ów odpowiednio wcześnie.

Dlaczego karta za kilka tysięcy złotych nie potrafi tego przepchnąć?

RTX 5090
resize icon

Na konsoli twórcy znają docelowy procesor, GPU, system operacyjny i sterownik. Każdy egzemplarz PS5 posiada tą samą architekturę, dlatego odpowiednie shadery można przygotować wcześniej i dostarczyć razem z grą. Na PC trzeba uwzględnić wiele generacji GeForce’ów, Radeonów i układów Intela, a do tego kolejne wersje sterowników. Kompilacja musi więc odbyć się po instalacji, podczas uruchamiania albo już w trakcie rozgrywki. Po pierwszym użyciu wynik trafia zwykle do pamięci podręcznej. Dlatego walka z nowym bossem może przycinać się za pierwszym razem, ale po śmierci i ponownym wejściu na arenę działać już znacznie płynniej (dobrym przykładem jest Final Fantasy VII: Rebirth na PC, które z czasem i po wgraniu wielu elementów gry działa znacznie lepiej). Cache nie jest jednak wieczny. Aktualizacja gry może zmienić shadery lub opis PSO, wymiana karty graficznej wymaga przygotowania kodu dla innej architektury, a instalacja nowego sterownika często unieważnia wcześniejsze dane. Microsoft w swojej dokumentacji potwierdza, że właśnie dlatego stutter potrafi wrócić natychmiast po aktualizacji driverów.

Najgorsza sytuacja występuje wtedy, gdy gra potrzebuje nieprzygotowanego pipeline’u do wyrenderowania bieżącej klatki i synchronicznie czeka na zakończenie kompilacji. Przy 60 FPS cała klatka musi powstać w około 16,7 ms, a przy 120 FPS zaledwie w 8,3 ms. W przykładowym teście Khronosa ponowne utworzenie pipeline’ów bez odpowiedniego cache’u zajmowało 50,4 ms, natomiast z cache’em 24,4 ms. Nawet lepszy wynik przekracza budżet jednej klatki przy 60 FPS, więc gracz zobaczy wyraźny skok czasu generowania obrazu. Mocniejszy procesor może skrócić kompilację, ale nie zawsze jest w stanie ją ukryć. Jeżeli główny wątek gry czeka na sterownik, GPU może pozostawać niewykorzystane, bo nie otrzymało jeszcze kompletnego polecenia renderowania. RTX 5090 nie narysuje pipeline’u, który dopiero powstaje, a generator klatek nie naprawi zatrzymania logiki i dostarczania nowych klatek bazowych. Dlatego shader stutter często wygląda niemal identycznie na sprzęcie ze średniej i najwyższej półki, choć przez pozostałe 99% czasu różnica wydajności jest ogromna.

Stuttering można rozpoznać po zachowaniu gry. Przycięcie pojawia się zwykle przy pierwszym wyświetleniu nowego efektu, materiału, przeciwnika lub ataku, a po ponownym rozegraniu tej samej sekwencji znika. Po usunięciu cache’u albo zmianie sterownika problem wraca. Wykres frametime’u pokazuje pojedynczy wysoki pik, mimo, że średnia liczba FPS może prezentować się znakomicie. Właśnie dlatego benchmark pokazujący wyłącznie średnie 100 FPS potrafi ukryć niedoskonałości, które w praktyce mocno wpływają na komfort zabawy i płynność. 

The Callisto Protocol
resize icon

Najgłośniejszym przykładem pozostaje pecetowa wersja The Callisto Protocol. Gra zadebiutowała bez skutecznego przygotowania wszystkich shaderów, więc podczas pierwszego przejścia kompilowała je w trakcie rozgrywki. Każdy nowy efekt, atak lub fragment otoczenia mógł wywołać szarpnięcie. Niedługo po premierze, Striking Distance wypuściło aktualizację i oficjalnie potwierdziło, że patch naprawia przycięcia wynikające z kompilacji shaderów. Studio ostrzegło jednocześnie, że po aktualizacji pierwsze uruchomienie może chwilowo przycinać w menu, ponieważ przygotowywana jest pamięć podręczna. Problem nie wymagał zatem zmniejszenia jakości grafiki, lecz prekompilowania wszystkich danych przed pierwszym uruchomieniem.

Równie ciekawy był przypadek Elden Ring. Na Windowsie gra potrafiła zacinać się przy pierwszym pojawieniu się nowych efektów, ale na słabszym przecież Steam Decku działała pod tym względem znacznie równiej. Valve wykorzystało fakt, że każdy Deck posiada tę samą kombinację GPU i sterownika. Jak tłumaczył Pierre-Loup Griffais, większość shaderów była przygotowywana na serwerach Valve i dostarczana użytkownikom, dzięki czemu lokalna kompilacja mogła zostać pominięta. Jednocześnie Valve zaznaczało, że część największych przycięć Elden Ring wynikała z tworzenia tysięcy innych zasobów, między innymi buforów poleceń. To istotne, bo nie każde szarpnięcie jest automatycznie shader stutterem. Opis rozwiązania Valve i wypowiedzi Griffaisa można znaleźć tutaj.

Osobną kategorią jest traversal stutter, dobrze widoczny w Star Wars Jedi: Survivor i remake’u Dead Space. Powstaje najczęściej podczas przekraczania niewidocznej granicy świata, gdy silnik wczytuje nową porcję geometrii, tekstur, dźwięku i danych rozgrywki, usuwa stare zasoby albo porządkuje pamięć. Respawn w oficjalnych informacjach o patchach pisało o zmianach budżetów streamingu, które miały ograniczyć „traversal hitching”, a później o poprawionym buforowaniu zawartości. Shader stutter może zniknąć przy drugim pokazaniu efektu. Traversal stutter potrafi wracać w tym samym przejściu między lokacjami, nawet kiedy wszystkie shadery są już gotowe.

Kompilować wcześniej, choćby w tle?

Elden Ring
resize icon

Najprostsze rozwiązanie to przygotowanie shaderów przed rozpoczęciem gry. Dlatego Horizon Zero Dawn, kolejne odsłony Call of Duty czy Star Wars Jedi: Survivor potrafią po zmianie sterownika wyświetlić pasek „compiling shaders” albo „optimizing game files”. Gracz czeka kilka minut w menu, ale właściwa rozgrywka powinna być później płynniejsza. To uczciwa wymiana, pod warunkiem, że proces rzeczywiście obejmuje wszystkie potrzebne warianty, a nie kończy się efektownym paskiem postępu i dalszą kompilacją podczas pierwszej walki.

Druga metoda to kompilacja asynchroniczna. Gra przygotowuje kolejne PSO w tle, wykorzystując dodatkowe wątki procesora, zanim dany obiekt pojawi się na ekranie. Unreal Engine rozwija w tym celu system PSO Precaching, automatycznie zbierający i kompilujący pipeline’y potrzebne materiałom, modelom oraz globalnym efektom. Dokumentacja Epic Games pokazuje nawet możliwość opóźnienia utworzenia obiektu albo tymczasowego zastąpienia jego materiału, jeśli właściwe PSO nie jest jeszcze gotowe. Lepiej przez moment zobaczyć uproszczony materiał, niż zatrzymać całą grę. Żadna z tych metod nie jest idealna. Pełna prekompilacja wydłuża pierwsze uruchomienie i wymaga znalezienia wszystkich kombinacji. Kompilacja w tle obciąża procesor i może nie zdążyć przed graczem poruszającym się szybko po świecie. Ręcznie budowany cache może pominąć rzadki efekt, broń lub ustawienie graficzne, którego testerzy nie aktywowali. Epic dlatego rozwija automatyczne PSO Precaching, ale sama dokumentacja wspomina o globalnych pipeline’ach, które nadal mogą powstawać podczas działania gry. Jeden brakujący wariant wystarczy, aby pojawiło się dobrze widoczne przycięcie i załamanie ekranu. 

Gracz ma tu niestety ograniczone pole manewru. Warto pozwolić grze dokończyć kompilację, nie kasować bez potrzeby pamięci shaderów i pamiętać, że po aktualizacji sterownika pierwsza sesja może działać gorzej. Zmniejszenie rozdzielczości zwykle nie pomaga, ponieważ nie skraca procesu tworzenia PSO. Wyłączenie ray-tracingu może ograniczyć liczbę potrzebnych wariantów, ale zmiana ustawień potrafi też uruchomić kompilację zupełnie nowego zestawu shaderów. Porady w rodzaju „usuń cały shader cache” czasem naprawiają jego uszkodzenie, lecz równie często powodują dokładnie to, z czym miały walczyć - konieczność zbudowania wszystkiego od początku.

Ciekawym krokiem jest rozwijane przez Microsoft Advanced Shader Delivery. System przygotowuje shadery dla konkretnego GPU i sterownika poza komputerem gracza, a następnie dostarcza je razem z grą - podobnie jak Valve robi to na Steam Decku. Microsoft informował, że w przypadku Avowed skróciło to start nawet o 85%, a Forza Horizon 6 na testowym Radeonie uruchamiała się w cztery sekundy zamiast niemal półtorej minuty. Od czerwca tego roku technologia jest dostępna w aplikacji Xbox na obsługiwanych komputerach z Windows 11 i układami AMD RDNA, choć lista zgodnych gier i sprzętu nadal pozostaje bardzo ograniczona. Tutaj Microsoft szczegółowo opisał etap wdrożenia.

Najważniejszy wniosek jest mało wygodny dla całej branży PC. Wysoka średnia liczba klatek nie gwarantuje płynności. Można kupić szybszą kartę, mocniejszy procesor i najlepszy dysk NVMe, ale źle zaprojektowanego systemu kompilacji nie da się po prostu zasypać teraflopami. Shader stutter jest problemem przygotowania danych, sterownika i silnika, a nie wyłącznie wydajności sprzętu. Dopóki pipeline potrzebny do następnej klatki nie jest gotowy, najmocniejszy komputer świata również musi na niego poczekać.

Google Chcesz częściej widzieć nasze treści w Google? Dodaj do źródeł
Źródło: Opracowanie własne
Maciej Zabłocki Strona autora
Swoją przygodę z recenzowaniem gier rozpoczął w 2005 roku. Z wykształcenia dziennikarz, ale zawodowo pracujący też w marketingu. Na PPE odpowiada głównie za testy sprzętów i dział tech. Gatunkowo uwielbia RPG, strategie i wyścigi. Uzależniony od codziennego czytania newsów i oglądania konferencji.
cropper