OpenGL - białe krawędzie na kostkach

12

W tworzonej przeze mnie grze typu minecraft mam białe krawędzie na kostkach:

wprowadź opis zdjęcia tutaj

Jest to znacznie bardziej widoczne w ciemniejszych teksturach. Tekstury są konfigurowane w następujący sposób: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Jakaś pomoc?

Luis Cruz
źródło
3
Czy potrafisz pokazać kod, jak renderujesz każdą kostkę i jak umieszczasz kostkę?
joncodo,
1
Czy zawijanie tekstur robi coś innego? Jak wygląda / rozmiar tekstury, z którą się wiążesz?
Chuck D,
Chciałem tylko zaznaczyć, że widziałem, że dzieje się to również w dużych atlasach tekstur, które wykorzystują małe płytki. Na przykład powiedzmy, że masz zestaw klocków / atlas 1024 * 1024, a używasz kafelków 32 * 32. Występują błędy zaokrąglania, ponieważ kropka dziesiętna odwzorowana na wspomnianą płytkę jest bardzo mała podwójna. To sprawia, że ​​precyzja jest prawie niemożliwa. Rozwiązanie? Podziel atlas kafelków na pojedyncze kafelki. To właśnie robi lub kiedyś robiło Minecraft. Mieli jeden duży zestaw kafelków, aw czasie wykonywania dzielili go na pojedyncze tekstury.
Krythic

Odpowiedzi:

19

Istnieją dwie możliwe przyczyny tego typu problemu, w zależności od tego, który dokładnie problem. Wymienię oba:

1. Widzisz inne kolory z tekstury wzdłuż krawędzi płytek.

Wygląda mi to na problem w tym przypadku, ponieważ wszystkie piksele krawędziowe są jednym z trzech kolorów, które są prawdopodobne w twojej teksturze: białym, czarnym i brązowym.

Jeśli używasz wielu obrazów sąsiadujących ze sobą w jednej teksturze (atlas tekstury), jak zakładam, robisz to jest nieuniknione. Dzieje się tak, ponieważ procesor GPU nie idealnie dopasowuje interpolację wzdłuż krawędzi trójkąta z interpolacją wzdłuż tekstury, a otrzymujesz małe kawałki sąsiedniej tekstury.

Istnieje wiele rzeczy, które możesz zrobić.

  • Użyj tekstury tablicy zamiast atlasu tekstury. Tekstura tablicy składa się ze stosu obrazów 2D o tym samym rozmiarze, a Ty wybierasz trzecią współrzędną, aby ją wybrać; jest pomyślany dokładnie jako zamiennik atlasów tekstur bez problemu z filtrowaniem. Tekstury tablic są jednak nowszą funkcją, która może nie być dostępna w używanej wersji OpenGL.
  • Wygeneruj 1-pikselową ramkę w każdym kafelku tekstury, który replikuje kolor sąsiedniego zwykłego piksela. (Zasadniczo polega to na ponownym wdrożeniu GL CLAMP[_TO_EDGE], ale w sposób, który jest świadomy atlasów tekstur - twoje użycie nie ma żadnego efektu, ponieważ większość twoich krawędzi płytek nie znajduje się na krawędzi tekstury.) To jest rozwiązanie, którego używam we własnym wpisie w gatunku Cubes . Nie znam żadnych szczególnych wad, z wyjątkiem tego, że wykorzystuje więcej pamięci tekstur.
  • Bardzo delikatnie wstaw współrzędne tekstury, aby nie dochodziły do ​​krawędzi kafelka tekstury. Wykonanie tego zbyt wiele doprowadzi do zauważalnej cienkości krawędzi tekstury w porównaniu do pikseli na środku.
  • Użyj jednej tekstury dla każdego rodzaju płytki. Nakłada to koszty zmiany tekstury.

2. Widzisz szczeliny między płytkami.

Nie sądzę, że jest to problem w tym przypadku, ponieważ nie ma zielonego gruntu widocznego przez luki, ale włączam go dla kompletności.

Może się to zdarzyć, gdy nie podajesz dokładnie tych samych współrzędnych dla wierzchołków krawędzi zetknięcia sąsiednich płytek, co zwykle powstaje z powodu błędu zmiennoprzecinkowego. Na przykład, jeśli masz płytki o wielkości 0,6 i obliczyć prawą krawędź płytki na x=100z (100*0.6) + 0.6, a lewa krawędź płytki na x=101z (100*0.6), nie dostaniesz dokładnie taką samą odpowiedź, a różnica może być widoczne jako małe plamki luki.

Rozwiązaniem jest upewnienie się, że arytmetyka jest spójna; niektóre sposoby na to:

  • Upewnij się, że nie jesteś (nawet pośrednio) informatykiem index*size + size, ale tylko (index+1)*size.
  • Upewnij się, że twoja arytmetyka jest dokładna; najprostszym sposobem na to jest dopasowanie wielkości kafelka dokładnie do 1,0, co spowoduje dokładną arytmetykę liczb całkowitych, nawet jeśli wykonasz obliczenia przy użyciu liczb zmiennoprzecinkowych 32-bitowych (w każdym razie do 16 milionów bloków od początku).
  • Użyj rzeczywistych liczb całkowitych do obliczeń współrzędnych wierzchołków; to daje ci jeszcze większy zasięg.
Kevin Reid
źródło
Wygląda mi na luki - brak krwawienia tekstur (chyba że jest to dość tekstura wysokiej rozdzielczości), biorąc pod uwagę małe i ostre kawałki.
Mario,
Dzięki, wstawienie nieco współrzędnych tekstury wydaje się to naprawić.
Luis Cruz,
@Mario Zakładam, że jest to z NAJBLIŻSZYM powiększeniem - zwróć uwagę na ostre obramowanie po wewnętrznej stronie płytki. W tej perspektywie jest to tekstura o nieskończonej rozdzielczości.
Kevin Reid,
Możesz także użyć tablicy tekstur, aby uniknąć kosztów zmiany.
danijar