Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[OpenGL, QTCreator C++] Poprawne wyświetlanie półprzezroczystych obiektów

Ostatnio zmodyfikowano 2012-03-16 16:09
Autor Wiadomość
Toboe
Temat założony przez niniejszego użytkownika
[OpenGL, QTCreator C++] Poprawne wyświetlanie półprzezroczystych obiektów
» 2012-03-15 15:31:29
Mam 2 płaszczyzny półprzezroczyste (0.8f i 0.5f kanał alfa), które przecinają się w przestrzeni. Nie jestem jednak w stanie ich wyświetlić poprawnie. DEPTH_TEST byłby dobry, gdybym mógł określać kolejność wyświetlania (przecinanie płaszczyzn to wyklucza), a ALPHA_TEST byłby dobry dla tekstur z alfa równym 0 lub 100 bez wartości pomiędzy. Program mój powinien radzić sobie z każdą sceną zdefiniowaną przez użytkownika nawet dla ponad setki takich płaszczyzn (potem będą to tekstury z różnymi wartościami kanału alfa) przecinających się i zdefiniowanymi w obojętnej kolejności.
C/C++
//do rysowania poza ekranem
QGLPixelBuffer * pbuff;
QGLFormat pbufferFormat = QGLFormat( QGL::DoubleBuffer | QGL::DepthBuffer );
pbufferFormat.setAlpha( true );
pbuff = new QGLPixelBuffer( QSize( 1000, 1000 ), pbufferFormat );
pbuff->makeCurrent();
//rzutowanie perspektywiczne
glFrustum( - 0.1, 0.1, - 0.1, 0.1, 0.1, 5 );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDepthFunc( GL_LESS );
glBegin( GL_POLYGON );

// kolejne wierzchołki wielokąta
glColor4f( 1.0f, 0.0f, 0.0f, 0.8f );
glVertex3f( 0.0, 0.0, - 3 );
glVertex3f( 0.0, 1.0, - 4 );
glVertex3f( 1.0, 1.0, - 4 );
glVertex3f( 1.0, 0.0, - 3 );

// koniec definicji prymitywu
glEnd();
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_DST_COLOR );
glBegin( GL_POLYGON );

// kolejne wierzchołki wielokąta
glColor4f( 0.0f, 1.0f, 0.0f, 0.5f );
glVertex3f( 0.5, - 0.2, - 4 );
glVertex3f( 0.5, 0.8, - 4 );
glColor4f( 0.0f, 0.0f, 1.0f, 0.5f );
glVertex3f( 0.5, 0.8, - 2 );
glVertex3f( 0.5, - 0.2, - 2 );

// koniec definicji prymitywu
glEnd();

glFlush();
QImage a = pbuff->toImage();
Moje pytanie brzmi: Jak tego dokonać?=/
Wersja OpenGL nie gra roli (choć nie wyższa niż 4_0, którą jako ostatnią obsługuje QTCreator)
P-52634
DejaVu
» 2012-03-15 21:26:02
Jeżeli nie znasz OpenGL-a to się zacznij jego uczyć. Qt nie ma nic wspólnego z problemem, który poruszyłeś.

Kursy
Definiowanie sceny 3DRozdział 3. Modyfikacja obszaru renderingu, rzutowanie prostokątne, rzutowanie perspektywiczne, położenie obserwatora, 5 przykładowych programów. (lekcja)
Mieszanie kolorówRozdział 15. Równanie mieszania kolorów, współczynniki mieszania kolorów; dwa programy przykładowe, w tym efekt przezroczystości. (lekcja)
P-52662
Toboe
Temat założony przez niniejszego użytkownika
» 2012-03-15 23:31:53
Czytałem i nie ma tu rozwiązania dla mojego problemu. Nadal nie mam możliwości narysowania dwóch przecinających się płaszczyzn/trójkątów whatever. Kolory umiem mieszać, ale mieszanie kolorów dla przeźroczystości daje wyłącznie efekty dla elementów, które da się posortować. Ja potrzebuję rozwiązania uniwersalnego dla każdej sceny i wielu półprzezroczystych obiektów. W kursach tutejszych nie ma rozwiązania problemu OIT (Order Independent Transparency).
P-52673
ison
» 2012-03-15 23:34:52
Ta, właśnie z półpzezroczystymi obiektami jest najwięcej problemów bo niestety opengl sam za nas tego nie 'wymiesza'. Dla nieprzecinających się elementów wystarczy sort po odległości, dla przecinających musisz już raczej niestety dzielić face'y na mniejsze części w punkcie przecięcia, nie wiem czy jest prostsza metoda.
P-52674
DejaVu
» 2012-03-15 23:35:05
W OpenGL-u gila Ciebie to w jakiej kolejności obiekty trafiają na scenę i niczego nie musisz sortować. Po prostu wrzucasz obiekty i OpenGL robi całą pozostałą robotę za Ciebie. Wystarczy tylko poustawiać odpowiednie flagi. W rozdziale, który podałem masz rozwiązanie Twojego problemu i widać to chociażby na screenie załączonym do lekcji.
P-52675
ison
» 2012-03-15 23:42:49
W OpenGL-u gila Ciebie to w jakiej kolejności obiekty trafiają na scenę i niczego nie musisz sortować.

kod z artykułu:
glDepthMask( GL_FALSE );

No niestety tak pięknie nie jest ;) W przypadku zwykłego renderowania półprzezroczystego face'a wszystko co będzie się znajdowało za tym obiektem nie będzie po prostu renderowane (tzn nie będzie go widać przez półprzezroczysty face) ponieważ te 'dalsze' pixele dzięki buforowi głębokości zostaną odrzucone - opengl stwierdzi że są zasłonięte. Właśnie dlatego na czas renderowania wyłącza się bufor głębokości i wszystko działa pięknie. Do czasu kiedy wyrenderujemy kilka półprzezroczystych faceów w różnej kolejności - wyłączyliśmy przecież depth mask więc zostaną wyrenderowane w takiej kolejności jak je podamy a nie w takiej jak powinny. Właśnie dlatego półprzezroczyste face'y trzeba sortować po odległościach. No tak, sortowanie odłegłościami nie jest trudne, ale co się dzieje jeśli 2 takie obiekty się przecinają? Żadne z rozwiązań nie będzie dobre, nie możemy wyświetlić najpierw 1 obiektu a potem drugiego ani na odwrót bo zawsze uzyskamy zły efekt.
P-52677
Toboe
Temat założony przez niniejszego użytkownika
» 2012-03-15 23:46:38
Albo jestem ślepy, albo nie wiem gdzie Ty widzisz rozwiązanie, bo jedynie widzę takie teksty jak:
"Niestety aby obiekty przezroczyste były prawidłowo renderowane należy je rysować w kolejności od najdalej położonego względem osi Z."
"Jest to oczywiście rozwiązanie dostosowane do realiów wyświetlanej sceny i nie ma niestety żadnych cech uniwersalności."
=/

EDIT: ison, w podręczniku ("OpenGL Księga Eksperta wydanie 5") widziałem metodę z wielopróbkowaniem z maskami oraz korzystanie z własnego shadera, ale miałem nadzieję na prostsze rozwiązanie i nieograniczone ilością przesłaniających się elementów (w podręczniku ograniczono do 4 nachodzeń w danym pikselu). Tam też pisali, że rozwiązanie nie jest dobre dla setek zasłaniających się obiektów...
Chyba porywam się z motyką (moimi umiejętnościami) na słońce (jeden z największych problemów OpenGL)...
P-52678
ison
» 2012-03-16 00:13:21
Do czego w ogóle to potrzebujesz? Jesteś pewien, że te 2 płaszczyzny będą się przecinać? Może jest prostsze rozwiązanie?
P-52682
« 1 » 2
  Strona 1 z 2 Następna strona