Warsztat » Forum

[DirectX] Quady zwrócone w stronę kamery

Nov 23, 2010 | Berg |
11 wypowiedzi na 1 stronach:
1
Berg
Nov 23, 2010

Quady zwrócone w stronę kamery

Witam, staram się napisać jakiś prosty particle system, niestety w sieci znalazłem praktycznie same informacje na temat systemu złożonego z duszków, a taki system mnie nie interesuje. Już na starcie pisania systemu złożonego z quadów mam jeden, pewnie banalny błąd - jak sprawić, że quad będzie zawsze zwrócony w stronę kamery? Rozumiem, że najlepiej obliczyć to za pomocą shadera, wysyłając do niego pozycję kamery z której on obliczy nową pozycje dla wierzchołków. Pytanie właśnie jak ma to policzyć? :)
Xion
Nov 25, 2010

Odp: Quady zwrócone w stronę kamery

Jak? Otóż... nijak właśnie :) Po prostu quady, które mają sprawiać wrażenie zwróconych w stronę kamery nie powinny być przekształcane do przestrzeni widoku. Pamiętaj, że nie ma czegoś takiego jak 'kamera', to tylko odpowiednie przekształcenie.

Tak więc zamiast mnożyć je przez world-view-proj, mnożysz je tylko przez world-proj.
maxest
Nov 25, 2010

Odp: Quady zwrócone w stronę kamery

Billboarding :)
Krzysiek K.
Nov 25, 2010

Odp: Quady zwrócone w stronę kamery

Cytat:
Jak? Otóż... nijak właśnie :) Po prostu quady, które mają sprawiać wrażenie zwróconych w stronę kamery nie powinny być przekształcane do przestrzeni widoku.

Powinny być przekształcane, bo inaczej nie będą się one miały nijak do położenia kamery i reszty świata.


Proponuję raczej przesłać do vertex shadera wektory "w górę" i "w bok" kamery i na podstawie tego rozciągać quada. :)
Regedit
Dec 1, 2010

Odp: Quady zwrócone w stronę kamery

Rozwijając to co powiedział Krzysiek K., tzw. billboarding robi się tak:

- Każdy quad to 4 wierzchołki i 6 indeksów.
- O ile nie używasz Geometry Shader z Shaderów w wersji 4 (GeForce 8, Vista i te sprawy...), to z jednego wierzchołka nie powstaną magicznie 4, musisz więc mieć w buforze wierzchołków prawdziwe 4 wierzchołki.
- Pomysł polega na tym, aby te 4 wierzchołki miały swoją pozycję w jednym i tym samym miejscu, a były rozsuwane w lewo-prawo i górę-dół przez Vertex Shader.
- Aby było wiadomo który z tych wierzchołków ma być rozsunięty w którą stronę, oprócz tej wspólnej dla całego quada pozycji początkowej, wierzchołek musi też mieć dodatkowe dane. Nazwijmy je off_x i off_y. Możesz je zapisać w wierzchołku jako dodatkowe tex-coordy albo bardziej oszczędnie, jako składowe koloru diffuse (kolor diffuse to pojedyncza liczba 4-bajtowa, podczas gdy 2-wymiarowy texcoord składa się z dwóch 4-bajtowych floatów, a nam niepotrzebna tutaj jego pełna dokładność).
- Tak więc, wypełniamy Vertex Buffer:
Kod: Vertices[0].Pos = ParticleCenterPos;
Vertices[1].Pos = ParticleCenterPos;
Vertices[2].Pos = ParticleCenterPos;
Vertices[3].Pos = ParticleCenterPos;
Vertices[0].Diffuse = D3DCOLOR_ARGB(0, 0, 0, 0);
Vertices[1].Diffuse = D3DCOLOR_ARGB(0, 0, 255, 0);
Vertices[2].Diffuse = D3DCOLOR_ARGB(0, 255, 255, 0);
Vertices[3].Diffuse = D3DCOLOR_ARGB(0, 255, 0, 0);

- Składową Diffuse wykorzystujemy tak:
R to off_x. Podana tutaj liczba 0..255 zamieni się w shaderze w 0..1 i będziemy interpretowali ją jako rozsunięcie wierzchołka:
0 - w lewo
1 - w prawo
G to off_y, analogicznie, tylko przesuwa w dół/w górę.
B, A - nieużywane.
- Zauważ też, że w kodzie C++ bajty są ułożone w kolejności od najstarszego A-R-G-B, a w shaderze inaczej - rgba.
- Shader potrzebuje dostawać przez stałą wektor w prawo i do góry. Skąd go wziąć, o tym później.
- Kod vertex shadera, który rozsuwa wierzchołek:
Kod: float2 Offset = Input.Diffuse.rg * 2 - 1; // Przeskalowanie 0..1 do -1..1
float3 NewPos = Input.Pos + Offset.x * RightVec + Offset.y * UpVec;
Output.Pos = mul(float4(NewPos, 1), WorldViewProj);

- TexCoordów nie musisz przekazywać osobno w wierzchołku, bo one łączą się z kierunkiem w jakim rozsuwasz dany wierzchołek, a właściwie to są identycznie z przekazywanym offsetem, bo też są w zakresie 0..1. Tak więc kolejna sprytna sztuczka trafia do vertex shadera:
Kod: Output.TexCoord = Input.Diffuse.rg;

- Wreszcie najtrudniejsze - wektory RightVec i UpVec. To są wektory znormalizowane wskazujące kierunek w prawo i w górę w przestrzeni lokalnej modelu. Jeśli nie używasz przestrzeni modelu i macierzy świata, czyli pozycje cząsteczek są wyrażone wprost w przestrzeni świata, te wektory otrzymuje się wprost wyciągając je z pierwszej i drugiej kolumny odwrotności macierzy widoku View zbudowanej dla aktualnej kamery, czyli jakoś tak (pisane z głowy, jak wszystkie kody w tej mojej wiadomości - bez gwarancji że działa):
Kod: D3DXMATRIX View;
// Wypełniam View - D3DXMatrixLookAtLH...
D3DXMATRIX ViewInv;
D3DXMatrixInverse(&ViewInv, View);
const D3DXVECTOR3 & RightDir = *(const D3DXVECTOR3*)&ViewInv._11;
const D3DXVECTOR3 & UpDir = *(const D3DXVECTOR3*)&ViewInv._21;

- Jeśli natomiast użwasz przejścia z przestrzeni lokalnej obiektu do przestrzeni świata, przekazuj do shadera macierz WorldViewProj jak gdyby nigdy nic, a rozsuwania dokonuj w przestrzeni lokalnej modelu, w takiej w jakiej wyrażone są pozycje cząsteczek. Aby to zrobić, przekazuj wektory RightVec i UpVec w przestrzeni lokalnej modelu. Takie wektory uzyskasz mnożąć te wyżej pobrane przez odwrotność macierzy świata twojego obiektu particlesów.
Berg
Dec 2, 2010

Odp: Quady zwrócone w stronę kamery

Dzięki wielkie dla wszystkich, w szczególności dla Regedita, bardzo pomocna wiadomość. Z nową wiedzą ruszam majstrować system cząstek :)
maxest
Oct 19, 2010

Odp: Quady zwrócone w stronę kamery

Cytat:

te wektory otrzymuje się wprost wyciągając je z pierwszej i drugiej kolumny odwrotności macierzy widoku View zbudowanej dla aktualnej kamery

Inwersja macierzy jest dosc kosztowna operacja, przynajmniej w stosunku do transpozycji. A wlasnie w tym miejscu mozna chyba zamiast odwracac macierz po prostu wziac jej transpozycje (bo zdaje sie "podmacierz" 3x3 macierzy swiata jest macierza ortonormalna). Poprawcie mnie prosze jesli sie myle
Regedit
Oct 23, 2010

Odp: Quady zwrócone w stronę kamery

Ta podmacierz 3x3 owszem, jest, bo zawiera same rotacje, ale co z translacją w czwartym wierszu? Ona też jest ważna.
Krzysiek K.
Oct 23, 2010

Odp: Quady zwrócone w stronę kamery

Cytat:
Ta podmacierz 3x3 owszem, jest, bo zawiera same rotacje, ale co z translacją w czwartym wierszu? Ona też jest ważna.

Jeżeli chcemy wyciągać wektory kierunków kamery, tak jak tutaj, to nie jest. :)
Regedit
Oct 26, 2010

Odp: Quady zwrócone w stronę kamery

Ale jeżeli chcemy przez odwrotność tej macierzy przekształcać potem punkty (nie wektory), np. pozycje cząsteczek, to jest.
Krzysiek K.
Oct 27, 2010

Odp: Quady zwrócone w stronę kamery

Cytat:
Ale jeżeli chcemy przez odwrotność tej macierzy przekształcać potem punkty (nie wektory), np. pozycje cząsteczek, to jest.

Punkty chcemy przekształcać z przestrzeni świata do przestrzeni kamery, więc potrzebujemy tej macierzy, a nie jej odwrotności. :)
Strony:
1