szklane rury w gl

0

Jak rysować przeźroczyste powierzchnie w opengl?

Z przeróżnych opisów rozumem, że to trzeba rysować w odpowiedniej kolejności, czyli najpierw bardziej odległe a później te bliższe, i z jakimś niezerowym alfa dla koloru, i chyba bez z-test w ogóle.

Tylko, że to jest chyba troszkę kłopotliwe w przypadku powierzchni złożonych z tysięcy kawałków, która dodatkowo się obraca!

Przecież ja nie mam bladego pojęcia co jest tu bliżej a co dalej, ponieważ rysuję cały czas to samo,
a wszelkie obroty robię za pomocą jednej transformacji na początku:

glRotate/translate... dowolna transforma na wstępie.

a potem ciach:
drawScene;

rysuję bryłę lub klika złożonych z miliona trójkątów;
i zawsze tak samo - w tej samej pozycji, nie mając nawet bladego pojęcia jak to będzie finalnie obrócone na ekranie!

Zatem o co tu chodzi z tym sortowaniem wzdłuż... z?

0

Przezroczystości w grafice czasu rzeczywistego to niestety spory problem jeśli ma to wyglądać poprawnie i obsługiwać wiele przykrywających się przezroczystych powierzchni.

Tak jak piszesz, jedną z metod rozwiązania tego problemu jest sortowanie poligonów - w takim przypadku można np. wyznaczyć środek każdego poligonu i przemnożyć przez macierze Model i View (w tej chwili zamiast macierzy stosujesz właśnie te glRotate() itd.) i posortować je od najdalszego do najbliższego i w takiej kolejności wyświetlać. Niestety nie jest to zbyt proste i wydajne, bo trzeba to robić co klatkę. Nie jest też perfekcyjne - kiedy poligony będą się przecinać, to może powstać efekt "pykania" kiedy raz jedna powierzchnia będzie bliżej kamery, a w następnej klatce już druga z przecinających się.

Lepszym, ale również niezbyt wydajnym rozwiązaniem jest zastosowanie algorytmu Depth Peeling/Dual Depth Peeling ([http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.18.9286&rep=rep1&type=pdf]), ale to wymaga zastosowania shaderów, stworzenia FBO i renderowania do tekstury. Jest za to pixel-perfect, ale może wymagać wielokrotnego renderowania przezroczystych obiektów w pojedynczej klatce.

Osobiście polecam tutorial http://www.opengl-tutorial.org/ - wyjaśnione są tam macierze, shadery, FBO, renderowanie do tekstury i generalnie stosuje nowsze podejście do generowania grafiki. Jeśli wersja OpenGL jest ograniczeniem, to wiele z tych rzeczy da się zastosować w OpenGL 2.1.

0

W ogólnym przypadku być może jest z tym problem,
ponieważ w naturze powierzchnie nie posiadają swojego koloru, a jedynie odbijają różnie poszczególne barwy światła (no i plus ewentualna emisja własna, co chyba nic nowego tu nie wnosi - to tylko kolejny składnik do sumy).

Jednak w przypadku jednolitego szklanego obiektu, który jest np. w 90% przeźroczysty, ale i zielonkawy zarazem,
i gdy on się tylko nakłada sam na siebie - dwa lub więcej razy, wtedy to sortowanie chyba nie ma znaczenia, nie?

Przecież to będzie zwyczajne tłumienie światła: im więcej razy się ponakładają warstwy, tym ta część ciemniejsza będzie: alfaalfa...

Kolejność przy sumowaniu i mnożeniu nie ma znaczenia, więc to powinno wyjść z marszu!

No, chyba że ten model w grafice komputerowej jest niekompatybilny z rzeczywistym.
Być może powinny być trzy alfy - osobno dla każdej składowej: r,g,b, a nie tylko jedna wspólna.. jak to jest obecnie.

0

Czy ta powierzchnia jest oświetlana? Jeśli tak, to kolejność renderowania poligonów ma znaczenie - inaczej będzie się oświetlać przednia ścianka rury, inaczej tylna.
Jeśli nie, to chyba faktycznie kolejność nie powinna mieć znaczenia. Możesz opisać w czym dokładnie jest problem? Albo najlepiej zamieścić jakiś screen z wynikiem?

0

Tak jak piszesz, jedną z metod rozwiązania tego problemu jest sortowanie poligonów - w takim przypadku można np. wyznaczyć środek każdego poligonu i przemnożyć przez macierze Model i View (w tej chwili zamiast macierzy stosujesz właśnie te glRotate() itd.)

glRotate robi glMultMatrix na aktywnej macierzy. wynik można pobrać glGetFloatv.

wyjaśnione są tam macierze, shadery, FBO, renderowanie do tekstury i generalnie stosuje nowsze podejście do generowania grafiki. Jeśli wersja OpenGL jest ograniczeniem, to wiele z tych rzeczy da się zastosować w OpenGL 2.1.

W 2.1 jeszcze nie było FBO w standardzie, chociaż mogą być dostępne jako rozszerzenie.

ponieważ w naturze powierzchnie nie posiadają swojego koloru, a jedynie odbijają różnie poszczególne barwy światła (no i plus ewentualna emisja własna, co chyba nic nowego tu nie wnosi - to tylko kolejny składnik do sumy).

Yyy.. czym się różni odbijanie poszczególnych barw z emisją własną od „posiadania koloru”? Co to jest według ciebie „posiadanie koloru”? :-)

No, chyba że ten model w grafice komputerowej jest niekompatybilny z rzeczywistym.
Być może powinny być trzy alfy - osobno dla każdej składowej: r,g,b, a nie tylko jedna wspólna.. jak to jest obecnie.

Jest „kompatybilny” w tym sensie że jest pewnym przybliżeniem. Nawet trzy składowe RGB są przybliżeniem. Są kolory niemożliwe do odtworzenia za pomocą RGB, np. pomarańczowy kolor niskoprężnej lampy sodowej.

0

Jeżeli rysujesz z włączonym depth testem to kolejność ma znaczenie ponieważ jeżeli najpierw wyrenderujesz elementy bliżej (np przednia ściana sześcianu) to nie narysujesz tych dalszych np tylnej ściany sześcianu. W przypadku przeźroczystego obiektu to błąd.
Jeżeli wyłączysz depth test to wtedy nie będzie tego problemu ale pojawi się inny, jeżeli masz scenę po której można się przemieszczać to obiekt bez depth test nie zostanie prawidłowo zakryty przez np ściany ponieważ przezroczyste obiekty rysujemy na końcu(kiedy jest już wyrenderowana scena i modele nieprzezroczyste)

Najprościej jest robić tak:

  1. Włączasz depth test i renderujesz scene + modele nieprzeźroczyste
  2. sortujesz ściany w modelach przeźroczystych i renderujesz od najdalszej do najbliższej.
0
Deselion napisał(a):

Czy ta powierzchnia jest oświetlana? Jeśli tak, to kolejność renderowania poligonów ma znaczenie - inaczej będzie się oświetlać przednia ścianka rury, inaczej tylna.
Jeśli nie, to chyba faktycznie kolejność nie powinna mieć znaczenia. Możesz opisać w czym dokładnie jest problem? Albo najlepiej zamieścić jakiś screen z wynikiem?

Powierzchnia jest symulowana maksymalnie realistycznie, zatem musi być oświetlana, aby nie była czarna: w nocy każdy kot jest czarny. :)

Wyniki mogę podać ale dopiero po rozwikłaniu problemu, który jest tu właśnie dyskutowany.

0

ponieważ w naturze powierzchnie nie posiadają swojego koloru, a jedynie odbijają różnie poszczególne barwy światła (no i plus ewentualna emisja własna, co chyba nic nowego tu nie wnosi - to tylko kolejny składnik do sumy).

Yyy.. czym się różni odbijanie poszczególnych barw z emisją własną od „posiadania koloru”? Co to jest według ciebie „posiadanie koloru”? :-)

Właśnie na tym polega problem, że ciała nie posiadają swojego koloru (pomijając źródła jak np. ogień z palika gazowego, rozpalony węgiel w piecu, błyskawice - pioruny, gwiazdy, itp.).

No, chyba że ten model w grafice komputerowej jest niekompatybilny z rzeczywistym.
Być może powinny być trzy alfy - osobno dla każdej składowej: r,g,b, a nie tylko jedna wspólna.. jak to jest obecnie.

Jest „kompatybilny” w tym sensie że jest pewnym przybliżeniem. Nawet trzy składowe RGB są przybliżeniem. Są kolory niemożliwe do odtworzenia za pomocą RGB, np. pomarańczowy kolor niskoprężnej lampy sodowej.

Jeśli tak jest, no to nie potrzeba sortować, bo przeźroczystość to faktycznie tłumienie światła.

Np. powierzchnia o przeźroczystości alfa ma kolor: kolor = alfa x światło.
Zatem gdy złożymy kilka takich warstwy, wówczas otrzymamy kilkukrotne tłumienie - im więcej warstw, tym ciemniej:
alfa1 x alfa2 x alfa3 x ... x światło (albo tło);
kolejność nie ma znaczenia w mnożeniu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1