Eu tenho um mecanismo de jogo 2D que desenha mapas de peças desenhando peças a partir de uma imagem de conjunto de peças. Como, por padrão, o OpenGL só pode agrupar toda a textura ( GL_REPEAT
), e não apenas parte dela, cada bloco é dividido em uma textura separada. Em seguida, as regiões do mesmo bloco são renderizadas adjacentes uma à outra. Aqui está o que parece quando está funcionando como pretendido:
No entanto, assim que você introduz a escala fracionária, as costuras aparecem:
Por que isso acontece? Eu pensei que era devido à filtragem linear misturando as bordas dos quadriláteros, mas ainda acontece com a filtragem de pontos. A única solução que encontrei até agora é garantir que todo posicionamento e escalonamento ocorram apenas em valores inteiros e usar a filtragem de pontos. Isso pode degradar a qualidade visual do jogo (particularmente que o posicionamento sub-pixel não funciona mais, portanto, o movimento não é tão suave).
Coisas que tentei / considerei:
- antialiasing reduz, mas não elimina completamente, as costuras
- desativar o mipmapping, não tem efeito
- renderize cada ladrilho individualmente e expulse as arestas em 1px - mas isso é uma des otimização, pois não pode mais renderizar regiões de ladrilhos de uma só vez e cria outros artefatos ao longo das arestas das áreas de transparência
- adicione uma borda de 1px ao redor das imagens de origem e repita os últimos pixels - mas eles não serão mais dois, causando problemas de compatibilidade com sistemas sem suporte a NPOT
- escrevendo um sombreador personalizado para lidar com imagens lado a lado - mas o que você faria de diferente?
GL_REPEAT
deve pegar o pixel do lado oposto da imagem nas bordas e não escolher transparência. - a geometria é exatamente adjacente, não há erros de arredondamento de ponto flutuante.
- se o sombreador do fragmento for codificado para retornar a mesma cor, as costuras desaparecerão .
- se as texturas estiverem definidas como em
GL_CLAMP
vez deGL_REPEAT
, as costuras desaparecerão (embora a renderização esteja incorreta). - se as texturas estiverem definidas
GL_MIRRORED_REPEAT
, as costuras desaparecerão (embora a renderização esteja incorreta novamente). - se eu tornar o fundo vermelho, as costuras ainda estão brancas. Isso sugere que está amostrando branco opaco de algum lugar, em vez de transparência.
Portanto, as costuras aparecem apenas quando GL_REPEAT
definidas. Por alguma razão apenas neste modo, nas bordas da geometria há algum sangramento / vazamento / transparência. Como pode ser? Toda a textura é opaca.
GL_NEAREST
amostragem na R
direção de coordenadas também funcionam tão bem quanto texturas de matriz para a maioria das coisas neste cenário. O mapeamento de mip não vai funcionar, mas, a julgar pelo seu aplicativo, você provavelmente não precisa de mipmaps.