Direct3D - Vertex shader 1.pdf
(
268 KB
)
Pobierz
DirectX - Vertex shader 1
1
DirectX ▪ Vertex shader 1
No cóż. Przykłady sypią się jak ulęgałki z drzewa, więc nie ma na co czekać. Pędzimy do przodu niczym rakieta i dziś
bierzemy się za nową, zupełnie odlotową i kosmiczną rzecz, czyli
vertex shader
! Może wielu z Was powie, że powinienem
najpierw napisać coś o mapowaniu środowiskowym (ang.
environment mapping
) czy mapowaniu wypukłości (ang.
bump
mapping
), ale doszedłem do wniosku, że jednak lepiej będzie najpierw powiedzieć coś o vertex shaderze a dopiero potem
brać się za kolejne techniki.
Czymże zatem jest ta rzecz o kosmicznie brzmiącej nazwie? Microsoft tłumaczy, że vertex shader kontroluje ładowanie i
przetwarzanie wierzchołków. Ale co to znaczy? Jeśli czytaliście dokumentację do Direct3D, pewnie nie raz spotkaliście się z
terminem "rendering pipeline". Cóż to jest takiego? Mi kojarzy się to z taśmociągiem, po którym jadą wierzchołki - z
pamięci, w której są przechowywane, na ekran. Na tym taśmociągu są jednak przystanki, w których wierzchołki te
przechodzą pewne przekształcenia, aby w końcowej fazie można ujrzeć na ekranie coś fajnego. Teraz przetłumaczę kawałek
SDK, ale myślę, że nikt się nie obrazi ;-). Tworzymy nasz świat jako zbiór wierzchołków. Świat ten zawiera definicje
wielkości obiektów, ich wzajemne położenie w przestrzeni oraz położenie obserwatora. Direct3D przekształca ten opis na
zbiór pikseli na ekranie. Ten pierwszy etap - przekształcania opisu świata na płaski obraz na ekranie - nazywa się (tutaj
załóżmy dla uproszczenia, że "pipeline" to nie rurociąg a raczej taśmociąg ;-) taśmociągiem geometrii, nazywanym również
taśmociągiem przekształceń. Po przejściu przez ten taśmociąg, dane pikseli są użyte do przeprowadzenia takich operacji jak
multiteksturowanie (ang.
multitexturing
) czy mieszanie (ang.
blending
). Są przeprowadzane różne operacje wykorzystujące
rozmaite bufory, ale będzie jeszcze okazja to omówić. My natomiast teraz zajmiemy się bardziej szczegółowo taśmociągiem
geometrii.
W Direct3D mamy dwa rodzaje taśmociągów geometrii. Jeden, dobrze nam już znany, to taśmociąg o określonej z góry
kolejności (ang.
fixed
) dokonywania przekształceń. Wielu z Was zna doskonale pokazany powyżej rysunek. Pokazuje on ten
taśmociąg oraz kolejne przekształcenia dokonywane na jadących w nim wierzchołkach. Direct3D określa obiekty i
obserwatora w świecie, przeprowadza rzutowanie na ekran oraz dokonuje obcinania wychodzących poza obszar widoku
wierzchołków. Na tym taśmociągu dokonywane są też obliczenia dotyczące oświetlenia, aby móc określić kolor oraz ilość
odbijanego światła przez wierzchołki. Mówiliśmy już sobie o tym, ale niezbyt dokładnie, więc teraz dowiemy się, co się
dzieje po kolei z naszymi wierzchołkami, które my każemy przetwarzać naszemu Direct3D. Na samym początku wrzucamy
na taśmociąg nasze wierzchołki. Po chwilowej jeździe, wierzchołki te napotykają na trzy podstawowe przekształcenia, które
my już sobie omawialiśmy - są to przekształcenia świata, widoku i rzutowania. Następnie wierzchołki dojeżdżają do
przystanku zwanego "obcinanie", który odrzuca wierzchołki niewidoczne (nie mieszczące się na ekranie) i po jego minięciu,
wierzchołki trafiają prosto do rasteryzera - czyli urządzenia, które spowoduje, że pojawią się one na ekranie. Teraz w
szczegółach: kiedy wrzucamy wierzchołki na taśmę, są one umieszczone w swoim własnym, lokalnym układzie
współrzędnych, mają własną orientację i położenie. Dane te nazywane są współrzędnymi modelu a jego położenie i
orientacja nazywana jest przestrzenią modelu. Na pierwszym przystanku na taśmie wszystkie dane wierzchołków są
przekształcane ze swojego układu współrzędnych, na układ używany przez wszystkie obiekty na scenie. Proces tego
przekształcania nazywany jest przekształceniem świata (ang.
world transformation
). Każdy wierzchołek od teraz nie używa
już swojego własnego układu współrzędnych czy orientacji - wszystko jest umieszczone przestrzeni wspólnego świata i
wszystkie wierzchołki mają współrzędne pasujące do tego ogólnego świata. Po tym przekształceniu wierzchołki udają się w
dalszą podróż po taśmie. Napotykają na swojej drodze kolejny przystanek, jakim jest przekształcenie widoku. Tutaj nasz
świat jest orientowany (ustawiany) względem kamery obecnej na scenie. Ponieważ mamy punkt widzenia, więc wszelkie
nasze wierzchołki są przemieszczane i obracane wokół widoku kamery i są przenoszone niejako z przestrzeni świata do
przestrzeni kamery. Po obejrzeniu sobie naszych wierzchołków przez kamerę, jedziemy dalej po taśmie no i trafiamy w
bardzo nieprzyjemne miejsce. Na tym przystanku, pomimo usilnych protestów naszych kochanych milusińskich, zostają one
stłoczone z trzech wymiarów do dwóch, czyli do płaskiego, zupełnie nieciekawego świata. Obiekty zostają przeskalowane ze
względu na swoją odległość od obserwatora, aby osiągnąć w ostatecznym rozrachunku złudzenie głębi. Bliższe obiekty
wydają się być większe, leżące dalej są mniejsze. To się nazywa rzutowanie a całe zamieszanie to przekształcenie projekcji
(ang.
projection transformation
). Na ostatnim przystanku wszystkie wierzchołki, które niestety nie miały szczęścia znaleźć
się w polu widzenia naszej kamery, są usuwane i rasteryzer nie liczy dla nich kolorów czy cieniowania. Nie ma sensu
2
DirectX ▪ Vertex shader 1
poświęcać czasu dla czegoś, co i tak nie będzie widoczne. Ten proces nazywa się obcinaniem (ang.
clipping
). Po fazie
obcinania, pozostałe wierzchołki są skalowane według parametrów widoku i są przekształcane na współrzędne na ekranie. W
efekcie, kiedy scena jest malowana przez rasteryzer, na ekranie otrzymujemy tylko widoczne wierzchołki.
DirectX 8.0 wprowadza nam zupełnie nową jakość, jeśli chodzi o taśmociąg geometrii. Od tej wersji będziemy mieli o wiele
większą kontrolę nad tym, co się dzieje z naszymi wierzchołkami. Będziemy mogli ustalać sobie, jakie będziemy mieć
przystanki i w jakiej kolejności. Poniższy rysunek, zresztą też doskonale Wam znany zapewne, pokazuje istotę takiej filozofii
działania. Nas w tym momencie interesuje tylko pierwsza część tego rysunku...
tam gdzie mamy taśmociąg geometrii. Jak widać, obok typowych operacji, jakie są przeprowadzane na wierzchołkach, mamy
tam taki mały, niewinnie wyglądający prostokącik noszący dumnie nazwę "vertex shader". Co to takiego w zasadzie jest? W
DirectX 8 proceduralnie (czyli my możemy o tym decydować) określane mogą być wszystkie operacje, jakie mają miejsce na
taśmociągu geometrii i oświetlenia a także na taśmociągu, na którym dokonywane jest mieszanie pikseli. Takie podejście do
sprawy, kiedy w sposób programowalny możemy określić zachowanie się naszego urządzenia ma oczywiście wiele zalet.
Po pierwsze - umożliwia bardziej ogólną składnię programu do określania zwykle przeprowadzanych operacji. Model o
ustalonej kolejności przetwarzania musi definiować modele, flagi oraz inne rzeczy dla rosnącej ciągle liczby operacji, które
muszą być wykonane. Co gorsze, wraz z rosnącą mocą naszego sprzętu - więcej kolorów, tekstur, strumieni wierzchołków i
całej reszty, operacje, które muszą zostać pomnożone przez przyrost danych, stają się coraz bardziej skomplikowane. W
przeciwieństwie do tego, model programowalny umożliwia przeprowadzanie prostych operacji, takich jak pobieranie
kolorów czy tekstur w bardziej bezpośredni sposób. Nie musimy się już przedzierać przez wszystkie możliwe tryby pracy
urządzenia, aby znaleźć ten właściwy. My musimy się tylko dowiedzieć, jak działa nasz sprzęt i zażądać od niego, aby
przeprowadził on zadany przez nas algorytm. Co możemy robić za pomocą takiego programowalnego przetwarzania? Oto
kilka dobrze znanych nam rzeczy:
• podstawowe przekształcenia geometryczne,
• proste oświetlanie obiektów,
• mieszanie wierzchołków (co to jest, dowiemy się kiedyś),
• morfing wierzchołków (pamiętacie delfina z przykładów?),
• przekształcenia tekstur,
• generowanie tekstur,
• mapowanie środowiskowe (ang.
environment mapping
).
Po drugie - programowalne podejście umożliwia łatwą implementację nowych operacji (naszych chorych pomysłów).
Programiści często podczas pracy dowiadują się, że muszą zrobić coś, ale konkretne API nie posiada akurat tej rzeczy. I
największy ból to ten, że to nie brak możliwości urządzenia, ale właśnie ograniczenia posiadanego przez programistę API
uniemożliwiają mu realizację jego zamiarów. Ogólnie rzecz biorąc, programowalne operacje są o wiele prostsze niż próby
ich przeprowadzenia z wykorzystaniem ustalonego taśmociągu. To, co będziemy mogli robić już w niedalekiej przyszłości,
to:
3
DirectX ▪ Vertex shader 1
• animacja postaci żywych,
• oświetlenie anizotropowe - teraz możemy robić tylko za pomocą tekstur,
• realistyczne modelowanie skóry, różnych rozciągliwych powłok,
• światła, które mogą wnikać pod powierzchnię,
• geometria proceduralna (np. mięśnie poruszające się pod skórą),
• modyfikowanie siatki na podstawie mapy bitowej (ang.
displace
).
Po trzecie - skalowalność i ewolucja. Jak widać, sprzęt na przestrzeni ostatnich kilku lat, rozwija się bardzo gwałtownie i
takie programowalne podejście pozwala dostosować posiadane API do możliwości sprzętu. Nowe właściwości i cechy mogą
być dodane na rosnącą ciągle ilość sposobów poprzez:
• dodawanie nowych instrukcji,
• dodawanie nowych wejść dla danych,
• dodawanie nowych właściwości dla ustalonego trybu przetwarzania jak i programowalnego.
Po czwarte - podejście proceduralne oferuje programistom coś bliższego skóry. Wiadomo, że bardziej znają się na
programowaniu niż na sprzęcie. API, które w pełni zaspokoi potrzeby programistów, powinno móc przenieść funkcjonalność
sprzętu na dostępny kod.
Po piąte - podejście proceduralne to krok w stronę renderingu fotorealistycznego. Przez wiele lat stosowano programowalne
shadery w takim sposobie renderingu. Ogólnie mówiąc, ten sposób nie jest ograniczony przez wydajność sprzętu, więc takie
programowalne podejście staje się na dziś celem ostatecznym, jeśli chodzi o techniki renderingu.
Po szóste i ostatnie - podejście proceduralne umożliwia bezpośrednie przeniesienie kodu na sprzęt. Większość obecnego
dzisiaj sprzętu 3D może być w jakiś określony sposób programowana, jeśli chodzi o przekształcanie wierzchołków.
Możliwość programowania urządzenia za pomocą API umożliwia przeniesienie aplikacji bezpośrednio na sprzęt. Umożliwia
nam zarządzanie zasobami sprzętu według wymagań aplikacji. Za pomocą ograniczonego zbioru rejestrów lub instrukcji
może zostać to wykonane. Natomiast trudniej jest zrobić funkcję o określonym przebiegu, która mogłaby wykonywać
wszystkie operacje niezależnie. Jeśli włączymy sobie do pakietu zbyt wiele funkcji wymagających zasobów shadera, mogą
one przestać działać i będą powodować różne dziwne zachowania. Model programowalnego API jest kontynuacją tradycji
DirectX-a, która miała na celu eliminowanie problemów poprzez umożliwienie programiście zwrócenie się bezpośrednio do
sprzętu i powodując zniesienie takich ograniczeń.
Jeśli włączymy nasz vertex shader, standardowy moduł do przeprowadzania transformacji i oświetlenia w Direct3D zostaje
przez niego zastąpiony na taśmociągu geometrii. W efekcie standardowe informacje (ustawienia) odnośnie transformacji i
oświetlenia są ignorowane przez Direct3D. Kiedy nasz shader wyłączymy i funkcja o ustalonej kolejności jest na powrót
włączona, wszystkie aktualne ustawienia są oczywiście przywracane. Na wyjściu vertex shader musi wystawiać współrzędne
wierzchołków w jednorodnym układzie obcinania. Mogą być oczywiście generowane dodatkowe dane takie, jak:
współrzędne teksturowania, kolory, współczynniki mgły i podobne. Taśmociąg geometrii zawierający nasz shader powinien
wykonywać następujące zadania:
• przetwarzanie prymitywów,
• obcinanie ze względu na ustalone punkty widzenia i płaszczyzny obcinania,
• skalowanie widoku,
• jednorodne dzielenie,
• obcinanie tylnych powierzchni i widoku,
• ustawienia trójkątów,
• rasteryzacja.
Programowalna geometria jest jednym z trybów Direct3D API. Jeśli jest włączona, zastępuje częściowo taśmociąg po którym
jadą wierzchołki. Kiedy jest wyłączona, API ma normalną kontrolę nad tym co się dzieje z danymi tak, jak miało to miejsce
w DirectX 6.0 i 7.0. Wykonywanie vertex shaderów nie powoduje zmian wewnątrz samego Direct3D a żaden stan z wnętrza
Direct3D nie jest dostępny dla shadera.
4
DirectX ▪ Vertex shader 1
No dobra. Wszystko to brzmi tak strasznie naukowo i okropnie. Jak wielu się słusznie domyśla, jest żywcem wręcz zerżnięte
z dokumentacji do SDK. A o co tak naprawdę tutaj chodzi? Popatrzmy chwilę na kolejny rysunek. Mamy coś jakby procesor
(ALU - ang.
A
rithmetic
L
ogic
U
nit
), który posiada pewne wejście i wyjście. Cały bajer polega na tym, że ten procesor
możemy teraz programować. Dawniej wrzucaliśmy do tego procesorka odpowiednie dane i on sam już nam się z tym
załatwiał. Miał jakiś ustalony z góry program i wykonywał grzecznie po kolei zaprogramowaną z góry sekwencję rozkazów.
Teraz dostaliśmy do ręki możliwość zmiany tego programu. Manipulując odpowiednio rozkazami i danymi, będziemy mogli
osiągać trochę bardziej "rozrywkowe" efekty niż do tej pory, co najlepiej sobie obejrzeć w NVEffectBrowserze panów z
dobrzej nam znanej firmy. No ale wracając do sedna sprawy. Skoro mamy procesor, to muszą być rejestry i rozkazy, prawda?
Tak też jest w istocie. Procesor posiada cały zestaw bardzo pożytecznych rozkazów, które nie raz będzie okazja omówić.
Zawierają się w nich wszelkie operacje arytmetyczne oraz kilka przydatnych operacji znanych z grafiki 3D w "klasycznym"
wykonaniu (dla przykładu iloczyn skalarny). Mamy rozkazy, więc czas na rejestry. Procesor geometrii ma ich kilka
zestawów zgromadzonych w pewne grupy. Jak widać na rysunku, są to rejestry wejściowe, tymczasowe, rejestry zawierające
pewne stałe oraz rejestr adresu. Obecny jest także tak zwany wektor wyjściowy, złożony z komórek, które przechowują
konkretne dane dla wierzchołków, które idą sobie dalej po przekształceniu przez nasz procesorek. Każdy vertex shader
definiuje funkcję, która jest aplikowana każdemu wierzchołkowi po kolei na scenie. Nie ma takiej sytuacji, że wierzchołki są
przetwarzane równolegle. Po prostu jeden wierzchołek wchodzi, jest obrabiany a następnie sobie wychodzi. Vertex shader
nie dokonuje operacji projekcji i ustawiania wierzchołków w widoku. Obcinanie wierzchołków i składanie ich w bryły też
nie jest przez niego dokonywane. Wszystko dzieje się już po samym fakcie zadziałania shadera.
Jak już wspominałem, w Direct3D 8 mamy dwa rodzaje taśmociągu geometrii. Jeden o ustalonej z góry kolejności operacji,
który ma taką samą funkcjonalność jak ten, obecny w DirectX 7.0, który zawiera transformacje, oświetlenie, mieszanie
wierzchołków oraz generację współrzędnych mapowania. W przeciwieństwie do vertex shadera, gdzie operacje wykonywane
na wierzchołkach są definiowane w jego obrębie, przetwarzanie wierzchołków w ustalonej kolejności jest kontrolowane
poprzez stan urządzenia renderującego za pomocą metod jego obiektu. Ustawiają one oświetlenie, transformacje i wszystko
co potrzebne. Wektor wejściowy dla przetwarzania o stałej kolejności przekształceń ma z góry ustaloną składnię. Dlatego też
deklaracje wierzchołków określają je za pomocą współrzędnych, koloru, normalnej i tak dalej. Dane wyjściowe dla
wierzchołków, które są przetwarzane przez funkcję o ustalonej kolejności przetwarzania, zawsze zawierają na wyjściu
współrzędne, kolor, wszystkie współrzędne teksturowania, które są wymagane przez aktualny stan urządzenia.
Programowalny vertex shader ma funkcję przetwarzającą, zdefiniowaną jako tablicę instrukcji, która to tablica jest
aplikowana każdemu wierzchołkowi podczas przetwarzania. Zależność pomiędzy tymi danymi, które przychodzą z aplikacji
do rejestrów wejściowych vertex shadera, jest zdefiniowana poprzez tzw. "deklarację shadera", ale dane te nie mają jakiegoś
ściśle określonego formatu. Zinterpretowanie danych nadchodzących należy tylko i wyłącznie do instrukcji zawartych w
vertex shaderze. Dane wyjściowe są wpisywane rejestrów wyjściowych także poprzez instrukcje zawarte w shaderze.
"Deklaracja vertex shadera" - definiuje zewnętrzny interfejs shadera, który będzie połączony z nadchodzącymi danymi. Taka
deklaracja zawiera między innymi:
• połączenie strumienia danych do rejestrów wejściowych shadera. Informacja ta definiuje typ i rejestr wejściowy dla
każdego elementu zawartego w strumieniu danych. Typ określa po prostu rodzaj danych - czy jest to liczba
całkowita, zmiennoprzecinkowa czy może wektor oraz, co za tym idzie, ich rozmiar. Wszystkie elementy
strumienia, które są mniejsze od czterech (mają mniej niż cztery elementy - np. współrzędne to trzy wartości) są
uzupełniane do czterech przez wartości 0 i 1.
5
DirectX ▪ Vertex shader 1
• łączy wejściowe rejestry vertex shadera z danymi niejawnymi pochodzącymi od takiego wewnętrznego urządzonka,
zwanego teselatorem prymitywów. Urządzonko to powoduje podział większych figur na pojedyncze trójkąty
strawne dla shadera. To umożliwia kontrolę ładowania danych wierzchołków, które nie pochodzą bezpośrednio z
bufora wierzchołków, ale tworzonych na przykład podczas teselacji (podziału) prymitywów.
• deklaracja ładuje pewne wartości do stałej pamięci, kiedy shader jest ustawiany jako bieżący. Każdy element
ładowany do takiej stałej pamięci zawiera wartości zapisywane do jednego lub wielu, ciągłych (występujących po
sobie) stałych rejestrów o wielkości 4 słów (
DWORD
) każdy.
Wróćmy na chwilkę do naszego obrazka z pseudo procesorkiem. Widzimy tam zestaw rejestrów wejściowych, które są
wiązane za pomocą deklaratora z danymi wejściowymi, Są także rejestry tymczasowe, które będą służyć do przechowywania
jakiś naszych tymczasowych obliczeń oraz dokonywania operacji, które mogą być przeprowadzane tylko na rejestrach.
Widzimy równie rejestr adresowy (nas na razie nie interesuje, ale wspomnimy o nim później) oraz rejestry pamięci stałej, o
których była mowa przed momentem. Na wyjściu, które niełatwo przegapić, otrzymujemy dane, które wykorzystamy do
naszych niecnych celów. Powiedziałem trochę o deklaratorze, dowiedzmy się więc jak to działa w praktyce.
Jak napisałem wyżej, deklarator łączy napływający strumień danych z rejestrami wejściowymi. Co to oznacza? Załóżmy, że
płynie sobie strumyczek bajtów, które niosą sobie tylko wiadomą informację. Deklarator umożliwi shaderowi określenie,
które spośród tych danych posłużą mu do poszczególnych obliczeń. Przyjrzyjmy się może deklaratorowi, ktorego my
użyjemy w naszym pierwszym vertex shaderze:
// first vertex shader
DWORD dwDecl[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR ),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2 ),
D3DVSD_END()
};
Jak nietrudno zauważyć, deklarator to tablica wartości typu
DWORD
(0xFFFFFFFF). Wartości te są w jakiś tam sposób
przydatne shaderowi, który na ich podstawie będzie potrafił przypisać określonemu rejestrowi wejściowemu, którąś z danych
w nadchodzącym strumieniu. Jak też nietrudno zauważyć, w tablicy tej nie mamy wartości (przynajmniej na razie), ale
wywołania pewnych, tajemniczych makr, zwanych makrami deklaratora. Cóż będą oznaczać poszczególne z nich?
D3DVSD_STREAM(0)
Domyśleć się jest bardzo łatwo. Po prostu będzie to numer strumienia (jako argument makra), z którego vertex shader będzie
pobierał dane na swoje potrzeby i przetwarzał je zgodnie ze swoim programem. Makro to weźmie numer naszego strumienia,
zmiesza to z czymś i umieści w tablicy deklaratora jako pewną liczbę. Shader widząc taką liczbę, będzie wiedział, że to
nakazuje mu pobierać dane ze strumienia o numerze 0.
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3 )
D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR ),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2 ),
Te makra mówią shaderowi, do którego rejestru wejściowego ma pobrać dane lecące strumieniem oraz ile tych danych ma
być. W tym przypadku będziemy mieć trzy różne wartości. Gdybyśmy popatrzyli na strumień danych pędzący po ścieżkach
naszej karty, widzielibyśmy tylko ciąg bajtów. Shader w zasadzie widzi tak samo, dla niego jest to tylko strumień nic nie
znaczących bajtów. Ale dzięki tym makrom dowie się on teraz, jak z tego chaosu wyłowić, coś co się nada do dalszych
obliczeń. Nie powiedzieliśmy sobie jeszcze o znaczeniu rejestrów, ale o nich może za chwilę dokładniej. My musimy
podeprzeć się tutaj naszą wyobraźnią, aby jakoś wybrnąć, ale obiecuję, że już za moment wszystko będzie jasne.
Przedstawione powyżej pierwsze makro mówi shaderowi tak: słuchaj, weź 3 wartości typu
float
(stała
D3DVSDT_FLOAT3
) z nadchodzącego strumienia i umieść je w rejestrze, w którym powinny być współrzędne
wierzchołków (stała
D3DVSDE_POSITION
). Następne makro sugeruje shaderowi, aby wziął cztery bajty (
D3DVSDT_D3DCOLOR
) i umieścił je w rejestrze, w którym przechowuje kolor wierzchołka. Na samym końcu widzimy
makro, które w ciągu bajtów znajduje współrzędne mapowania tekstury na poziomie 0 (
D3DVSDE_TEXCOORD0
), które
będą potrzebne shderowi. Wszystkie te konstrukcje, dzięki makrom, zostaną zastąpione liczbami
DWORD
(bo taką mamy
tablicę!) i tam też zmagazynowane. Shader dostając taką tablicę, sobie tylko znanymi sposobami będzie potrafił
zinterpretować odpowiednio znajdujące się tam informacje a nasze wierzchołki zaczną się zachowywać w nader przedziwne
sposoby. No ale to już będzie zależało już tylko i wyłącznie od naszej wyobraźni.
Funkcja.
Powiedzieliśmy sobie trochę o deklaratorze, więc trzeba coś napomknąć o funkcji vertex shadera. Co to znowu jest takiego.
Pamiętacie rozważania o taśmociągach geometrii? Na taśmociągu o ustalonej kolejności przetwarzania wszystkie operacje
były z góry zaprogramowane i były wykonywane w określonej kolejności. Nasz taśmociąg, z programowanym
przetwarzaniem wierzchołków będzie musiał poradzić sobie sam, bez pomocy funkcji, która jest stosowana w standardowych
przypadkach. Ale to nic złego a może nawet lepiej! My napiszemy sobie własną, o wiele, wiele lepszą, która pozwoli nam
rozwinąć naszą wyobraźnię w sposób dotychczas niespotykany! Ale zanim zajmiemy się tworzeniem funkcji shadera,
musimy powiedzieć sobie sporo o instrukcjach i rejestrach.
Plik z chomika:
jacekplacekjacek
Inne pliki z tego folderu:
Andrzej Daniluk - USB - Praktyczne Programowanie Z Windows API W C.pdf
(10525 KB)
VbApiGuide.pdf
(7822 KB)
Charles Petzold - Programming Windows - 5th Ed.pdf
(3058 KB)
winapi_wprowadzenie01.pdf
(1473 KB)
winapi_wprowadzenie02.pdf
(872 KB)
Inne foldery tego chomika:
Arduino
Asembler
C++
DirectX
GDB
Zgłoś jeśli
naruszono regulamin