Com base no código de sombreador que você postou, você não está interpolando os UVs dos vértices - parece que você está interpolando a posição 3D ( fragVert
) e calculando os UVs transformando em coordenadas esféricas.
Sua análise está correta, pois o menor mipmap é escolhido quando há uma descontinuidade, pois a seleção do mipmap é baseada em derivadas estimadas numericamente a partir dos UVs usados nos pixels vizinhos. Quando um pixel tem u = 0 e outro tem u = 1, você obtém uma derivada muito grande. Sua tentativa de correção tem o mesmo problema: derivadas grandes ocorrem em torno de u = 0,01 e u = 0,99, e é por isso que duas costuras aparecem nos dois lados de onde estava a costura original.
Uma abordagem relativamente simples para corrigir o problema seria decidir qual nível de mip usar e chamar textureLod
para amostrá-lo diretamente. Se o planeta sempre estiver próximo da câmera, você poderá codificar o nível mip para 0 (ou, nesse caso, apenas não incluir os níveis mip na textura). Caso contrário, poderia ser baseado no log2 da distância do ponto da câmera, dimensionado por alguns fatores adequados. Observe que isso desativará efetivamente a filtragem anisotrópica.
Uma abordagem mais "correta" seria calcular alguns derivativos de maior qualidade. Em vez de usar dFdx
e dFdy
nos UVs, que têm descontinuidades devido a atan2
, você pode aplicar dFdx
e dFdy
ao fragVert
(que será contínuo por toda a esfera), depois use algum cálculo (regra da cadeia) para encontrar a fórmula para obter os derivados UV dos derivativos da posição. Isso será mais complicado e mais lento, mas tem a vantagem de que a filtragem anisotrópica deve funcionar.
Finalmente, como você é novo no OpenGL, observarei que, embora o cálculo de UVs a partir de coordenadas esféricas seja uma maneira perfeitamente válida de texturizar uma esfera, não é a maneira "usual" que a maioria das pessoas escolhe. É mais comum construir uma malha de esfera com UVs especificados por vértice e simplesmente passar do sombreador de vértice para o sombreador de pixels (interpolado linearmente em cada triângulo). Os vértices são colocados ao longo da costura, assim , de modo que haja duas cópias de cada vértice, exatamente nas mesmas posições, mas metade com u = 0 conectado aos triângulos de um lado e a outra metade com u = 1 conectado a os triângulos do outro lado. Isso elimina qualquer costura visível e não requer truques no pixel shader.