Próbujesz zrozumieć światło na Opengl, jak symulować realistyczne światło słoneczne?

13

Nie wiem, czy robię coś źle, czy coś pomijam, ale chcę symulować światło słoneczne, jak w słoneczny dzień.

Kiedy obiekt jest skierowany w stronę światła kierunkowego, jest dobrze oświetlony i nie ma żadnych problemów. Jeśli obejdę przedmiot i spojrzę na niego, jest ciemno. Nie jest zbyt ciemno, ponieważ używam, GL_AMBIENTale wciąż jest zbyt ciemno na słoneczny dzień. Jeśli zwiększę wartość, nigdy nie będzie wyglądać lepiej, ponieważ strona obiektu skierowana w stronę światła będzie zbyt jasna.

I jest jeszcze jeden irytujący problem ze światłem otoczenia, gdy patrzę na tył obiektu, nie widzę żadnego kształtu, tylko zwykły kolor. Trudno to wyjaśnić, oto kilka zdjęć:

Obiekt z przodu: http://i.stack.imgur.com/YW53X.png
Obiekt z tyłu: http://i.stack.imgur.com/Qufha.png

Jak łatwo zauważyć, przednia strona wygląda ładnie, widać kształt tej czerwonej rzeczy. Z tyłu jest prosty, nie widać tego samego kształtu.

Teraz wiem, że patrzę na tył obiektu i patrzę w kierunku światła, które powinno być ciemniejsze niż przednia strona. Ale to nie powinno wyglądać tak prosto. Tego nie widzimy, gdy patrzymy na światło słoneczne, patrząc na jakiś obiekt, widzimy, że obiekty kształtują się.

Jak mogę uzyskać taki sam (lub podobny) efekt w OpenGL?

Moje światło jest obecnie zdefiniowane w następujący sposób:

float posLight0[4] = {-1.0f, 1.0f, 1.0f, 0.0f};
float ambLight0[4] = {0.5f, 0.5f, 0.5f, 0.5f};

glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight0);
rfgamaral
źródło
Sugeruję, aby rozważyć użycie shaderów, jeśli to możliwe. Strumień stałoprądowy OpenGL wykorzystuje dość prosty model oświetlenia, natomiast shadery zapewniają pełną kontrolę nad matematyką.
Incredulous Monk

Odpowiedzi:

11

Przy świetle otoczenia twoje obiekty wydają się zbyt jasne, ponieważ światło rozproszone jest dodawane do światła otoczenia, a światło rozproszone ma domyślną wartość 1.0. Daje to 1,5, a wszystko powyżej 1,0 jest zaciśnięte. Ustaw światło rozproszone na 0,5:

float difLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, difLight0);

Drugi problem jest trudniejszy do rozwiązania. Możesz spróbować dodać do powierzchni kilka drobnych szczegółów, takich jak tekstura lub mapa wypukłości. W OpenGL światło otoczenia jest stałe, ale w prawdziwym świecie tak nigdy nie jest. Aby symulować rzeczywisty świat, potrzebna jest jakaś forma globalnego rozwiązania oświetleniowego . Okluzja otoczenia bardzo pomaga tutaj, ale trudniej ją wdrożyć niż ustawienie stanów OpenGL. Możesz upiec okluzję otoczenia na wierzchołkach modelu w oprogramowaniu do modelowania 3D lub użyć SSAO , ale nie będę przechodził do szczegółów.

To, co możesz łatwo zrobić, to dodać kolejne ściemniające źródło światła z innego kierunku (np. Przeciwnego kierunku). Nie będzie to realistyczne, ale przynajmniej nada pewien kształt tylnym bokom twoich obiektów.

Zastanów się również nad dodaniem do aplikacji wyróżnień. Sprawi, że przedmioty będą lśniące.

float specLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_SPECULAR, specLight0);
glMaterialfv(GL_FRONT, GL_SHININESS, 10.0f); // Shininess between 0 and 128

Możesz również osobno określić kolory światła i materiału, zwłaszcza jeśli domyślne ustawienia nie są odpowiednie dla Ciebie.

sprzedać
źródło
Nie ma więc prostego i bezpośredniego sposobu robienia tego, co chcę w OpengGL ... Szkoda. Może spróbuję dodać kolejne źródło światła, ale jak dokładnie określić natężenie światła?
rfgamaral
GL_SPECULARI GL_SHININESSnie wydaje się, aby produkować żadnego wpływu chociaż ... Zrobiłem zmianę glMaterialfvcelu glMateriali, ponieważ nie było kompilacją. Próbowałem też większej wartości, takiej jak 128. Wygląda to tak samo ... Może problem dotyczy mojego załadowanego modelu (obj / mtl), trzeba będzie rzucić okiem.
rfgamaral
1
@Nazgulled Właśnie sprawdziłem, czy wziernik light0 ma domyślną wartość 1.0, ale domyślny wziernik materiału to 0.0. Więc zmień glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); do glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); Dobrze jest również ustawić glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); lub odbicie lustrzane może zostać niepoprawnie obliczone, gdy kamera się obraca.
sprzedać
1
@Nazgulled W przypadku światła wtórnego ustaw otoczenie i odbłysk na zero, a także niewielką wartość, taką jak 0,2 dla rozproszenia. Możesz także ustawić otoczenie wszystkich świateł na zero i zamiast tego użyć globalnego otoczenia z GL_LIGHT_MODEL_AMBIENT.
sprzedać
2

Światło otoczenia OpenGL jest jednokolorowe, ale światło otoczenia w świecie rzeczywistym jest zwykle jaśniejsze od góry i ciemniejsze od dołu. Możesz to przybliżyć w OpenGL, ustawiając światło otoczenia na bardzo ciemnoniebieskie i dodając ciemnoniebieskie światło kierunkowe skierowane w dół. To plus jasne białe światło kierunkowe, pochodzące z dowolnego miejsca, w którym znajduje się słońce, może całkiem dobrze przybliżyć się na zewnątrz.

To, co naprawdę powinieneś zrobić, to napisać moduł cieniujący, który oblicza światło na piksel, ale dotarcie tam z miejsca, w którym się znajdujesz, zajmie trochę czasu.

bmcnett
źródło
1

Odpowiedź, którą tu masz, jest całkiem dobra. Tylko jeden dodatek. Gdy będziesz chciał, aby było ładniej, spróbuj zastosować rozpraszanie atmosferyczne

Notabene
źródło