Realistyczny rendering dla potrzeb gier komputerowych Projekt i realizacja przykładowego silnika Piotr Turecki Praca magisterska pod kierunkiem dr Witolda Aldy Katedra Informatyki – AGH Kraków 2007
Plan prezentacji Cel pracy Budowa i działanie silnika Przedstawienie możliwości renderera Demonstracja możliwości silnika Podsumowanie
Cel pracy „Profesjonalny” silnik do gier o następujących cechach: Budowa i działanie podobne do produktów komercyjnych Podział na komponenty Możliwość uruchomienia w oknie aplikacji napisanej w MFC Łatwo „obudować” okno silnika w rozbudowany interfejs użytkownika (np. Edytor) Łatwa modyfikacja zawartości gry Widok w edytorze jest identyczny z widokiem z poziomu gry
Cel pracy Nacisk położony na grafikę Pozostałe podsystemy nieobecne lub mocno ograniczone Wykorzystanie najnowszych (już nie) technologii graficznych (DX9.0) Rozbudowany system materiałów Możliwość zdefiniowania praktycznie dowolnego typu powierzchni
Cel pracy Realistyczny rendering Dla potrzeb gier Czyli poprawny fizycznie Dla potrzeb gier Czyli szybki Poprawny fizycznie i szybki Czyli praktycznie niemożliwy Trzeba znaleźć kompromis! Szczegóły w dalszych przykładach
Budowa silnika Podział systemu na komponenty: Silnik (GameEngine.dll) Łatwo uaktualnić do nowszej wersji Gra (Game.dll) Cała logika gry – jw. łatwo uaktualnić Potrzebne dla edytora Moduł uruchomienia gry (Game.exe) Korzysta z Game.dll Edytor świata gry Korzysta z Game.dll i GameEngine.dll
W rzeczywistości edytor korzysta również bezpośrednio z silnika Budowa silnika Schemat zależności między komponentami Game.exe Game.dll GameEngine.dll Editor.exe W rzeczywistości edytor korzysta również bezpośrednio z silnika
Budowa silnika Funkcjonalność silnika udostępniona jest tylko poprzez interfejsy Funkcjonalność podstawowa, z której korzystają wszystkie komponenty znajduje się w bibliotece statycznej
Działanie silnika w grze Gra inicjalizuje silnik Silnik tworzy okno, w którym renderuje świat gry i które pośredniczy w odbiorze wiadomości od systemu operacyjnego Gra uruchamia blokującą metodę Run silnika Od tej pory kod gry uruchamiany jest przez zarejestrowane wcześniej funkcje Obsługa wejścia, obsługa logiki gry
Działanie silnika w edytorze Nie można wywołać blokującej metody ani przejąć kontroli nad myszką i klawiaturą Edytor inicjalizuje silnik (poprzez interfejs gry!) podając jako parametr już utworzone okno Silnik będzie renderował świat w tym oknie Edytor podczas swojego działania: Cyklicznie wywołuje metodę silnika OnFrame Obsługa logiki wewnątrz silnika Wywoływanie zarejestrowanych funkcji gry Przekazuje do silnika wiadomości od myszki i klawiatury Logika gry jest uruchamiana również w edytorze!
Renderer Najbardziej rozbudowana część silnika Najważniejsze zagadnienia System materiałów Rysowanie sceny
Renderer – system materiałów Jak zaprojektować system materiałów tak aby Umożliwiał łatwe definiowanie materiałów Miał duże możliwości Korzystał z najnowszych technologii Obsługiwał najnowsze efekty Implementacja jednego efektu „nie jest trudna” Trudnością jest obsługa wielu efektów naraz!
Zastosowane rozwiązanie Własny prosty język opisu materiałów Łatwo definiować nowe materiały Dwuczęściowa definicja materiału Klasa materiału - plik *.fx Kod dla karty graficznej Opis właściwości oraz wymagań materiału Definicja parametrów materiału Instancja materiału - plik *.ge_mat Określenie używanych tekstur Określenie wartości parametrów
Renderer – system materiałów Właściwość Typ wierzchołków Plik *.fx param: vertex = Normal; param: ViewPos; bool Specular = true; float Shininess = 50; … kod dla karty graficznej Wymaganie Położenie kamery definicja parametrów
Renderer – system materiałów Plik *.ge_mat material "stone01" { tex[DiffuseMap] = "stone/stucco8.jpg"; tex[BumpMap] = "up.tga"; fx = "Solid.fx" Specular = false; Parallax = false; } Używane tekstury Używany plik *.fx Nadpisanie wartości parametrów
Renderer – Rysowanie sceny Typowa scena składa się z setek obiektów pokrytych różnymi materiałami Trzeba ją narysować szybko Dlaczego to jest takie trudne?
Renderer – Rysowanie sceny Jeden obiekt może być pokryty wieloma materiałami Nie da się rysować obiektu jako całości Kolejność rysowania materiałów ma znaczenie Materiały przezroczyste, załamanie światła Lustra wymagają dwukrotnego rysowania całej sceny Woda, zwykłe lustro Dynamiczne cienie Dodatkowy przebieg głębi dla każdego światła Dla punktowych nawet 6 przebiegów Nowoczesne efekty – zajmują więcej czasu Mapowanie nierówności, cienie, woda, rozbudowane oświetlenie Dodanie nowego efektu często wymaga zmiany w obecnej implementacji W kodzie dla karty graficznej i w C++ Np. dynamiczne cienie – Dużo zmian w przebiegu oświetlenia w C++ i w shaderach A to tylko aspekt graficzny Co z fizyką, logiką, zarządzaniem widocznością, całym procesem rysowania sceny, itp.?
Rozwiązanie Podział sceny na atomowe fragmenty Łatwo posortować i wyświetlić tak aby było najmniej zmian stanu karty graficznej Proces renderowania rozbity na osobne przebiegi Przebieg koloru Przebieg oświetlenia Przebieg rysowania głębi Upraszcza obliczenia w każdym przebiegu i umożliwia zastosowanie bardziej rozbudowanych efektów Np. obsługa wielu świateł z dynamicznymi cieniami
Demonstracja możliwości silnika We wszystkich demach: F1 – zrzut ekranu F2 – automatyczna kamera F3 / F4 – następna / poprzednia kamera F5 x2 – zapis danych kamery Enter – przejęcie kontroli nad myszką Esc – zwolnienie myszki Esc x2 – wyjście Sterowanie kamerą – strzałki + myszka
Wyspa C – zmiana oświetlenia
Duża wyspa – wersja 1
Duża wyspa – wersja 2
Symulacja wody na karcie graficznej
Teren Edycja: S – znak modyfikacji +/- A – zmiany: alpha / vertex 1-4 – aktywna warstwa Obsługa: Wyłącz kamerę – F2 Przywłaszcz myszkę - Enter
Załamanie światła
Parallax mapping
Podsumowanie
Realizacja celu Wszystkie główne założenia zostały zrealizowane Budowa i działanie silnika podobne do produktów komercyjnych Zaawansowana grafika Duże możliwości systemu materiałów Zdobyte doświadczenie oraz wiedza Jednak nie wszystko udało się zrealizować Perspektywiczne mapy cienia Efekty wolumetryczne „Porządny” edytor
Wykorzystanie Dla innych programistów Pomoc w wykładach / ćwiczeniach Wiele problemów jest rozwiązanych, zerknięcie do kodu może oszczędzić wiele czasu Pomoc w wykładach / ćwiczeniach Dobry punkt wyjścia (dokumentacja) Demonstracja różnych efektów
Rozbudowa Autor od początku prac nie planował rozbudowy projektu Projekt służył zapoznaniu się z tego typu zadaniem (jak bardzo to jest trudne?) Zmierzenie się z napotkanymi problemami Zebranie doświadczenia Wszystko po to aby napisać następny – dużo lepszy silnik Nie wyklucza to możliwości rozbudowy lub wykorzystania przez innych
Dziękuję za uwagę