chore: added dots everywhere

This commit is contained in:
Krzysztof kuhy Rudnicki 2026-02-07 16:43:12 +01:00
parent 9238f53e90
commit 2add3b3e6c
14 changed files with 691 additions and 567 deletions

Binary file not shown.

View File

@ -72,7 +72,7 @@
%------------------------------------- %-------------------------------------
\cleardoublepage % Zaczynamy od nieparzystej strony \cleardoublepage % Zaczynamy od nieparzystej strony
\abstract \abstract
Przez ostatnią dekadę rynek tworzenia gier komputerowych \\ zdominowały dwa silniki: Unity oraz Przez ostatnią dekadę rynek tworzenia gier komputerowych zdominowały dwa silniki: Unity oraz
Unreal Engine. Niniejsza praca podejmuje się wyzwania przeprowadzenia analizy Unreal Engine. Niniejsza praca podejmuje się wyzwania przeprowadzenia analizy
porównawczej porównawczej
obu tych silników pod kątem wyd ajności oraz procesu obu tych silników pod kątem wyd ajności oraz procesu
@ -204,9 +204,9 @@ Game development, Frame time, Engine architecture, Version control, GPU
%\begin{table}[!h] \centering %\begin{table}[!h] \centering
% \caption{Tabela w załączniku.} % \caption{Tabela w załączniku.}
% \begin{tabular} {| c | c | r |} \hline % \begin{tabular} {| c | c | r |} \hline
% Kolumna 1 & Kolumna 2 & Liczba \\ \hline\hline % Kolumna 1 & Kolumna 2 & Liczba \hline\hline
% cell1 & cell2 & 60 \\ \hline % cell1 & cell2 & 60 \hline
% \multicolumn{2}{|r|}{Suma:} & 123,45 \\ \hline % \multicolumn{2}{|r|}{Suma:} & 123,45 \hline
% \end{tabular} % \end{tabular}
%\end{table} %\end{table}
%\lipsum[3-4] %\lipsum[3-4]

View File

@ -17,11 +17,11 @@ oraz końcową jakość produktu.
\subsection{Zakres pracy} \subsection{Zakres pracy}
Praca obejmuje analizę następujących aspektów: Praca obejmuje analizę następujących aspektów:
\begin{itemize} \begin{itemize}
\item Wydajność renderowania grafiki \item Wydajność renderowania grafiki.
\item Możliwości i~funkcjonalności oferowane przez różne silniki \item Możliwości i~funkcjonalności oferowane przez różne silniki.
\item Łatwość użycia i~krzywa uczenia się \item Łatwość użycia i~krzywa uczenia się.
\item Praca z narzędziem przy użycji dużych modeli językowch \item Praca z narzędziem przy użycji dużych modeli językowch.
\item Ekosystem narzędzi i~społeczność deweloperska \item Ekosystem narzędzi i~społeczność deweloperska.
\end{itemize} \end{itemize}
\subsection{Wybór gry testowej -- gatunek bullet hell}\label{subsec:bullet-hell} \subsection{Wybór gry testowej -- gatunek bullet hell}\label{subsec:bullet-hell}
@ -39,14 +39,14 @@ ogromne ilości pocisków tworzących skomplikowane wzory na ekranie. Kluczowe c
\begin{itemize} \begin{itemize}
\item \textbf{Masowa ilość pocisków} -- na ekranie jednocześnie może znajdować się od kilkuset \item \textbf{Masowa ilość pocisków} -- na ekranie jednocześnie może znajdować się od kilkuset
do kilku tysięcy pocisków, tworzących złożone formacje \\ geometryczne do kilku tysięcy pocisków, tworzących złożone formacje geometryczne.
\item \textbf{Precyzyjne hitboxy} -- obszar kolizji postaci gracza jest znacznie mniejszy niż \item \textbf{Precyzyjne hitboxy} -- obszar kolizji postaci gracza jest znacznie mniejszy niż
jej wizualna reprezentacja (często ograniczony do kilku pikseli), co umożliwia nawigację między jej wizualna reprezentacja (często ograniczony do kilku pikseli), co umożliwia nawigację między
pociskami pociskami.
\item \textbf{Duża liczba przeciwników} -- na ekranie jednocześnie pojawia się wiele jednostek przeciwnika, co zwiększa złożoność sytuacji i obciążenie systemu \item \textbf{Duża liczba przeciwników} -- na ekranie jednocześnie pojawia się wiele jednostek przeciwnika, co zwiększa złożoność sytuacji i obciążenie systemu.
\item \textbf{Ciągły ruch} -- gracz musi nieustannie przemieszczać się po ekranie, unikając kolizji \item \textbf{Ciągły ruch} -- gracz musi nieustannie przemieszczać się po ekranie, unikając kolizji.
\item \textbf{Eskalacja trudności} -- wraz z~postępem gry wzrasta liczba przeciwników \item \textbf{Eskalacja trudności} -- wraz z~postępem gry wzrasta liczba przeciwników
i~gęstość pocisków i~gęstość pocisków.
\end{itemize} \end{itemize}
Klasyczne przykłady gatunku to serie \textit{Touhou Project}, Klasyczne przykłady gatunku to serie \textit{Touhou Project},
@ -66,19 +66,19 @@ Klasyczne przykłady gatunku to serie \textit{Touhou Project},
Gatunek bullet hell został wybrany jako podstawa testów wydajnościowych z~następujących powodów: Gatunek bullet hell został wybrany jako podstawa testów wydajnościowych z~następujących powodów:
\begin{enumerate} \begin{enumerate}
\item \textbf{Intensywne wykorzystanie zasobów} -- jednoczesne renderowanie setek lub tysięcy obiektów (pocisków) stanowi znaczące obciążenie dla systemu renderowania \item \textbf{Intensywne wykorzystanie zasobów} -- jednoczesne renderowanie setek lub tysięcy obiektów (pocisków) stanowi znaczące obciążenie dla systemu renderowania.
\item \textbf{Testowanie zarządzania pamięcią} -- ciągłe tworzenie i~niszczenie obiektów \item \textbf{Testowanie zarządzania pamięcią} -- ciągłe tworzenie i~niszczenie obiektów
pocisków eksponuje różnice w~implementacji \\ garbage collectora (Unity/C\#) versus ręcznego pocisków eksponuje różnice w~implementacji garbage collectora (Unity/C\#) versus ręcznego
zarządzania pamięcią (Unreal/C++) zarządzania pamięcią (Unreal/C++).
\item \textbf{Wymagania systemu fizyki} -- wykrywanie kolizji między graczem a~setkami pocisków w~każdej klatce obciąża system fizyki \item \textbf{Wymagania systemu fizyki} -- wykrywanie kolizji między graczem a~setkami pocisków w~każdej klatce obciąża system fizyki.
\item \textbf{Prostota implementacji} -- podstawowa mechanika gry jest stosunkowo prosta koncepcyjnie, co pozwala skupić się na porównaniu wydajności, a~nie złożoności logiki gry \item \textbf{Prostota implementacji} -- podstawowa mechanika gry jest stosunkowo prosta koncepcyjnie, co pozwala skupić się na porównaniu wydajności, a~nie złożoności logiki gry.
\item \textbf{Skalowalność testu} -- łatwo kontrolować poziom obciążenia poprzez modyfikację liczby aktywnych pocisków i~przeciwników \item \textbf{Skalowalność testu} -- łatwo kontrolować poziom obciążenia poprzez modyfikację liczby aktywnych pocisków i~przeciwników.
\item \textbf{Reprezentatywność dla gier 2D} -- gatunek jest typowym przedstawicielem gier 2D, co pozwala ocenić wsparcie silników dla tego segmentu rynku \item \textbf{Reprezentatywność dla gier 2D} -- gatunek jest typowym przedstawicielem gier 2D, co pozwala ocenić wsparcie silników dla tego segmentu rynku.
\end{enumerate} \end{enumerate}
@ -87,10 +87,10 @@ Gatunek bullet hell został wybrany jako podstawa testów wydajnościowych z~nas
Zaimplementowana gra testowa charakteryzuje się następującymi parametrami: Zaimplementowana gra testowa charakteryzuje się następującymi parametrami:
\begin{itemize} \begin{itemize}
\item Czas rozgrywki: 90 sekund \item Czas rozgrywki: 90 sekund.
\item Eskalacja trudności: liniowy wzrost częstotliwości spawnu przeciwników \item Eskalacja trudności: liniowy wzrost częstotliwości spawnu przeciwników.
\item Typy przeciwników: 3 warianty z~różnymi wzorami strzelania \item Typy przeciwników: 3 warianty z~różnymi wzorami strzelania.
\item System punktacji oparty na eliminacji przeciwników \item System punktacji oparty na eliminacji przeciwników.
\end{itemize} \end{itemize}
Te parametry zapewniają wystarczające obciążenie systemu do ujawnienia różnic wydajnościowych między silnikami, pozostając jednocześnie w~granicach typowych dla gier indie z~tego gatunku. Te parametry zapewniają wystarczające obciążenie systemu do ujawnienia różnic wydajnościowych między silnikami, pozostając jednocześnie w~granicach typowych dla gier indie z~tego gatunku.
@ -100,24 +100,24 @@ Te parametry zapewniają wystarczające obciążenie systemu do ujawnienia róż
Praca składa się z~następujących rozdziałów: Praca składa się z~następujących rozdziałów:
\begin{enumerate} \begin{enumerate}
\item \textbf{Wstęp} -- wprowadzenie do tematyki, motywacja, cel i~zakres pracy \item \textbf{Wstęp} -- wprowadzenie do tematyki, motywacja, cel i~zakres pracy.
\item \textbf{Przegląd literatury} -- analiza istniejących badań porównawczych silników gier \item \textbf{Przegląd literatury} -- analiza istniejących badań porównawczych silników gier.
\item \textbf{Charakterystyka silników} -- szczegółowy opis Unity i~Unreal Engine \item \textbf{Charakterystyka silników} -- szczegółowy opis Unity i~Unreal Engine.
\item \textbf{Metodologia} -- opis metodyki badawczej i~kryteriów porównania \item \textbf{Metodologia} -- opis metodyki badawczej i~kryteriów porównania.
\item \textbf{Analiza wywiadów} -- wyniki badań jakościowych z~deweloperami \item \textbf{Analiza wywiadów} -- wyniki badań jakościowych z~deweloperami.
\item \textbf{Implementacja gry testowej} -- doświadczenia z~tworzenia gry w~obu silnikach \item \textbf{Implementacja gry testowej} -- doświadczenia z~tworzenia gry w~obu silnikach.
\item \textbf{Narzędzia profilowania} -- opis NVIDIA Nsight i~metodyki pomiarów \item \textbf{Narzędzia profilowania} -- opis NVIDIA Nsight i~metodyki pomiarów.
\item \textbf{Testy wydajności} -- wyniki pomiarów wydajnościowych \item \textbf{Testy wydajności} -- wyniki pomiarów wydajnościowych.
\item \textbf{Analiza możliwości} -- porównanie funkcjonalności silników \item \textbf{Analiza możliwości} -- porównanie funkcjonalności silników.
\item \textbf{Porównanie wyników} -- synteza i~analiza zebranych danych \item \textbf{Porównanie wyników} -- synteza i~analiza zebranych danych.
\item \textbf{Podsumowanie} -- wnioski i~rekomendacje \item \textbf{Podsumowanie} -- wnioski i~rekomendacje.
\end{enumerate} \end{enumerate}
\subsection{Metodologia} \subsection{Metodologia}
\begin{itemize} \begin{itemize}
\item \textbf{Testy wydajnościowe} -- Pomiary z~wykorzystaniem NVIDIA Nsight Graphics, zapewniające porównywalność wyników między silnikami \item \textbf{Testy wydajnościowe} -- Pomiary z~wykorzystaniem NVIDIA Nsight Graphics, zapewniające porównywalność wyników między silnikami.
\item \textbf{Wywiady z~deweloperami} -- badania jakościowe dostarczające kontekstu \\ praktycznego użytkowania silników \item \textbf{Wywiady z~deweloperami} -- badania jakościowe dostarczające kontekstu praktycznego użytkowania silników.
\item \textbf{Implementacja porównawcza} -- stworzenie identycznej gry w~obu silnikach, dokumentując różnice w~procesie deweloperskim \item \textbf{Implementacja porównawcza} -- stworzenie identycznej gry w~obu silnikach, dokumentując różnice w~procesie deweloperskim.
\end{itemize} \end{itemize}

View File

@ -15,14 +15,14 @@ gier charakteryzują się modularną architekturą, która umożliwia
ponowne wykorzystanie komponentów między różnymi projektami. ponowne wykorzystanie komponentów między różnymi projektami.
Gregory \cite{gregory2018game} w~swojej pracy ,,Game Engine Architecture'' Gregory \cite{gregory2018game} w~swojej pracy ,,Game Engine Architecture''
przedstawia kompleksowy \\ przegląd ewolucji silników gier, definiując je jako przedstawia kompleksowy przegląd ewolucji silników gier, definiując je jako
,,oprogramowanie zaprojektowane specjalnie do tworzenia gier''. ,,oprogramowanie zaprojektowane specjalnie do tworzenia gier''.
Jego analiza pokazuje, że współczesne silniki gier składają się z~kilku Jego analiza pokazuje, że współczesne silniki gier składają się z~kilku
kluczowych warstw: warstwy platformy (platform layer), kluczowych warstw: warstwy platformy (platform layer),
warstwy podstawowych systemów (core systems), warstwy zasobów warstwy podstawowych systemów (core systems), warstwy zasobów
(resource manager), warstwy renderingu (rendering engine), (resource manager), warstwy renderingu (rendering engine),
systemów animacji, fizyki oraz gameplay. systemów animacji, fizyki oraz gameplay.
Ta architektura warstwowa umożliwia modularność i~ponowne \\ Ta architektura warstwowa umożliwia modularność i~ponowne
wykorzystanie komponentów. wykorzystanie komponentów.
Pierwsze silniki gier były ściśle powiązane z konkretnym sprzętem Pierwsze silniki gier były ściśle powiązane z konkretnym sprzętem
@ -39,13 +39,13 @@ zaawansowanymi narzędziami do debugowania.
\subsection{Klasyfikacja silników gier} \subsection{Klasyfikacja silników gier}
\subsubsection{Architektura silników według Gregory'ego} \subsubsection{Architektura silników według Gregory'ego}
Gregory \cite{gregory2018game} przedstawia taksonomię architektur silników gier, \\ Gregory \cite{gregory2018game} przedstawia taksonomię architektur silników gier,
wyróżniając kilka kluczowych typów organizacji: wyróżniając kilka kluczowych typów organizacji:
\begin{itemize} \begin{itemize}
\item \textbf{Silniki obiektowe} - bazujące na hierarchii obiektów gry z dziedziczeniem \item \textbf{Silniki obiektowe} - bazujące na hierarchii obiektów gry z dziedziczeniem.
\item \textbf{Silniki komponentowe} - wykorzystujące systemy \\ entity-component-system (ECS) \item \textbf{Silniki komponentowe} - wykorzystujące systemy entity-component-system (ECS).
\item \textbf{Silniki hybrydowe} - łączące elementy różnych podejść architektonicznych \item \textbf{Silniki hybrydowe} - łączące elementy różnych podejść architektonicznych.
\end{itemize} \end{itemize}
Autor podkreśla, że wybór architektury ma fundamentalny wpływ na wydajność, skalowalność i łatwość rozwoju gier. Systemy ECS zyskują na popularności ze względu na lepszą wydajność cache procesora i większą elastyczność w definiowaniu zachowań obiektów gry. Autor podkreśla, że wybór architektury ma fundamentalny wpływ na wydajność, skalowalność i łatwość rozwoju gier. Systemy ECS zyskują na popularności ze względu na lepszą wydajność cache procesora i większą elastyczność w definiowaniu zachowań obiektów gry.

View File

@ -16,22 +16,22 @@ kilkoma kluczowymi czynnikami:
\begin{itemize} \begin{itemize}
\item \textbf{Dominacja rynkowa} -- według raportu Video Game Insights, \item \textbf{Dominacja rynkowa} -- według raportu Video Game Insights,
w~2024 roku 51\% gier wydanych na platformie Steam powstało w~Unity, w~2024 roku 51\% gier wydanych na platformie Steam powstało w~Unity,
\\ a 28\% w~Unreal Engine \cite{vgi2025engines} a 28\% w~Unreal Engine \cite{vgi2025engines}.
\item \textbf{Reprezentatywność podejść architektonicznych} -- \item \textbf{Reprezentatywność podejść architektonicznych} --
silniki reprezentują odmienne filozofie: Unity opiera się na silniki reprezentują odmienne filozofie: Unity opiera się na
języku C\# z~garbage collectorem, \\ a~Unreal wykorzystuje C++ języku C\# z~garbage collectorem, a~Unreal wykorzystuje C++
z~własnym systemem refleksji, makrami oraz garbage collectorem z~własnym systemem refleksji, makrami oraz garbage collectorem
dla obiektów UObject dla obiektów UObject.
\item \textbf{Różnorodność zastosowań} -- Unity dominuje \item \textbf{Różnorodność zastosowań} -- Unity dominuje
w~segmencie gier mobilnych (71\% z~top 1000 gier mobilnych) w~segmencie gier mobilnych (71\% z~top 1000 gier mobilnych)
oraz wśród deweloperów indie, natomiast oraz wśród deweloperów indie, natomiast
Unreal generuje większe przychody w~produkcjach AAA Unreal generuje większe przychody w~produkcjach AAA
(31\% przychodów Steam w~2024 vs 26\% dla Unity) (31\% przychodów Steam w~2024 vs 26\% dla Unity)
\cite{vgi2025engines, g2gameengines} \cite{vgi2025engines, g2gameengines}.
\item \textbf{Dostępność} -- oba silniki oferują darmowe wersje \item \textbf{Dostępność} -- oba silniki oferują darmowe wersje
dla małych zespołów i projektów edukacyjnych dla małych zespołów i projektów edukacyjnych.
\item \textbf{Aktywna społeczność} -- Unity posiada ponad \item \textbf{Aktywna społeczność} -- Unity posiada ponad
5~milionów zarejestrowanych deweloperów \cite{g2gameengines} 5~milionów zarejestrowanych deweloperów \cite{g2gameengines}.
\end{itemize} \end{itemize}
\subsection{Unity}\label{subsec:unity} \subsection{Unity}\label{subsec:unity}
@ -51,16 +51,16 @@ deweloperów i małych studiów \cite{unity_wikipedia}. Decyzja ta
przyczyniła się do wzrostu popularności silnika w segmencie gier przyczyniła się do wzrostu popularności silnika w segmencie gier
mobilnych oraz indie. mobilnych oraz indie.
Unity wykorzystuje język programowania \textbf{C\#} działający \\ Unity wykorzystuje język programowania \textbf{C\#} działający
na platformie .NET/Mono, co zapewnia: na platformie .NET/Mono, co zapewnia:
\begin{itemize} \begin{itemize}
\item Automatyczne zarządzanie pamięcią poprzez garbage collector \item Automatyczne zarządzanie pamięcią poprzez garbage collector.
\item Bezpieczeństwo typów i obsługę wyjątków \item Bezpieczeństwo typów i obsługę wyjątków.
\item Bogatą bibliotekę standardową \item Bogatą bibliotekę standardową.
\end{itemize} \end{itemize}
Architektura Unity opiera się na wzorcu \textit{GameObject-Component}, Architektura Unity opiera się na wzorcu \textit{GameObject-Component},
gdzie \\ każdy obiekt w scenie (GameObject) może posiadać dowolną gdzie każdy obiekt w scenie (GameObject) może posiadać dowolną
liczbę komponentów definiujących jego zachowanie. liczbę komponentów definiujących jego zachowanie.
Podejście to promuje kompozycję nad dziedziczeniem i ułatwia Podejście to promuje kompozycję nad dziedziczeniem i ułatwia
tworzenie modularnego kodu. tworzenie modularnego kodu.
@ -73,32 +73,32 @@ Unity oferuje kompleksowy zestaw narzędzi do tworzenia gier 2D i 3D:
\item \textbf{Rendering} -- wsparcie dla wielu pipeline'ów \item \textbf{Rendering} -- wsparcie dla wielu pipeline'ów
renderowania: Built-in, Universal Render Pipeline (URP) dla platform renderowania: Built-in, Universal Render Pipeline (URP) dla platform
mobilnych oraz High Definition Render Pipeline (HDRP) dla wysokiej mobilnych oraz High Definition Render Pipeline (HDRP) dla wysokiej
jakości grafiki jakości grafiki.
\item \textbf{Fizyka} -- integracja z silnikami PhysX (3D) i Box2D (2D) \item \textbf{Fizyka} -- integracja z silnikami PhysX (3D) i Box2D (2D).
\item \textbf{Animacja} -- system Mecanim z obsługą maszyn stanów \item \textbf{Animacja} -- system Mecanim z obsługą maszyn stanów
i blendingu animacji i blendingu animacji.
\item \textbf{Audio} -- wbudowany system dźwięku przestrzennego \item \textbf{Audio} -- wbudowany system dźwięku przestrzennego.
\item \textbf{UI} -- dwa systemy interfejsu użytkownika: uGUI oraz \item \textbf{UI} -- dwa systemy interfejsu użytkownika: uGUI oraz
nowoczesny UI Toolkit nowoczesny UI Toolkit.
\item \textbf{Multiplayer} -- Netcode for GameObjects oraz \item \textbf{Multiplayer} -- Netcode for GameObjects oraz
integracja z usługami sieciowymi integracja z usługami sieciowymi.
\end{itemize} \end{itemize}
\subsubsection{Narzędzia deweloperskie} \subsubsection{Narzędzia deweloperskie}
Edytor Unity zapewnia interfejs graficzny z~następującymi \\ Edytor Unity zapewnia interfejs graficzny z~następującymi
funkcjonalnościami \cite{unity_wikipedia}: funkcjonalnościami \cite{unity_wikipedia}:
\begin{itemize} \begin{itemize}
\item Hierarchiczny widok sceny z możliwością edycji w czasie \item Hierarchiczny widok sceny z możliwością edycji w czasie
rzeczywistym rzeczywistym.
\item Inspektor właściwości z obsługą serializacji pól \\ poprzez \item Inspektor właściwości z obsługą serializacji pól poprzez
atrybut \texttt{[SerializeField]} atrybut \texttt{[SerializeField]}.
\item Wbudowany profiler wydajności (CPU, GPU, pamięć) \item Wbudowany profiler wydajności (CPU, GPU, pamięć)
\cite{unity_profiler} \cite{unity_profiler}.
\item Asset Store -- marketplace z gotowymi zasobami i \item Asset Store -- marketplace z gotowymi zasobami i
rozszerzeniami rozszerzeniami.
\item Obsługa hot reload -- możliwość edycji kodu podczas działania \item Obsługa hot reload -- możliwość edycji kodu podczas działania
gry gry.
\end{itemize} \end{itemize}
\subsection{Unreal Engine}\label{subsec:unreal} \subsection{Unreal Engine}\label{subsec:unreal}
@ -120,9 +120,9 @@ technologie takie jak Nanite (wirtualizowana geometria) i Lumen
Unreal Engine wykorzystuje język programowania \textbf{C++} z Unreal Engine wykorzystuje język programowania \textbf{C++} z
rozszerzeniami specyficznymi dla silnika (makra UE), co zapewnia: rozszerzeniami specyficznymi dla silnika (makra UE), co zapewnia:
\begin{itemize} \begin{itemize}
\item Maksymalną wydajność dzięki kompilacji do kodu natywnego \item Maksymalną wydajność dzięki kompilacji do kodu natywnego.
\item Pełną kontrolę nad zarządzaniem pamięcią \item Pełną kontrolę nad zarządzaniem pamięcią.
\item Strome krzywe uczenia, szczególnie dla programistów bez doświadczenia w C++ \item Strome krzywe uczenia, szczególnie dla programistów bez doświadczenia w C++.
\end{itemize} \end{itemize}
Dodatkowo Unreal oferuje system \textbf{Blueprints} -- Dodatkowo Unreal oferuje system \textbf{Blueprints} --
@ -136,25 +136,25 @@ być mniej wydajne niż natywny C++.
Unreal Engine wyróżnia się zaawansowanymi możliwościami graficznymi: Unreal Engine wyróżnia się zaawansowanymi możliwościami graficznymi:
\begin{itemize} \begin{itemize}
\item \textbf{Rendering} -- fotorealistyczna grafika z obsługą ray tracingu, Nanite i Lumen \item \textbf{Rendering} -- fotorealistyczna grafika z obsługą ray tracingu, Nanite i Lumen.
\item \textbf{Fizyka} -- silnik Chaos Physics z obsługą destrukcji i symulacji ciał miękkich \item \textbf{Fizyka} -- silnik Chaos Physics z obsługą destrukcji i symulacji ciał miękkich.
\item \textbf{Animacja} -- Control Rig, Animation Blueprints, IK Retargeting \item \textbf{Animacja} -- Control Rig, Animation Blueprints, IK Retargeting.
\item \textbf{Landscape} -- zaawansowane narzędzia do tworzenia dużych terenów \item \textbf{Landscape} -- zaawansowane narzędzia do tworzenia dużych terenów.
\item \textbf{Niagara} -- system efektów cząsteczkowych nowej generacji \item \textbf{Niagara} -- system efektów cząsteczkowych nowej generacji.
\item \textbf{Sequencer} -- narzędzie do tworzenia cinematików i cutscen \item \textbf{Sequencer} -- narzędzie do tworzenia cinematików i cutscen.
\end{itemize} \end{itemize}
\subsubsection{Narzędzia deweloperskie} \subsubsection{Narzędzia deweloperskie}
Unreal Editor oferuje rozbudowane środowisko deweloperskie~\cite{unreal_docs}: Unreal Editor oferuje rozbudowane środowisko deweloperskie~\cite{unreal_docs}:
\begin{itemize} \begin{itemize}
\item Edytor poziomów z obsługą streamingu i Level of Detail (LOD) \item Edytor poziomów z obsługą streamingu i Level of Detail (LOD).
\item Blueprint Visual Scripting -- programowanie wizualne \item Blueprint Visual Scripting -- programowanie wizualne.
\item Material Editor -- węzłowy edytor materiałów \item Material Editor -- węzłowy edytor materiałów.
\item Wbudowany profiler z analizą GPU/CPU i pamięci \item Wbudowany profiler z analizą GPU/CPU i pamięci.
\item Marketplace -- sklep z zasobami i pluginami \item Marketplace -- sklep z zasobami i pluginami.
\item Dostęp do kodu źródłowego silnika \item Dostęp do kodu źródłowego silnika.
\item Live Coding -- eksperymentalne wsparcie dla hot reload w C++ \item Live Coding -- eksperymentalne wsparcie dla hot reload w C++.
\end{itemize} \end{itemize}
\textbf{Porównanie architektoniczne} \textbf{Porównanie architektoniczne}
@ -198,15 +198,15 @@ analizę dwóch fundamentalnie różnych podejść do tworzenia gier:
\item \textbf{Produktywność vs wydajność} -- C\# w Unity oferuje \item \textbf{Produktywność vs wydajność} -- C\# w Unity oferuje
szybszy rozwój kosztem pewnego narzutu wydajnościowego, podczas szybszy rozwój kosztem pewnego narzutu wydajnościowego, podczas
gdy C++ w Unreal wymaga więcej pracy, ale zapewnia maksymalną gdy C++ w Unreal wymaga więcej pracy, ale zapewnia maksymalną
kontrolę kontrolę.
\item \textbf{Dostępność vs specjalizacja} -- Unity celuje w \item \textbf{Dostępność vs specjalizacja} -- Unity celuje w
szeroki rynek z niskim progiem wejścia, Unreal koncentruje się szeroki rynek z niskim progiem wejścia, Unreal koncentruje się
na produkcjach premium na produkcjach premium.
\item \textbf{Elastyczność vs integracja} -- Unity pozwala \item \textbf{Elastyczność vs integracja} -- Unity pozwala
na większą swobodę w doborze zewnętrznych narzędzi, Unreal na większą swobodę w doborze zewnętrznych narzędzi, Unreal
oferuje bardziej zintegrowane rozwiązania oferuje bardziej zintegrowane rozwiązania.
\end{enumerate} \end{enumerate}
Analiza tych dwóch silników dostarcza kompleksowego obrazu \\ Analiza tych dwóch silników dostarcza kompleksowego obrazu
współczesnego stanu technologii do tworzenia gier i~pozwala na \\ współczesnego stanu technologii do tworzenia gier i~pozwala na
sformułowanie praktycznych rekomendacji dla deweloperów. sformułowanie praktycznych rekomendacji dla deweloperów.

View File

@ -15,15 +15,15 @@ za pomocą narzędzia NVIDIA Nsight Systems:
\begin{itemize} \begin{itemize}
\item \textbf{Czas klatki} (ang. \emph{frame time}) -- czas potrzebny \item \textbf{Czas klatki} (ang. \emph{frame time}) -- czas potrzebny
na wyrenderowanie pojedynczej klatki, wyrażony w~milisekundach na wyrenderowanie pojedynczej klatki, wyrażony w~milisekundach.
\item \textbf{Liczba klatek na sekundę} (FPS) -- wartość \\ pochodna \item \textbf{Liczba klatek na sekundę} (FPS) -- wartość pochodna
od czasu klatki, kluczowa dla płynności rozgrywki od czasu klatki, kluczowa dla płynności rozgrywki.
\item \textbf{Wykorzystanie GPU} -- procentowe obciążenie karty graficznej, \item \textbf{Wykorzystanie GPU} -- procentowe obciążenie karty graficznej,
mierzone poprzez liczniki sprzętowe NVIDIA mierzone poprzez liczniki sprzętowe NVIDIA.
\item \textbf{Wywołania Vulkan API} -- szczegółowa analiza wywołań \item \textbf{Wywołania Vulkan API} -- szczegółowa analiza wywołań
interfejsu graficznego, w~tym funkcji synchronizacji i~prezentacji interfejsu graficznego, w~tym funkcji synchronizacji i~prezentacji.
\item \textbf{Wywołania systemowe} -- analiza mechanizmów wielowątkowości \item \textbf{Wywołania systemowe} -- analiza mechanizmów wielowątkowości
i~synchronizacji na poziomie systemu operacyjnego i~synchronizacji na poziomie systemu operacyjnego.
\end{itemize} \end{itemize}
\subsection{Środowisko testowe} \subsection{Środowisko testowe}
@ -33,13 +33,13 @@ za pomocą narzędzia NVIDIA Nsight Systems:
Wszystkie testy wydajnościowe przeprowadzono na komputerze o następującej specyfikacji: Wszystkie testy wydajnościowe przeprowadzono na komputerze o następującej specyfikacji:
\begin{itemize} \begin{itemize}
\item \textbf{Procesor}: AMD Ryzen 9 7900X3D 12-Core Processor (24 rdzenie, 48 wątków) \item \textbf{Procesor}: AMD Ryzen 9 7900X3D 12-Core Processor (24 rdzenie, 48 wątków).
\item \textbf{Karta graficzna}: NVIDIA GeForce RTX 3090 \item \textbf{Karta graficzna}: NVIDIA GeForce RTX 3090.
\item \textbf{Pamięć GPU}: 24 GB GDDR6X \item \textbf{Pamięć GPU}: 24 GB GDDR6X.
\item \textbf{Sterowniki NVIDIA}: wersja 590.48.01 \item \textbf{Sterowniki NVIDIA}: wersja 590.48.01.
\item \textbf{Pamięć RAM}: 32 GB \item \textbf{Pamięć RAM}: 32 GB.
\item \textbf{System operacyjny}: Arch Linux (jądro Linux 6.18.5-arch1-1) \item \textbf{System operacyjny}: Arch Linux (jądro Linux 6.18.5-arch1-1).
\item \textbf{Dysk}: SSD o pojemności 3,6 TB \item \textbf{Dysk}: SSD o pojemności 3,6 TB.
\end{itemize} \end{itemize}
\label{subsubsec:specyfikacja-oprogramowania} \label{subsubsec:specyfikacja-oprogramowania}
@ -47,9 +47,9 @@ Wszystkie testy wydajnościowe przeprowadzono na komputerze o następującej spe
W badaniach wykorzystano następujące wersje oprogramowania: W badaniach wykorzystano następujące wersje oprogramowania:
\begin{itemize} \begin{itemize}
\item \textbf{Unity}: 6.0 (6000.0.58f2) LTS \item \textbf{Unity}: 6.0 (6000.0.58f2) LTS.
\item \textbf{Unreal Engine}: 5.5.3 \item \textbf{Unreal Engine}: 5.5.3.
\item \textbf{NVIDIA Nsight Systems}: 2025.5.2 \item \textbf{NVIDIA Nsight Systems}: 2025.5.2.
\end{itemize} \end{itemize}
Wybór wersji LTS silnika Unity podyktowany był stabilnością oraz długoterminowym wsparciem, Wybór wersji LTS silnika Unity podyktowany był stabilnością oraz długoterminowym wsparciem,
@ -64,11 +64,11 @@ Na potrzeby badań porównawczych zaimplementowano identyczną grę w gatunku
\emph{bullet hell} w obu silnikach. Gra charakteryzuje się następującymi cechami: \emph{bullet hell} w obu silnikach. Gra charakteryzuje się następującymi cechami:
\begin{itemize} \begin{itemize}
\item Sterowana przez gracza postać \item Sterowana przez gracza postać.
\item System generowania przeciwników z progresywnie rosnącym obciążeniem \item System generowania przeciwników z progresywnie rosnącym obciążeniem.
\item Generowanie wzorców pocisków \item Generowanie wzorców pocisków.
\item Wykrywanie kolizji między obiektami \item Wykrywanie kolizji między obiektami.
\item Tryb przetrwania trwający 90 sekund \item Tryb przetrwania trwający 90 sekund.
\end{itemize} \end{itemize}
Wybór gatunku \emph{bullet hell} podyktowany był możliwością generowania dużej Wybór gatunku \emph{bullet hell} podyktowany był możliwością generowania dużej
@ -83,14 +83,14 @@ progresywnie zwiększała obciążenie poprzez:
\begin{itemize} \begin{itemize}
\item \textbf{Przyspieszanie spawnu przeciwników} -- interwał między \item \textbf{Przyspieszanie spawnu przeciwników} -- interwał między
spawnem zmniejsza się liniowo od 0,25~s (początek) do 0,08~s (koniec), spawnem zmniejsza się liniowo od 0,25~s (początek) do 0,08~s (koniec),
z~dodatkowym ,,finalnym szturmem'' przez ostatnie 5~sekund z~dodatkowym ,,finalnym szturmem'' przez ostatnie 5~sekund.
\item \textbf{Zwiększanie różnorodności typów przeciwników} -- \item \textbf{Zwiększanie różnorodności typów przeciwników} --
początkowo \\ (0--25\% czasu) pojawiają się tylko podstawowi początkowo (0--25\% czasu) pojawiają się tylko podstawowi
przeciwnicy, później wprowadzane są kolejno szybsze jednostki przeciwnicy, później wprowadzane są kolejno szybsze jednostki
(25--50\%), strzelające wieżyczki (50--75\%) oraz wytrzymałe (25--50\%), strzelające wieżyczki (50--75\%) oraz wytrzymałe
czołgi (75--100\%) czołgi (75--100\%).
\item \textbf{Maksymalna liczba przeciwników} -- limit jednoczesnych \item \textbf{Maksymalna liczba przeciwników} -- limit jednoczesnych
przeciwników na scenie wynosi 200 jednostek przeciwników na scenie wynosi 200 jednostek.
\end{itemize} \end{itemize}
\newpage \newpage
Na potrzeby profilowania rozgrywka została podzielona na trzy fazy czasowe: Na potrzeby profilowania rozgrywka została podzielona na trzy fazy czasowe:
@ -110,21 +110,21 @@ interwał spawnu osiąga minimum 0,08~s. Ostatnie 5~sekund to
Przeprowadzono cztery sesje pomiarowe -- po dwie dla każdego silnika: Przeprowadzono cztery sesje pomiarowe -- po dwie dla każdego silnika:
\begin{enumerate} \begin{enumerate}
\item \textbf{Unity -- tryb statyczny}: Gracz nieruchomy z~włączoną \\ \item \textbf{Unity -- tryb statyczny}: Gracz nieruchomy z~włączoną
nieśmiertelnością, pełne 90~sekund rozgrywki profilowane w~jednej sesji nieśmiertelnością, pełne 90~sekund rozgrywki profilowane w~jednej sesji.
\item \textbf{Unity -- tryb dynamiczny}: Gracz aktywnie poruszający się \item \textbf{Unity -- tryb dynamiczny}: Gracz aktywnie poruszający się
i~strzelający, pełne 90~sekund rozgrywki i~strzelający, pełne 90~sekund rozgrywki.
\item \textbf{Unreal Engine -- tryb statyczny}: Ze względu na ograniczenia \item \textbf{Unreal Engine -- tryb statyczny}: Ze względu na ograniczenia
techniczne (awaria przy śledzeniu Vulkan API) rozgrywkę podzielono na techniczne (awaria przy śledzeniu Vulkan API) rozgrywkę podzielono na
trzy 30-sekundowe fazy, uruchamiane z~flagą \texttt{-{}-start-time=N} trzy 30-sekundowe fazy, uruchamiane z~flagą \texttt{-{}-start-time=N}.
\item \textbf{Unreal Engine -- tryb dynamiczny}: Analogicznie do trybu \item \textbf{Unreal Engine -- tryb dynamiczny}: Analogicznie do trybu
statycznego, trzy fazy po 30~sekund z~aktywnym graczem statycznego, trzy fazy po 30~sekund z~aktywnym graczem.
\end{enumerate} \end{enumerate}
Narzędzie NVIDIA Nsight Systems rejestrowało: Narzędzie NVIDIA Nsight Systems rejestrowało:
\begin{itemize} \begin{itemize}
\item Wywołania Vulkan API (dla Unity -- dla Unreal niemożliwe z~powodu \item Wywołania Vulkan API (dla Unity -- dla Unreal niemożliwe z~powodu
awarii) awarii).
\item Metryki sprzętowe GPU z~częstotliwością 10\,000~Hz \item Metryki sprzętowe GPU z~częstotliwością 10\,000~Hz.
\item Wywołania funkcji systemowych (pthread, futex itp.) \item Wywołania funkcji systemowych (pthread, futex itp.).
\end{itemize} \end{itemize}

View File

@ -1,16 +1,17 @@
\clearpage \clearpage
\raggedbottom
\section{Testy wydajności} \section{Testy wydajności}
\label{sec:testy-wydajnosci} \label{sec:testy-wydajnosci}
Dla każdego scenariusza i~silnika rejestrowano następujące metryki przy użyciu NVIDIA Nsight Systems: Dla każdego scenariusza i~silnika rejestrowano następujące metryki przy użyciu NVIDIA Nsight Systems:
\begin{itemize} \begin{itemize}
\item \textbf{Czas klatki} (frame time) -- czas renderowania pojedynczej klatki w~milisekundach \item \textbf{Czas klatki} (frame time) -- czas renderowania pojedynczej klatki w~milisekundach.
\item \textbf{FPS} (frames per second) -- liczba klatek na sekundę, wyliczana jako \\ $1000 / \text{frame time}$ \item \textbf{FPS} (frames per second) -- liczba klatek na sekundę, wyliczana jako $1000 / \text{frame time}$.
\item \textbf{Wykorzystanie GPU} -- procent wykorzystania mocy obliczeniowej karty graficznej \item \textbf{Wykorzystanie GPU} -- procent wykorzystania mocy obliczeniowej karty graficznej.
\item \textbf{Zużycie pamięci VRAM} -- ilość zajętej pamięci karty graficznej w~megabajtach \item \textbf{Zużycie pamięci VRAM} -- ilość zajętej pamięci karty graficznej w~megabajtach.
\item \textbf{Liczba wywołań rysowania} (draw calls) -- liczba instrukcji renderowania na klatkę \item \textbf{Liczba wywołań rysowania} (draw calls) -- liczba instrukcji renderowania na klatkę.
\item \textbf{Liczba wierzchołków} -- całkowita liczba przetworzonych wierzchołków na klatkę \item \textbf{Liczba wierzchołków} -- całkowita liczba przetworzonych wierzchołków na klatkę.
\end{itemize} \end{itemize}
\subsection{Wyniki testów dla silnika Unity} \subsection{Wyniki testów dla silnika Unity}
@ -60,12 +61,12 @@ klatki 0,08 ms odpowiada sytuacjom, gdy kolejne wywołania prezentacji następuj
sobie -- może to wynikać z mechanizmu sobie -- może to wynikać z mechanizmu
podwójnego buforowania (ang. \textit{double buffering}) lub chwilowego braku pracy do wykonania przez GPU. podwójnego buforowania (ang. \textit{double buffering}) lub chwilowego braku pracy do wykonania przez GPU.
Wartość maksymalna 1\,239,62 ms (ponad sekunda) występuje podczas \\ fazy inicjalizacji aplikacji, Wartość maksymalna 1\,239,62 ms (ponad sekunda) występuje podczas fazy inicjalizacji aplikacji,
gdy silnik Unity wykonuje jednorazowe \\ operacje: kompilację shaderów, alokację dużych bloków pamięci \\ GPU, gdy silnik Unity wykonuje jednorazowe operacje: kompilację shaderów, alokację dużych bloków pamięci \\ GPU,
tworzenie obiektów swapchain oraz tworzenie obiektów swapchain oraz
inicjalizację systemu renderowania. \\ Jest to zachowanie typowe dla aplikacji Vulkan, gdzie znaczna część inicjalizację systemu renderowania. Jest to zachowanie typowe dla aplikacji Vulkan, gdzie znaczna część
pracy inicjalizacyjnej wykonywana jest przy pracy inicjalizacyjnej wykonywana jest przy
starcie, w przeciwieństwie \\ do OpenGL, gdzie inicjalizacja jest bardziej rozłożona w czasie. starcie, w przeciwieństwie do OpenGL, gdzie inicjalizacja jest bardziej rozłożona w czasie.
Współczynnik zmienności (CV) wynoszący 153,24\% jest wysoki, jednak wynika on głównie z Współczynnik zmienności (CV) wynoszący 153,24\% jest wysoki, jednak wynika on głównie z
uwzględnienia ekstremalnych wartości inicjalizacyjnych. uwzględnienia ekstremalnych wartości inicjalizacyjnych.
@ -167,15 +168,15 @@ renderującego na poziomie pojedynczych funkcji API. Podczas testu zarejestrowan
\end{tabular} \end{tabular}
\end{table} \end{table}
\texttt{vkWaitForFences} \\ pochłonęła \textbf{95,2\% całkowitego czasu} \texttt{vkWaitForFences} pochłonęła \textbf{95,2\% całkowitego czasu}
profilowania wywołań Vulkan API, co stanowi 77,04 sekundy z profilowania wywołań Vulkan API, co stanowi 77,04 sekundy z
94-sekundowego testu. Funkcja ta, zdefiniowana w specyfikacji Vulkan w rozdziale 7.3 dotyczącym 94-sekundowego testu. Funkcja ta, zdefiniowana w specyfikacji Vulkan w rozdziale 7.3 dotyczącym
synchronizacji, realizuje blokujące oczekiwanie synchronizacji, realizuje blokujące oczekiwanie
procesora na sygnalizację obiektów ogrodzenia (ang. \textit{fence}) przez GPU. procesora na sygnalizację obiektów ogrodzenia (ang. \textit{fence}) przez GPU.
Mechanizm ogrodzeń w Vulkan działa następująco: aplikacja tworzy \\ obiekt fence, Mechanizm ogrodzeń w Vulkan działa następująco: aplikacja tworzy obiekt fence,
dołącza go do operacji przesyłanej do kolejki GPU \\ dołącza go do operacji przesyłanej do kolejki GPU
(np. poprzez \texttt{vkQueueSubmit}), a następnie może \\wywołać \texttt{vkWaitForFences}, (np. poprzez \texttt{vkQueueSubmit}), a następnie może wywołać \texttt{vkWaitForFences},
aby zablokować wątek CPU do momentu zakończenia aby zablokować wątek CPU do momentu zakończenia
powiązanej pracy przez GPU. Jest to fundamentalny mechanizm synchronizacji w architekturze powiązanej pracy przez GPU. Jest to fundamentalny mechanizm synchronizacji w architekturze
producent-konsument między CPU a GPU. producent-konsument między CPU a GPU.
@ -189,7 +190,7 @@ zdąża przygotować pracę dla GPU przed zakończeniem poprzedniej klatki.
Różnica między średnią a medianą (0,26 ms) wynika z obecności bardzo krótkich Różnica między średnią a medianą (0,26 ms) wynika z obecności bardzo krótkich
czasów oczekiwania w niektórych sytuacjach (np. gdy GPU zakończył pracę przed wywołaniem wait). czasów oczekiwania w niektórych sytuacjach (np. gdy GPU zakończył pracę przed wywołaniem wait).
Maksymalny czas 1\,181,17 ms odpowiada fazie Maksymalny czas 1\,181,17 ms odpowiada fazie
inicjalizacji, \\ podczas której GPU wykonuje jednorazowe, kosztowne operacje. inicjalizacji, podczas której GPU wykonuje jednorazowe, kosztowne operacje.
Stosunek liczby wywołań \texttt{vkWaitForFences} (12\,895) do liczby klatek (13\,556) wskazuje, że Stosunek liczby wywołań \texttt{vkWaitForFences} (12\,895) do liczby klatek (13\,556) wskazuje, że
Unity stosuje strategię oczekiwania, prawie na Unity stosuje strategię oczekiwania, prawie na
@ -233,7 +234,7 @@ odbywa się asynchronicznie na GPU.
Tabela~\ref{tab:unity-vulkan-cmd} przedstawia statystyki funkcji związanych z buforami poleceń. Tabela~\ref{tab:unity-vulkan-cmd} przedstawia statystyki funkcji związanych z buforami poleceń.
Liczba wywołań \texttt{vkBeginCommandBuffer} \\ oraz Liczba wywołań \texttt{vkBeginCommandBuffer} oraz
\texttt{vkEndCommandBuffer} (po 40\,679) oznacza, że Unity nagrywa średnio 3 bufory poleceń na klatkę. Jest to typowa wartość dla nowoczesnych \texttt{vkEndCommandBuffer} (po 40\,679) oznacza, że Unity nagrywa średnio 3 bufory poleceń na klatkę. Jest to typowa wartość dla nowoczesnych
silników stosujących wielowątkowe nagrywanie poleceń. silników stosujących wielowątkowe nagrywanie poleceń.
@ -269,14 +270,15 @@ Tabela~\ref{tab:unity-vulkan-init} przedstawia jednorazowe operacje inicjalizacy
urządzenie Vulkan -- jest to najdroższa pojedyncza operacja, obejmująca negocjację możliwości GPU, alokację struktur wewnętrznych sterownika i urządzenie Vulkan -- jest to najdroższa pojedyncza operacja, obejmująca negocjację możliwości GPU, alokację struktur wewnętrznych sterownika i
inicjalizację kolejek. inicjalizację kolejek.
\texttt{vkCreateSwapchainKHR} (77,02 ms) tworzy łańcuch wymiany (swapchain), \\ czyli zestaw \texttt{vkCreateSwapchainKHR} (77,02 ms) tworzy łańcuch wymiany (swapchain), czyli zestaw
buforów służących do prezentacji obrazu. Operacja ta buforów służących do prezentacji obrazu. Operacja ta
obejmuje alokację pamięci dla buforów, konfigurację formatów i synchronizację z systemem okienkowym. obejmuje alokację pamięci dla buforów, konfigurację formatów i synchronizację z systemem okienkowym.
Utworzenie 341 obiektów fence (łącznie 135,60 ms) wskazuje na przygotowanie puli ogrodzeń do Utworzenie 341 obiektów fence (łącznie 135,60 ms) wskazuje na
wielokrotnego użytku w cyklu renderowania. przygotowanie puli ogrodzeń do wielokrotnego użytku w cyklu renderowania.
\\ Unity stosuje Unity stosuje
strategię pre-alokacji zamiast tworzenia ogrodzeń na żądanie, co jest praktyką zalecaną w dokumentacji strategię \\ pre-alokacji zamiast tworzenia ogrodzeń na żądanie, co
jest praktyką zalecaną w dokumentacji
Vulkan. Vulkan.
@ -361,21 +363,22 @@ Duża liczba wywołań \texttt{openat64} (22\,155) wskazuje na intensywne operac
gry (tekstur, modeli, shaderów) z dysku. Średni czas 1,07 $\mu$s potwierdza efektywne buforowanie przez system operacyjny. gry (tekstur, modeli, shaderów) z dysku. Średni czas 1,07 $\mu$s potwierdza efektywne buforowanie przez system operacyjny.
\texttt{ioctl} (1\,907 wywołań) służy do kontroli urządzeń -- w kontekście grafiki Vulkan jest \texttt{ioctl} (1\,907 wywołań) służy do kontroli urządzeń -- w kontekście grafiki Vulkan jest
używane do komunikacji ze sterownikiem GPU poprzez \\ używane do komunikacji ze sterownikiem GPU poprzez
interfejs DRM/KMS (Direct Rendering Manager / Kernel Mode Setting). interfejs DRM/KMS (Direct Rendering Manager / Kernel Mode Setting).
Przeprowadzona analiza pozwala na sformułowanie następujących wniosków dotyczących wydajności i architektury silnika Unity: Przeprowadzona analiza pozwala na sformułowanie następujących wniosków dotyczących wydajności i architektury silnika Unity:
Dominacja \texttt{vkWaitForFences} \\ (95,2\% czasu Vulkan) i \texttt{futex} (95,9\% czasu systemowego) Dominacja \texttt{vkWaitForFences} (95,2\% czasu Vulkan) i \texttt{futex} (95,9\% czasu systemowego)
jednoznacznie wskazuje na scenariusz jednoznacznie wskazuje na scenariusz
\textbf{GPU-bound}. Procesor główny efektywnie przygotowuje i przesyła pracę renderowania, po czym oczekuje na GPU. Jest to optymalny wzorzec dla \textbf{GPU-bound}. Procesor główny efektywnie przygotowuje i przesyła pracę renderowania, po czym oczekuje na GPU. Jest to optymalny wzorzec dla
aplikacji graficznych, gdzie GPU wykonuje większość obliczeniowo intensywnej pracy. aplikacji graficznych, gdzie GPU wykonuje większość obliczeniowo intensywnej pracy.
W scenariuszu CPU-bound obserwowalibyśmy niższy udział funkcji synchronizacyjnych i wyższy udział W scenariuszu CPU-bound obserwowalibyśmy niższy udział funkcji
funkcji przygotowujących polecenia \\ synchronizacyjnych i wyższy udział
(\texttt{vkBeginCommandBuffer}, \texttt{vkCmdBindPipeline} itp.), co wskazywałoby na wąskie gardło po stronie procesora. funkcji przygotowujących polecenia
(\texttt{vkBeginCommandBuffer}, \\ \texttt{vkCmdBindPipeline} itp.), co wskazywałoby na wąskie gardło po stronie procesora.
Stosunek liczby wywołań \texttt{vkQueueSubmit} (27\,112) do \texttt{vkQueuePresentKHR} (13\,556) wynoszący 2:1 wskazuje na dwuetapowy potok Stosunek liczby wywołań \texttt{vkQueueSubmit} (27\,112) do \texttt{vkQueuePresentKHR} (13\,556) wynoszący 2:1 wskazuje na dwuetapowy potok
@ -383,7 +386,7 @@ renderowania dla każdej klatki. Może to odpowiadać architekturze z oddzielnym
odroczonego renderowania (ang. \textit{deferred rendering}). odroczonego renderowania (ang. \textit{deferred rendering}).
Niska liczba wywołań \texttt{vkCmdBindPipeline} (27\,027, ~2 na klatkę) Niska liczba wywołań \texttt{vkCmdBindPipeline} (27\,027, ~2 na klatkę)
sugeruje \\ efektywne grupowanie obiektów renderowanych tym samym shaderem, sugeruje efektywne grupowanie obiektów renderowanych tym samym shaderem,
minimalizujące kosztowne zmiany stanu GPU. minimalizujące kosztowne zmiany stanu GPU.
@ -391,23 +394,23 @@ Pomimo wysokiego współczynnika zmienności (153\%) wynikającego z wartości e
inicjalizacji, właściwa stabilność renderowania jest inicjalizacji, właściwa stabilność renderowania jest
wysoka. Świadczy o tym: wysoka. Świadczy o tym:
\begin{itemize} \begin{itemize}
\item Wąski rozstęp międzykwartylowy (0,08 ms) \item Wąski rozstęp międzykwartylowy (0,08 ms).
\item Zbieżność mediany (6,94 ms) ze średnią (6,95 ms) \item Zbieżność mediany (6,94 ms) ze średnią (6,95 ms).
\item Mała różnica między 50. a 99. percentylem (0,64 ms, 9,2\%) \item Mała różnica między 50. a 99. percentylem (0,64 ms, 9,2\%).
\item 98,24\% klatek w przedziale 5--10 ms \item 98,24\% klatek w przedziale 5--10 ms.
\end{itemize} \end{itemize}
Należy jednak podkreślić, że obserwowana stabilność jest w znacznej mierze wynikiem Należy jednak podkreślić, że obserwowana stabilność jest w znacznej mierze wynikiem
działania synchronizacji pionowej (V-Sync), która sztucznie \\ działania synchronizacji pionowej (V-Sync), która sztucznie
wyrównuje czasy klatek poprzez oczekiwanie na sygnał odświeżania monitora. \\ Bez V-Sync wyrównuje czasy klatek poprzez oczekiwanie na sygnał odświeżania monitora. Bez V-Sync
zmienność czasów klatek mogłaby być wyższa. zmienność czasów klatek mogłaby być wyższa.
Analiza wywołań systemowych potwierdza intensywne wykorzystanie wielowątkowości: Analiza wywołań systemowych potwierdza intensywne wykorzystanie wielowątkowości:
\begin{itemize} \begin{itemize}
\item 81 utworzonych wątków wskazuje na rozbudowany system zadań \item 81 utworzonych wątków wskazuje na rozbudowany system zadań.
\item Dominacja \texttt{futex} sugeruje częstą komunikację między wątkami \item Dominacja \texttt{futex} sugeruje częstą komunikację między wątkami.
\item Użycie zmiennych warunkowych z timeoutem świadczy o responsywnej architekturze \item Użycie zmiennych warunkowych z timeoutem świadczy o responsywnej architekturze.
\end{itemize} \end{itemize}
Unity 2023 LTS stosuje architekturę DOTS (Data-Oriented Technology Stack) z systemem zadań (Job System), który automatycznie dystrybuuje pracę na Unity 2023 LTS stosuje architekturę DOTS (Data-Oriented Technology Stack) z systemem zadań (Job System), który automatycznie dystrybuuje pracę na
@ -418,44 +421,47 @@ dostępne rdzenie procesora. Wyniki profilowania potwierdzają aktywne wykorzyst
Profilowanie silnika Unreal Engine 5.5 przeprowadzono przy użyciu NVIDIA Nsight Systems w Profilowanie silnika Unreal Engine 5.5 przeprowadzono przy użyciu NVIDIA Nsight Systems w
wersji 2025.5.2. Ze względu na problemy ze stabilnością wersji 2025.5.2. Ze względu na problemy ze stabilnością
połączenia agenta Nsight podczas długich sesji profilowania, 90-sekundową \\ rozgrywkę połączenia agenta Nsight podczas długich sesji profilowania, 90-sekundową rozgrywkę
podzielono na \textbf{trzy fazy po 30 sekund każda}: podzielono na \textbf{trzy fazy po 30 sekund każda}:
\begin{itemize} \begin{itemize}
\item \textbf{Faza 1} (0--30 s): Początkowa rozgrywka z niską trudnością \item \textbf{Faza 1} (0--30 s): Początkowa rozgrywka z niską trudnością.
\item \textbf{Faza 2} (30--60 s): Środkowa rozgrywka ze średnią trudnością \item \textbf{Faza 2} (30--60 s): Środkowa rozgrywka ze średnią trudnością.
\item \textbf{Faza 3} (60--90 s): Końcowa rozgrywka z wysoką trudnością + ekran zwycięstwa \item \textbf{Faza 3} (60--90 s): Końcowa rozgrywka z wysoką trudnością + ekran zwycięstwa.
\end{itemize} \end{itemize}
Każda faza była uruchamiana z flagą \texttt{--start-time=N}, która przesuwa \\ zarówno stan gry Każda faza była uruchamiana z flagą \texttt{--start-time=N}, która przesuwa
zarówno stan gry
(w \texttt{STGGameDirector}), jak i poziom trudności (w \texttt{STGGameDirector}), jak i poziom trudności
spawnu przeciwników \\ (w \texttt{STGEnemySpawner}) do odpowiedniej sekundy. \\ Grę skompilowano w konfiguracji DebugGame, która zachowuje symbole spawnu przeciwników \\ (w \texttt{STGEnemySpawner}) do odpowiedniej sekundy. Grę skompilowano w konfiguracji DebugGame, która zachowuje symbole
debugowania przy częściowych optymalizacjach. debugowania przy częściowych optymalizacjach.
Ze względu na bardzo dużą ilość danych generowanych przez Unreal Engine podczas śledzenia wywołań Vulkan API (około 13 milionów zdarzeń Ze względu na bardzo dużą ilość danych generowanych przez Unreal Engine podczas śledzenia wywołań Vulkan API (około 13 milionów zdarzeń
na 30 sekund rozgrywki, w porównaniu z 0,5 miliona dla Unity), 90-sekundową rozgrywkę podzielono na \textbf{trzy fazy po 30 sekund każda}: na 30 sekund rozgrywki, w porównaniu z 0,5 miliona dla Unity), 90-sekundową rozgrywkę podzielono na \textbf{trzy fazy po 30 sekund każda}:
\begin{itemize} \begin{itemize}
\item \textbf{Faza 1} (0--30 s): Początkowa rozgrywka z niską trudnością \item \textbf{Faza 1} (0--30 s): Początkowa rozgrywka z niską trudnością.
\item \textbf{Faza 2} (30--60 s): Środkowa rozgrywka ze średnią trudnością \item \textbf{Faza 2} (30--60 s): Środkowa rozgrywka ze średnią trudnością.
\item \textbf{Faza 3} (60--90 s): Końcowa rozgrywka z wysoką trudnością + ekran zwycięstwa \item \textbf{Faza 3} (60--90 s): Końcowa rozgrywka z wysoką trudnością + ekran zwycięstwa.
\end{itemize} \end{itemize}
Każda faza była uruchamiana z flagą \texttt{--start-time=N}, która przesuwa zarówno stan gry Każda faza była uruchamiana z flagą \texttt{--start-time=N},
(w \texttt{STGGameDirector}), jak i poziom trudności spawnu \\ przeciwników (w \texttt{STGEnemySpawner}) która przesuwa zarówno stan gry
(w \texttt{STGGameDirector}), jak i poziom trudności spawnu przeciwników
\\ (w \texttt{STGEnemySpawner})
do odpowiedniej sekundy. do odpowiedniej sekundy.
\\ Grę skompilowano w konfiguracji DebugGame, która zachowuje symbole debugowania przy częściowych optymalizacjach. Grę skompilowano w konfiguracji DebugGame, która zachowuje symbole debugowania przy częściowych optymalizacjach.
Profilowanie przeprowadzono z wykorzystaniem tych samych metryk co dla Unity: Profilowanie przeprowadzono z wykorzystaniem tych samych metryk co dla Unity:
\begin{itemize} \begin{itemize}
\item \textbf{Śledzenia wywołań Vulkan API} (\texttt{--trace=vulkan}) -- przechwytywanie \\ wszystkich funkcji Vulkan \item \textbf{Śledzenia wywołań Vulkan API} (\texttt{--trace=vulkan}) -- przechwytywanie wszystkich funkcji Vulkan.
\item \textbf{Śledzenia wywołań systemowych} (\texttt{--trace=osrt}) -- przechwytywanie funkcji OS Runtime \item \textbf{Śledzenia wywołań systemowych} (\texttt{--trace=osrt}) -- przechwytywanie funkcji OS Runtime.
\item \textbf{Metryk sprzętowych GPU} (\texttt{--gpu-metrics-devices=0}) -- próbkowanie \\ liczników wydajności GPU \item \textbf{Metryk sprzętowych GPU} (\texttt{--gpu-metrics-devices=0}) -- próbkowanie liczników wydajności GPU.
\end{itemize} \end{itemize}
NVIDIA Nsight Systems zbiera metryki sprzętowe GPU poprzez bezpośredni dostęp do liczników NVIDIA Nsight Systems zbiera metryki sprzętowe GPU poprzez bezpośredni dostęp do liczników
wydajności zintegrowanych w karcie graficznej. wydajności zintegrowanych w karcie graficznej.
\\ Podczas trzech 35-sekundowych sesji (30 sekund rozgrywki + 5 sekund buforu) zebrano łącznie \textbf{1\,050\,555 próbek} dla każdej z Podczas trzech 35-sekundowych sesji (30 sekund rozgrywki + 5 sekund buforu) zebrano łącznie \textbf{1\,050\,555 próbek} dla każdej z
31 monitorowanych metryk. 31 monitorowanych metryk.
\begin{table}[H] \begin{table}[H]
@ -503,7 +509,7 @@ Liczba próbek & 350\,205 & 350\,249 & 350\,101 \\
Tabela~\ref{tab:unreal-gpu-phases} pokazuje stabilność metryk GPU między fazami 1 i 2 Tabela~\ref{tab:unreal-gpu-phases} pokazuje stabilność metryk GPU między fazami 1 i 2
różnice <0,5 pp.), różnice <0,5 pp.),
co potwierdza poprawność metodologii co potwierdza poprawność metodologii
fazowego profilowania. \\ fazowego profilowania.
Wyraźny spadek w fazie Wyraźny spadek w fazie
3 odzwierciedla zakończenie aktywnej rozgrywki i przejście do ekranu zwycięstwa. 3 odzwierciedla zakończenie aktywnej rozgrywki i przejście do ekranu zwycięstwa.
@ -565,17 +571,17 @@ Unallocated Warps in Active SMs & 20,73 & 90,0 \\
Tabela~\ref{tab:unreal-warps} przedstawia rozkład typów aktywnych wątków shader Tabela~\ref{tab:unreal-warps} przedstawia rozkład typów aktywnych wątków shader
(warps -- grupy 32 wątków CUDA wykonywanych synchronicznie). (warps -- grupy 32 wątków CUDA wykonywanych synchronicznie).
\\Dominacja \texttt{Compute Warps} (13,03\%) nad \texttt{Pixel Warps} (9,36\%) wskazuje na znaczące wykorzystanie compute shaderów, prawdopodobnie do: Dominacja \texttt{Compute Warps} (13,03\%) nad \texttt{Pixel Warps} (9,36\%) wskazuje na znaczące wykorzystanie compute shaderów, prawdopodobnie do:
\begin{itemize} \begin{itemize}
\item Culling (odrzucanie niewidocznych obiektów na GPU) \item Culling (odrzucanie niewidocznych obiektów na GPU).
\item Post-processing i tone mapping \item Post-processing i tone mapping.
\item Symulacji cząsteczek lub fizyki na GPU \item Symulacji cząsteczek lub fizyki na GPU.
\end{itemize} \end{itemize}
Niski udział \texttt{Vertex/Tess/Geometry Warps} (0,45\%) sugeruje prostą geometrię sceny bez intensywnego wykorzystania teselacji -- Niski udział \texttt{Vertex/Tess/Geometry Warps} (0,45\%) sugeruje prostą geometrię sceny bez intensywnego wykorzystania teselacji --
co jest zgodne z charakterystyką testowanej gry bullet-hell, gdzie większość efektów wizualnych to płaskie sprite'y i efekty cząsteczkowe. co jest zgodne z charakterystyką testowanej gry bullet-hell, gdzie większość efektów wizualnych to płaskie sprite'y i efekty cząsteczkowe.
\texttt{Unallocated Warps in Active SMs} (20,73\%) reprezentuje \\ niewykorzystaną pojemność \texttt{Unallocated Warps in Active SMs} (20,73\%) reprezentuje niewykorzystaną pojemność
aktywnych multiprocesorów. Wartość ta wskazuje na aktywnych multiprocesorów. Wartość ta wskazuje na
potencjał optymalizacji przez zwiększenie granularności pracy lub lepsze grupowanie operacji. potencjał optymalizacji przez zwiększenie granularności pracy lub lepsze grupowanie operacji.
@ -672,7 +678,7 @@ wskazuje na konsystentną architekturę potoku renderowania niezależną od obci
W przeciwieństwie do Unity, gdzie dominującą funkcją był \texttt{vkWaitForFences}, W przeciwieństwie do Unity, gdzie dominującą funkcją był \texttt{vkWaitForFences},
w Unreal Engine \textbf{57--72\% czasu} Vulkan API w Unreal Engine \textbf{57--72\% czasu} Vulkan API
pochłonęły funkcje tworzenia potoków. pochłonęły funkcje tworzenia potoków.
\\ Co istotne, liczba wywołań \texttt{vkCreateComputePipelines} i \\ Co istotne, liczba wywołań \texttt{vkCreateComputePipelines} i
\texttt{vkCreateGraphicsPipelines} jest \texttt{vkCreateGraphicsPipelines} jest
\textbf{niemal identyczna we wszystkich trzech fazach}, co wskazuje na strategię \textbf{ciągłej rekompilacji potoków} (Pipeline State Object) \textbf{niemal identyczna we wszystkich trzech fazach}, co wskazuje na strategię \textbf{ciągłej rekompilacji potoków} (Pipeline State Object)
przez cały czas działania gry. przez cały czas działania gry.
@ -682,7 +688,7 @@ przez cały czas działania gry.
Średni czas tworzenia potoku compute (18,63--19,21 ms) jest ponad \textbf{14 razy dłuższy} Średni czas tworzenia potoku compute (18,63--19,21 ms) jest ponad \textbf{14 razy dłuższy}
niż dla potoku graficznego (1,14--1,39 ms). Różnica ta niż dla potoku graficznego (1,14--1,39 ms). Różnica ta
wynika z większej złożoności shaderów obliczeniowych używanych \\ przez Unreal Engine do culling, post-processingu i systemu Nanite. wynika z większej złożoności shaderów obliczeniowych używanych przez Unreal Engine do culling, post-processingu i systemu Nanite.
Wywołanie \texttt{vkCreateDevice} pojawia się raz w każdej fazie z czasem 541--590 ms, co odpowiada momentowi startu gry w tej fazie -- narzędzie Wywołanie \texttt{vkCreateDevice} pojawia się raz w każdej fazie z czasem 541--590 ms, co odpowiada momentowi startu gry w tej fazie -- narzędzie
Nsight Systems tworzy nową sesję dla każdej fazy. Nsight Systems tworzy nową sesję dla każdej fazy.
@ -707,13 +713,13 @@ Nsight Systems tworzy nową sesję dla każdej fazy.
W ostrzym kontraście z Unity (gdzie \texttt{vkWaitForFences} stanowił 95,2\% czasu), w Unreal Engine funkcja ta pochłonęła zaledwie W ostrzym kontraście z Unity (gdzie \texttt{vkWaitForFences} stanowił 95,2\% czasu), w Unreal Engine funkcja ta pochłonęła zaledwie
\textbf{0,5\% czasu} ze średnim czasem oczekiwania 3,63 $\mu$s. Tak niski czas oczekiwania wskazuje na: \textbf{0,5\% czasu} ze średnim czasem oczekiwania 3,63 $\mu$s. Tak niski czas oczekiwania wskazuje na:
\begin{itemize} \begin{itemize}
\item Efektywne wykorzystanie wielokrotnego buforowania (triple buffering) \item Efektywne wykorzystanie wielokrotnego buforowania (triple buffering).
\item Asynchroniczne przesyłanie pracy do GPU bez blokowania \item Asynchroniczne przesyłanie pracy do GPU bez blokowania.
\item Lepsze rozłożenie pracy między CPU a GPU eliminujące przestoje \item Lepsze rozłożenie pracy między CPU a GPU eliminujące przestoje.
\end{itemize} \end{itemize}
Stosunek wywołań \texttt{vkQueueSubmit} (186\,589) do \\ \texttt{vkQueuePresentKHR} (11\,531) Stosunek wywołań \texttt{vkQueueSubmit} (186\,589) do \texttt{vkQueuePresentKHR} (11\,531)
wynosi \textbf{16,2:1}, co oznacza średnio \\ 16 wynosi \textbf{16,2:1}, co oznacza średnio 16
przesyłek pracy na klatkę. Jest to znacznie więcej niż w Unity (2:1), odzwierciedlając przesyłek pracy na klatkę. Jest to znacznie więcej niż w Unity (2:1), odzwierciedlając
bardziej złożony potok renderowania Unreal Engine z bardziej złożony potok renderowania Unreal Engine z
wieloma przebiegami (deferred rendering, post-processing, UI). wieloma przebiegami (deferred rendering, post-processing, UI).
@ -735,13 +741,13 @@ wieloma przebiegami (deferred rendering, post-processing, UI).
\end{tabular} \end{tabular}
\end{table} \end{table}
Liczba wywołań \\ \texttt{vkCmdBindPipeline} (\textbf{5\,771\,642} Liczba wywołań \texttt{vkCmdBindPipeline} (\textbf{5\,771\,642}
łącznie we wszystkich fazach) jest \\ ponad \textbf{213 razy większa} niż w łącznie we wszystkich fazach) jest ponad \textbf{213 razy większa} niż w
Unity (27\,027), \\ co odpowiada około 218 zmianom potoku na klatkę. Tak wysoka wartość wynika z: Unity (27\,027), co odpowiada około 218 zmianom potoku na klatkę. Tak wysoka wartość wynika z:
\begin{itemize} \begin{itemize}
\item Dynamicznego systemu materiałów Unreal Engine \item Dynamicznego systemu materiałów Unreal Engine.
\item Wielu wariantów shaderów dla różnych kombinacji oświetlenia \item Wielu wariantów shaderów dla różnych kombinacji oświetlenia.
\item Złożonego potoku renderowania z wieloma przebiegami \item Złożonego potoku renderowania z wieloma przebiegami.
\end{itemize} \end{itemize}
Funkcja \texttt{vkCmdPipelineBarrier2KHR} (4\,090\,071 wywołań) synchronizuje dostęp do zasobów w obrębie GPU -- wysoka liczba wywołań wskazuje Funkcja \texttt{vkCmdPipelineBarrier2KHR} (4\,090\,071 wywołań) synchronizuje dostęp do zasobów w obrębie GPU -- wysoka liczba wywołań wskazuje
@ -750,9 +756,9 @@ na staranną kontrolę zależności między operacjami, typową dla nowoczesnych
Interesującą obserwacją jest obecność wywołań związanych z ray tracingiem we wszystkich fazach: Interesującą obserwacją jest obecność wywołań związanych z ray tracingiem we wszystkich fazach:
\begin{itemize} \begin{itemize}
\item \texttt{vkCreateAccelerationStructureKHR}: 23\,960 + 26\,275 + 11\,884 = 62\,119 wywołań \item \texttt{vkCreateAccelerationStructureKHR}: 23\,960 + 26\,275 + 11\,884 = 62\,119 wywołań.
\item \texttt{vkDestroyAccelerationStructureKHR}: 20\,571 + 23\,063 + 9\,181 = 52\,815 wywołań \item \texttt{vkDestroyAccelerationStructureKHR}: 20\,571 + 23\,063 + 9\,181 = 52\,815 wywołań.
\item \texttt{vkGetAccelerationStructureBuildSizesKHR}: 41\,161 + 46\,147 + 18\,379 = 105\,687 wywołań \item \texttt{vkGetAccelerationStructureBuildSizesKHR}: 41\,161 + 46\,147 + 18\,379 = 105\,687 wywołań.
\end{itemize} \end{itemize}
Pomimo że testowana gra nie wykorzystuje widocznych efektów ray tracingu, Unreal Engine przygotowuje struktury akceleracji BVH Pomimo że testowana gra nie wykorzystuje widocznych efektów ray tracingu, Unreal Engine przygotowuje struktury akceleracji BVH
@ -782,7 +788,7 @@ wielowątkowego Unreal Engine. Łącznie zarejestrowano ponad \textbf{9 milionó
\end{tabular} \end{tabular}
\end{table} \end{table}
Funkcja \texttt{pthread\_cond\_wait} \\ pochłonęła \textbf{64,6\% czasu} przy \textbf{3\,095\,188 wywołaniach} we wszystkich trzech fazach. Funkcja \texttt{pthread\_cond\_wait} pochłonęła \textbf{64,6\% czasu} przy \textbf{3\,095\,188 wywołaniach} we wszystkich trzech fazach.
Jest to funkcja POSIX do oczekiwania na zmienną warunkową, używana gdy wątek musi czekać na spełnienie określonego warunku sygnalizowanego przez Jest to funkcja POSIX do oczekiwania na zmienną warunkową, używana gdy wątek musi czekać na spełnienie określonego warunku sygnalizowanego przez
inny wątek. inny wątek.
@ -790,10 +796,10 @@ Tak wysoka liczba wywołań (ponad 40 razy więcej niż dla Unity)
odzwierciedla architekturę wielowątkową Unreal Engine opartą na systemie odzwierciedla architekturę wielowątkową Unreal Engine opartą na systemie
\textbf{TaskGraph}. System ten dekomponuje pracę renderowania na małe zadania (ang. \textit{tasks}), \textbf{TaskGraph}. System ten dekomponuje pracę renderowania na małe zadania (ang. \textit{tasks}),
które są wykonywane przez pulę wątków roboczych. które są wykonywane przez pulę wątków roboczych.
Każde zadanie po zakończeniu sygnalizuje swoją gotowość, a zależne zadania są budzone \\ poprzez Każde zadanie po zakończeniu sygnalizuje swoją gotowość, a zależne zadania są budzone poprzez
\texttt{pthread\_cond\_signal}/\texttt{pthread\_cond\_broadcast}. \texttt{pthread\_cond\_signal}/\texttt{pthread\_cond\_broadcast}.
Średni czas pojedynczego oczekiwania (0,97 ms) jest krótki, co wskazuje \\ na częste, ale krótkotrwałe synchronizacje -- Średni czas pojedynczego oczekiwania (0,97 ms) jest krótki, co wskazuje na częste, ale krótkotrwałe synchronizacje --
typowe dla drobnoziarnistego paralelizmu. Maksymalny czas 22,23 sekundy odpowiada prawdopodobnie wywołaniu podczas długotrwałej operacji typowe dla drobnoziarnistego paralelizmu. Maksymalny czas 22,23 sekundy odpowiada prawdopodobnie wywołaniu podczas długotrwałej operacji
inicjalizacyjnej w fazie 2. inicjalizacyjnej w fazie 2.
@ -819,18 +825,18 @@ Tabela~\ref{tab:unreal-osrt-phases} pokazuje konsystencję wzorców wywołań mi
fazie 3 (zawierającej ekran zwycięstwa). Szczególnie interesująca jest wysoka liczba wywołań \texttt{backtrace} (ponad 5,5 miliona łącznie), fazie 3 (zawierającej ekran zwycięstwa). Szczególnie interesująca jest wysoka liczba wywołań \texttt{backtrace} (ponad 5,5 miliona łącznie),
co sugeruje intensywne wykorzystanie mechanizmów debugowania lub profilowania wbudowanych w Unreal Engine nawet w konfiguracji DebugGame. co sugeruje intensywne wykorzystanie mechanizmów debugowania lub profilowania wbudowanych w Unreal Engine nawet w konfiguracji DebugGame.
(19,2\%, 163\,783 \\ wywołań) różni się od (19,2\%, 163\,783 wywołań) różni się od
\texttt{pthread\_cond\_wait} możliwością określenia maksymalnego czasu \texttt{pthread\_cond\_wait} możliwością określenia maksymalnego czasu
oczekiwania. Użycie tej funkcji wskazuje na mechanizmy: oczekiwania. Użycie tej funkcji wskazuje na mechanizmy:
\begin{itemize} \begin{itemize}
\item Timeoutów zapobiegających zakleszczeniom (deadlock prevention) \item Timeoutów zapobiegających zakleszczeniom (deadlock prevention).
\item Okresowego sprawdzania warunków (polling pattern) \item Okresowego sprawdzania warunków (polling pattern).
\item Synchronizacji czasowej dla frame pacing \item Synchronizacji czasowej dla frame pacing.
\end{itemize} \end{itemize}
Średni czas 5,46 ms sugeruje użycie do synchronizacji między-klatkowej, \\ Średni czas 5,46 ms sugeruje użycie do synchronizacji między-klatkowej,
gdzie wątki oczekują na gotowość kolejnej klatki z timeout'em gdzie wątki oczekują na gotowość kolejnej klatki z timeout'em
\\ zapobiegającym nieskończonemu oczekiwaniu w przypadku błędu. zapobiegającym nieskończonemu oczekiwaniu w przypadku błędu.
Funkcja \texttt{usleep} (4,7\%, 26\,062 wywołań, średnio 7,79 ms) wprowadza precyzyjne opóźnienia czasowe. Średni czas 7,79 ms jest zbliżony do Funkcja \texttt{usleep} (4,7\%, 26\,062 wywołań, średnio 7,79 ms) wprowadza precyzyjne opóźnienia czasowe. Średni czas 7,79 ms jest zbliżony do
@ -857,21 +863,21 @@ Liczba próbek GPU (10 kHz) & -- & 1\,050\,555 \\
Tabela~\ref{tab:sync-comparison} ujawnia fundamentalną różnicę architektoniczną między silnikami: Tabela~\ref{tab:sync-comparison} ujawnia fundamentalną różnicę architektoniczną między silnikami:
\textbf{Unity} stosuje mechanizm \texttt{futex} z niewielką liczbą wywołań (247) \\ i \textbf{Unity} stosuje mechanizm \texttt{futex} z niewielką liczbą wywołań (247) i
długim średnim czasem (444 ms). Wskazuje to na architekturę z długim średnim czasem (444 ms). Wskazuje to na architekturę z
większymi, bardziej autonomicznymi jednostkami pracy i rzadszą synchronizacją między wątkami. większymi, bardziej autonomicznymi jednostkami pracy i rzadszą synchronizacją między wątkami.
\textbf{Unreal Engine} używa \texttt{pthread\_cond\_wait} z ogromną liczbą wywołań \textbf{Unreal Engine} używa \texttt{pthread\_cond\_wait} z ogromną liczbą wywołań
\\ (ponad 3 miliony w 90-sekundowym teście) \\ i bardzo krótkim średnim (ponad 3 miliony w 90-sekundowym teście) i bardzo krótkim średnim
czasem (0,97 ms). Odzwierciedla to drobnoziarnisty paralelizm systemu TaskGraph, gdzie praca jest dzielona na małe zadania często komunikujące się ze czasem (0,97 ms). Odzwierciedla to drobnoziarnisty paralelizm systemu TaskGraph, gdzie praca jest dzielona na małe zadania często komunikujące się ze
sobą. sobą.
Różnica ta ma implikacje praktyczne: Różnica ta ma implikacje praktyczne:
\begin{itemize} \begin{itemize}
\item \textbf{Skalowalność}: Drobnoziarnisty model Unreal lepiej skaluje się na procesory z wieloma rdzeniami \item \textbf{Skalowalność}: Drobnoziarnisty model Unreal lepiej skaluje się na procesory z wieloma rdzeniami.
\item \textbf{Narzut synchronizacji}: Model Unity ma mniejszy narzut \\ z powodu rzadszych wywołań \item \textbf{Narzut synchronizacji}: Model Unity ma mniejszy narzut z powodu rzadszych wywołań.
\item \textbf{Responsywność}: Unreal może szybciej reagować na zmiany (np. przerwanie zadania) \item \textbf{Responsywność}: Unreal może szybciej reagować na zmiany (np. przerwanie zadania).
\item \textbf{Debugowanie}: Model Unity jest łatwiejszy do analizy ze względu na prostszą strukturę \item \textbf{Debugowanie}: Model Unity jest łatwiejszy do analizy ze względu na prostszą strukturę.
\end{itemize} \end{itemize}
@ -880,33 +886,33 @@ Zebrane dane z trzech faz profilowania pozwalają na charakterystykę architekto
Unreal Engine 5 stosuje zaawansowaną architekturę wielowątkową złożoną z: Unreal Engine 5 stosuje zaawansowaną architekturę wielowątkową złożoną z:
\begin{itemize} \begin{itemize}
\item \textbf{Game Thread} -- główny wątek logiki gry \item \textbf{Game Thread} -- główny wątek logiki gry.
\item \textbf{Render Thread} -- wątek przygotowujący polecenia renderowania \item \textbf{Render Thread} -- wątek przygotowujący polecenia renderowania.
\item \textbf{RHI Thread} (Render Hardware Interface) -- wątek komunikujący się z API graficznym \item \textbf{RHI Thread} (Render Hardware Interface) -- wątek komunikujący się z API graficznym.
\item \textbf{Worker Threads} -- pula wątków roboczych systemu TaskGraph \item \textbf{Worker Threads} -- pula wątków roboczych systemu TaskGraph.
\end{itemize} \end{itemize}
Obserwowana dominacja \texttt{pthread\_cond\_wait} (3+ miliony wywołań) \\ potwierdza intensywną Obserwowana dominacja \texttt{pthread\_cond\_wait} (3+ miliony wywołań) potwierdza intensywną
komunikację między tymi wątkami. komunikację między tymi wątkami.
\\ Wysokie wykorzystanie Wysokie wykorzystanie
GPU (90,98\% w fazach aktywnej rozgrywki) przy jednoczesnej intensywnej synchronizacji CPU sugeruje efektywne wykorzystanie zasobów obu procesorów. GPU (90,98\% w fazach aktywnej rozgrywki) przy jednoczesnej intensywnej synchronizacji CPU sugeruje efektywne wykorzystanie zasobów obu procesorów.
Na podstawie zebranych metryk można \\ scharakteryzować profil obciążenia GPU: Na podstawie zebranych metryk można scharakteryzować profil obciążenia GPU:
\begin{itemize} \begin{itemize}
\item \textbf{Charakter pracy}: Mieszany graficzno-obliczeniowy (GR Active 85,59\%, Sync Compute 43,23\%) \item \textbf{Charakter pracy}: Mieszany graficzno-obliczeniowy (GR Active 85,59\%, Sync Compute 43,23\%).
\item \textbf{Wykorzystanie SM}: Umiarkowane (42,88\%), wskazujące na potencjał optymalizacji \item \textbf{Wykorzystanie SM}: Umiarkowane (42,88\%), wskazujące na potencjał optymalizacji.
\item \textbf{Przepustowość pamięci}: Niewysoka (10,30\% odczyt, 10,10\% zapis), nie jest wąskim gardłem \item \textbf{Przepustowość pamięci}: Niewysoka (10,30\% odczyt, 10,10\% zapis), nie jest wąskim gardłem.
\item \textbf{Transfer PCIe}: Niski (1,50\% RX), dane pozostają w pamięci GPU \item \textbf{Transfer PCIe}: Niski (1,50\% RX), dane pozostają w pamięci GPU.
\item \textbf{Async Copy Engine}: Aktywny w 24--25\% czasu, wskazując na efektywne wykorzystanie asynchronicznych transferów \item \textbf{Async Copy Engine}: Aktywny w 24--25\% czasu, wskazując na efektywne wykorzystanie asynchronicznych transferów.
\end{itemize} \end{itemize}
Porównanie faz 1 i 2 (tabela~\ref{tab:unreal-gpu-phases}) pokazuje niezwykłą stabilność metryk GPU: Porównanie faz 1 i 2 (tabela~\ref{tab:unreal-gpu-phases}) pokazuje niezwykłą stabilność metryk GPU:
\begin{itemize} \begin{itemize}
\item GPU Active: różnica 0,36 pp. (91,16\% vs 90,80\%) \item GPU Active: różnica 0,36 pp. (91,16\% vs 90,80\%).
\item GR Active: różnica 0,21 pp. (85,69\% vs 85,48\%) \item GR Active: różnica 0,21 pp. (85,69\% vs 85,48\%).
\item SMs Active: różnica 0,18 pp. (42,79\% vs 42,97\%) \item SMs Active: różnica 0,18 pp. (42,79\% vs 42,97\%).
\end{itemize} \end{itemize}
Ta konsystencja potwierdza poprawność metodologii fazowego profilowania i sugeruje deterministyczne zachowanie silnika renderującego niezależnie od Ta konsystencja potwierdza poprawność metodologii fazowego profilowania i sugeruje deterministyczne zachowanie silnika renderującego niezależnie od
@ -967,11 +973,15 @@ vkCmdBindPipeline / klatkę & 2 & 218 \\
Analiza wywołań Vulkan API ujawnia fundamentalnie różne profile obciążenia (tabela~\ref{tab:gpu-comparison}): Analiza wywołań Vulkan API ujawnia fundamentalnie różne profile obciążenia (tabela~\ref{tab:gpu-comparison}):
Dominacja \texttt{vkWaitForFences} (95,2\% czasu) \\ wskazuje, że CPU efektywnie przygotowuje pracę i oczekuje na GPU. Dominacja \texttt{vkWaitForFences} (95,2\% czasu) wskazuje, że CPU efektywnie
Jest to pożądany wzorzec w aplikacjach graficznych, gdzie GPU wykonuje większość obliczeń. \\ Niski stosunek przygotowuje pracę i oczekuje na GPU.
\texttt{vkQueueSubmit}/klatkę (2:1) świadczy o prostym, dwuetapowym potoku renderowania. Jest to pożądany wzorzec w aplikacjach graficznych, gdzie GPU wykonuje
większość obliczeń. Niski stosunek
\texttt{vkQueueSubmit}/klatkę (2:1) świadczy o prostym, dwuetapowym potoku
renderowania.
W Unreal Engine dominującymi operacjami były \texttt{vkCreateComputePipelines} \\ oraz \texttt{vkCreateGraphicsPipelines}, W Unreal Engine dominującymi operacjami były \texttt{vkCreateComputePipelines}
oraz \texttt{vkCreateGraphicsPipelines},
pochłaniające łącznie 57--72\% czasu Vulkan. Silnik tworzy około \textbf{1000 potoków w każdej 30-sekundowej fazie} pochłaniające łącznie 57--72\% czasu Vulkan. Silnik tworzy około \textbf{1000 potoków w każdej 30-sekundowej fazie}
(vs 3 potoki w całym teście Unity), co wskazuje na strategię dynamicznej kompilacji shaderów. (vs 3 potoki w całym teście Unity), co wskazuje na strategię dynamicznej kompilacji shaderów.
@ -1003,6 +1013,7 @@ większe jednostki pracy autonomicznie, co minimalizuje narzut komunikacji.
\textbf{Unreal Engine} implementuje drobnoziarnisty paralelizm poprzez system TaskGraph. Praca jest dzielona na tysiące \textbf{Unreal Engine} implementuje drobnoziarnisty paralelizm poprzez system TaskGraph. Praca jest dzielona na tysiące
małych zadań często komunikujących się ze sobą (ponad 3 miliony wywołań synchronizacji w 90 sekund). małych zadań często komunikujących się ze sobą (ponad 3 miliony wywołań synchronizacji w 90 sekund).
\subsection{Podsumowanie wyników testów wydajności} \subsection{Podsumowanie wyników testów wydajności}
\label{subsec:podsumowanie-testow} \label{subsec:podsumowanie-testow}
@ -1024,7 +1035,6 @@ Potoki graficzne utworzone & 3 & $\sim$2\,400 \\
\hline \hline
\end{tabular} \end{tabular}
\end{table} \end{table}
\newpage
Przeprowadzone testy wydajnościowe pozwalają na sformułowanie następujących wniosków: Przeprowadzone testy wydajnościowe pozwalają na sformułowanie następujących wniosków:
@ -1033,11 +1043,13 @@ Przeprowadzone testy wydajnościowe pozwalają na sformułowanie następujących
oba silniki osiągają zbliżoną wydajność: Unity 1\% low 132 FPS vs Unreal 162 FPS. Różnica oba silniki osiągają zbliżoną wydajność: Unity 1\% low 132 FPS vs Unreal 162 FPS. Różnica
około 23\% na korzyść Unreal wynika częściowo z różnych konfiguracji V-Sync. około 23\% na korzyść Unreal wynika częściowo z różnych konfiguracji V-Sync.
\item \textbf{Wykorzystanie GPU}: Unity wykorzystuje jedynie 23\% mocy GPU \\ (ograniczony V-Sync), \item \textbf{Wykorzystanie GPU}: Unity wykorzystuje jedynie 23\% mocy GPU
\\ (ograniczony V-Sync),
podczas gdy Unreal Engine osiąga 91\% wykorzystania w fazach 1--2. Sugeruje to znaczny podczas gdy Unreal Engine osiąga 91\% wykorzystania w fazach 1--2. Sugeruje to znaczny
zapas wydajności Unity przy wyłączonym V-Sync. zapas wydajności Unity przy wyłączonym V-Sync.
\item \textbf{Stabilność}: Unity wykazał stabilne czasy klatek dzięki V-Sync, \\ natomiast \item \textbf{Stabilność}: Unity wykazał stabilne czasy klatek dzięki
V-Sync, natomiast
Unreal Engine pokazał dużą zmienność między fazami (332--339 FPS w fazach 1--2 vs 162 FPS Unreal Engine pokazał dużą zmienność między fazami (332--339 FPS w fazach 1--2 vs 162 FPS
w fazie 3) -- spadek o ponad 50\%. w fazie 3) -- spadek o ponad 50\%.
@ -1046,7 +1058,7 @@ Przeprowadzone testy wydajnościowe pozwalają na sformułowanie następujących
z rzadkimi synchronizacjami, podczas gdy Unreal stosuje drobnoziarnisty system TaskGraph z rzadkimi synchronizacjami, podczas gdy Unreal stosuje drobnoziarnisty system TaskGraph
z milionami wywołań synchronizacyjnych. z milionami wywołań synchronizacyjnych.
\item \textbf{Narzut Unreal}: Dynamiczna kompilacja potoków \\ (ponad 1000 potoków na \item \textbf{Narzut Unreal}: Dynamiczna kompilacja potoków (ponad 1000 potoków na
30-sekundową fazę vs 3 w całym teście Unity) i 60-krotnie większa liczba wywołań Vulkan API \\ 30-sekundową fazę vs 3 w całym teście Unity) i 60-krotnie większa liczba wywołań Vulkan API
stanowią znaczący narzut, który może przyczyniać się do spadków wydajności w wymagających scenach. stanowią znaczący narzut, który może przyczyniać się do spadków wydajności w wymagających scenach.
\end{enumerate} \end{enumerate}

View File

@ -9,50 +9,50 @@ Niniejszy rozdział przedstawia porównanie kluczowych możliwości technicznych
Unity oferuje dwa główne pipeline'y renderowania: Built-in Render Pipeline (legacy), Universal Render Pipeline (URP) oraz High Definition Render Pipeline (HDRP). URP jest zoptymalizowany pod kątem wydajności i~kompatybilności między platformami, podczas gdy HDRP koncentruje się na~wysokiej jakości grafiki dla~platform o~dużej mocy obliczeniowej~\cite{gregory2018game}. Unity oferuje dwa główne pipeline'y renderowania: Built-in Render Pipeline (legacy), Universal Render Pipeline (URP) oraz High Definition Render Pipeline (HDRP). URP jest zoptymalizowany pod kątem wydajności i~kompatybilności między platformami, podczas gdy HDRP koncentruje się na~wysokiej jakości grafiki dla~platform o~dużej mocy obliczeniowej~\cite{gregory2018game}.
\begin{itemize} \begin{itemize}
\item \textbf{Forward rendering} -- domyślny tryb w~URP, efektywny dla~scen z~niewielką liczbą źródeł światła \item \textbf{Forward rendering} -- domyślny tryb w~URP, efektywny dla~scen z~niewielką liczbą źródeł światła.
\item \textbf{Deferred rendering} -- dostępny w~HDRP, umożliwia obsługę większej liczby świateł \item \textbf{Deferred rendering} -- dostępny w~HDRP, umożliwia obsługę większej liczby świateł.
\item \textbf{Ray tracing} -- wsparcie w~HDRP dla~kart graficznych NVIDIA RTX~\cite{parker2010optix} \item \textbf{Ray tracing} -- wsparcie w~HDRP dla~kart graficznych NVIDIA RTX~\cite{parker2010optix}.
\end{itemize} \end{itemize}
Unreal Engine wykorzystuje zaawansowany deferred rendering pipeline z~obsługą ray tracingu w~czasie rzeczywistym~\cite{unreal_docs}. Unreal Engine wykorzystuje zaawansowany deferred rendering pipeline z~obsługą ray tracingu w~czasie rzeczywistym~\cite{unreal_docs}.
\begin{itemize} \begin{itemize}
\item \textbf{Deferred shading} -- standardowy pipeline dla~większości projektów~\cite{gregory2018game} \item \textbf{Deferred shading} -- standardowy pipeline dla~większości projektów~\cite{gregory2018game}.
\item \textbf{Forward shading} -- opcjonalny tryb dla~projektów VR wymagających niskiej latencji~\cite{unreal_docs} \item \textbf{Forward shading} -- opcjonalny tryb dla~projektów VR wymagających niskiej latencji~\cite{unreal_docs}.
\item \textbf{Ray tracing} -- pełne wsparcie dla~Lumen (global illumination) i~ray-traced reflections \item \textbf{Ray tracing} -- pełne wsparcie dla~Lumen (global illumination) i~ray-traced reflections.
\item \textbf{Nanite} -- zwirtualizowana geometria pozwalająca na~renderowanie miliardów poligonów \item \textbf{Nanite} -- zwirtualizowana geometria pozwalająca na~renderowanie miliardów poligonów.
\end{itemize} \end{itemize}
Unity oferuje Shader Graph -- wizualny edytor do~tworzenia shaderów \\ bez~pisania kodu. Dodatkowo wspiera shadery pisane w~HLSL oraz~Cg~\cite{farina2013shader}. Unity oferuje Shader Graph -- wizualny edytor do~tworzenia shaderów bez~pisania kodu. Dodatkowo wspiera shadery pisane w~HLSL oraz~Cg~\cite{farina2013shader}.
\begin{itemize} \begin{itemize}
\item \textbf{Shader Graph} -- intuicyjny, oparty na~węzłach interfejs \item \textbf{Shader Graph} -- intuicyjny, oparty na~węzłach interfejs.
\item \textbf{HLSL/Cg} -- możliwość pisania custom shaderów~\cite{farina2013shader} \item \textbf{HLSL/Cg} -- możliwość pisania custom shaderów~\cite{farina2013shader}.
\item \textbf{Shader variants} -- system wariantów dla~optymalizacji \item \textbf{Shader variants} -- system wariantów dla~optymalizacji.
\end{itemize} \end{itemize}
Unreal oferuje Material Editor -- zaawansowany system węzłowy do~tworzenia materiałów~\cite{unreal_docs}. Unreal oferuje Material Editor -- zaawansowany system węzłowy do~tworzenia materiałów~\cite{unreal_docs}.
\begin{itemize} \begin{itemize}
\item \textbf{Material Editor} -- bogaty zestaw węzłów i~funkcji \item \textbf{Material Editor} -- bogaty zestaw węzłów i~funkcji.
\item \textbf{Material Functions} -- możliwość tworzenia wielokrotnego użytku komponentów \item \textbf{Material Functions} -- możliwość tworzenia wielokrotnego użytku komponentów.
\item \textbf{Custom HLSL} -- integracja własnego kodu HLSL~\cite{farina2013shader} \item \textbf{Custom HLSL} -- integracja własnego kodu HLSL~\cite{farina2013shader}.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Real-time lighting} -- dynamiczne oświetlenie w~czasie rzeczywistym \item \textbf{Real-time lighting} -- dynamiczne oświetlenie w~czasie rzeczywistym.
\item \textbf{Baked lighting} -- przedkalkulowane mapy oświetlenia (lightmaps) \item \textbf{Baked lighting} -- przedkalkulowane mapy oświetlenia (lightmaps).
\item \textbf{Mixed lighting} -- połączenie światła dynamicznego i~baked \item \textbf{Mixed lighting} -- połączenie światła dynamicznego i~baked.
\item \textbf{Global Illumination} -- Progressive Lightmapper dla~światła odbitego~\cite{gregory2018game} \item \textbf{Global Illumination} -- Progressive Lightmapper dla~światła odbitego~\cite{gregory2018game}.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Lumen} -- dynamiczne global illumination w~czasie rzeczywistym \item \textbf{Lumen} -- dynamiczne global illumination w~czasie rzeczywistym.
\item \textbf{Lightmass} -- high-quality baked lighting~\cite{gregory2018game} \item \textbf{Lightmass} -- high-quality baked lighting~\cite{gregory2018game}.
\item \textbf{Ray-traced lighting} -- fizycznie dokładne oświetlenie~\cite{parker2010optix} \item \textbf{Ray-traced lighting} -- fizycznie dokładne oświetlenie~\cite{parker2010optix}.
\item \textbf{Volumetric fog} -- zaawansowane efekty atmosferyczne \item \textbf{Volumetric fog} -- zaawansowane efekty atmosferyczne.
\end{itemize} \end{itemize}
\subsection{Systemy fizyki i symulacji} \subsection{Systemy fizyki i symulacji}
@ -61,87 +61,87 @@ Unreal oferuje Material Editor -- zaawansowany system węzłowy do~tworzenia mat
Unity wykorzystuje NVIDIA PhysX jako~silnik fizyki~\cite{nvidia_physx}. Unity wykorzystuje NVIDIA PhysX jako~silnik fizyki~\cite{nvidia_physx}.
\begin{itemize} \begin{itemize}
\item \textbf{Rigidbody} -- komponent dla~obiektów fizycznych \item \textbf{Rigidbody} -- komponent dla~obiektów fizycznych.
\item \textbf{Colliders} -- różne typy koliderów (box, sphere, mesh, etc.) \item \textbf{Colliders} -- różne typy koliderów (box, sphere, mesh, etc.).
\item \textbf{Joints} -- więzy i~połączenia (hinge, spring, fixed, etc.) \item \textbf{Joints} -- więzy i~połączenia (hinge, spring, fixed, etc.).
\item \textbf{Wydajność} -- efektywne dla~setek obiektów fizycznych~\cite{messaoudi2017performance} \item \textbf{Wydajność} -- efektywne dla~setek obiektów fizycznych~\cite{messaoudi2017performance}.
\end{itemize} \end{itemize}
Unreal przeszedł z~PhysX \\ na~Chaos Physics -- Unreal przeszedł z~PhysX na~Chaos Physics --
własny silnik fizyki~\cite{unreal_docs}. własny silnik fizyki~\cite{unreal_docs}.
\begin{itemize} \begin{itemize}
\item \textbf{Chaos Physics} -- nowy, zaawansowany system fizyki \item \textbf{Chaos Physics} -- nowy, zaawansowany system fizyki.
\item \textbf{Destruction} -- wbudowane wsparcie dla~destrukcji obiektów \item \textbf{Destruction} -- wbudowane wsparcie dla~destrukcji obiektów.
\item \textbf{Cloth simulation} -- symulacja tkanin \item \textbf{Cloth simulation} -- symulacja tkanin.
\item \textbf{Vehicles} -- zaawansowany system pojazdów~\cite{gregory2018game} \item \textbf{Vehicles} -- zaawansowany system pojazdów~\cite{gregory2018game}.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Shuriken Particle System} -- klasyczny system cząstek \item \textbf{Shuriken Particle System} -- klasyczny system cząstek.
\item \textbf{Visual Effect Graph} -- system cząstek GPU-based dla~milionów cząstek \item \textbf{Visual Effect Graph} -- system cząstek GPU-based dla~milionów cząstek.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Cascade} -- legacy system cząstek \item \textbf{Cascade} -- legacy system cząstek.
\item \textbf{Niagara} -- zaawansowany, skalowalny system efektów wizualnych \item \textbf{Niagara} -- zaawansowany, skalowalny system efektów wizualnych.
\end{itemize} \end{itemize}
\subsection{Systemy audio} \subsection{Systemy audio}
\begin{itemize} \begin{itemize}
\item Obsługiwane formaty: WAV, MP3, OGG, AIFF \item Obsługiwane formaty: WAV, MP3, OGG, AIFF.
\item Kompresja: Vorbis, MP3, ADPCM \item Kompresja: Vorbis, MP3, ADPCM.
\item Audio middleware: integracja z~Wwise, FMOD~\cite{firat2022sound} \item Audio middleware: integracja z~Wwise, FMOD~\cite{firat2022sound}.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Obsługiwane formaty: WAV, OGG, FLAC \item Obsługiwane formaty: WAV, OGG, FLAC.
\item Natywna integracja z~MetaSounds \item Natywna integracja z~MetaSounds.
\item Wsparcie dla~Wwise, FMOD~\cite{firat2022sound} \item Wsparcie dla~Wwise, FMOD~\cite{firat2022sound}.
\end{itemize} \end{itemize}
Oba silniki oferują zaawansowane systemy dźwięku przestrzennego \\ z~obsługą~\cite{firat2022sound}: Oba silniki oferują zaawansowane systemy dźwięku przestrzennego z~obsługą~\cite{firat2022sound}:
\begin{itemize} \begin{itemize}
\item Attenuation curves (krzywe tłumienia) \item Attenuation curves (krzywe tłumienia).
\item Occlusion i~obstruction (przesłanianie i~blokowanie) \item Occlusion i~obstruction (przesłanianie i~blokowanie).
\item Reverb zones (strefy pogłosu) \item Reverb zones (strefy pogłosu).
\item Doppler effect (efekt Dopplera) \item Doppler effect (efekt Dopplera).
\end{itemize} \end{itemize}
\subsection{Narzędzia deweloperskie} \subsection{Narzędzia deweloperskie}
\begin{itemize} \begin{itemize}
\item \textbf{Scene View} -- intuicyjny edytor sceny 2D/3D \item \textbf{Scene View} -- intuicyjny edytor sceny 2D/3D.
\item \textbf{Inspector} -- edycja właściwości komponentów \item \textbf{Inspector} -- edycja właściwości komponentów.
\item \textbf{Prefab Mode} -- izolowana edycja prefabrykatów \item \textbf{Prefab Mode} -- izolowana edycja prefabrykatów.
\item \textbf{UI Builder} -- wizualny edytor interfejsów użytkownika \item \textbf{UI Builder} -- wizualny edytor interfejsów użytkownika.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Viewport} -- zaawansowany edytor poziomów \item \textbf{Viewport} -- zaawansowany edytor poziomów.
\item \textbf{Details Panel} -- szczegółowa konfiguracja aktorów \item \textbf{Details Panel} -- szczegółowa konfiguracja aktorów.
\item \textbf{Blueprint Editor} -- wizualne programowanie \item \textbf{Blueprint Editor} -- wizualne programowanie.
\item \textbf{UMG Designer} -- projektowanie UI \item \textbf{UMG Designer} -- projektowanie UI.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Unity Profiler -- analiza wydajności CPU, GPU, pamięci \item Unity Profiler -- analiza wydajności CPU, GPU, pamięci.
\item Console -- logi i~błędy w~czasie rzeczywistym \item Console -- logi i~błędy w~czasie rzeczywistym.
\item Frame Debugger -- analiza procesu renderowania klatka po~klatce \item Frame Debugger -- analiza procesu renderowania klatka po~klatce.
\item Memory Profiler -- szczegółowa analiza alokacji pamięci \item Memory Profiler -- szczegółowa analiza alokacji pamięci.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Unreal Insights -- kompleksowe narzędzie profilowania \item Unreal Insights -- kompleksowe narzędzie profilowania.
\item Visual Logger -- wizualizacja logów w~kontekście gry \item Visual Logger -- wizualizacja logów w~kontekście gry.
\item Session Frontend -- monitoring wielu instancji gry \item Session Frontend -- monitoring wielu instancji gry.
\item GPU Visualizer -- analiza wydajności GPU \item GPU Visualizer -- analiza wydajności GPU.
\end{itemize} \end{itemize}
\subsection{Wsparcie dla platform docelowych} \subsection{Wsparcie dla platform docelowych}
@ -211,17 +211,17 @@ Oba silniki oferują wsparcie dla~głównych konsol (PlayStation 5, Xbox Series
\begin{itemize} \begin{itemize}
\item Ponad 100\,000 zasobów dostępnych \item Ponad 100\,000 zasobów dostępnych.
\item Modele 3D, tekstury, skrypty, narzędzia, kompletne projekty \item Modele 3D, tekstury, skrypty, narzędzia, kompletne projekty.
\item Ceny od~darmowych do~kilkuset dolarów \item Ceny od~darmowych do~kilkuset dolarów.
\item System ocen i~recenzji \item System ocen i~recenzji.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Dziesiątki tysięcy zasobów wysokiej jakości \item Dziesiątki tysięcy zasobów wysokiej jakości.
\item Miesięczne darmowe zasoby dla~subskrybentów \item Miesięczne darmowe zasoby dla~subskrybentów.
\item Integracja z~Quixel Megascans (biblioteka fotogrametryczna) \item Integracja z~Quixel Megascans (biblioteka fotogrametryczna).
\item Często wyższa jakość, ale~mniejszy wybór niż~Unity \item Często wyższa jakość, ale~mniejszy wybór niż~Unity.
\end{itemize} \end{itemize}
@ -250,13 +250,13 @@ Wielkość i~aktywność społeczności deweloperskiej jest istotnym czynnikiem
\begin{itemize} \begin{itemize}
\item \textbf{Dokumentacja oficjalna} -- ponad 5000 stron dokumentacji API \item \textbf{Dokumentacja oficjalna} -- ponad 5000 stron dokumentacji API.
\item \textbf{Unity Learn} -- ponad 750 darmowych kursów i~tutoriali~\cite{christopoulou2017overview} \item \textbf{Unity Learn} -- ponad 750 darmowych kursów i~tutoriali~\cite{christopoulou2017overview}.
\item \textbf{Certyfikacje} -- 4 poziomy certyfikacji \\ (User, Associate, Professional, Expert)~\cite{barczak2019comparative} \item \textbf{Certyfikacje} -- 4 poziomy certyfikacji (User, Associate, Professional, Expert)~\cite{barczak2019comparative}.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Dokumentacja oficjalna} -- obszerna dokumentacja z~ponad 3000 stron \item \textbf{Dokumentacja oficjalna} -- obszerna dokumentacja z~ponad 3000 stron.
\item \textbf{Unreal Online Learning} -- ponad 200 darmowych kursów wideo~\cite{christopoulou2017overview} \item \textbf{Unreal Online Learning} -- ponad 200 darmowych kursów wideo~\cite{christopoulou2017overview}.
\item \textbf{Epic Developer Community} -- oficjalne forum wsparcia~\cite{barczak2019comparative} \item \textbf{Epic Developer Community} -- oficjalne forum wsparcia~\cite{barczak2019comparative}.
\end{itemize} \end{itemize}

View File

@ -72,10 +72,10 @@ Analiza możliwości (rozdział~6) wykazała, że~oba silniki oferują bogate ze
Znaczenie poszczególnych kryteriów różni się w~zależności od~typu projektu: Znaczenie poszczególnych kryteriów różni się w~zależności od~typu projektu:
\begin{itemize} \begin{itemize}
\item \textbf{Gry indie} -- priorytet: łatwość nauki, koszt, społeczność \item \textbf{Gry indie} -- priorytet: łatwość nauki, koszt, społeczność.
\item \textbf{Gry mobilne} -- priorytet: wydajność, optymalizacja, wsparcie platform \item \textbf{Gry mobilne} -- priorytet: wydajność, optymalizacja, wsparcie platform.
\item \textbf{Gry AAA} -- priorytet: jakość grafiki, zaawansowane funkcje, skalowalność \item \textbf{Gry AAA} -- priorytet: jakość grafiki, zaawansowane funkcje, skalowalność.
\item \textbf{Gry edukacyjne} -- priorytet: prostota, dokumentacja, stabilność \item \textbf{Gry edukacyjne} -- priorytet: prostota, dokumentacja, stabilność.
\end{itemize} \end{itemize}
\subsection{Przypadki użycia} \subsection{Przypadki użycia}
@ -83,11 +83,11 @@ Znaczenie poszczególnych kryteriów różni się w~zależności od~typu projekt
\begin{itemize} \begin{itemize}
\item Niższy próg wejścia dla~początkujących deweloperów \item Niższy próg wejścia dla~początkujących deweloperów.
\item Bogaty Asset Store z~dostępnymi cenowo zasobami \item Bogaty Asset Store z~dostępnymi cenowo zasobami.
\item Większa społeczność -- łatwiej znaleźć pomoc \item Większa społeczność -- łatwiej znaleźć pomoc.
\item Szybsze prototypowanie \item Szybsze prototypowanie.
\item Mniejsze wymagania sprzętowe dla~deweloperów \item Mniejsze wymagania sprzętowe dla~deweloperów.
\end{itemize} \end{itemize}
Jeśli gra wymaga grafiki najwyższej jakości (photorealistic), rozważ Unreal Engine. Jeśli gra wymaga grafiki najwyższej jakości (photorealistic), rozważ Unreal Engine.
@ -95,11 +95,11 @@ Jeśli gra wymaga grafiki najwyższej jakości (photorealistic), rozważ Unreal
\begin{itemize} \begin{itemize}
\item Lepsza optymalizacja pod~platformy mobilne \item Lepsza optymalizacja pod~platformy mobilne.
\item Mniejsze rozmiary buildu \item Mniejsze rozmiary buildu.
\item Lepsze wsparcie dla~starszych urządzeń \item Lepsze wsparcie dla~starszych urządzeń.
\item Więcej narzędzi i~assetów mobilnych \item Więcej narzędzi i~assetów mobilnych.
\item Większość gier mobilnych używa Unity (udowodniona skuteczność) \item Większość gier mobilnych używa Unity (udowodniona skuteczność).
\end{itemize} \end{itemize}
Według danych z~2023 roku, około 70\% gier mobilnych na~iOS i~Android zostało stworzonych w~Unity~\cite{statista_unity_market, unity_gaming_report}. Według danych z~2023 roku, około 70\% gier mobilnych na~iOS i~Android zostało stworzonych w~Unity~\cite{statista_unity_market, unity_gaming_report}.
@ -107,11 +107,11 @@ Według danych z~2023 roku, około 70\% gier mobilnych na~iOS i~Android zostało
\begin{itemize} \begin{itemize}
\item Wyższa jakość grafiki out-of-the-box \item Wyższa jakość grafiki out-of-the-box.
\item Nanite -- rendering miliardów poligonów \item Nanite -- rendering miliardów poligonów.
\item Lumen -- dynamiczne global illumination \item Lumen -- dynamiczne global illumination.
\item Lepsze wsparcie dla~dużych zespołów \item Lepsze wsparcie dla~dużych zespołów.
\item Sprawdzone w~produkcjach AAA (Fortnite, Gears of~War) \item Sprawdzone w~produkcjach AAA (Fortnite, Gears of~War).
\end{itemize} \end{itemize}
Unreal Engine wykorzystywano w~produkcjach takich jak: Final Fantasy VII Remake, Jedi: Fallen Order, Borderlands 3. Unreal Engine wykorzystywano w~produkcjach takich jak: Final Fantasy VII Remake, Jedi: Fallen Order, Borderlands 3.
@ -119,15 +119,15 @@ Unreal Engine wykorzystywano w~produkcjach takich jak: Final Fantasy VII Remake,
\begin{itemize} \begin{itemize}
\item Aplikacje edukacyjne VR/AR \item Aplikacje edukacyjne VR/AR.
\item Mobilny AR (ARCore, ARKit) \item Mobilny AR (ARCore, ARKit).
\item Projekty wymagające szybkiego rozwoju \item Projekty wymagające szybkiego rozwoju.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item High-end VR experiences \item High-end VR experiences.
\item Architekturalna wizualizacja VR \item Architekturalna wizualizacja VR.
\item Training simulations wymagające fotorealizmu \item Training simulations wymagające fotorealizmu.
\end{itemize} \end{itemize}
\subsection{Weryfikacja hipotez badawczych} \subsection{Weryfikacja hipotez badawczych}
@ -148,10 +148,10 @@ Na~początku pracy (rozdział~\ref{sec:wstep}) postawiono następujące hipotezy
\textbf{Uzasadnienie}: Analiza wywiadów (rozdział~wywiady-analiza) wykazała, że~100\% respondentów z~doświadczeniem poniżej 2~lat oceniło Unity jako bardziej przystępne. Składają się na~to: \textbf{Uzasadnienie}: Analiza wywiadów (rozdział~wywiady-analiza) wykazała, że~100\% respondentów z~doświadczeniem poniżej 2~lat oceniło Unity jako bardziej przystępne. Składają się na~to:
\begin{itemize} \begin{itemize}
\item Lepiej udokumentowane API \item Lepiej udokumentowane API.
\item Większa dostępność tutoriali dla~początkujących \item Większa dostępność tutoriali dla~początkujących.
\item C\# jako język bardziej przyjazny niż~C++ \item C\# jako język bardziej przyjazny niż~C++.
\item Prostszy interfejs edytora \item Prostszy interfejs edytora.
\end{itemize} \end{itemize}
@ -161,10 +161,10 @@ Na~początku pracy (rozdział~\ref{sec:wstep}) postawiono następujące hipotezy
\textbf{Uzasadnienie}: \textbf{Uzasadnienie}:
\begin{itemize} \begin{itemize}
\item Mniejsze rozmiary buildów mobilnych w~Unity \item Mniejsze rozmiary buildów mobilnych w~Unity.
\item Lepsza optymalizacja dla~urządzeń niskiej klasy \item Lepsza optymalizacja dla~urządzeń niskiej klasy.
\item Większy ekosystem mobile-specific assetów \item Większy ekosystem mobile-specific assetów.
\item Dominacja na~rynku gier mobilnych (70\% udziału) \item Dominacja na~rynku gier mobilnych (70\% udziału).
\end{itemize} \end{itemize}
@ -174,53 +174,53 @@ Na~początku pracy (rozdział~\ref{sec:wstep}) postawiono następujące hipotezy
\textbf{Uzasadnienie}: \textbf{Uzasadnienie}:
\begin{itemize} \begin{itemize}
\item Technologie Nanite i~Lumen oferują funkcje niedostępne w~Unity \item Technologie Nanite i~Lumen oferują funkcje niedostępne w~Unity.
\item Lepsze domyślne materiały i~shadery \item Lepsze domyślne materiały i~shadery.
\item Zaawansowane efekty post-processingu out-of-the-box \item Zaawansowane efekty post-processingu out-of-the-box.
\item Większość projektów wymagających fotorealizmu wykorzystuje Unreal \item Większość projektów wymagających fotorealizmu wykorzystuje Unreal.
\end{itemize} \end{itemize}
\subsection{Ograniczenia badań} \subsection{Ograniczenia badań}
\begin{itemize} \begin{itemize}
\item \textbf{Ograniczona liczba scenariuszy testowych} -- skupiono się na~grze typu bullet-hell, co~nie~pokrywa wszystkich możliwych zastosowań silników \item \textbf{Ograniczona liczba scenariuszy testowych} -- skupiono się na~grze typu bullet-hell, co~nie~pokrywa wszystkich możliwych zastosowań silników.
\item \textbf{Pojedyncza konfiguracja sprzętowa} -- testy przeprowadzono tylko na~jednym zestawie komputerowym \item \textbf{Pojedyncza konfiguracja sprzętowa} -- testy przeprowadzono tylko na~jednym zestawie komputerowym.
\item \textbf{Mała próba wywiadów} -- 8~respondentów może nie~reprezentować całej społeczności deweloperów \item \textbf{Mała próba wywiadów} -- 8~respondentów może nie~reprezentować całej społeczności deweloperów.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item \textbf{Wersje silników} -- wyniki dotyczą konkretnych wersji Unity i~Unreal; nowsze wersje mogą mieć odmienną wydajność \item \textbf{Wersje silników} -- wyniki dotyczą konkretnych wersji Unity i~Unreal; nowsze wersje mogą mieć odmienną wydajność.
\item \textbf{Wpływ object poolingu} -- optymalizacja wpływa na~wyniki; bez~niej różnice mogłyby być większe \item \textbf{Wpływ object poolingu} -- optymalizacja wpływa na~wyniki; bez~niej różnice mogłyby być większe.
\item \textbf{Profilowanie} -- NVIDIA Nsight może wprowadzać własny narzut wydajnościowy \item \textbf{Profilowanie} -- NVIDIA Nsight może wprowadzać własny narzut wydajnościowy.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Silniki gier rozwijają się dynamicznie -- wyniki mogą dezaktualizować się w~ciągu roku \item Silniki gier rozwijają się dynamicznie -- wyniki mogą dezaktualizować się w~ciągu roku.
\item Nie~testowano funkcji wprowadzonych w~najnowszych wersjach beta \item Nie~testowano funkcji wprowadzonych w~najnowszych wersjach beta.
\end{itemize} \end{itemize}
\subsection{Implikacje praktyczne} \subsection{Implikacje praktyczne}
\begin{itemize} \begin{itemize}
\item Rozpoczynając naukę tworzenia gier, Unity stanowi bezpieczniejszy wybór \item Rozpoczynając naukę tworzenia gier, Unity stanowi bezpieczniejszy wybór.
\item Dla projektów 2D, Unity jest jednoznacznie lepszym wyborem \item Dla projektów 2D, Unity jest jednoznacznie lepszym wyborem.
\item Inwestycja w~naukę C++ może być wartościowa długoterminowo \item Inwestycja w~naukę C++ może być wartościowa długoterminowo.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Unity pozwala na~szybsze MVP i~iteracje \item Unity pozwala na~szybsze MVP i~iteracje.
\item Unreal wymaga co~najmniej jednego doświadczonego programisty C++ \item Unreal wymaga co~najmniej jednego doświadczonego programisty C++.
\item Asset Store Unity oferuje więcej ready-to-use rozwiązań \item Asset Store Unity oferuje więcej ready-to-use rozwiązań.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Unreal Engine jest standardem przemysłowym dla~gier 3D wysokiej jakości \item Unreal Engine jest standardem przemysłowym dla~gier 3D wysokiej jakości.
\item Wsparcie Epic Games dla~dużych projektów jest lepsze \item Wsparcie Epic Games dla~dużych projektów jest lepsze.
\item Source code access w~Unreal daje większą kontrolę \item Source code access w~Unreal daje większą kontrolę.
\end{itemize} \end{itemize}

View File

@ -1,20 +1,21 @@
\clearpage \clearpage
\raggedbottom
\section{Podsumowanie i wnioski} \section{Podsumowanie i wnioski}
Celem niniejszej pracy było porównanie wydajności i~możliwości dwóch wiodących silników gier komputerowych -- Unity oraz Unreal Engine -- ze~szczególnym uwzględnieniem ich wpływu na~proces tworzenia gier oraz~końcową jakość produktu. Cel ten został zrealizowany poprzez: Celem niniejszej pracy było porównanie wydajności i~możliwości dwóch wiodących silników gier komputerowych -- Unity oraz Unreal Engine -- ze~szczególnym uwzględnieniem ich wpływu na~proces tworzenia gier oraz~końcową jakość produktu. Cel ten został zrealizowany poprzez:
\begin{enumerate} \begin{enumerate}
\item Przeprowadzenie szczegółowych testów wydajnościowych \\ z~wykorzystaniem niezależnego narzędzia NVIDIA Nsight Systems \item Przeprowadzenie szczegółowych testów wydajnościowych z~wykorzystaniem niezależnego narzędzia NVIDIA Nsight Systems.
\item Implementację identycznej gry typu bullet hell w~obu silnikach \item Implementację identycznej gry typu bullet hell w~obu silnikach.
\item Analizę porównawczą funkcjonalności i~możliwości obu silników \item Analizę porównawczą funkcjonalności i~możliwości obu silników.
\item Przeprowadzenie wywiadów jakościowych z~ośmioma deweloperami gier \item Przeprowadzenie wywiadów jakościowych z~ośmioma deweloperami gier.
\end{enumerate} \end{enumerate}
\subsection{Weryfikacja hipotezy badawczej} \subsection{Weryfikacja hipotezy badawczej}
Postawiona hipoteza badawcza brzmiała: \\ \textit{,,Silnik Unity, dzięki natywnemu wsparciu Postawiona hipoteza badawcza brzmiała: \textit{,,Silnik Unity, dzięki natywnemu wsparciu
dla~grafiki 2D, osiągnie lepszą wydajność w~grze typu bullet hell niż Unreal Engine, dla~grafiki 2D, osiągnie lepszą wydajność w~grze typu bullet hell niż Unreal Engine,
który jest zoptymalizowany \\ przede wszystkim pod~kątem aplikacji 3D.''} który jest zoptymalizowany przede wszystkim pod~kątem aplikacji 3D.''}
Wyniki badań \textbf{częściowo potwierdzają} tę hipotezę, jednak obraz jest bardziej złożony niż początkowo zakładano: Wyniki badań \textbf{częściowo potwierdzają} tę hipotezę, jednak obraz jest bardziej złożony niż początkowo zakładano:
@ -24,9 +25,9 @@ Unity wykorzystywał jedynie 23\% mocy obliczeniowej GPU (ograniczony przez V-Sy
Analiza wywołań Vulkan API ujawniła fundamentalne różnice architektoniczne: Analiza wywołań Vulkan API ujawniła fundamentalne różnice architektoniczne:
\begin{itemize} \begin{itemize}
\item Unity: prosty, dwuetapowy potok renderowania \\ (2 wywołania \texttt{vkQueueSubmit} na~klatkę), \item Unity: prosty, dwuetapowy potok renderowania (2 wywołania \\ \texttt{vkQueueSubmit} na~klatkę),
zdominowany przez \\ oczekiwanie na~GPU (\texttt{vkWaitForFences} -- 95,2\% czasu) zdominowany przez oczekiwanie na~GPU \\ (\texttt{vkWaitForFences} -- 95,2\% czasu).
\item Unreal Engine: złożony potok z~16 wywołaniami \texttt{vkQueueSubmit} na~klatkę, zdominowany przez dynamiczną kompilację potoków (47--72\% czasu) \item Unreal Engine: złożony potok z~16 wywołaniami \texttt{vkQueueSubmit} na~klatkę, zdominowany przez dynamiczną kompilację potoków (47--72\% czasu).
\end{itemize} \end{itemize}
Unity wykazał większą stabilność czasów klatek (98,24\% klatek w~przedziale 5--10~ms), podczas gdy Unreal Engine doświadczył spadku wydajności o~ponad 50\% między fazami niskiego (332--339~FPS) a~wysokiego obciążenia (162~FPS). Unity wykazał większą stabilność czasów klatek (98,24\% klatek w~przedziale 5--10~ms), podczas gdy Unreal Engine doświadczył spadku wydajności o~ponad 50\% między fazami niskiego (332--339~FPS) a~wysokiego obciążenia (162~FPS).
@ -53,28 +54,28 @@ Potoki graficzne utworzone & 3 & $\sim$2\,400 \\
\end{table} \end{table}
Praktyczna implementacja gry bullet hell potwierdziła przewagę Unity \\ dla~tego typu projektów: Praktyczna implementacja gry bullet hell potwierdziła przewagę Unity dla~tego typu projektów:
\begin{itemize} \begin{itemize}
\item \textbf{Czas implementacji}: Unity wymagał około 60\% czasu potrzebnego na~implementację w~Unreal Engine \item \textbf{Czas implementacji}: Unity wymagał około 60\% czasu potrzebnego na~implementację w~Unreal Engine.
\item \textbf{Wsparcie 2D}: Unity oferuje natywne komponenty 2D \\ (\texttt{Rigidbody2D}, \texttt{Collider2D}), podczas gdy Unreal symuluje 2D w~środowisku 3D \item \textbf{Wsparcie 2D}: Unity oferuje natywne komponenty 2D (\texttt{Rigidbody2D}, \texttt{Collider2D}), podczas gdy Unreal symuluje 2D w~środowisku 3D.
\item \textbf{Object pooling}: Implementacja w~Unity jest prostsza \\ \item \textbf{Object pooling}: Implementacja w~Unity jest prostsza
(pojedyncza metoda \texttt{SetActive}) vs Unreal (trzy osobne metody: \\ (pojedyncza metoda \\ \texttt{SetActive}) vs Unreal (trzy osobne metody:
\texttt{SetActorHiddenInGame}, \texttt{SetActorHiddenInGame},
\texttt{SetActorEnableCollision}, \\ \texttt{SetActorEnableCollision},
\\ \texttt{SetActorTickEnabled}) \texttt{SetActorTickEnabled}).
\item \textbf{Instalacja na~Linux}: Unity -- około 30 minut, Unreal -- 2--4 godziny \item \textbf{Instalacja na~Linux}: Unity -- około 30 minut, Unreal -- 2--4 godziny.
\end{itemize} \end{itemize}
Badania jakościowe z~udziałem 8~deweloperów potwierdziły: Badania jakościowe z~udziałem 8~deweloperów potwierdziły:
\begin{itemize} \begin{itemize}
\item Unity charakteryzuje się niższym progiem wejścia i~lepszą dokumentacją \item Unity charakteryzuje się niższym progiem wejścia i~lepszą dokumentacją.
\item Unreal Engine wymusza bardziej uporządkowaną strukturę projektu \item Unreal Engine wymusza bardziej uporządkowaną strukturę projektu.
\item System Blueprints ułatwia współpracę z~osobami nietechnicznymi \item System Blueprints ułatwia współpracę z~osobami nietechnicznymi.
\item Problemy z~garbage collectorem w~Unity są znane, ale~rzadko doświadczane przy stosowaniu dobrych praktyk (object pooling) \item Problemy z~garbage collectorem w~Unity są znane, ale~rzadko doświadczane przy stosowaniu dobrych praktyk (object pooling).
\item Obie społeczności deweloperskie są aktywne, choć Unity ma~przewagę ilościową w~materiałach edukacyjnych \item Obie społeczności deweloperskie są aktywne, choć Unity ma~przewagę ilościową w~materiałach edukacyjnych.
\end{itemize} \end{itemize}
\subsection{Rekomendacje praktyczne} \subsection{Rekomendacje praktyczne}
@ -83,22 +84,22 @@ Na~podstawie przeprowadzonych badań sformułowano następujące rekomendacje:
\begin{itemize} \begin{itemize}
\item Projekt dotyczy gry 2D lub mobilnej \item Projekt dotyczy gry 2D lub mobilnej.
\item Zespół składa się z~początkujących deweloperów \item Zespół składa się z~początkujących deweloperów.
\item Wymagany jest szybki cykl iteracji (hot reload) \item Wymagany jest szybki cykl iteracji (hot reload).
\item Projekt ma~ograniczony budżet czasowy na~naukę narzędzia \item Projekt ma~ograniczony budżet czasowy na~naukę narzędzia.
\item Preferowany jest język C\# nad C++ \item Preferowany jest język C\# nad C++.
\item Wymagana jest dobra integracja z~Git (tekstowa serializacja scen) \item Wymagana jest dobra integracja z~Git (tekstowa serializacja scen).
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Projekt wymaga fotorealistycznej grafiki 3D \item Projekt wymaga fotorealistycznej grafiki 3D.
\item Zespół posiada doświadczenie w~C++ \item Zespół posiada doświadczenie w~C++.
\item Projekt jest typu FPS lub AAA \item Projekt jest typu FPS lub AAA.
\item W~zespole znajdują się osoby nietechniczne (designerzy, artyści) \item W~zespole znajdują się osoby nietechniczne (designerzy, artyści).
\item Wymagane są zaawansowane funkcje wizualne (Nanite, Lumen) \item Wymagane są zaawansowane funkcje wizualne (Nanite, Lumen).
\item Projekt wymaga dostępu do~kodu źródłowego silnika \item Projekt wymaga dostępu do~kodu źródłowego silnika.
\end{itemize} \end{itemize}
\begin{table}[H] \begin{table}[H]
@ -131,19 +132,19 @@ Prototyp & Unity & Szybki cykl iteracji \\
Niniejsza praca wnosi następujące elementy do~dziedziny badań nad~silnikami gier: Niniejsza praca wnosi następujące elementy do~dziedziny badań nad~silnikami gier:
\begin{enumerate} \begin{enumerate}
\item \textbf{Zunifikowana metodyka pomiaru} -- wykorzystanie \\ NVIDIA Nsight Systems jako \item \textbf{Zunifikowana metodyka pomiaru} -- wykorzystanie NVIDIA Nsight Systems jako
niezależnego narzędzia profilowania \\ eliminuje różnice wynikające z~wbudowanych profilerów niezależnego narzędzia profilowania eliminuje różnice wynikające z~wbudowanych profilerów
silników, zapewniając porównywalność wyników silników, zapewniając porównywalność wyników.
\item \textbf{Szczegółowa analiza wywołań API} -- dokumentacja ponad 32~milionów wywołań \item \textbf{Szczegółowa analiza wywołań API} -- dokumentacja ponad 32~milionów wywołań
Vulkan API dla~Unreal Engine i~0,5~miliona dla~Unity dostarcza wglądu w~architekturę Vulkan API dla~Unreal Engine i~0,5~miliona dla~Unity dostarcza wglądu w~architekturę
renderowania obu silników renderowania obu silników.
\item \textbf{Triangulacja metod badawczych} -- połączenie testów wydajnościowych, analizy \item \textbf{Triangulacja metod badawczych} -- połączenie testów wydajnościowych, analizy
funkcjonalności, doświadczeń implementacyjnych i~wywiadów jakościowych daje kompleksowy funkcjonalności, doświadczeń implementacyjnych i~wywiadów jakościowych daje kompleksowy
obraz porównawczy obraz porównawczy.
\item \textbf{Praktyczne przypadki użycia} -- konkretne rekomendacje oparte na~danych empirycznych mogą służyć jako przewodnik dla~deweloperów \item \textbf{Praktyczne przypadki użycia} -- konkretne rekomendacje oparte na~danych empirycznych mogą służyć jako przewodnik dla~deweloperów.
\end{enumerate} \end{enumerate}
\subsection{Ograniczenia badań} \subsection{Ograniczenia badań}
@ -151,16 +152,17 @@ Niniejsza praca wnosi następujące elementy do~dziedziny badań nad~silnikami g
Przeprowadzone badania posiadają następujące ograniczenia: Przeprowadzone badania posiadają następujące ograniczenia:
\begin{enumerate} \begin{enumerate}
\item \textbf{Zakres gatunkowy} -- koncentracja na~grach typu bullet hell \\ nie~pokrywa \item \textbf{Zakres gatunkowy} -- koncentracja na~grach typu bullet hell
wszystkich możliwych zastosowań silników gier; \\ inne gatunki (RPG, RTS, puzzle) nie~pokrywa
mogą wykazywać odmienne charakterystyki wydajnościowe wszystkich możliwych zastosowań silników gier; inne gatunki (RPG, RTS, puzzle)
mogą wykazywać odmienne charakterystyki wydajnościowe.
\item \textbf{Pojedyncza konfiguracja sprzętowa} -- testy na~wysokowydajnym sprzęcie (RTX 3090, Ryzen 9 7900X3D) nie~odzwierciedlają wydajności na~typowych konfiguracjach graczy \item \textbf{Pojedyncza konfiguracja sprzętowa} -- testy na~wysokowydajnym sprzęcie (RTX 3090, Ryzen 9 7900X3D) nie~odzwierciedlają wydajności na~typowych konfiguracjach graczy.
\item \textbf{Próba badawcza} -- 8~wywiadów stanowi relatywnie małą próbę, choć~wystarczającą dla~badań jakościowych o~charakterze eksploracyjnym \item \textbf{Próba badawcza} -- 8~wywiadów stanowi relatywnie małą próbę, choć~wystarczającą dla~badań jakościowych o~charakterze eksploracyjnym.
\item \textbf{Ewolucja silników} -- szybki rozwój obu silników może spowodować dezaktualizację wyników w~ciągu 12--24 miesięcy \item \textbf{Ewolucja silników} -- szybki rozwój obu silników może spowodować dezaktualizację wyników w~ciągu 12--24 miesięcy.
\end{enumerate} \end{enumerate}
\subsection{Propozycje dalszych badań} \subsection{Propozycje dalszych badań}
@ -168,48 +170,48 @@ Przeprowadzone badania posiadają następujące ograniczenia:
Na~podstawie zidentyfikowanych ograniczeń proponuje się następujące kierunki przyszłych badań: Na~podstawie zidentyfikowanych ograniczeń proponuje się następujące kierunki przyszłych badań:
Przeprowadzenie analogicznych testów Przeprowadzenie analogicznych testów
\\ dla~gier RPG (open world), strategii czasu rzeczywistego, gier puzzle oraz symulatorów dla~gier RPG (open world), strategii czasu rzeczywistego, gier puzzle oraz symulatorów
pozwoliłoby na~bardziej kompleksową ocenę wydajności silników. pozwoliłoby na~bardziej kompleksową ocenę wydajności silników.
Porównanie wydajności na~różnych konfiguracjach \\ sprzętowych Porównanie wydajności na~różnych konfiguracjach sprzętowych
(PC low-end, mid-range, high-end; urządzenia mobilne; konsole) dostarczyłoby (PC low-end, \\ mid-range, high-end; urządzenia mobilne; konsole) dostarczyłoby
praktycznych informacji dla~deweloperów celujących w~różne platformy. praktycznych informacji dla~deweloperów celujących w~różne platformy.
Badanie Total Cost of Ownership (TCO) uwzględniające \\ czas nauki zespołu, Badanie Total Cost of Ownership (TCO) uwzględniające czas nauki zespołu,
koszty licencji, assetów, czas rozwoju i~koszty utrzymania projektu mogłoby koszty licencji, assetów, czas rozwoju i~koszty utrzymania projektu mogłoby
dostarczyć cennych informacji biznesowych. dostarczyć cennych informacji biznesowych.
Śledzenie wydajności obu silników przez~2--3 lata, dokumentując wpływ kolejnych aktualizacji, pozwoliłoby na~ocenę długoterminowej stabilności i~kierunków rozwoju. Śledzenie wydajności obu silników przez~2--3 lata, dokumentując wpływ kolejnych aktualizacji, pozwoliłoby na~ocenę długoterminowej stabilności i~kierunków rozwoju.
Stworzenie frameworka \\ do~automatycznego uruchamiania i~profilowania scenariuszy testowych Stworzenie frameworka do~automatycznego uruchamiania i~profilowania scenariuszy testowych
umożliwiłoby powtarzalne badania na~większą skalę. umożliwiłoby powtarzalne badania na~większą skalę.
\subsection{Refleksje końcowe} \subsection{Refleksje końcowe}
Przeprowadzone badania potwierdzają, że~nie~istnieje jednoznaczna odpowiedź \\na~pytanie ,, Przeprowadzone badania potwierdzają, że~nie~istnieje jednoznaczna odpowiedź na~pytanie ,,
który silnik jest lepszy''. Unity i~Unreal Engine reprezentują różne filozofie projektowe który silnik jest lepszy''. Unity i~Unreal Engine reprezentują różne filozofie projektowe
i~są zoptymalizowane pod~odmienne przypadki użycia. i~są zoptymalizowane pod~odmienne przypadki użycia.
\textbf{Unity} wyróżnia się jako silnik oferujący: \textbf{Unity} wyróżnia się jako silnik oferujący:
\begin{itemize} \begin{itemize}
\item Niższy próg wejścia i~szybszą krzywą uczenia \item Niższy próg wejścia i~szybszą krzywą uczenia.
\item Lepsze natywne wsparcie dla~grafiki 2D \item Lepsze natywne wsparcie dla~grafiki 2D.
\item Prostszy i~bardziej przewidywalny potok renderowania \item Prostszy i~bardziej przewidywalny potok renderowania.
\item Efektywniejszą pracę na~platformach mobilnych \item Efektywniejszą pracę na~platformach mobilnych.
\item Większą społeczność i~więcej materiałów edukacyjnych \item Większą społeczność i~więcej materiałów edukacyjnych.
\end{itemize} \end{itemize}
\textbf{Unreal Engine} natomiast dominuje w~obszarach: \textbf{Unreal Engine} natomiast dominuje w~obszarach:
\begin{itemize} \begin{itemize}
\item Zaawansowanej grafiki 3D i~fotorealizmu \item Zaawansowanej grafiki 3D i~fotorealizmu.
\item Produkcji wysokobudżetowych (AAA) \item Produkcji wysokobudżetowych (AAA).
\item Współpracy z~osobami nietechnicznymi (Blueprints) \item Współpracy z~osobami nietechnicznymi (Blueprints).
\item Dostępu do~kodu źródłowego silnika \item Dostępu do~kodu źródłowego silnika.
\item Wbudowanych zaawansowanych funkcji (Nanite, Lumen) \item Wbudowanych zaawansowanych funkcji (Nanite, Lumen).
\end{itemize} \end{itemize}
\newpage \newpage
W~kontekście testowanej gry bullet hell hipoteza o~przewadze Unity została częściowo potwierdzona -- W~kontekście testowanej gry bullet hell hipoteza o~przewadze Unity została częściowo potwierdzona --
silnik oferuje prostszą architekturę renderowania, \\ stabilniejsze czasy klatek i~znacznie silnik oferuje prostszą architekturę renderowania, stabilniejsze czasy klatek i~znacznie
łatwiejszy proces implementacji. Jednakże Unreal Engine wykazał zdolność do~osiągania porównywalnej łatwiejszy proces implementacji. Jednakże Unreal Engine wykazał zdolność do~osiągania porównywalnej
wydajności w~wymagających scenach, co~sugeruje, że~różnice wydajnościowe są mniejsze niż różnice wydajności w~wymagających scenach, co~sugeruje, że~różnice wydajnościowe są mniejsze niż różnice
w~doświadczeniu deweloperskim. w~doświadczeniu deweloperskim.

View File

@ -6,14 +6,14 @@ W~ramach pracy zaimplementowano identyczną grę typu bullet-hell w~obu silnikac
\subsection{Implementacja w Unity} \subsection{Implementacja w Unity}
\label{subsec:impl-unity} \label{subsec:impl-unity}
Projekt Unity został utworzony w~wersji LTS z~wykorzystaniem \\ standardowego renderera 2D. Instalacja Projekt Unity został utworzony w~wersji LTS z~wykorzystaniem standardowego renderera 2D. Instalacja
silnika na systemie Linux przebiegła bezproblemowo dzięki Unity Hub silnika na systemie Linux przebiegła bezproblemowo dzięki Unity Hub
\cite{unity_hub} \cite{unity_hub_download_arch}, który zapewnia spójne \cite{unity_hub} \cite{unity_hub_download_arch}, który zapewnia spójne
zarządzanie wersjami edytora i~projektami. zarządzanie wersjami edytora i~projektami.
\begin{figure}[H] \begin{figure}[H]
\centering \centering
\includegraphics[width=0.9\textwidth]{tex/img/unity_hub_default_screen.png} \includegraphics[width=0.8\textwidth]{tex/img/unity_hub_default_screen.png}
\caption{Ekran powitalny Unity Hub.} \caption{Ekran powitalny Unity Hub.}
\label{fig:unity_hub_welcome} \label{fig:unity_hub_welcome}
\end{figure} \end{figure}
@ -34,8 +34,8 @@ zarządzanie wersjami edytora i~projektami.
Implementacja Unity wykorzystuje kilka kluczowych wzorców projektowych: Implementacja Unity wykorzystuje kilka kluczowych wzorców projektowych:
Klasa \texttt{GameBootstrap} wykorzystuje atrybut \\ \texttt{[Runtime\-Initialize\-OnLoad\-Method]} Klasa \texttt{GameBootstrap} wykorzystuje atrybut \texttt{[Runtime\-Initialize\-OnLoad\-Method]}
do zapewnienia, że obiekt \\ \texttt{GameInitializer} istnieje w~scenie przed rozpoczęciem gry. do zapewnienia, że obiekt \texttt{GameInitializer} istnieje w~scenie przed rozpoczęciem gry.
Jest to eleganckie rozwiązanie problemu inicjalizacji singletonów w~Unity. Jest to eleganckie rozwiązanie problemu inicjalizacji singletonów w~Unity.
System \texttt{BulletPool} stanowi rdzeń optymalizacji wydajnościowej. Zamiast ciągłego tworzenia i niszczenia obiektów pocisków (co generowałoby znaczące obciążenie garbage collectora), pociski są recyklingowane z puli: System \texttt{BulletPool} stanowi rdzeń optymalizacji wydajnościowej. Zamiast ciągłego tworzenia i niszczenia obiektów pocisków (co generowałoby znaczące obciążenie garbage collectora), pociski są recyklingowane z puli:
@ -57,7 +57,8 @@ public Bullet Spawn(Vector2 position, Vector2 direction,
Pula jest wstępnie rozgrzewana (\textit{warm capacity}) podczas inicjalizacji, co eliminuje alokacje podczas rozgrywki. Pula jest wstępnie rozgrzewana (\textit{warm capacity}) podczas inicjalizacji, co eliminuje alokacje podczas rozgrywki.
Klasy \texttt{GameDirector} i~\texttt{EnemySpawner} wykorzystują \\ wzorzec Singleton z~właściwością \texttt{Instance}, zapewniając \\ globalny punkt dostępu do kluczowych systemów gry. Klasy \texttt{GameDirector} i~\texttt{EnemySpawner} wykorzystują wzorzec Singleton z~właściwością \texttt{Instance},
zapewniając globalny punkt dostępu do kluczowych systemów gry.
\texttt{EnemySpawner} implementuje system eskalującej trudności poprzez interpolację czasu między spawnami: \texttt{EnemySpawner} implementuje system eskalującej trudności poprzez interpolację czasu między spawnami:
@ -73,20 +74,20 @@ Przeciwnicy są definiowani przez strukturę \texttt{EnemyBlueprint}, która zaw
Podczas implementacji napotkano następujące wyzwania: Podczas implementacji napotkano następujące wyzwania:
\begin{enumerate} \begin{enumerate}
\item \textbf{Garbage Collection} -- początkowa implementacja bez \\ object poolingu powodowała zauważalne spadki klatek przy dużej liczbie pocisków \item \textbf{Garbage Collection} -- początkowa implementacja bez object poolingu powodowała zauważalne spadki klatek przy dużej liczbie pocisków.
\item \textbf{Kolejność inicjalizacji} -- konieczność użycia wzorca Bootstrap wynikała z~nieprzewidywalnej kolejności wywoływania metod \texttt{Awake()} i~\texttt{Start()} \item \textbf{Kolejność inicjalizacji} -- konieczność użycia wzorca Bootstrap wynikała z~nieprzewidywalnej kolejności wywoływania metod \texttt{Awake()} i~\texttt{Start()}.
\item \textbf{Serializacja} -- atrybuty \texttt{[SerializeField]} wymagały \\ starannego rozplanowania, które pola powinny być edytowalne w~inspektorze \item \textbf{Serializacja} -- atrybuty \texttt{[SerializeField]} wymagały starannego rozplanowania, które pola powinny być edytowalne w~inspektorze.
\item Interfejs użytkownika nie jest odświeżany po otwarciu menu \cite{linux_editor_does_not_redraw} -- wymagało to ręcznego wymuszenia odświeżenia inspektora \item Interfejs użytkownika nie jest odświeżany po otwarciu menu \cite{linux_editor_does_not_redraw} -- wymagało to ręcznego wymuszenia odświeżenia inspektora.
\end{enumerate} \end{enumerate}
\begin{itemize} \begin{itemize}
\item Natywne wsparcie dla 2D -- dedykowany tryb 2D z odpowiednimi komponentami fizyki (\texttt{Rigidbody2D}, \texttt{Collider2D}) \item Natywne wsparcie dla 2D -- dedykowany tryb 2D z odpowiednimi komponentami fizyki (\texttt{Rigidbody2D}, \texttt{Collider2D}).
\item Hot reload -- możliwość edycji kodu i natychmiastowego testowania zmian \item Hot reload -- możliwość edycji kodu i natychmiastowego testowania zmian.
\item Intuicyjny inspektor -- łatwa konfiguracja parametrów gry bez rekompilacji \item Intuicyjny inspektor -- łatwa konfiguracja parametrów gry bez rekompilacji.
\item Bogata dokumentacja C\# i społeczność \item Bogata dokumentacja C\# i społeczność.
\item Skupienie się na kodzie -- większość logiki gry zaimplementowana została w kodzie źródłowym co przyśpieszyło proces tworzenia gry \item Skupienie się na kodzie -- większość logiki gry zaimplementowana została w kodzie źródłowym co przyśpieszyło proces tworzenia gry.
\item Dobre wsparcie dla LLM -- unity posiada narzędzie mcp oferującą prostą integrację edytora i narzędzi AI \cite{unity_mcp} \item Dobre wsparcie dla LLM -- unity posiada narzędzie mcp oferującą prostą integrację edytora i narzędzi AI \cite{unity_mcp}.
\end{itemize} \end{itemize}
\newpage \newpage
\subsection{Implementacja w Unreal Engine} \subsection{Implementacja w Unreal Engine}
@ -96,8 +97,8 @@ Podczas implementacji napotkano następujące wyzwania:
Instalacja Unreal Engine na systemie Linux okazała się znacznie bardziej skomplikowana niż w przypadku Unity. Dostępne są dwie ścieżki: Instalacja Unreal Engine na systemie Linux okazała się znacznie bardziej skomplikowana niż w przypadku Unity. Dostępne są dwie ścieżki:
\begin{enumerate} \begin{enumerate}
\item Uzyskanie dostępu do oficjalnego repozytorium GitHub Epic Games i samodzielna kompilacja silnika ze źródeł \cite{unreal_arch_installation_source} \item Uzyskanie dostępu do oficjalnego repozytorium GitHub Epic Games i samodzielna kompilacja silnika ze źródeł \cite{unreal_arch_installation_source}.
\item Pobranie prekompilowanej wersji binarnej \cite{unreal_arch_installation_binary} \item Pobranie prekompilowanej wersji binarnej \cite{unreal_arch_installation_binary}.
\end{enumerate} \end{enumerate}
\begin{figure}[H] \begin{figure}[H]
@ -127,9 +128,9 @@ tryb 2D z~wyspecjalizowanymi komponentami.
Ta różnica ma praktyczne konsekwencje: Ta różnica ma praktyczne konsekwencje:
\begin{itemize} \begin{itemize}
\item W Unreal konieczne jest ręczne konfigurowanie kamery ortograficznej \item W Unreal konieczne jest ręczne konfigurowanie kamery ortograficznej.
\item Fizyka 2D w~Unreal wykorzystuje te same komponenty co 3D, z~ograniczeniami na odpowiednich osiach \item Fizyka 2D w~Unreal wykorzystuje te same komponenty co 3D, z~ograniczeniami na odpowiednich osiach.
\item Sprite'y w Unreal są renderowane jako płaskie meshe w przestrzeni 3D \item Sprite'y w Unreal są renderowane jako płaskie meshe w przestrzeni 3D.
\end{itemize} \end{itemize}
@ -138,42 +139,42 @@ Unreal oferuje dwa podejścia do programowania logiki gry:
W praktyce korzystanie z nich dla osoby która zna tradycyjne programowanie okazazało się frustrujące ze względu na: W praktyce korzystanie z nich dla osoby która zna tradycyjne programowanie okazazało się frustrujące ze względu na:
\begin{itemize} \begin{itemize}
\item Problemy z kontrolą wersji \item Problemy z kontrolą wersji.
\item Trudności w debugowaniu \item Trudności w debugowaniu.
\item Ograniczoną czytelność i skalowalność \item Ograniczoną czytelność i skalowalność.
\item Ograniczenie w funkcjach z którycj można korzytsać \item Ograniczenie w funkcjach z którycj można korzytsać.
\end{itemize} \end{itemize}
użycie go ostatecznie okazało się bardziej intujcywne i prostsze dla projektu z uwagi na doświadczenie w pisaniu programów w użycie go ostatecznie okazało się bardziej intujcywne i prostsze dla projektu z uwagi na doświadczenie w pisaniu programów w
tradycyjny sposób tradycyjny sposób
Implementacja object poolingu w~Unreal wymaga innego podejścia \\ niż w Unity. Implementacja object poolingu w~Unreal wymaga innego podejścia niż w Unity.
Zamiast prostego \texttt{SetActive(true/\allowbreak false)}, Unreal wykorzystuje: Zamiast prostego \texttt{SetActive(true/\allowbreak false)}, Unreal wykorzystuje:
\begin{itemize} \begin{itemize}
\item \texttt{SetActorHiddenInGame()} -- kontrola widoczności \item \texttt{SetActorHiddenInGame()} -- kontrola widoczności.
\item \texttt{SetActorEnableCollision()} -- kontrola kolizji \item \texttt{SetActorEnableCollision()} -- kontrola kolizji.
\item \texttt{SetActorTickEnabled()} -- kontrola aktualizacji logiki \item \texttt{SetActorTickEnabled()} -- kontrola aktualizacji logiki.
\end{itemize} \end{itemize}
Ta granularność daje większą kontrolę, ale wymaga więcej kodu do osiągnięcia tego samego efektu. Ta granularność daje większą kontrolę, ale wymaga więcej kodu do osiągnięcia tego samego efektu.
\begin{enumerate} \begin{enumerate}
\item \textbf{Brak natywnego 2D} -- konieczność ``symulowania'' środowiska 2D w silniku 3D \item \textbf{Brak natywnego 2D} -- konieczność ``symulowania'' środowiska 2D w silniku 3D.
\item \textbf{Czas kompilacji} -- kompilacja projektów C++ jest znacznie wolniejsza niż kompilacja C\# w Unity \item \textbf{Czas kompilacji} -- kompilacja projektów C++ jest znacznie wolniejsza niż kompilacja C\# w Unity.
\item \textbf{Rozmiar projektu} -- nawet prosty projekt Unreal zajmuje wielokrotnie więcej miejsca na dysku \item \textbf{Rozmiar projektu} -- nawet prosty projekt Unreal zajmuje wielokrotnie więcej miejsca na dysku.
\item \textbf{Dokumentacja} -- dla mniej popularnych zastosowań (jak gry 2D) dokumentacja jest ograniczona \item \textbf{Dokumentacja} -- dla mniej popularnych zastosowań (jak gry 2D) dokumentacja jest ograniczona.
\item \textbf{Blueprinty i kontrola wersji} -- pliki Blueprintów są binarne, co \\ utrudnia merge'owanie i code review \item \textbf{Blueprinty i kontrola wersji} -- pliki Blueprintów są binarne, co utrudnia merge'owanie i code review.
\end{enumerate} \end{enumerate}
\begin{itemize} \begin{itemize}
\item Potężny system materiałów i efektów wizualnych \item Potężny system materiałów i efektów wizualnych.
\item Wbudowane zaawansowane narzędzia profilowania \item Wbudowane zaawansowane narzędzia profilowania.
\item Blueprinty umożliwiają szybkie prototypowanie przez osoby nietechniczne \item Blueprinty umożliwiają szybkie prototypowanie przez osoby nietechniczne.
\item Doskonałe wsparcie dla grafiki 3D i fotorealizmu \item Doskonałe wsparcie dla grafiki 3D i fotorealizmu.
\end{itemize} \end{itemize}
\subsection{Porównanie doświadczeń implementacyjnych} \subsection{Porównanie doświadczeń implementacyjnych}
@ -210,11 +211,11 @@ Rozmiar projektu & Mały & Duży \\
Doświadczenia z implementacji gry bullet-hell potwierdzają, że wybór silnika powinien być uzależniony od typu projektu: Doświadczenia z implementacji gry bullet-hell potwierdzają, że wybór silnika powinien być uzależniony od typu projektu:
\begin{enumerate} \begin{enumerate}
\item \textbf{Dla gier 2D} -- Unity oferuje znacznie lepsze wsparcie natywne, niższy próg wejścia i szybszy cykl iteracji \item \textbf{Dla gier 2D} -- Unity oferuje znacznie lepsze wsparcie natywne, niższy próg wejścia i szybszy cykl iteracji.
\item \textbf{Dla gier 3D AAA} -- Unreal Engine dysponuje lepszymi narzędziami do tworzenia fotorealistycznej grafiki \item \textbf{Dla gier 3D AAA} -- Unreal Engine dysponuje lepszymi narzędziami do tworzenia fotorealistycznej grafiki.
\item \textbf{Dla prototypowania} -- Unity pozwala na szybsze testowanie koncepcji dzięki hot reloadowi i prostszej konfiguracji \item \textbf{Dla prototypowania} -- Unity pozwala na szybsze testowanie koncepcji dzięki hot reloadowi i prostszej konfiguracji.
\item \textbf{Dla zespołów mieszanych} -- Blueprinty Unreal mogą być \\ wartościowe dla współpracy \item \textbf{Dla zespołów mieszanych} -- Blueprinty Unreal mogą być wartościowe dla współpracy
z designerami, choć problemy \\ z kontrolą wersji stanowią wyzwanie z designerami, choć problemy z kontrolą wersji stanowią wyzwanie.
\end{enumerate} \end{enumerate}
Implementacja gry bullet-hell w~Unity zajęła około 60\% czasu Implementacja gry bullet-hell w~Unity zajęła około 60\% czasu

View File

@ -8,15 +8,16 @@
Zarówno Unity, jak i~Unreal Engine oferują własne, wbudowane narzędzia do analizy wydajności. Każde z~nich posiada unikalne cechy dostosowane do specyfiki danego silnika. Zarówno Unity, jak i~Unreal Engine oferują własne, wbudowane narzędzia do analizy wydajności. Każde z~nich posiada unikalne cechy dostosowane do specyfiki danego silnika.
Unity dostarcza rozbudowany profiler dostępny bezpośrednio w~edytorze \\ (Window $\rightarrow$ Analysis $\rightarrow$ Profiler)~\cite{unity_profiler}. \\ Narzędzie to oferuje: Unity dostarcza rozbudowany profiler dostępny bezpośrednio w~edytorze
(Window $\rightarrow$ Analysis $\rightarrow$ Profiler)~\cite{unity_profiler}. Narzędzie to oferuje:
\begin{itemize} \begin{itemize}
\item \textbf{CPU Profiler} -- analiza czasu wykonania poszczególnych funkcji, z podziałem na kategorie (rendering, skrypty, fizyka, animacje) \item \textbf{CPU Profiler} -- analiza czasu wykonania poszczególnych funkcji, z podziałem na kategorie (rendering, skrypty, fizyka, animacje).
\item \textbf{GPU Profiler} -- pomiar czasu renderowania na karcie graficznej \item \textbf{GPU Profiler} -- pomiar czasu renderowania na karcie graficznej.
\item \textbf{Memory Profiler} -- szczegółowa analiza alokacji pamięci, wykrywanie wycieków \item \textbf{Memory Profiler} -- szczegółowa analiza alokacji pamięci, wykrywanie wycieków.
\item \textbf{Audio Profiler} -- monitorowanie obciążenia systemu dźwiękowego \item \textbf{Audio Profiler} -- monitorowanie obciążenia systemu dźwiękowego.
\item \textbf{Physics Profiler} -- analiza wydajności silnika fizyki \item \textbf{Physics Profiler} -- analiza wydajności silnika fizyki.
\item \textbf{Frame Debugger} -- krokowa analiza procesu renderowania \\ pojedynczej klatki \item \textbf{Frame Debugger} -- krokowa analiza procesu renderowania pojedynczej klatki.
\end{itemize} \end{itemize}
Unity Profiler umożliwia również zdalne profilowanie aplikacji uruchomionej na urządzeniu Unity Profiler umożliwia również zdalne profilowanie aplikacji uruchomionej na urządzeniu
@ -34,16 +35,16 @@ Unreal Engine oferuje narzędzie Unreal Insights, które zastąpiło starszy sys
Session Frontend~\cite{unreal_insights}. Kluczowe funkcjonalności obejmują: Session Frontend~\cite{unreal_insights}. Kluczowe funkcjonalności obejmują:
\begin{itemize} \begin{itemize}
\item \textbf{Timing Insights} -- precyzyjny pomiar czasu wykonania poszczególnych systemów silnika \item \textbf{Timing Insights} -- precyzyjny pomiar czasu wykonania poszczególnych systemów silnika.
\item \textbf{Asset Loading Insights} -- analiza czasu ładowania zasobów \item \textbf{Asset Loading Insights} -- analiza czasu ładowania zasobów.
\item \textbf{Memory Insights} -- monitorowanie alokacji i~dealokacji pamięci \item \textbf{Memory Insights} -- monitorowanie alokacji i~dealokacji pamięci.
\item \textbf{Animation Insights} -- profilowanie systemu animacji \item \textbf{Animation Insights} -- profilowanie systemu animacji.
\item \textbf{Network Insights} -- analiza ruchu sieciowego w~grach multiplayer \item \textbf{Network Insights} -- analiza ruchu sieciowego w~grach multiplayer.
\end{itemize} \end{itemize}
Dodatkowo Unreal Engine udostępnia komendy konsolowe \\ Dodatkowo Unreal Engine udostępnia komendy konsolowe
(np.~\texttt{stat fps}, \texttt{stat unit}, \texttt{stat gpu}) pozwalające na szybki \\ (np.~\texttt{stat fps}, \texttt{stat unit}, \texttt{stat gpu}) pozwalające na szybki
podgląd podstawowych metryk wydajności podczas \\ rozgrywki~\cite{unreal_docs}. podgląd podstawowych metryk wydajności podczas rozgrywki~\cite{unreal_docs}.
\begin{figure}[H] \begin{figure}[H]
\centering \centering
@ -58,10 +59,10 @@ w~kontekście porównawczych badań wydajnościowych:
\begin{enumerate} \begin{enumerate}
\item \textbf{Brak standaryzacji metryk} -- każdy silnik definiuje i~mierzy parametry \item \textbf{Brak standaryzacji metryk} -- każdy silnik definiuje i~mierzy parametry
w~odmienny sposób, co utrudnia bezpośrednie porównania w~odmienny sposób, co utrudnia bezpośrednie porównania.
\item \textbf{Różna granularność danych} -- poziom szczegółowości raportów różni się \\ między silnikami \item \textbf{Różna granularność danych} -- poziom szczegółowości raportów różni się między silnikami.
\item \textbf{Narzut profilowania} -- wbudowane profilery same generują \\ obciążenie, które może być różne dla każdego silnika \item \textbf{Narzut profilowania} -- wbudowane profilery same generują obciążenie, które może być różne dla każdego silnika.
\item \textbf{Nieporównywalność formatów wyjściowych} -- dane \\ eksportowane przez różne profilery mają odmienne struktury \item \textbf{Nieporównywalność formatów wyjściowych} -- dane eksportowane przez różne profilery mają odmienne struktury.
\end{enumerate} \end{enumerate}
Z~powyższych powodów zdecydowano się na zastosowanie zewnętrznego, niezależnego od silnika narzędzia profilowania. Z~powyższych powodów zdecydowano się na zastosowanie zewnętrznego, niezależnego od silnika narzędzia profilowania.
@ -85,37 +86,37 @@ Wybór NVIDIA Nsight jako głównego narzędzia pomiarowego podyktowany
był następującymi czynnikami: był następującymi czynnikami:
\begin{itemize} \begin{itemize}
\item \textbf{Niezależność od silnika} -- Nsight analizuje aplikację na poziomie wywołań API graficznego (DirectX, Vulkan, OpenGL), co zapewnia porównywalność wyników między Unity a~Unreal Engine \item \textbf{Niezależność od silnika} -- Nsight analizuje aplikację na poziomie wywołań API graficznego (DirectX, Vulkan, OpenGL), co zapewnia porównywalność wyników między Unity a~Unreal Engine.
\item \textbf{Standaryzowane metryki} -- narzędzie dostarcza zunifikowany zestaw metryk sprzętowych (GPU utilization, memory bandwidth, shader throughput) \item \textbf{Standaryzowane metryki} -- narzędzie dostarcza zunifikowany zestaw metryk sprzętowych (GPU utilization, memory bandwidth, shader throughput).
\item \textbf{Minimalny narzut} -- profilowanie na poziomie sterownika generuje mniejsze zakłócenia niż profilery działające wewnątrz silnika \item \textbf{Minimalny narzut} -- profilowanie na poziomie sterownika generuje mniejsze zakłócenia niż profilery działające wewnątrz silnika.
\item \textbf{Dostęp do danych niskopoziomowych} -- możliwość analizy \\ poszczególnych wywołań draw call, shaderów, transferów pamięci \item \textbf{Dostęp do danych niskopoziomowych} -- możliwość analizy poszczególnych wywołań draw call, shaderów, transferów pamięci.
\item \textbf{Spójny format danych} -- wyniki z~obu silników mają identyczną strukturę, co ułatwia automatyzację analizy \item \textbf{Spójny format danych} -- wyniki z~obu silników mają identyczną strukturę, co ułatwia automatyzację analizy.
\end{itemize} \end{itemize}
NVIDIA Nsight Graphics oferuje szereg funkcjonalności istotnych dla badań wydajnościowych: NVIDIA Nsight Graphics oferuje szereg funkcjonalności istotnych dla badań wydajnościowych:
Główny moduł analizy wydajności, umożliwiający: Główny moduł analizy wydajności, umożliwiający:
\begin{itemize} \begin{itemize}
\item Przechwycenie i~analizę pojedynczej klatki (frame capture) \item Przechwycenie i~analizę pojedynczej klatki (frame capture).
\item Hierarchiczny widok wszystkich wywołań GPU \item Hierarchiczny widok wszystkich wywołań GPU.
\item Pomiar czasu wykonania każdego etapu renderowania \item Pomiar czasu wykonania każdego etapu renderowania.
\item Identyfikację wąskich gardeł (bottlenecks) \item Identyfikację wąskich gardeł (bottlenecks).
\item Analizę wykorzystania jednostek obliczeniowych GPU \item Analizę wykorzystania jednostek obliczeniowych GPU.
\end{itemize} \end{itemize}
Moduł do długoterminowej analizy wydajności: Moduł do długoterminowej analizy wydajności:
\begin{itemize} \begin{itemize}
\item Rejestrowanie metryk przez określony czas (nie tylko pojedyncza klatka) \item Rejestrowanie metryk przez określony czas (nie tylko pojedyncza klatka).
\item Wykrywanie spadków wydajności i~ich przyczyn \item Wykrywanie spadków wydajności i~ich przyczyn.
\item Analiza zmienności czasów klatek (frame time variance) \item Analiza zmienności czasów klatek (frame time variance).
\item Korelacja obciążenia GPU z~wydarzeniami w~grze \item Korelacja obciążenia GPU z~wydarzeniami w~grze.
\end{itemize} \end{itemize}
Narzędzie do optymalizacji shaderów: Narzędzie do optymalizacji shaderów:
\begin{itemize} \begin{itemize}
\item Analiza wydajności poszczególnych shaderów \item Analiza wydajności poszczególnych shaderów.
\item Identyfikacja nieefektywnych instrukcji \item Identyfikacja nieefektywnych instrukcji.
\item Pomiar occupancy (wykorzystania jednostek obliczeniowych) \item Pomiar occupancy (wykorzystania jednostek obliczeniowych).
\end{itemize} \end{itemize}
\subsection{Przetwarzanie danych z~Nsight} \subsection{Przetwarzanie danych z~Nsight}
@ -126,9 +127,9 @@ Dane zebrane przez NVIDIA Nsight wymagają odpowiedniego przetworzenia w~celu uz
Nsight umożliwia eksport danych w~kilku formatach: Nsight umożliwia eksport danych w~kilku formatach:
\begin{itemize} \begin{itemize}
\item \textbf{CSV} -- tabularyczne dane liczbowe \item \textbf{CSV} -- tabularyczne dane liczbowe.
\item \textbf{JSON} -- strukturalne dane z~pełną hierarchią wywołań \item \textbf{JSON} -- strukturalne dane z~pełną hierarchią wywołań.
\item \textbf{HTML Report} -- graficzny raport z~wykresami \item \textbf{HTML Report} -- graficzny raport z~wykresami.
\end{itemize} \end{itemize}
W~niniejszej pracy wykorzystano format CSV ze względu na łatwość importu do narzędzi analizy statystycznej. W~niniejszej pracy wykorzystano format CSV ze względu na łatwość importu do narzędzi analizy statystycznej.
@ -167,8 +168,8 @@ Memory Bandwidth & GB/s & Przepustowość pamięci GPU \\
Zastosowanie NVIDIA Nsight jako głównego narzędzia profilowania zapewnia: Zastosowanie NVIDIA Nsight jako głównego narzędzia profilowania zapewnia:
\begin{enumerate} \begin{enumerate}
\item \textbf{Obiektywność} -- pomiary wykonywane na tym samym poziomie abstrakcji dla obu silników \item \textbf{Obiektywność} -- pomiary wykonywane na tym samym poziomie abstrakcji dla obu silników.
\item \textbf{Porównywalność} -- identyczne metryki i~format danych \item \textbf{Porównywalność} -- identyczne metryki i~format danych.
\item \textbf{Powtarzalność} -- standaryzowana procedura pomiarowa \item \textbf{Powtarzalność} -- standaryzowana procedura pomiarowa.
\end{enumerate} \end{enumerate}

View File

@ -10,14 +10,14 @@ W ramach badań jakościowych przeprowadzono osiem pogłębionych wywiadów z de
Respondenci zostali dobrani według kryterium posiadania co najmniej rocznego doświadczenia amatorskiego lub profesjonalnego w jednym z badanych silników. Profil uczestników przedstawia się następująco: Respondenci zostali dobrani według kryterium posiadania co najmniej rocznego doświadczenia amatorskiego lub profesjonalnego w jednym z badanych silników. Profil uczestników przedstawia się następująco:
\begin{itemize} \begin{itemize}
\item \textbf{Respondent 1}: Około 6-10 lat doświadczenia amatorskiego w Unity, semestr zajęć z Unreal Engine, 10-20 projektów w Unity \item \textbf{Respondent 1}: Około 6-10 lat doświadczenia amatorskiego w Unity, semestr zajęć z Unreal Engine, 10-20 projektów w Unity.
\item \textbf{Respondent 2}: 7 lat doświadczenia amatorskiego w Unity, pół roku profesjonalnego, 15-20 projektów \item \textbf{Respondent 2}: 7 lat doświadczenia amatorskiego w Unity, pół roku profesjonalnego, 15-20 projektów.
\item \textbf{Respondent 3}: 1,5 roku amatorskiego doświadczenia w Unity, 4 projekty zakończone \item \textbf{Respondent 3}: 1,5 roku amatorskiego doświadczenia w Unity, 4 projekty zakończone.
\item \textbf{Respondent 4}: 2 lata profesjonalne w Unreal, 2 miesiące w Unity (z przerwami przez kilka lat), projekty w obu silnikach \item \textbf{Respondent 4}: 2 lata profesjonalne w Unreal, 2 miesiące w Unity (z przerwami przez kilka lat), projekty w obu silnikach.
\item \textbf{Respondent 5}: 9 lat doświadczenia zawodowego (od 2012 Unity amatorsko, od 2016 profesjonalnie; od 2019 Unreal profesjonalnie), 10-30 projektów w Unity, 5-6 w Unreal \item \textbf{Respondent 5}: 9 lat doświadczenia zawodowego (od 2012 Unity amatorsko, od 2016 profesjonalnie; od 2019 Unreal profesjonalnie), 10-30 projektów w Unity, 5-6 w Unreal.
\item \textbf{Respondent 6}: Dekada doświadczenia amatorskiego w Unity, kilka projektów game jamowych \item \textbf{Respondent 6}: Dekada doświadczenia amatorskiego w Unity, kilka projektów game jamowych.
\item \textbf{Respondent 7}: 9 lat hobbystycznego doświadczenia w Unity, 2 lata profesjonalnego; 1-1,5 roku amatorskiego w Unreal \item \textbf{Respondent 7}: 9 lat hobbystycznego doświadczenia w Unity, 2 lata profesjonalnego; 1-1,5 roku amatorskiego w Unreal.
\item \textbf{Respondent 8}: 2 lata amatorsko w Unity, 1,5 roku profesjonalnie + pół roku stażu w Unreal, kilkanaście projektów w obu silnikach \item \textbf{Respondent 8}: 2 lata amatorsko w Unity, 1,5 roku profesjonalnie + pół roku stażu w Unreal, kilkanaście projektów w obu silnikach.
\end{itemize} \end{itemize}
@ -46,7 +46,7 @@ Wybór Unreal Engine często był podyktowany specyfiką projektu lub wymaganiam
W zakresie dokumentacji oficjalnej respondenci wyraźnie faworyzowali Unity. Dokumentacja tego silnika była opisywana jako dogłębna i szczegółowa -- praktycznie wszystkie klasy, metody i właściwości są dokładnie opisane, a dodatkowo często zawierają działające przykłady kodu, które można bezpośrednio skopiować i uruchomić w projekcie. W zakresie dokumentacji oficjalnej respondenci wyraźnie faworyzowali Unity. Dokumentacja tego silnika była opisywana jako dogłębna i szczegółowa -- praktycznie wszystkie klasy, metody i właściwości są dokładnie opisane, a dodatkowo często zawierają działające przykłady kodu, które można bezpośrednio skopiować i uruchomić w projekcie.
Dokumentacja Unreal Engine była oceniana znacznie gorzej. Respondenci Dokumentacja Unreal Engine była oceniana znacznie gorzej. Respondenci
\\ określali ją jako szkieletową lub wręcz nieistniejącą w~praktycznym określali ją jako szkieletową lub wręcz nieistniejącą w~praktycznym
sensie. Wiele stron dokumentacji zawiera jedynie nazwę funkcji i~nazwy sensie. Wiele stron dokumentacji zawiera jedynie nazwę funkcji i~nazwy
parametrów, bez jakiegokolwiek opisu działania. Jeden z~respondentów parametrów, bez jakiegokolwiek opisu działania. Jeden z~respondentów
porównał czytanie dokumentacji Unreal do przeglądania plików porównał czytanie dokumentacji Unreal do przeglądania plików
@ -60,9 +60,9 @@ W przypadku materiałów nieoficjalnych (YouTube, blogi, fora) Unity również d
Poradniki do Unreal Engine były oceniane jako: Poradniki do Unreal Engine były oceniane jako:
\begin{itemize} \begin{itemize}
\item Mniej liczne niż dla Unity \item Mniej liczne niż dla Unity.
\item Często nieaktualne -- dotyczące starszych wersji silnika (np. Unreal 4), które mogą, ale nie muszą działać w nowszych wersjach \item Często nieaktualne -- dotyczące starszych wersji silnika (np. Unreal 4), które mogą, ale nie muszą działać w nowszych wersjach.
\item Zbyt skoncentrowane na systemie Blueprints kosztem programowania w C++ \item Zbyt skoncentrowane na systemie Blueprints kosztem programowania w C++.
\end{itemize} \end{itemize}
@ -79,7 +79,7 @@ Architektura Unity oparta na komponentach była oceniana pozytywnie pod względe
Jednocześnie wskazywano na problemy wynikające z długu technologicznego Unity. Silnik jest bardzo monolityczny, z głęboką hierarchią dziedziczenia podstawowych konceptów. Niektóre obiekty bazowe zajmują tak dużo pamięci, że nie mieszczą się w pojedynczej linii cache procesora, co na współczesny hardware stanowi istotny problem wydajnościowy. Jednocześnie wskazywano na problemy wynikające z długu technologicznego Unity. Silnik jest bardzo monolityczny, z głęboką hierarchią dziedziczenia podstawowych konceptów. Niektóre obiekty bazowe zajmują tak dużo pamięci, że nie mieszczą się w pojedynczej linii cache procesora, co na współczesny hardware stanowi istotny problem wydajnościowy.
Architektura Unreal Engine wymusza bardziej uporządkowany \\ styl pracy. Respondenci zauważali, Architektura Unreal Engine wymusza bardziej uporządkowany styl pracy. Respondenci zauważali,
że nawet podstawowe projekty tworzone w Unreal mają tendencję do bycia lepiej zorganizowanymi, że nawet podstawowe projekty tworzone w Unreal mają tendencję do bycia lepiej zorganizowanymi,
ponieważ silnik narzuca określoną strukturę. ponieważ silnik narzuca określoną strukturę.
@ -94,14 +94,14 @@ Respondenci zauważyli, że Unreal Engine jest wyraźnie zoptymalizowany pod gry
Czas kompilacji w Unity był identyfikowany jako znaczący problem przy większych projektach. W miarę rozrastania się bazy kodu, czas potrzebny na rekompilację po każdej zmianie rośnie. Czas kompilacji w Unity był identyfikowany jako znaczący problem przy większych projektach. W miarę rozrastania się bazy kodu, czas potrzebny na rekompilację po każdej zmianie rośnie.
Unity oferuje mechanizm Assembly Definitions jako rozwiązanie tego \\ Unity oferuje mechanizm Assembly Definitions jako rozwiązanie tego
problemu. Bez podziału projektu na osobne assemblies każda zmiana w~kodzie powoduje rekompilację całego projektu. Podział na mniejsze moduły pozwala kompilować tylko zmienione fragmenty, znacząco skracając czas iteracji. problemu. Bez podziału projektu na osobne assemblies każda zmiana w~kodzie powoduje rekompilację całego projektu. Podział na mniejsze moduły pozwala kompilować tylko zmienione fragmenty, znacząco skracając czas iteracji.
Istotną różnicą między silnikami jest obsługa błędów krytycznych. W Unity gra uruchomiona w edytorze działa jako osobny proces -- gdy wystąpi błąd krytyczny, zamyka się tylko ten proces, a edytor pozostaje stabilny. W Unreal Engine silnik i gra działają jako jeden proces, więc crash w grze powoduje utratę całego edytora wraz z ewentualnymi niezapisanymi zmianami. Istotną różnicą między silnikami jest obsługa błędów krytycznych. W Unity gra uruchomiona w edytorze działa jako osobny proces -- gdy wystąpi błąd krytyczny, zamyka się tylko ten proces, a edytor pozostaje stabilny. W Unreal Engine silnik i gra działają jako jeden proces, więc crash w grze powoduje utratę całego edytora wraz z ewentualnymi niezapisanymi zmianami.
Ta różnica architekturalna ma istotne konsekwencje dla produktywności, \\ Ta różnica architekturalna ma istotne konsekwencje dla produktywności,
szczególnie przy debugowaniu. Przy dużych projektach, gdzie uruchomienie \\ szczególnie przy debugowaniu. Przy dużych projektach, gdzie uruchomienie
silnika może trwać kilkanaście minut, każdy crash oznacza znaczną stratę czasu. silnika może trwać kilkanaście minut, każdy crash oznacza znaczną stratę czasu.
@ -113,8 +113,8 @@ Unreal Engine był krytykowany za problemy z kompatybilnością między wersjami
Współpraca z systemem Git była oceniana lepiej dla Unity ze względu na tekstową serializację assetów. Pliki scen i prefabów w Unity są zapisywane w formacie YAML, co teoretycznie umożliwia ich mergowanie. Nowoczesne narzędzia (np. merge w Rider) potrafią automatycznie rozwiązywać niektóre konflikty na scenach. Współpraca z systemem Git była oceniana lepiej dla Unity ze względu na tekstową serializację assetów. Pliki scen i prefabów w Unity są zapisywane w formacie YAML, co teoretycznie umożliwia ich mergowanie. Nowoczesne narzędzia (np. merge w Rider) potrafią automatycznie rozwiązywać niektóre konflikty na scenach.
Pliki binarne w Unreal Engine stanowią znaczące wyzwanie. Respondenci \\ Pliki binarne w Unreal Engine stanowią znaczące wyzwanie. Respondenci
zwracali uwagę, że nawet pliki Blueprintów, które ewidentnie mają serializację \\ zwracali uwagę, że nawet pliki Blueprintów, które ewidentnie mają serializację
tekstową, są zapisywane na dysku jako binaria. To znacznie utrudnia współpracę wielu programistów nad tym samym projektem. tekstową, są zapisywane na dysku jako binaria. To znacznie utrudnia współpracę wielu programistów nad tym samym projektem.
@ -131,27 +131,27 @@ Blueprinty w Unreal Engine były postrzegane jako skuteczne narzędzie ułatwiaj
Jednocześnie integracja Blueprintów z kodem C++ nie jest idealna. Przejście między oboma systemami wymaga dodatkowej pracy, a wystawianie funkcji C++ do Blueprintów nie zawsze działa bezproblemowo. Jednocześnie integracja Blueprintów z kodem C++ nie jest idealna. Przejście między oboma systemami wymaga dodatkowej pracy, a wystawianie funkcji C++ do Blueprintów nie zawsze działa bezproblemowo.
Unity wymaga więcej pracy przy tworzeniu narzędzi dla osób \\ Unity wymaga więcej pracy przy tworzeniu narzędzi dla osób
nietechnicznych. Respondenci wskazywali, że w~Unreal Engine osoby \\ nietechnicznych. Respondenci wskazywali, że w~Unreal Engine osoby
nietechniczne mają lepsze wsparcie ,,out of the box'', podczas gdy nietechniczne mają lepsze wsparcie ,,out of the box'', podczas gdy
w~Unity \\ zazwyczaj trzeba przeprowadzać szkolenia lub tworzyć w~Unity zazwyczaj trzeba przeprowadzać szkolenia lub tworzyć
dedykowane \\ narzędzia edytorowe, aby umożliwić artystom dedykowane narzędzia edytorowe, aby umożliwić artystom
i~designerom samodzielną pracę. i~designerom samodzielną pracę.
\subsection{Asset Store i zasoby zewnętrzne} \subsection{Asset Store i zasoby zewnętrzne}
\label{subsec:asset-store} \label{subsec:asset-store}
Asset Store Unity był oceniany jako lepiej zarządzany i bogatszy. \\ Asset Store Unity był oceniany jako lepiej zarządzany i bogatszy.
Respondenci wskazywali na silniejsze wsparcie społeczności i większe szanse na Respondenci wskazywali na silniejsze wsparcie społeczności i większe szanse na
znalezienie potrzebnych zasobów. znalezienie potrzebnych zasobów.
Interesującą obserwacją było to, że najlepsze produkty z Asset Store mają tendencję do Interesującą obserwacją było to, że najlepsze produkty z Asset Store mają tendencję do
opuszczania platformy -- twórcy zakładają własne \\ strony internetowe po osiągnięciu określonego opuszczania platformy -- twórcy zakładają własne strony internetowe po osiągnięciu określonego
poziomu popularności. poziomu popularności.
Unreal Marketplace przeszedł niedawno transformację w~platformę Fab, \\ Unreal Marketplace przeszedł niedawno transformację w~platformę Fab,
co według respondentów pogorszyło doświadczenie użytkownika \\ co według respondentów pogorszyło doświadczenie użytkownika
i~zwiększyło liczbę kroków potrzebnych do pobrania darmowych zasobów. i~zwiększyło liczbę kroków potrzebnych do pobrania darmowych zasobów.
@ -162,7 +162,7 @@ Assety były rekomendowane głównie do prototypowania, nie do produkcji komercy
Większość respondentów miała ograniczone doświadczenia Większość respondentów miała ograniczone doświadczenia
\\ z~wykorzystaniem AI w~pracy z~silnikami gier. Główna obserwacja z~wykorzystaniem AI \\ w~pracy z~silnikami gier. Główna obserwacja
dotyczyła niskiej jakości generowanego kodu -- naprawianie błędów dotyczyła niskiej jakości generowanego kodu -- naprawianie błędów
w~kodzie wygenerowanym przez ChatGPT często zajmowało więcej czasu w~kodzie wygenerowanym przez ChatGPT często zajmowało więcej czasu
niż napisanie rozwiązania od podstaw. niż napisanie rozwiązania od podstaw.
@ -178,7 +178,7 @@ Pozytywne doświadczenia zgłoszono w zakresie generowania placeholderów grafic
\label{subsec:optymalizacja} \label{subsec:optymalizacja}
Respondenci wskazywali, że Unity ma mniejszy narzut wydajnościowy niż \\ Respondenci wskazywali, że Unity ma mniejszy narzut wydajnościowy niż
Unreal dla prostych projektów. Czas ładowania projektów w~Unity jest znacznie krótszy, co respondenci przypisywali domyślnie niższym rozdzielczościom tekstur i~prostszym ustawieniom graficznym. Unreal dla prostych projektów. Czas ładowania projektów w~Unity jest znacznie krótszy, co respondenci przypisywali domyślnie niższym rozdzielczościom tekstur i~prostszym ustawieniom graficznym.
@ -191,8 +191,8 @@ Problem garbage collectora w Unity był wielokrotnie wspominany jako znany probl
\label{subsec:przyszlosc} \label{subsec:przyszlosc}
Nowy system DOTS/ECS w Unity był oczekiwaną funkcjonalnością, \\ która w momencie przeprowadzania Nowy system DOTS/ECS w Unity był oczekiwaną funkcjonalnością, która w momencie przeprowadzania
wywiadów została już oficjalnie wydana. \\ System ten pozwala na pisanie wysoce wydajnego, wywiadów została już oficjalnie wydana. System ten pozwala na pisanie wysoce wydajnego,
zorientowanego na dane kodu, kosztem większej złożoności programistycznej. zorientowanego na dane kodu, kosztem większej złożoności programistycznej.
@ -201,13 +201,13 @@ Nowy system UI w Unity (UI Toolkit) był wskazywany jako obszar wymagający popr
Część respondentów wyraziła zainteresowanie silnikiem Godot jako alternatywą dla Unity i Unreal. Główne przyczyny to: Część respondentów wyraziła zainteresowanie silnikiem Godot jako alternatywą dla Unity i Unreal. Główne przyczyny to:
\begin{itemize} \begin{itemize}
\item Model licencyjny royalty-free (brak opłat od przychodów) \item Model licencyjny royalty-free (brak opłat od przychodów).
\item Otwarte źródła umożliwiające modyfikację silnika \item Otwarte źródła umożliwiające modyfikację silnika.
\item Mniejsza złożoność ułatwiająca naukę \item Mniejsza złożoność ułatwiająca naukę.
\item Kontrowersje związane z próbą zmiany modelu licencyjnego Unity w 2023 roku \item Kontrowersje związane z próbą zmiany modelu licencyjnego Unity w 2023 roku.
\end{itemize} \end{itemize}
Respondenci przewidywali, że jeśli Unity nie poprawi swojego wizerunku \\ Respondenci przewidywali, że jeśli Unity nie poprawi swojego wizerunku
i~oferty, Godot może w~przyszłości stać się poważną konkurencją w~segmencie gier indie. i~oferty, Godot może w~przyszłości stać się poważną konkurencją w~segmencie gier indie.
\newpage \newpage
\subsection{Podsumowanie wyników badań jakościowych} \subsection{Podsumowanie wyników badań jakościowych}
@ -216,28 +216,28 @@ i~oferty, Godot może w~przyszłości stać się poważną konkurencją w~segmen
Na podstawie przeprowadzonych wywiadów można sformułować następujące wnioski: Na podstawie przeprowadzonych wywiadów można sformułować następujące wnioski:
\begin{itemize} \begin{itemize}
\item Wysoka jakość oficjalnej dokumentacji \item Wysoka jakość oficjalnej dokumentacji.
\item Bogaty ekosystem materiałów edukacyjnych \item Bogaty ekosystem materiałów edukacyjnych.
\item Niższy próg wejścia dla początkujących \item Niższy próg wejścia dla początkujących.
\item Lepsza integracja z systemami kontroli wersji (tekstowa serializacja) \item Lepsza integracja z systemami kontroli wersji (tekstowa serializacja).
\item Przystępny język programowania (C\#) \item Przystępny język programowania (C\#).
\item Elastyczna architektura komponentowa \item Elastyczna architektura komponentowa.
\item Mniejszy narzut wydajnościowy dla prostych projektów \item Mniejszy narzut wydajnościowy dla prostych projektów.
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Wymuszona struktura projektu promująca dobre praktyki \item Wymuszona struktura projektu promująca dobre praktyki.
\item System Blueprints ułatwiający współpracę z osobami \\ nietechnicznymi \item System Blueprints ułatwiający współpracę z osobami nietechnicznymi.
\item Więcej gotowych funkcjonalności ,,out of the box'' \item Więcej gotowych funkcjonalności ,,out of the box''.
\item Lepsze wsparcie dla projektów wysokobudżetowych (grafika, multiplayer) \item Lepsze wsparcie dla projektów wysokobudżetowych (grafika, multiplayer).
\item Dostęp do kodu źródłowego silnika \item Dostęp do kodu źródłowego silnika.
\item Lepsza integracja z zewnętrznymi narzędziami graficznymi (np. Blender) \item Lepsza integracja z zewnętrznymi narzędziami graficznymi (np. Blender).
\end{itemize} \end{itemize}
\begin{itemize} \begin{itemize}
\item Trudności z mergowaniem assetów graficznych w systemach kontroli wersji \item Trudności z mergowaniem assetów graficznych w systemach kontroli wersji.
\item Poradniki koncentrujące się na implementacji kosztem dobrych praktyk \item Poradniki koncentrujące się na implementacji kosztem dobrych praktyk.
\item Problemy z kompatybilnością między wersjami silników \item Problemy z kompatybilnością między wersjami silników.
\end{itemize} \end{itemize}
Na podstawie wywiadów można zasugerować następujące kryteria wyboru silnika: Na podstawie wywiadów można zasugerować następujące kryteria wyboru silnika:
@ -263,6 +263,6 @@ Wymagania graficzne & Standardowe & Wysokie \\
\end{tabular} \end{tabular}
\end{table} \end{table}
Wyniki badań jakościowych uzupełniają obiektywne testy wydajnościowe \\ Wyniki badań jakościowych uzupełniają obiektywne testy wydajnościowe
przedstawione w~rozdziale \ref{sec:testy-wydajnosci}, dostarczając \\ przedstawione w~rozdziale \ref{sec:testy-wydajnosci}, dostarczając
kontekstu praktycznego użytkowania obu silników w~rzeczywistych \\ projektach. kontekstu praktycznego użytkowania obu silników w~rzeczywistych projektach.

108
scripts/fix_item_dots.py Normal file
View File

@ -0,0 +1,108 @@
#!/usr/bin/env python3
"""Add missing periods at the end of \\item entries in LaTeX files."""
import re
import os
def process_file(filepath):
with open(filepath, 'r') as f:
lines = f.readlines()
modified = False
in_lstlisting = False
for i in range(len(lines)):
line = lines[i]
# Track lstlisting/verbatim environments
if re.search(r'\\begin\{(lstlisting|verbatim)\}', line):
in_lstlisting = True
if re.search(r'\\end\{(lstlisting|verbatim)\}', line):
in_lstlisting = False
continue
if in_lstlisting:
continue
# Check if this line is a boundary (start of next item or end of list)
is_boundary = (
bool(re.match(r'\s*\\item\b', line)) or
bool(re.match(r'\s*\\end\{(itemize|enumerate|description)\}', line.strip()))
)
if not is_boundary:
continue
# Find the previous non-empty line
j = i - 1
while j >= 0 and lines[j].strip() == '':
j -= 1
if j < 0:
continue
prev_stripped = lines[j].strip()
if not prev_stripped:
continue
# Skip structural/non-content lines
skip_patterns = [
r'^\\begin\{',
r'^\\end\{',
r'^\\hline',
r'^\\label',
r'^%',
r'^\\centering',
r'^\\caption',
r'^\\\\$', # bare line break
r'^\\clearpage',
r'^\\newpage',
r'^\\raggedbottom',
r'^\\small$',
r'^\\footnotesize$',
r'^\\endgroup',
r'^\\begingroup',
]
if any(re.match(p, prev_stripped) for p in skip_patterns):
continue
last_char = prev_stripped[-1]
if last_char not in '.?!':
lines[j] = lines[j].rstrip() + '.\n'
modified = True
display = prev_stripped[-70:] if len(prev_stripped) > 70 else prev_stripped
print(f" L{j+1}: {display} -> +dot")
if modified:
with open(filepath, 'w') as f:
f.writelines(lines)
return True
return False
tex_dir = '/home/kuhy/praca_magisterska/latex/tex'
files = [
'1-wstep.tex',
'2-przeglad-literatury.tex',
'3-silniki-gier.tex',
'4-metodologia.tex',
'5-testy-wydajnosci.tex',
'6-analiza-mozliwosci.tex',
'7-porownanie-wynikow.tex',
'8-podsumowanie.tex',
'narzedzia-profilowania.tex',
'implementacja-gry.tex',
'wywiady-analiza.tex',
]
changes = 0
for f in files:
path = os.path.join(tex_dir, f)
print(f"\n=== {f} ===")
if process_file(path):
changes += 1
else:
print(" No changes needed")
print(f"\n\nModified {changes} files")