Post on 03-Jan-2016
description
Wykład 4.
Rendering - informacje podstawowe
Programowanie gier komputerowychTomasz Martyn
OpenGL vs. DirectX (The API Wars)
Z punktu widzenia dzisiejszego programowania gier:
• Direct3D− jest najczęściej wykorzystywanym przez profesjonalnych deweloperów
gier API graficznym na platformie Microsoft Windows
− jest de facto jedynym API graficznym na platformach konsolowych Microsoft XBox i Xbox 360 oraz mobilnych Windows Phone
• OpenGL (i jego warianty, np. OpenGL ES) − jest wieloplatformowy – sterowniki OpenGLa istnieją dla prawie każdego
sprzętu 3D
− jest nadal popularny wśród programistów gier na platformie Microsoft Windows
− jest standardem de facto na platformach Mac OS i iPhone, linuksowych (PC i wiele smartfonów - Android), Nintendo, Sony
Wniosek: Jeżeli tworzona gra jest przeznaczona na różne platformy, wówczas w silniku gry warto utworzyć warstwę abstrakcji renderera, która oddziela konkretne API graficzne od reszty modułów silnika.
OpenGL vs. OpenGL i DirectX vs. DirectX
Jednakże nawet w ramach konkretnego API bywają duże różnice w odniesieniu do jego poszczególnych wersji, które powodują, że w implementacji interfejsu renderera różne wersje danego API muszą być traktowane odrębnie.
Z punktu widzenia przenoszenia gier na różne platformy, największą zmianą było odejście (w obydwu API) od wspierania postulatu wsteczniej kompatybilności.
Zmiana ta odbyła się za sprawą usunięcia funkcjonalności stałego potoku graficznego (fixed-function pipeline) na rzecz potoku programowanego (programmable pipeline) przy użyciu shaderów.
Nastąpiło to wraz z wprowadzaniem wersji OpenGL 3.1 (odpowiednio OpenGL ES 2.0) oraz DirectX 10.
Ewolucja potoku graficznego (1)
stały potok (OpenGL 1.5, DirectX 7)
programowalny potok Shader Model 2 i 3 (OpenGL 2.0, DirectX 9)
Ewolucja potoku graficznego (2)
programowalny potok Shader Model 4 (OpenGL 3.0, DirectX 10)
programowalny potok Shader Model 5 (OpenGL 4.0, DirectX 11)
Potok transformacji współrzędnych wierzchołków
• w stałym potoku poszczególne transformacje przekazywane są do potoku za pośrednictwem odpowiednich funkcji API i potok sam stosuje je do nadchodzących wierzchołków
• w programowalnym potoku OpenGL 2.0 jest prawie tak samo, za wyjątkiem faktu, że o zastosowanie transformacji do wierzchołków musimy zadbać sami w kodzie shadera wierzchołków (transformacje są widoczne jako zmienne wbudowane)
• w programowalnych potokach OpenGL 3.0 i 4.0 oraz DirectX transformacje przekazywane są do shadera wierzchołków po prostu jako jedne z jego możliwych parametrów (zmienne uniform – OpenGL i DirectX 9 lub bufory stałych cbuffer – DirectX 10 i 11)
Lewoskrętny i prawoskrętny układ współrzędnych
DirectX OpenGL (i XNA)
Aby przejść z jednego układu na drugi trzeba zastosować do wizualizowanego świata odbicie zwierciadlane w płaszczyźnie XY.
Czasem należy również zmienić kierunek „nawinięcia” (winding) wielokątów w siatkach na przeciwny (w przypadku gdy stosowany jest backface culling) w celu określenia widocznej strony wielokąta.
Domyślnie OpenGL uznaje wielokąty o nawinięciu przeciwnym do ruchu wskazówek zegara za ułożone przodem, zaś DirectX (i XNA) wprost przeciwnie.
Przestrzeń modelu
Przestrzenią modelu (model space, local space) nazywany jest układ współrzędnych skojarzony bezpośrednio z danym modelem, zwykle w procesie modelowania.
W konsekwencji, z każdym z modeli związany jest odrębny układ współrzędnych modelu, względem którego określone są wartości współrzędnych wierzchołków siatki wielokątów.
Przestrzeń świata Współrzędne wierzchołków danego modelu określone w przestrzeni modelu przekształcane
są do przestrzeni świata (world space, global space), która jest układem współrzędnych związanych z wizualizowaną sceną.
Transformacja danego modelu do przestrzeni świata dokonywana jest przy użyciu – związanego z tym modelem - przekształcenia świata (world transformation), które jest wyznaczane w procesie komponowania sceny i ew. aktualizowane na bieżąco w przypadku modelu dynamicznie przemieszczającego się po scenie (w przypadku modeli statycznych odwzorowanie jest stałe).
Stały potok DirectX
Stały potok OpenGL i programowalny OpenGL 2.0
Przestrzeń kamery
Następnie, współrzędne wierzchołków przekształcane są do przestrzeni kamery (view space, camera space), która jest układem współrzędnych związanych z punktem położenia kamery (obserwatora) w świecie i kierunkiem jej „patrzenia”.
Transformacja ta dokonywana jest przy użyciu – związanego z kamerą - przekształcenia obserwatora (view transformation), które jest wyznaczane w procesie komponowania sceny i następnie aktualizowane na bieżąco gdy kamera przemieszcza się po scenie.
Stały potok DirectX
Stały potok OpenGL i programowalny OpenGL 2.0
Przekształcenie rzutowania (1)Ostrosłup widzenia
Ostrosłup widzenia (frustum) można rozpatrywać jako uproszczony model kamery.
Jest on zdefiniowany przez:
• kąt widzenia (field of view) mierzony zwykle w pionie (fovy)
• przednią i tylną płaszczyznę obcinania
• stosunek szerokości do wysokości (aspect ratio) powierzchni (matrycy), na którą jest rzutowany obraz „postrzegany” przez kamerę
Przekształcenie rzutowania (2)Znormalizowane współrzędne urządzenia
Na podstawie parametrów ostrosłupa widzenia konstruowane jest przekształcenie rzutowania perspektywicznego. 1. Przekształcenie to najpierw sprowadza – przy użyciu macierzy rzutowania
perspektywicznego - współrzędne wierzchołków w przestrzeni kamery do tzw. jednorodnej przestrzeni obcinania (homogeneous clip space, projection space), w której ma m.in. miejsce operacja obcinania wielokątów wzgl. bryły widzenia.
2. Następnie ma miejsce operacja dzielenia perspektywicznego współrzędnych wierzchołków, w wyniku której współrzędne te sprowadzane są do układu znormalizowanych współrzędnych urządzenia (NDC). Stosując standardową macierz rzutowania konkretnego API otrzymamy:
a. współrzędne x i y [-1, 1]
b. współrzędna z [-1, 1] w OpenGL oraz z [0, 1] w DirectX.
Stały potok DirectX
Stały potok OpenGL i programowalny OpenGL 2.0
Przekształcenie widoku
W ostatniej fazie potoku przekształceń współrzędne wierzchołków przekształcane są przy wykorzystaniu transformacji widoku (viewport transformation) w celu wyświetlenia we wskazanym „widoku” (viewport), tj. prostokątnym obszarze okna .
Okno może posiadać kilka widoków (np. ukazujących obraz sceny z różnych kamer).
DirectX 9 (DirectX 10 i 11 podobnie – funkcje RSSetViewports() interfejsów, odpowiednio, ID3D10Device i ID3D11DeviceContext
OpenGL
Podstawowe zasoby renderera
Podstawowe zasoby, które powinien obsługiwać renderer to:
• geometria – wyrażana jest w języku wierzchołków i ich atrybutów (położenie, kolor, normalne, współrzędne tekstur, ...) i reprezentowana przez bufory wierzchołków i indeksów
• współczynniki globalne materiałów – opisują globalne właściwości optyczne danej geometrii istotne z punktu widzenia interakcji ze światłem (współczynnik rozproszenia, współczynnik odbicia, etc.)
• tekstury – opisują lokalne właściwości optyczne danej geometrii
• shadery – definiują sposób działania programowalnych części potoku graficznego
• stany renderingu (render states) – określają parametry i właściwości nieprogramowalnych części potoku graficznego, które można zmieniać (mieszanie i test alfa, włączanie i wyłączanie z-bufora, backface culling, ...)
Współczynniki globalne materiałów, tekstury, shadery i stany renderingu często wykorzystywane są łącznie do zdefiniowania materiału.
• światła
• kamery (i skojarzone z nimi widoki - viewports)
• bufory renderingu (render targets) - bufor kolorów, z-bufor, bufor szablonu,...
• czcionki
• ...