Inne
Artykuł
Maciej Zabłocki, Sobota, 9 września 2017, 16:30

Wiele jest pojęć, którymi posługujemy się w artykułach, a które są trudne do zrozumienia. Jednym z nich jest rasteryzacja, która występuje w kontekście gier w połączeniu z teksturowaniem albo renderowaniem. Postaram się wyjaśnić kilka takich zagadnień, żeby nasi Czytelnicy mogli łatwiej zrozumieć treści, które pojawiają się nie tylko u nas, ale też w innych witrynach. Szczególnie ci, który interesują się grami.

Wykreowany trójwymiarowy świat każdej gry trzeba przekształcić w dwuwymiarowy obraz złożony z pikseli, który może zostać wyświetlony na ekranie. Właśnie ten proces nazywamy rasteryzacją, czyli przedstawieniem grafiki w wersji rastrowej – za pomocą siatki pikseli (albo punktów), z których każdy ma przyporządkowany jakiś kolor. Rasteryzacji mogą podlegać wszystkie obiekty, punkty, krzywe, linie, wierzchołki, łuki czy przekroje stożkowe, które znajdują się w trójwymiarowej scenie. Doskonale pokazuje to poniższe zdjęcie: 

Tutaj widzimy standardową rasteryzację odcinka, łuku i wielokąta zamieszczoną na siatce pikseli

Jak widzicie, podczas standardowej rasteryzacji piksele wychodzą poza kontury figury wyświetlanej na ekranie. Między innymi stąd biorą się tak zwane ząbki w grach, będące efektem rasteryzowania obrazu (czyli spłaszczania go). Istnieje wiele metod usuwania poszarpanych krawędzi, ale w tym artykule wyjaśnię tylko ogólne założenia tego procesu. Najpierw jednak skończmy temat rasteryzacji. 

Wyświetlanie obrazu w grafice 3D

Każdy punkt podczas wyświetlania trójwymiarowej sceny ma swoje współrzędne, określane literami: x, y, z. O ile przeniesienie do 2D pierwszych dwóch jest bardzo proste (wskazują położenie od lewej do prawej i od góry do dołu sceny), o tyle trzeci staje się problematyczny dla każdego z monitorów. Punkt „z” określa „głębokość”, na jakiej obiekt zostanie osadzony. Im jest ona większa, tym dalej obiekt będzie się znajdował od obserwatora (kamery).

W dzisiejszych grach wykorzystujemy 32-bitową głębię obrazu, która zapewnia aż 4 294 967 296 (blisko 4,3 miliarda) możliwych pozycji obiektu. Musimy zatem określić nie tylko to, czy taki piksel zostanie wyświetlony, ale także gdzie to nastąpi. Właśnie w tym pomaga nam parametr głębokości, który dokładnie wskazuje pozycję piksela.

Żeby zrozumieć zasadę wyświetlania obrazu w grafice 3D, trzeba się zaznajomić z pojęciem renderowania. Nazywamy tak proces przekształcenia danych trójwymiarowych w dane dwuwymiarowe. Przekształcenie polega na przeliczeniu danych wejściowych, reprezentujących scenę graficzną, w czego wyniku powstaje obraz dwuwymiarowy. Rendering w uproszczeniu znajduje się pomiędzy obrazem 3D a sceną 2D:

Dane wejściowe stanowią model opisujący trójwymiarowe obiekty w określonym języku programowania lub określonej strukturze danych, zrozumiałej dla elementu renderującego, którym najczęściej jest karta graficzna. Opis programowy może dotyczyć wielkości i koloru obiektów, oświetlenia, położenia obserwatora (lub kamery) czy ruchu obiektów na scenie. W procesie renderowania uwzględniane są różne zjawiska fizyczne, między innymi odbicia promieni, cienie, załamania światła, przezroczystość oraz inne zjawiska optyczne. Powstawanie obrazu 3D można znacząco uprościć przez rozłożenie każdej z takich powierzchni na odpowiednio dużą liczbę wielokątów płaskich, zwykle trójkątów (nazywanych poligonami). Każdy z wierzchołków trójkąta jest zawieszony w przestrzeni 3D za pomocą wspomnianych współrzędnych x, y i z. Jeden obiekt na ekranie może się składać nawet z kilkudziesięciu tysięcy trójkątów, a cała scena – z kilku milionów.

Jak możecie zauważyć, większa liczba poligonów pozwala osiągnąć większą szczegółowość obiektu, co przekłada się na wyższą jakość oprawy graficznej. Niestety, im więcej poligonów, tym większe zapotrzebowanie na moc obliczeniową. Projektowanie trójwymiarowej sceny to proces wielokrotnie złożony, więc przekształcenie sceny 3D na 2D odbywa się wieloetapowo.

Wszystkie te etapy nazywamy potokiem graficznym. Każdy etap potoku graficznego jest stosowany na wszystkich obiektach w danej scenie, w czego wyniku otrzymujemy gotowe do wyświetlenia piksele końcowego obrazu. To właśnie te piksele widzimy na wyświetlaczu. Cały proces renderowania obrazu przez kartę graficzną można okroić do poniższego schematu: 

Bufor ramki (ang. frame buffer) jest gotową klatką animacji 3D. Tworzenie kolejnych ramek przebiega sekwencyjnie, przybierając postać animacji komputerowej, której płynność określamy liczbą klatek na sekundę. Trzyliterowe dopiski oznaczają kolejno: 

  • MCS (Modelling Coordinate System) – lokalny układ współrzędnych jednego obiektu (modelu) osadzonego za pomocą osi x, y, z;
  • WCS (World Coordinate System) – globalny układ współrzędnych x, y i z, opisujący całą scenę, w tym kamerę i oświetlenie;
  • VCS (Viewer Coordinate System) – odwzorowanie z perspektywy kamery, za pomocą której oglądamy daną scenę;
  • NDCS (Normalized Device Coordinate System) – współrzędne znormalizowane, w których punktem odniesienia dalej jest kamera, ale wszystkie punkty rzutowane są na jedną płaszczyznę;
  • SCS (Screen Coordinate System) – współrzędne ekranowe, w których punktem odniesienia zawsze jest lewy górny punkt ekranu.

Potok 3D zostaje wstępnie wygenerowany przez procesor (CPU), który rozpoznaje typ danych i sprawdza, czy ma do czynienia z obrazami, wektorami albo kodem programu. Po przetworzeniu tych informacji CPU przekazuje je do dalszej obróbki. Następnie obiekt jest transformowany, czyli zostaje obrócony i ustawiony zgodnie z wolą projektanta. Tutaj następuje przekształcenie współrzędnych pojedynczego modelu do współrzędnych globalnych, czyli dotyczących całej sceny. Później obliczane jest oświetlenie, czyli GPU jest informowane, które piksele mają zostać wyświetlone w jaśniejszym, odmiennym kolorze. 

Potem jest trochę trudniej, ponieważ wszystkie obiekty znajdujące się na scenie muszą zostać przeniesione do współrzędnych kamery. Zwykle kamera znajduje się w środku układu współrzędnych i jest zwrócona w kierunku ujemnych wartości osi z.

W następnym kroku (rzutowania) współrzędne kamery są przenoszone na dwuwymiarową płaszczyznę (czyli to, co zostanie wyświetlone przez monitor). Wtedy następuje proces obcinania – eliminowania tych pikseli (punktów, wierzchołków), których nie zobaczymy na wyświetlaczu w końcowej scenie. Pozwala to zaoszczędzić moce przerobowe GPU i znacząco wpływa na efektywność renderowania. Karta graficzna już nie uwzględnia w obliczeniach odrzuconych pikseli. 

Są różne sposoby mapowania tekstur

Następnym krokiem jest mapowanie (równie często wspominane w kontekście tworzenia gier komputerowych). Polega na przesunięciu środka układu współrzędnych z miejsca położenia kamery do lewego górnego wierzchołka płaszczyzny ekranu. Dzięki temu karta graficzna wie, w jaki sposób powinna oteksturować daną scenę. Teksturowanie polega na nakładaniu obrazu 2D na obiekt 3D. Nazywamy to mapowaniem tekstur

Pozostaje już tylko proces rasteryzacji, czyli przekształcenia sceny w zbiór pikseli, które zostaną wyświetlone na ekranie monitora.

Jak widzicie, proces wyświetlenia jednej klatki obrazu w dowolnej grze jest bardzo złożony i czasochłonny, a programiści uciekają się do przeróżnych sztuczek, które mogą przyspieszyć te obliczenia. 

Ocena artykułu:
Ocen: 20
Zaloguj się, by móc oceniać
agent_x007 (2017.09.09, 16:42)
Ocena: 12

0%
Świetny artykuł :)
Wreszcie coś technicznego, a nie tylko testy i recenzje.
Tak na przyszłość :
Będzie porównanie Tile based rendering vs. Immediate-mode rendering (tj. Maxwell/Vega vs. Kepler/Polaris) ?
Putout (2017.09.09, 16:47)
Ocena: 7

0%
Technik wygładzania jest od grzmota. Mam nadzieję że dacie też jakieś testy wydajności i jakości technik
GranatXD (2017.09.09, 21:30)
Ocena: 2

0%
Łoo! Super artykuł!
Filip454 (2017.09.10, 01:24)
Ocena: 3

0%
Na PCL wyrastają coraz lepsze artykuły, niczym grzyby po deszczu (po ostatniej sekcji komentarzy użytkowników na temat PCLab w rocznicowym artykule).

Jest bardzo fajnie ;)
ReznoR (2017.09.10, 11:34)
Ocena: 8

0%
Całkiem niezły artykuł, ale jednak nie do końca łatwo jest podążać tokiem rozumowania piszącego - zbyt dużo nazw (czasem brak angielskich odpowiedników, nie wszędzie są - np. culling, mapping) przy zbyt małej ilości łatwej do przyswojenia teorii. Inaczej mówiąc - dużo żargonu, mało wyjaśniania 'o co kaman'. Nawet ja mogę się tutaj pogubić, a co dopiero ci bardziej początkujący czytelnicy. Podczas czytania ciągle miałem wrażenie że w teście jednej ze starszych mikroarchitektur NVidii, kopę lat temu, proces rasteryzacji był przystępniej wyjaśniony - nie świadczy to dobrze. Przez to nie mogę niestety z czystym sumieniem nikomu zalinkować, głównie przez to, że nie jestem do końca pewien, dla jakiego typu czytelników był on napisany. Trochę szkoda...
matekmz (2017.09.10, 11:44)
Ocena: 0

0%
ReznoR @ 2017.09.10 11:34  Post: 1093808
Całkiem niezły artykuł, ale jednak nie do końca łatwo jest podążać tokiem rozumowania piszącego - zbyt dużo nazw (czasem brak angielskich odpowiedników, nie wszędzie są - np. culling, mapping) przy zbyt małej ilości łatwej do przyswojenia teorii. Inaczej mówiąc - dużo żargonu, mało wyjaśniania 'o co kaman'. Nawet ja mogę się tutaj pogubić, a co dopiero ci bardziej początkujący czytelnicy. Podczas czytania ciągle miałem wrażenie że w teście jednej ze starszych mikroarchitektur NVidii, kopę lat temu, proces rasteryzacji był przystępniej wyjaśniony - nie świadczy to dobrze. Przez to nie mogę niestety z czystym sumieniem nikomu zalinkować, głównie przez to, że nie jestem do końca pewien, dla jakiego typu czytelników był on napisany. Trochę szkoda...

Dzięki za fajny komentarz! Wezmę to pod uwagę ;)
revcorey (2017.09.10, 18:29)
Ocena: 2

0%
hmm jak bym otworzył książkę do opengl, wyrzucił kod i większość tekstu. Mam mieszane uczucia, ale to lepsze niż test myszki.
MichagM (2017.09.10, 22:20)
Ocena: 3

33%
Taki ma być artykuł krótki i jasny.
Tak ma być ''J.Polski Techniczny'' a nie zwykły J.Polski
Drugi raz szacunek dla M.Zabłockiego
Zaloguj się, by móc komentować
Artykuły spokrewnione
Facebook
Ostatnio komentowane