W oparciu o opublikowany kod modułu cieniującego nie interpolujesz promieni UV z wierzchołków - raczej wydaje się, że interpolujesz pozycję 3D (fragVert
), a następnie obliczasz promieniowanie UV, przekształcając je we współrzędne sferyczne.
Twoja analiza jest poprawna, ponieważ najmniejszą mipmapę wybiera się, gdy występuje nieciągłość, ponieważ wybór mipmapy opiera się na pochodnych, które są szacowane liczbowo na podstawie UVs używanych w sąsiednich pikselach. Gdy jeden piksel ma u = 0, a drugi ma u = 1, otrzymujesz bardzo dużą pochodną. Twoja próba naprawy ma ten sam problem, ponieważ duże pochodne występują około u = 0,01 iu = 0,99, dlatego dwa szwy pojawiają się po obu stronach miejsca, w którym znajdował się pierwotny szew.
Stosunkowo proste podejście do rozwiązania problemu polegałoby na podjęciu decyzji, który poziom mipa użyć samemu i wywołaniu w textureLod
celu jego bezpośredniego pobrania. Jeśli planeta zawsze będzie dość blisko kamery, możesz po prostu zakodować poziom mip na 0 (lub, w tym przypadku, po prostu nie zawierać poziomów mip w teksturze). W przeciwnym razie może być oparty na log2 odległości punktu od kamery, skalowanej przez niektóre odpowiednie czynniki. Zauważ, że to skutecznie wyłączy filtrowanie anizotropowe.
Bardziej „poprawnym” podejściem byłoby obliczenie niektórych instrumentów pochodnych wyższej jakości. Zamiast używać dFdx
i dFdy
na UV, które mają nieciągłości z powodu atan2
, możesz zastosować dFdx
i dFdy
do fragVert
(który będzie ciągły przez całą kulę), a następnie użyj rachunku różniczkowego (reguła łańcuchowa), aby znaleźć wzór na uzyskanie pochodnych UV z pozycji instrumentów pochodnych. Będzie to bardziej skomplikowane i wolniejsze, ale ma tę zaletę, że powinno działać filtrowanie anizotropowe.
Wreszcie, ponieważ jesteś nowy w OpenGL, po prostu zauważę, że podczas obliczania UV ze współrzędnych sferycznych jest doskonale poprawnym sposobem na teksturowanie kuli, nie jest to „zwykły” sposób wybierany przez większość ludzi. Bardziej powszechne jest budowanie siatki sferycznej, która ma UV określone dla wierzchołka i po prostu przechodzi z modułu cieniującego wierzchołek do modułu cieniującego piksele (interpolowana liniowo w każdym trójkącie). Wierzchołki są umieszczone wzdłuż szwu, tak , że są dwie kopie każdego wierzchołka, dokładnie w tych samych pozycjach, ale połowa z u = 0 połączona z trójkątami po jednej stronie, a druga połowa z u = 1 połączona z trójkąty po drugiej stronie. Eliminuje to wszelkie widoczne szwy i nie wymaga żadnych sztuczek w module cieniującym piksele.