Autor Wątek: [SOLVED] Problem z oświetleniem lamberta  (Przeczytany 1696 razy)

Offline ekicam2

  • Użytkownik

# Lipiec 04, 2017, 13:48:12
Hej wszystkim, troszkę wstyd się przyznać ale mam problem z poprawnym oświetleniem. Kombinuje już 3 dzień z rzędu i powoli styki mi się przegrzewają.

<pierwszy obrazek z załącznika>
Cylinder po prawej jest oświetlany od przodu a mimo to na środku podstawy tworzy się cień.

Wszystkie obliczenia przeprowadzam w World space(mnożąc przez model matrix) a normalne(mnożąc przez inverse transpose model) ażeby ich rzecz jasna nie skalować.

<drugi obrazek z załącznika>
Z Suzanne też nie jest lepiej, chociaż przez teksture drewna i lekko podbity ambient nie jest to aż tak widoczne.

<trzeci obrazek totalny sajgon>
Parafrazując: jak to bardzo nie działa każdy widzi.

cały kod do wglądu na githubie: https://github.com/ekicam2/tiny_renderer/tree/master/tiny_renderer/res/shaders

Mesh.cpp; shader.vs; shader.fs; Source.cpp
« Ostatnia zmiana: Lipiec 15, 2017, 01:31:01 wysłana przez ekicam2 »

Offline Mr. Spam

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

Offline Icy Tower

  • Użytkownik

# Lipiec 04, 2017, 20:13:52
Hej,
zacząłbym od wykomentowania cieniowania typu specular w kodzie. Bo ono na pewno jest złe. Samo cieniowanie diffuse wydaje się być ok w twoim kodzie.

Jeśli chodzi o specular to chyba próbujesz uzyskać cieniowanie Phong'a - w takim razie ten zakomentowany kod na dole wydaje się to robić.

Może być jeszcze tak, że przekazujesz złe dane do shader'a w Constant Bufferze - może np przekazujesz macierze w postaci wierszowej a shader oczekuje w kolumnowej (w sensie tego, gdzie w macierzy są osie bazowe przekształcenia - x, y, z i translacja).

Ale zacząłbym od wykomentowania kodu specular i sprawdzeniu jak się to zachowuje. W przypadku niektórych modeli - np cylindra może być tak, że masz w modelu dziwne normalki i one się interpolują dając dziwny efekt. Powinno być tak, że wierzchołki na brzegu są zdublowane - jedne dla sufitu a drugie dla boku. Te dla sufitu mają normalkę w górę a te z boku w bok :) Ale jeśli w modelu jest to jedna grupa wierzchołków na krawędzi (regulują to smoothgrupy w 3D Maxie chyba i pewnie opcje eksportu itp) to wtedy ta normalka może być np na skos. I zarówno sufit i ściany będą źle wyglądały - może tak jak u Ciebie.

Wrzucaj kolejne screeny i na pewno się uda rozwiązać.
« Ostatnia zmiana: Lipiec 04, 2017, 20:15:46 wysłana przez Icy Tower »

Offline Mergul

  • Użytkownik

  • +2
# Lipiec 04, 2017, 20:38:23
I normalizuj normalke we fragment shaderze. Bo ze względu na interpolacje może zmieniać się długość.

Offline ekicam2

  • Użytkownik

# Lipiec 04, 2017, 21:51:55
@Icy Tower
Używam glm to chyba powinno rozwiązać problem z macierzami?
Specular jest zły bo jest to blinn pomieszany z normalnym phongiem (aka. kupong).

Wierzchołki w cylindrze nie są zdublowane i to może być problem w przypadku cylindra. Aczkolwiek w blenderze obiekt jest oświetlony poprawnie, to samo w visual studio(tak ta kobyła ma takie ficzery).
Najgorsze że małpa też się sypie.

Obiekty ładuję tinyobj. Ale to chyba nie ma znaczenia.

@Mergul
Wiem wiem ale próbuje już wszystkiego, wiesz tonący brzytwa ;)
« Ostatnia zmiana: Lipiec 04, 2017, 22:04:32 wysłana przez ekicam2 »

Offline Icy Tower

  • Użytkownik

# Lipiec 04, 2017, 22:56:24
GLM chyba niewiele tu zmienia. To kwestia konwencji jaką przyjmujesz i jaką OpenGL przyjmuje. Możesz trzymać macierze w postaci wierszowej w kodzie w C++ i kolumnowej w shaderze - nic Tobie nie zabrania. Na dodatek przy przesyłaniu do shader'a istotne jest rozmieszczenie tych elementów w pamięci - to samo może wpłynąć na to, że twoja macierz zostanie źle zinterpretowana w shaderze. Spróbowałbym dla testu zrobić transpozycje macierzy podczas wysyłania ich do shader'a (ale w C++ mają zostać jak są).

A ten specular to u Ciebie jakby diffuse podniesiony do potęgi. Dla mnie to nie ma żadnego sensu. Wywal go najlepiej i pokaż screeny znowu.

Offline DezerteR

  • Użytkownik

# Lipiec 04, 2017, 23:04:42
Akurat jak używa GLM to dobrze, przynajmniej ma dobrze policzone macieże, przy tym kierunku mnożenia jest ok.

A to jeśli normalki są w worldspace to mnożenie przez modelMatrix nie będzie ok?
No i co to jest?
vertexInWorld = (modelMatrix * vec4(vertexPosition, 0.0f)).xyz;
Jak masz tam zero to nie przesuniesz wierzchołka -> masz złą pozycję.

No i specular to się dodaje do kolor*diffuse, no i źle go liczysz, ale to wiesz.

Offline Mergul

  • Użytkownik

# Lipiec 04, 2017, 23:08:09
Jakby macierze były złe to prawdopodobnie obiekty byłyby niewidoczne (jeżeli chodzi o wierszowy/kolumnowy). Patrzyłem na kod mnożący macierze i wydaje się normalny.

To samo co wyżej napisano, specular aktualny jest bez sensu, a vertexInWorld nie jest wierzchołkiem w świecie.

Kod nie pasuje mi do tego co widze na ekranie, bo kod się troche zmienia. Ciekawy dobór tekstur... "siusiak" :P

Offline ekicam2

  • Użytkownik

# Lipiec 04, 2017, 23:29:24
@Mergul
Różnica między pierwszym screenem a drugim w kodzie jest żadna.
Natomiast w trzecim linia
  sun.Direction = glm::vec3(0.0f, 0.0f, -1.0f);Zmienia się na
  sun.Direction = glm::vec3(0.0f, 0.0f, -144.0f);Dzięki temu że w FS nie normalizuje -sun.direction dostaje podbite światło.

Co do speculara jest to zdesperowana pijana interpretacja popółnocna, dlatego wygląda to tak a nie inaczej. Poprawny specular jest zakomentowany na samym dole shadera.

Co do vertexInWorld błąd poprawię po powrocie do domu. W chwili obecnej jestem królem BP!

Offline DezerteR

  • Użytkownik

  • +1
# Lipiec 05, 2017, 00:01:27
Njalepiej żeby zdebugować to wrzuć abs(normalki) na wyjście fs, jeśli jest tam błąd będzie widać po kolorze. Potem możesz się pobawić i zamienić normalMatrix na modelMatrix, wyrysować też dot(N, light), a w końcu pewnie poprawić loader modelu/export z blendera bo ewidentnie nie splituje ci wierzchołków.

No i to:
layout(location = 1) in vec3 vertexIndices;
jest złe.

Indeksóy nie należą do wierzchołka, nie powinieneś ich pchać do shadera, jak zauważysz jest ich inna ilość niż wierzchołków.
if (Indices.size() > 0)
            {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[1]);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indices.size() * sizeof(uint16_t), &Indices[0], GL_STATIC_DRAW);
                wywalić /// glEnableVertexAttribArray(1);
                wywalić /// glVertexAttribPointer(1, 3, GL_UNSIGNED_SHORT, GL_FALSE, 0, (void*)0);
}

Polecam zbindować index buffer na samym końcu i zostawić go w spokoju, najprawdopodobniej to psuje ci normalki i UV(to nawet widać na małpce).

I jeszcze:
glDrawElementsBaseVertex(GL_TRIANGLES, pQuad->GetIndicesCount(), GL_UNSIGNED_SHORT, (void*)0, 0);
jest ok, ale możesz uprościć do samego glDrawElements(GL_TRIANGLES, pQuad->GetIndicesCount(), GL_UNSIGNED_SHORT, (void*)0);

Offline ekicam2

  • Użytkownik

# Lipiec 05, 2017, 00:14:29
@DezerteR
Zgadza się przecież indeksów może być znacznie więcej niż vertexów(w sumie nawet powinno cała idea indeksowania).
To idzie pierwsze do zmiany!

Co do Suzi to ona chyba tak czy siak będzie ubogo otekstorowana. Ze mnie taki blenderoman jak z "koziej dupy trąba".

Dzięki serdeczne wszystkim za zainteresowanie i chęć pomocy. Już nie mogę się doczekać aż siądę w domu do kompa i będę mógł testować!

Offline ekicam2

  • Użytkownik

# Lipiec 06, 2017, 10:59:37
<pierwszy załącznik>
Przeniosłem indeksy na koniec i wyrzuciłem je z shadera! Również normalizuję light.dir i normalInWorld :)
Niestety to nic nie pomaga.

<drugi załącznik>
Abs normalek na output.
Podstawa cylindra świruje- pojawia się i znika mniejszy czarny okrąg do tego ten czerwony półksiężyc. Wygląda to tak jakby się przesuwały w płaszczyźnie.
Co do małpy to zastanawia mnie jej broda w niektórych miejscach jest zielona- i dokładnie w tych miejscach jest czarna przy cieniowaniu.

<trzeci załącznik>
Dziwna sprawa podkreśliłem wartość wektora określającego kierunek światła. Wygląda to tak jakby małpa brała te wartości z -y?

Offline DezerteR

  • Użytkownik

# Lipiec 06, 2017, 12:29:37
No to już nie wiem, spróbuj może nie transformować normalek.

Offline ekicam2

  • Użytkownik

# Lipiec 06, 2017, 14:01:56
Załączniki w chwili obecnej jako śmieszki ;)

Zdecydowałem że przepnę się na assimp'a ponieważ ewidentnie jest coś nie tak z normalnymi, a sam tinyobj jest dość mocno ograniczony i w zamyśle miał być w przyszłości zmieniony.
« Ostatnia zmiana: Lipiec 06, 2017, 14:06:23 wysłana przez ekicam2 »

Offline Mergul

  • Użytkownik

  • +1
# Lipiec 06, 2017, 14:33:17
Jeszcze jedna sprawa. Liczysz światło jako vec4, a wątpię zebyś chciał mieć alpha na np. 5.8 na wyjściu ;) Licz to jako vec3. I spróbuj dla pewności zamiast normal matrix wykorzystać mat3(ViewMatrix).

Offline ekicam2

  • Użytkownik

# Lipiec 06, 2017, 15:34:01
@Mergul
Nie powinno być w moim przypadku: vec3(modelMatrix) ja światło liczę w world space? A co do tego że nie chce mieć alphy za wysokiej to już poprawiłem dzięki ;)

A wynik taki sam bo nie skaluję tego w żaden sposób. :/