Managed » Direct3D

7. Obsługa kamery

Spis treści

     1 Wstęp
     2 Ustawienie kamery
     3 Ustawienie świata
     4 Wygładzanie pełnoekranowe
     5 Kod źródłowy


Wstęp


W poprzednim kroku 6. Wyświetlanie figur w przestrzeni 3D wykonaliśmy aplikację, która renderowała obiekty w przestrzeni 3D. Teraz rozbudujemy ją o dynamiczny ruch kamery.

Okno aplikacji ze statyczną sceną i ruchomą kamerą
<center>Rys. 5. Okno aplikacji ze statyczną sceną i ruchomą kamerą</center>

Oczywiście można ten problem rozwiązać przesuwając obiekty samej sceny, przez manipulację ich współrzędnych. Jednak nie jest to ani konieczne, ani zalecane. Direct3D oferuje do tego doskonałe narzędzie: macierze widoku (View Matrix), projekcji (Projection Matrix oraz świata (World Matrix).

Ustawienie kamery


Konfiguracja kamery wymaga określenia współrzędnych kamery, punktu obserwowanego, wektora wskazującego górę (dla zorientowania kamery). Dodatkowo należy określić kąt widzenia, proporcje obrazu, minimalny i maksymalny zakres położenia obiektów, uwzględnianych w renderowaniu.

Macierze należy odpowiednio wypełnić przed funkcją device.EndScene. Pierwsze z tych parametrów opisuje macierz widoku, pozostałe macierz projekcji:

device.Transform.View = Matrix.LookAtLH(
        new Vector3((float)Math.Cos(time/1000f)*5f, 1f, (float)Math.Sin(time/1000f)*5f),
        new Vector3(0f, 0f, 0f),
        new Vector3(0f, 1f, 0f));
 
device.Transform.Projection = Matrix.PerspectiveFovLH(
        (float)Math.PI/4f,
        parent.Width/parent.Height,
        1f,
        100f);


W powyższym przykładzie macierz widoku wypełniono w następujący sposób:
  • pozycja kamery jest zależna od czasu; kamera porusza się po okręgu o promieniu 5, w płaszczyźnie XZ dla Y równego 1.
  • kamera obserwuje środek układu współrzędnych
  • kamera jest obrócona tak, że góra ekranu odpowiada kierunkowi osi Y

Macierz projekcji wypełniono w następujący sposób:
  • kamera obejmuje kąt 90 stopni (PI/4 w obie strony)
  • kamera renderuje obraz w proporcjach wysokość/szerokość okna (dla trybu pełnoekranowego można na przykład podać stałą 4/3f lub 16/9f).
  • kamera renderuje obiekty dalsze niż 1 jednostka
  • kamera renderuje obiekty bliższe niż 100 jednostek

Ustawienie świata


Dodatkowo programista dostaje do dyspozycji macierz skierowania świata. Pozwala ona na przesunięcie układu współrzędnych. Można wykorzystać ją w taki sposób:

device.Transform.World = Matrix.Translation(0f, 1f, 0f) * Matrix.RotationX((float)Math.PI);


Mnożenie macierzy przesunięcia (o 1 w osi Y) oraz macierzy obrotu (o 180 stopni w osi X) da nam macierz transformacji, którą ustawimy jako macierz świata. Dzięki temu, mimo ustawienia kamery w określonym miejscu, renderowane obiekty będą posiadały inne współrzędne niż domyślnie.

Wygładzanie pełnoekranowe


Jak dotąd, renderowaliśmy obraz bez jakiegokolwiek wygładzania. Włączenie tego mechanizmu, choć wymagające obliczeniowo, jest nieskomplikowane - wystarczy znów zmodyfikować parametry urządzenia przed jego utworzeniem:

//Próbkowanie podwójne lub wyższe, wspierane przez urządzenie
presentParameters.MultiSample = MultiSampleType.TwoSamples; 
presentParameters.MultiSampleQuality = 0;


Podczas renderowania warto upewnić się, że w międzyczasie nie zmieniliśmy stanu renderowania na pomijający antialiasing:

device.RenderState.AntiAliasedLineEnable = true;
device.RenderState.MultiSampleAntiAlias = true;


Kod źródłowy


Całość kodu źródłowego projektu: d3dkurs7.zip (5,63 KB)