OpenGL - arestas brancas em cubos

12

Em um jogo parecido com minecraft que estou criando, obtenho bordas brancas em meus cubos:

insira a descrição da imagem aqui

É muito mais visível em texturas mais escuras. As texturas estão sendo configuradas assim: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Qualquer ajuda?

Luis Cruz
fonte
3
Você pode mostrar algum código sobre como renderizar cada cubo e como colocar cubos?
joncodo
1
A quebra das texturas faz algo diferente? Como é a textura / tamanho ao qual você está vinculando?
mandril D
Eu só queria ressaltar que já vi isso acontecer em grandes atlas de textura, que usam pequenos ladrilhos. Como exemplo, suponha que você tenha um conjunto de peças / atlas de 1024 * 1024 e que esteja usando peças de 32 * 32. Você recebe erros de arredondamento porque o ponto decimal que mapeia para o referido bloco é um duplo muito pequeno. Isso torna a precisão quase impossível. Uma solução? Divida o atlas de peças em peças individuais. É isso que o Minecraft faz ou costumava fazer. Eles tinham um grande conjunto de peças e, em tempo de execução, dividiam-no em texturas individuais.
Krythic 9/04/19

Respostas:

19

Existem duas causas possíveis para esse tipo de problema, dependendo exatamente de qual é o problema. Vou listar os dois:

1. Você está vendo outras cores da sua textura ao longo das bordas dos ladrilhos.

Isso me parece o problema neste caso, porque todos os pixels das bordas são uma das três cores que são plausíveis na sua textura: branco, preto e marrom.

Se você estiver usando várias imagens lado a lado em uma única textura (um atlas de textura), como suponho que esteja fazendo, isso é inevitável. Isso ocorre porque a GPU não combina perfeitamente a interpolação ao longo da borda de um triângulo com a interpolação ao longo da textura, e você obtém pequenos pedaços da textura adjacente.

Há várias coisas que você pode fazer.

  • Use uma textura de matriz em vez de um atlas de textura. Uma textura de matriz é composta de uma pilha de imagens 2D do mesmo tamanho e você especifica uma terceira coordenada para selecionar uma; destina-se exatamente como um substituto para atlas de textura sem o problema de filtragem. No entanto, as texturas de matriz são um recurso mais recente que pode não estar disponível na versão do OpenGL que você está usando.
  • Gere uma borda de 1 pixel em cada um dos blocos de textura, que replica a cor do pixel regular adjacente. (Isso é essencialmente reimplementar GLs CLAMP[_TO_EDGE], mas de uma maneira que esteja ciente dos atlas de textura - seu uso não tem efeito, porque a maioria das bordas de seu ladrilho não está na borda da textura.) Essa é a solução que eu uso em minha própria entrada no gênero, Cubos . Não conheço nenhuma desvantagem em particular, exceto que ela usa mais memória de textura.
  • Inserir levemente suas coordenadas de textura, para que elas não cheguem até a borda do ladrilho de textura. Fazer isso demais levará a uma fina espessura perceptível das bordas da textura em comparação com os pixels no meio.
  • Use uma única textura por tipo de bloco. Isso impõe custos de troca de textura.

2. Você está vendo lacunas entre os ladrilhos.

Eu não acho que esse seja o problema neste caso, já que não há um terreno verde visível através das lacunas, mas estou incluindo-o por completo.

Isso pode ocorrer quando você não está fornecendo exatamente as mesmas coordenadas para os vértices das arestas da reunião de blocos adjacentes, o que geralmente ocorre devido a um erro de ponto flutuante. Por exemplo, se você tem telhas de tamanho 0,6 e calcular a margem direita da telha no x=100com (100*0.6) + 0.6, ea borda esquerda da telha no x=101com (100*0.6), você não vai ter exatamente a mesma resposta, e a diferença pode ser visível como pequenas manchas de lacunas.

A solução é garantir que sua aritmética seja consistente; algumas maneiras de fazer isso são:

  • Verifique se você não está (mesmo que indiretamente) computando index*size + size, mas apenas (index+1)*size.
  • Verifique se sua aritmética é exata; a maneira mais fácil de fazer isso é fazer com que o tamanho do seu bloco seja exatamente 1,0, o que resultará em aritmética inteira exata, mesmo se você fizer seus cálculos com flutuadores de 32 bits (até 16 milhões de blocos a partir da origem).
  • Use números inteiros reais para cálculos de coordenadas de vértices; isso te dá ainda mais alcance.
Kevin Reid
fonte
Parece lacunas para mim - sem sangramento na textura (a menos que seja uma textura bastante alta), considerando os pequenos e aguçados pedaços.
Mario
Obrigado, inserir um pouco as coordenadas da textura parece corrigi-lo.
Luis Cruz
@ Mario Suponho que isso seja feito com a ampliação MAIS PRÓXIMA - observe a borda nítida no interior do ladrilho. Portanto, para essa perspectiva, é uma textura de resolução infinita.
Kevin Reid
Você também pode usar uma matriz de textura para evitar custos de troca.
31513 danijar