Deferred Shading - pakowanie pozycji i normalnej

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

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

Comments

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