Artefakt tekstury Skybox na krawędzi

12

Mam dziwny problem z rysowaniem tekstury Skybox na Macu. Na iPhonie wszystko idzie dobrze. Próbowałem zmienić wartość bliskich i dalekich samolotów bez powodzenia.

Jest to skybox sześciu tekstur i dla każdej tekstury ustawiam to:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Co może być problemem?

Zrzut ekranu:

Obraz nieba z widocznymi krawędziami skybox

EDYTOWAĆ:

Próbowałem ustawić kolor tła na czerwony, aby upewnić się, że przecieka przez teksturę

Próbowałem również zmienić współrzędne tekstury na to:

float err_corr = 0.5 / TEXTURE_SIZE;

GLfloat vertices[24] = {    
        -1.0f - err_corr, -1.0f - err_corr,  1.0f + err_corr,
    1.0f + err_corr, -1.0f - err_corr,  1.0f + err_corr,
    -1.0f - err_corr,  1.0f + err_corr,  1.0f + err_corr,
    1.0f + err_corr,  1.0f + err_corr,  1.0f + err_corr,
    -1.0f - err_corr, -1.0f - err_corr, -1.0f - err_corr,
    1.0f + err_corr, -1.0f - err_corr, -1.0f - err_corr,
    -1.0f - err_corr,  1.0f + err_corr, -1.0f - err_corr,
    1.0f + err_corr,  1.0f + err_corr, -1.0f - err_corr,
    };

I pudełko jest rysowane w tej kolejności:
GLubyte indices[14] = {0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1};

ROZWIĄZANIE:

Rozwiązaniem jest ustawienie GL_CLAMP_TO_EDGE dla samej mapy kubatury!

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
martin pilch
źródło

Odpowiedzi:

8

Czy jesteś pewien, że ustawiłeś GL_CLAMP_TO_EDGE dla każdej tekstury ? Jest to część indywidualnego stanu tekstury i domyślnie jest to GL_REPEAT, więc należy to zrobić po powiązaniu z glBindTexture. Rozumiem w oryginalnym poście, że dosłownie mówisz, że ustawiłeś go dla każdej tekstury, ale zastanawiam się, jak naprawdę wygląda kod?

Na przykład:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_2D, tex1);
//upload texture, etc.

glBindTexture(GL_TEXTURE_2D, tex2);
//upload texture, etc.

To nie to samo, co:

glBindTexture(GL_TEXTURE_2D, tex1);
//upload texture, etc.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_2D, tex2);
//upload texture, etc.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
użytkownik_123abc
źródło
Znalazłem błąd! Konieczne było nie ustawianie GL_CLAMP_TO_EDGE dla każdej tekstury mapy kostki, ale dla samej aplikacji cubemapp! glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);orazglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
martin pilch
1

wstaw „0,5f / texture_width” z lewej i prawej strony tekstury oraz „0,5f / texture_height” od góry i dołu. Widzisz artefakty próbkowania - próbniki tekstury zwykle próbkują od środka tekstur, więc po lewej i prawej stronie, u góry i na dole (przy 0 i 1 UV) dostajesz 50% tego, co texel dostaje sampler, gdy jest poza zakresem . To albo druga strona tekstury, albo domyślny kolor próbkowania.

Luther
źródło
Dlatego ma GL_CLAMP_TO_EDGEzestaw, który powinien sprawić, że próbki poza granicami przyjmą wartość najbliższych pikseli tekstur. To, co opisujesz, może bardzo dobrze działać, ale nie wyjaśnia, dlaczego problem istnieje.
aaaaaaaaaaaa
Próbowałem bez zmian: /
martin pilch
0

Domyślam się, że różnica między MAC a iPhone'em jest spowodowana antyaliasingiem na MAC. Moje programowanie 3D jest trochę zardzewiałe, ale myślę, że musielibyście zrobić wszystkie kwadraty częścią tej samej siatki lub coś w tym rodzaju.

Brudne rozwiązanie polegałoby na tym, że wszystkie kwadraty byłyby trochę za duże, aby nakładały się na siebie i zaciskały i odpowiednio dostosowywały współrzędne UV.

aaaaaaaaaaaa
źródło
Próbowałem wyłączyć wygładzanie (przez glDisable (GL_POLYGON_SMOOTH);) bez efektu. Rysuję skybox jako trójkątny pasek z kordami od -1 do 1
martin pilch
1
Dla mnie brzmi dobrze. Przynajmniej na razie nie zgaduję, ale możesz zawęzić problem, dowiadując się, czy ta czerń jest prześwitującym tłem, czy krawędź tekstury ma kolor czarny. Jeśli umieścisz czerwony wielokąt gdzieś za artefaktem, czy artefakt przyjmie swój kolor?
aaaaaaaaaaaa
Chcę spróbować rozszerzyć ściany, aby się nakładały (tak jak napisał eBiznes) - myślę, że wystarczy 0,0001. Nie musisz zmieniać współrzędnych UV.
zacharmarz
1/10000 z pewnością nie wystarczy, wielkość problemu wydaje się mieścić w zakresie od 1/4 do 1/2 piksela, więc w zależności od rozmiaru tekstury minimalna wielkość do działania będzie wynosić około 1/1000. Brak dostosowania współrzędnych UV jest dość niechlujny, biorąc pod uwagę naturę tekstury, wynikowy skok wizualny może nie być zauważalny, ale nadal byłby błędny. W każdym razie dalsze porady dotyczące hacków powinny zależeć od odpowiedzi na pytanie, które zadałem w poprzednim komentarzu.
aaaaaaaaaaaa
Artefakt nie jest tłem krwawiącym przez teksturę. Ustawiłem kolor tła na czerwony bez zmian. Próbowałem także rozszerzyć współrzędne tekstury
martin pilch
0

Jest to zwykły problem z mapami kubatury na starszych urządzeniach sprzętowych (lub na telefonach). Sprawdź, czy

GL_ARB_seamless_cube_map

rozszerzenie, jeśli jest dostępne na twoim sprzęcie. W takim razie. Problem można rozwiązać za pomocą go.

Notabene
źródło
Problem dotyczy GeForce 9400M, a nie iPhone'a. To rozszerzenie nie jest dla mnie dostępne.
martin pilch
To zdecydowanie NIE jest problem powodowany przez mapy kubatury, niezależnie od tego, czy są płynne, czy nie. Jest to problem z zawijaniem tekstur.
Tara,
0

Czy sześć tekstur jest skonfigurowanych konkretnie jako mapa kostki, czy też każda ze ścian skybox jest renderowana osobno z własną teksturą? Słyszałem, że niektóre wczesne systemy komputerowe miały dość słabe filtrowanie, jeśli chodzi o obsługę map kubatur, ponieważ niekoniecznie filtrowały one teksturę jednej powierzchni do drugiej, gdy próbkowałeś w pobliżu krawędzi kostki. AFAIK, GPX (iPhone GPU) powinien poprawnie filtrować między krawędziami.

Przyszło mi do głowy, że spód twoich bocznych tekstur wygląda jak odcień niebieskiego do artefaktu. Czy możesz spróbować, powiedzmy, uczynić dolny rząd (lub kilka rzędów) pikseli ohydnym odcieniem magenty i zobaczyć, czy to zmieni kolor artefaktu? To może dać więcej wyobrażenia o tym, co może się dziać, a co nie.

Simon F.
źródło