May 2008

Uwaga! Informacje na tej stronie mają ponad 6 lat. Nadal je udostępniam, ale prawdopodobnie nie odzwierciedlają one mojej aktualnej wiedzy ani przekonań.

# Praca magisterska o silniku 3D

Fri
30
May 2008

Wiem o istnieniu trzech prac dyplomowych poświęconych silnikowi 3D, jakie dotychczas były obronione w Polsce:

Wkrótce do tego grona dołączy moja praca magisterska:

Właśnie dotarłem do kolejnego kamienia milowego w jej przygotowaniu - praca została wydrukowana i oprawiona :)

Moja praca magisterska

Comments | #rendering #engine #studies Share

# Nowy artykuł - Szybki alokator FreeList

Wed
28
May 2008

Mój następny artykuł nosi tytuł Szybki alokator FreeList. Opisuje przykład implementacji mechanizmu zwanego Free List. Jest to samodzielne zarządznie pamięcią polegające na utrzymywaniu listy wolnych elementów, z której można przydzielać elementy dużo szybciej, niż to robi alokacja pamięci ze sterty standardowym operatorem new. Mój kod oparty jest na artykułach z książek "Game Programming Gems", a przeprowadzony test pokazuje, że faktycznie osiąga on bardzo dobrą wydajność.

Comments | #productions #c++ #algorithms Share

# Nowy artykuł - Preprocesor w shaderach HLSL

Thu
22
May 2008

W następnym artykule opisałem, jak używa się preprocesora w języku shaderów HLSL. Pisząc coś bardziej skomplikowanego niż pojedyncze efekty graficzne - np. silnik - na vertex shader i pixel shader trzeba czasem spojrzeć jak na zestaw ustawień, tak jak w starym dobrym Fixed Function Pipeline. Pojawia się taki problem, że każda kombinacja ustawień to powinien być osobny shader. W artykule przedstawiłem jedno z rozwiązań - kompilowanie kodu HLSL z użyciem proprocesora (#if itp.), z ustawieniami wpisanymi jako wartości makr. Zapraszam do lektury: Preprocesor w shaderach HLSL.

Comments | #rendering #productions #directx Share

# Nowy artykuł - Unicode w Visual C++

Wed
21
May 2008

Mój kolejny artykuł to Unicode w Visual C++. Jest prosty - wymaga tylko znajomości podstaw programowania w C++. Wszystkim tym, którzy kodują pod Windows i z użyciem Visual C++, może pomóc zacząć używać w swoich projektach kodowania znaków Unicode. Trzeba jednak przyznać, że to nie zawsze ma sens - przynosi korzyści tylko jeśli program ma używać plików tekstowych Unicode albo będzie tłumaczony na różne języki. W przeciwym razie szkoda zachodu :)

Comments | #productions #c++ #visual studio Share

# Nowy artykuł - Kwaterniony w praktyce

Tue
20
May 2008

Mój następny artykuł nosi tytuł Kwaterniony w praktyce. Przeznaczony jest dla tych, którzy znają już podstawy matematyki potrzebnej w programowaniu grafiki 3D (wektory, macierze), ale dotychczas omijali temat kwaternionów szerokim łukiem myśląc, że są bardzo trudne. Artykuł pokazuje (mam nadzieję), że nie ma w nich żadnej czarnej magii - są po prostu wygodnym narzędziem do zapisywanie obrotów i orientacji w 3D, z którego można się nauczyć korzystać bez rozumienia, że kwaternion to rozszerzenie liczb zespolonych mające trzy pierwiastki urojone :) Zamiast wzorów pokazałem fragmenty kodu C++.

Comments | #productions #math Share

# Nowy artykuł - Biblioteka FastDelegate

Mon
19
May 2008

Jak wiadomo (zwłaszcza tym, którzy pisali swój system GUI), w języku C++ brakuje mechanizmu wskaźników na metody (a dokładnie - wskaźników na konkretną metodę o zgodnym nagłówku konkretnego obiektu dowolnej klasy), który bywa nazywany delegatami, zdarzeniami, sygnałami i slotami itp. i występuje np. w Delphi czy C#.

Ten brak próbują uzupełnić różne biblioteki - np. sigslot, Boost.Signals oraz moja ulubiona - FastDelegate. Ta ostatnia jest opisana i udostępniona za darmo na portalu CodeProject, ale z tym źródłem wiąże się kilka problemów. Po pierwsze, żeby ściągnąć plik, trzeba się zarejestrować w tym portalu. Po drugie, artykuł jest bardzo długi, jest w języku angielskim, a opis używania biblioteki miesza się w nim ze szczegółami implementacyjnymi. Dlatego postanowiłem napisać swój artykuł na temat tej biblioteki - wrzuciłem go na gamedev.pl jako Biblioteka FastDelegate.

Comments | #productions #libraries #c++ Share

# D3DPTEXTURECAPS_NONPOW2CONDITIONAL

Tue
13
May 2008

Jak wiadomo, tekstury nie muszą być kwadratowe, ale generalnie powinny mieć boki będące potęgami dwójki - tj. 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 itd. Ograniczenie to znoszą jedynie układy firmy nVidia z SM3 (od GF6), ale karty ATI z SM3 nadal je mają. Odpowiada za to flaga D3DPTEXTURECAPS_POW2 pola TextureCaps struktury D3DCAPS9.

Jest jednak taka sytuacja, kiedy to ograniczenie jest bardzo uciążliwe. Chodzi o użycie tekstury jako Render Target. Wówczas, jeśli powinna mieć co najmniej rozmiar ekranu, przykładowo dla rozdzielczości 1280 x 1024 musiałaby mieć rozmiar 2048 x 1024 i dużo miejsca by się marnowało.

Dlatego jakby specjalnie w tym celu, praktycznie wszystkie układy graficzne posiadają flagę D3DPTEXTURECAPS_NONPOW2CONDITIONAL, która pozwala na używanie tekstur o dowolnych rozmiarach pod pewnymi warunkami (opisanymi w DX SDK pod hasłem "D3DCAPS9"):

Comments | #directx #rendering Share

# Zależności pliku EXE

Sun
11
May 2008

Jak można sprawdzić, jakich plików DLL używa dany plik EXE lub DLL? Ja znam dwa programy do tego celu:

  1. Fileinfo - wtyczka do Total Commandera. Po zainstalowaniu pokazuje jako podgląd F3 dla plików wykonywalnych specjalne okno z informacjami, w tym używane biblioteki oraz eksportowane i importowane funkcje.
  2. Dependency Walker - dużo bardziej rozbudowany program do analizowania zależności. Wchodzi w skład Microsoft Visual Studio, ale nie ma do niego skrótu w Menu Start. Można go znaleźć w podkatalogu Common7\Tools\Bin\Depends.exe.

Comments | #tools Share

# Floor, ceil i reszta

Fri
09
May 2008

Mieliśmy właśnie przed chwilą na IRC-u dyskusję o zasadach, według jakich działa zaokrąglanie/obcinanie liczb zmiennoprzecinkowych przez funkcje floor, ceil i rzutowanie na int. Przypomniałem sobie, że to temat, z którym nieraz się już spotkałem i pomyślałem, że warto to usystematyzować:

x          -2.9  -2.2   2.2   2.9
---------------------------------
(int)x     -2    -2     2     2
floor(x)   -3.0  -3.0   2.0   2.0
ceil(x)    -2.0  -2.0   3.0   3.0
round(x)   -3.0  -2.0   2.0   3.0

Problem w tym, że funkcji zaokrąglającej round w C++ nie ma, trzeba ją sobie napisać. Podobnie brakuje funkcji zostawiającej samą część ułamkową 0..1, a jest ona bardzo potrzebna np. do robienia funkcji okresowych i występuje np. w języku HLSL jako frac.

inline int round(float x) {
  return (int)(x+0.5f);
}
inline float frac(float x) {
  return x - (float)(int)(x);
}

Nie jestem tylko pewny, czy rzutowanie na int faktycznie zawsze obcina część ułamkową. Na moim Visual C++, Windows XP i procesorze Intel Core2Duo 32bit tak jest, ale nie zaglądałem do standardu C++, więc nie wiem czy tak samo jest wszędzie. Wkrótce jakiś językoznawca powinien wyjaśnić tą kwestię w tym wątku forum. Gdyby się jednak okazało, że nie można polegać na tym rzutowaniu, funkcję obcinającą część ułamkową można sobie napisać samemu:

inline float trunc(float x) {
  return (x < 0.0f) ? ceilf(x) : floorf(x);
}

Takich niby prostych (prostych dla tego co już je zna) sztuczek matematycznych jest bardzo dużo. Przydałoby się je kiedyś porządnie spisać :) Na przykład ta nasza dyskusja IRC-owa zaczęła się od pytania, jak obciąć liczbę do 2 miejsc po przecinku. Rozwiązaniem jest:

y = (float)(int)(x * 100.0f) / 100.0f;

Comments | #c++ #math #algorithms Share

# Ciekawe rzeczy się dzieją

Thu
08
May 2008

Ciekawe rzeczy się ostatnio dzieją. Na jutro zaplanowane jest rozpoczęcie nowej edycji naszego konkursu Compo - o tyle nietypowej, że tematem będzie intro 4k (małe demo w pliku wykonywalnym niewiększym niż 4 KB). Jak się okazuje, takich rzeczy nie trzeba pisać w asemblerze - można do tego używać zwykłego Visual C++. Myślę, że warto opanować tą sztukę - nie jest to aż tak trudne, a może być interesujące. Ja też zainteresowałem się tym tematem i mam zamiar wziąć udział. Więcej informacji na temat konkursu i sztuki pisania intr 4k w tym wątku forum. Przy jego organizacji współpracujemy z odwiedzającymi nasze forum scenowcami, tak więc dialog międzykulturowy się rozwija :) Osobno planowana jest też międzynarodowa edycja Compo.

Poza tym Goliatus poddał do publicznej dykusji temat robienia ewentualnej zrzutki na artykuły czy innej formy zarabiania pieniędzy (reklamy? płacenie SMS-em?). Oprócz płacenia autorom artykułów pojawił się też pomysł porządnego, odpłatnego zmodernizowania skryptów serwisu. k_b z pomocą innych osób z forum zaczął redagować niewielki elektroniczny magazyn - WMag. Dotychczas wyszły już dwa numery. Xion z kolei zaczął pisać drugą część opowiadania fantastycznego Władca Kodu.

Spoza Warsztatu, ciekawą inicjatywą jest konkurs Procedural Generation Competition serwisu TIGSource. Trzeba w nim w czasie od 5 maja do 2 czerwca napisać grę, w której dane są generowane proceduralnie. Może i w tym warto wziąć udział? :)

Comments | #events #warsztat Share

# DirectX Debug i dxcpl

Mon
05
May 2008

Jeśli masz zainstalowany DirectX SDK, możesz przestawić swojego DirectX w wersję Debug. W tym celu wybierz Start > Uruchom > "dxcpl" i w oknie 1. przesuń suwak "Debug Output Level" na przedostatni ząbek 2. przełącz na "Use Debug Version of Direct3D 9" 3. wciśnij "Apply".

dxcpl

DirectX w wersji Debug prawdopodobnie działa wolniej, dlatego nie zostawiałbym go tak na stałe, ale chwilowe przełączenie w ten tryb może się bardzo przydać. Po zrobieniu tego trzeba uruchomić swój program w trybie debugowania (w Visual C++ to będzie F5) i w czasie pracy programu albo po jego zakończeniu obserwować panel Output. Będą tam wypisywane różne ostrzeżenia i błędy, a wiele wywołań funkcji D3D może się wręcz nie udać, bo DirectX dużo lepiej sprawdza wszystkie dane i zależności.

Mnie w ten sposób udało się znaleźć nie tylko wiele błędów które powodowały niedziałanie programu, ale i takich rzeczy, które na mojej karcie graficznej działały mimo, że nie musiały. Na przykład blokowanie z flagą D3DLOCK_DISCARD zamiast 0 bufora, który nie miał D3DUSAGE_DYNAMIC, albo nawet używanie wypełnionego bufora dynamicznego do renderowania zanim go odblokowałem :)

Comments | #directx #tools Share

# Deferred Shading - pakowanie pozycji i normalnej

Sun
04
May 2008

Piszemy Deferred Shading... Pierwsze co przychodzi do głowy, to zapisywanie do G-buforów pozycji i wektora normalnego w przestrzeni kamery jako pełne (x,y,z). Żeby oszczędzić komponentów, można je spakować. Zakładając, że wszystkie widoczne ścianki są zwrócone przodem do kamery, jako wektor normalny wystarczy zapisać tylko (x,y), a trzecią składową odzyskać ze wzoru:

Normal.z = - sqrt(1 - Normal.x*Normal.x - Normal.y*Normal.y);

Długo szukałem działającego wzoru na kodowanie pozycji jako pojedyncza odległość/głębokość, więc tym chętniej się nim podzielę. Są tutaj różne szkoły. Można zapisywać głębokość z/w, można odległość od kamery, można też odległość od bliskiej płaszczyzny przycinania. U mnie sprawdziło się takie rozwiązanie:

// Kodowanie - VS:
Out.ViewPos = mul(float4(In.Pos, 1), (float4x3)WorldView);
// Kodowanie - PS:
G1.b = length(In.ViewPos);

// Dekodowanie - VS:
Out.EyeVec = float3(In.Pos.x * AspectRatio, In.Pos.y, TanFovY);
// Dekodowanie - PS:
Pos = normalize(In.EyeVec) * G1.b;

Gdzie podczas dekodowania: Pos.xy to pozycja wierzchołków fullscreen quada w przestrzeni rzutowania -1..1, TanFovY to tangens kąta widzenia pionowego w radianach używanego w macierzy rzutowania tan(FovY), AspectRatio to stosunek szerokości do wysokości widoku.

Trzeba jeszcze pamiętać, że jeśli tekstura G-bufora nie jest w formacie zmiennoprzecinkowym (jak u mnie A16B16G16R16F), to zapisywane wartości trzeba jakoś skalować do przedziału 0..1.

Comments | #algorithms #rendering Share

# Zrobiłem Deferred Shading

Sat
03
May 2008

Zrobiłem Deferred Shading. To fajna technika, bo miło jest dodawać oświetlenie sceny kolejnym światłem tylko przez narysowanie następnego fullscreen quada (albo mniejszego obszaru ograniczonego przez Scissor Test, jeśli udałoby się zaimplementować algorytm Lengyela). Używam dwóch render-targetów (nazywanych tu G-buforami) w formacie A16B16G16R16F, wypełnianych na raz dzięki MRT, zbudowanych tak:

  1. RGB = Diffuse, A = Nieużywany
  2. RG = Normal.xy, B = Odległość od kamery, A = Indeks materiału

Wszystkie obliczenia odbywają się w przestrzeni kamery (View). Ciekawym pomysłem jest zakodowanie właściwości materiałów w specjalnej teksturze, której pionową współrzędną adresuje numer materiału zapisany w G-buforze. U mnie to jest tekstura w formacie A32B32G32R32F o szerokości 1px, w której: RGB = SpecularColor, A = SpecularPower.

Deferred Shading

Z czego warto się uczyć Deferred Shading? Referat Riddlemastera z IGK 2008 może zainteresować tematem, ale zawiera niewiele konkretów. Deferred Shading Tutorial autorstwa Fabio Policarpo i Francisco Fonseca jest bardzo dobry, ale zniknął z Sieci. Na szczęście jest jego kopia w Internet Archive. Jest też długa dyskusja na forum GameDev.net. Z materiałów papierowych polecam Game Programming Gems tom 6 rozdz. 5.7 o enigmatycznym tytule "Fast Per-Pixel Lighting with Many Lights" (Frank Puig Placeres), a także GPU Gems 2 rozdz. 9 - "Deferred Shading in STALKER" (Oles Shishkovtsov).

Comments | #rendering Share

# Policzone tangenty do mapy

Thu
01
May 2008

Wieści z pierwszej linii frontu: Chyba udało mi się policzyć normalne i tangenty dla mapy Indoor, z wygładzeniem zależnie od kąta krawędzi. Wzory na tangenty wziąłem z tego artykułu. Ciekawy patent wymyśliłem, żeby w poszukiwaniu wierzchołków leżacych w pobliżu nie działać ze złożnością kwadratową. Otóż posortowałem wierzchołki w każdej grupie (rysowane danym materiałem) wg współrzędnej X. Potem dla każdego wierzchołka przeglądam tylko kilka następnych, tak długo jak (v2.x - v1.x) < EPSILON_DIST. Czyż to nie dużo prostsze, niż jakieś Octree czy k-d tree? :D

Mapa Indoor - Normal

Comments | #rendering #math Share

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2024