Autor Wątek: Vertex normals dla heightmapy.  (Przeczytany 4048 razy)

Offline x6itru

  • Użytkownik

# Marzec 27, 2013, 02:26:46
Witam, mam mały problem, ostatnio próbuje wygenerować sobie normale dla hmapki, niby wszystko ok - ino dostaje dziwny wynik.. < pewnie coś źle licze, i właśnie po to założyłem ten temat >
To tak gdy liczyłem normale per triangle, wynik był beznadziejny choć chyba poprawny?
http://img255.imageshack.us/img255/1088/98867991.png
Jednak taki efekt mnie nie zadowalał, próbowałem wyliczyć normale per vertex, jednak dostaje dziwne "zmarszczki" - nieco złe normale, nie wiem z czego mogą wynikać takie zniekształcenia ? Oczywiście "It's not bug, it's feature!"
http://img801.imageshack.us/img801/2748/61885384.png
Jak liczę? Obmyśliłem plan, rozrysowałem, nie wiem czy to jest do końca poprawnie<zdaje mi się że wynik jest prawie poprawny>.
Czyli robię po prostu tak, że obliczam  dla wszystkich sąsiadujących faceów normalną, po czym sumuje je wszystkie, normalizuje i to tyle, pewnie o czymś zapomniałem i dlatego tak wychodzi.
Będę wdzięczny za wszelakie pouczenia itd.
Pozdrawiam. :)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline hashedone

  • Użytkownik

  • +1
# Marzec 27, 2013, 08:55:37
A nie lepiej jest mieć wyliczoną normalmapę dla heightmapy w osobnej teksturze i z tamtąd próbkować ją per fragment? (w ogóle jej nie wyliczać i ew. ustawić na [0; 1; 0] jeśli chcesz użyć tego samego fragment shadera co do normalnego normal mappingu). Tak na moje to właśnie liczenie per vertex jest tu powodem zniekształceń - to normalne że przy takim liczeniu widać trójkąty (tyle że wygładzone - licząc per triangle masz też trójkąty, tylko nie wygładzone).
« Ostatnia zmiana: Marzec 27, 2013, 08:57:36 wysłana przez hashedone »

Offline mwojt

  • Użytkownik

  • +1
# Marzec 27, 2013, 09:45:01
Ja mam tak (dla punktu):
pt3d normal (pt3d b1, pt3d b2, pt3d b3)
{
pt3d n,ab,ac;     
double d; //dystans
ab.x=b2.x-b1.x; ab.y=b2.y-b1.y; ab.z=b2.z-b1.z;
ac.x=b3.x-b1.x; ac.y=b3.y-b1.y; ac.z=b3.z-b1.z;
n.x = (ab.y * ac.z) - (ab.z * ac.y);
n.y = (ab.z * ac.x) - (ab.x * ac.z);
n.z = (ab.x * ac.y) - (ab.y * ac.x);
d = sqrt((n.x*n.x) + (n.y*n.y) + (n.z*n.z));
n.x=n.x / d;   n.y=n.y / d;   n.z=n.z / d;
return n;
}
Uśrednione:
pt3d trn::cnpt(float ppx,float ppy) //pozycja na mapie
{           
      float px[7]={0,-1,-1, 0, 1, 1, 0};  // trojkaty
      float py[7]={0, 0,-1,-1, 0, 1, 1};               
      float pz[7]; // wysokosc
      pt3d nn, n;
     
      for (int x=0; x<7; x++) { pz[x]=(float)data[(int)(ppx+px[x])+((int)(ppy+py[x]))*sx]/64; }
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[1],py[1],pz[1]),pk(px[2],py[2],pz[2]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[2],py[2],pz[2]),pk(px[3],py[3],pz[3]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[3],py[3],pz[3]),pk(px[4],py[4],pz[4]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[4],py[4],pz[4]),pk(px[5],py[5],pz[5]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[5],py[5],pz[5]),pk(px[6],py[6],pz[6]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
     
      n=normal(pk(px[0],py[0],pz[0]),pk(px[6],py[6],pz[6]),pk(px[1],py[1],pz[1]));
      nn.x+=n.x; nn.y+=n.y; nn.z+=n.z;
           
      nn.x/=6; nn.y/=6; nn.z/=6;
     
      return nn;
}     

Offline Kos

  • Użytkownik
    • kos.gd

# Marzec 27, 2013, 10:14:17
Coś to zmieni, jeśli zrobisz sum += 2*f0 oraz 2*f3?

Offline bluebat

  • Użytkownik

# Marzec 27, 2013, 11:08:30
Normalizuj crossy przed sumowaniem. Inaczej v1 v0 v6 wnosi do sredniej wiecej niz v6 v0 v5.

Offline Kos

  • Użytkownik
    • kos.gd

# Marzec 27, 2013, 11:19:11
@Up To jest zamierzone :-) Ale dzięki że przypominasz; zapomniałem o tym pisząc poprzedniego posta.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

  • +1
# Marzec 27, 2013, 13:13:29
v0Normal = normalize( cross(v3-v6,v4-v1) );
I tyle. :)

Offline Veldrin

  • Użytkownik

# Marzec 27, 2013, 16:37:35
@up: czy to nie jest rozwiązanie, które pojawiło się kiedyś w Perełkach?

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Marzec 27, 2013, 17:25:22
@up: czy to nie jest rozwiązanie, które pojawiło się kiedyś w Perełkach?
Nie wiem. Dla mnie jest to rozwiązanie po prostu oczywiste. :)

Offline x6itru

  • Użytkownik

# Marzec 28, 2013, 13:45:23
Nie wiem. Dla mnie jest to rozwiązanie po prostu oczywiste. :)
Ino brak jakiejkolwiek zmiany :p efekt jest ten sam, dziwne to bardzo, chyba jednak będę musiał zrobić to sposobem hashedone.

Offline Kos

  • Użytkownik
    • kos.gd

# Marzec 28, 2013, 13:48:26
To może masz błąd zupełnie gdzie indziej, skoro masz zły efekt jakkolwiek nie liczysz normalnych?

Offline x6itru

  • Użytkownik

# Marzec 28, 2013, 16:07:15
To może masz błąd zupełnie gdzie indziej, skoro masz zły efekt jakkolwiek nie liczysz normalnych?
No tak nad tym też już myślałem, lecz ja tylko to obliczam, ładuje do VBO i tyle, w shaderze otrzymuje już wadliwe normale, więc nie ma zbytnio gdzie tam błędu zrobić, jedyną możliwością są złe obliczenia, choć w sumie dla płaskiej powierzchni zwraca 0;1;0 więc jest ok, nie mam już żadnych pomysłów co może być źle. ;ss anyway dzięki wszystkim za pomoc.
« Ostatnia zmiana: Marzec 28, 2013, 16:11:09 wysłana przez x6itru »

Offline Oti

  • Użytkownik

# Marzec 28, 2013, 19:51:49
No tak nad tym też już myślałem, lecz ja tylko to obliczam, ładuje do VBO i tyle, w shaderze otrzymuje już wadliwe normale, więc nie ma zbytnio gdzie tam błędu zrobić, jedyną możliwością są złe obliczenia, choć w sumie dla płaskiej powierzchni zwraca 0;1;0 więc jest ok, nie mam już żadnych pomysłów co może być źle. ;ss anyway dzięki wszystkim za pomoc.
Coś w stylu.. wadliwy shader, np. nieprawidłowy model oświetlenia? Albo przy transformowaniu normalnej do przestrzeni świata jakiś błąd?

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Marzec 28, 2013, 22:07:53
Cytuj
Albo przy transformowaniu normalnej do przestrzeni świata jakiś błąd?
W opisanym przypadku to każda próba transformacji do przestrzeni świata była by błędem, bo normalna w przestrzeni świata już jest. ;)

Offline Oti

  • Użytkownik

# Marzec 28, 2013, 22:28:17
Nie no, jest w przestrzeni heightmapy. Jak np. obrócimy heightmapę to normalne też trzeba będzie obrócić.