Como evitar valores de subpixel em um jogo 2D independente de resolução com projeção ortográfica?

8

Estou tentando fazer a renderização independente de resolução de sprites em movimento em um jogo 2D. Meu plano é trabalhar em um sistema de coordenadas fixo no meu mundo (por exemplo, 960x540) e usar a projeção ortográfica para escalar isso para cima ou para baixo para se ajustar à janela de visualização. Eu faço letterboxing para lidar com diferentes proporções.

De acordo com a maioria dos tutoriais, sou livre para usar as dimensões que desejar para o modo de exibição de exibição, mas descobri que, em muitos casos, isso leva ao problema e acabo usando valores de subpixel na janela de exibição. Por exemplo, um vértice em (62,62) em um sistema de coordenadas de 960 x 540 termina em (51.6666667,51.6666667) em uma viewport com as dimensões 800 x 450.

Notei dois tipos de problemas com isso:

  • a amostragem de textura muda o tempo todo para objetos que estão em movimento, dependendo de onde os vértices estão em relação ao centro de pixels
  • meus objetos são esticados horizontalmente ou verticalmente por um pixel de vez em quando devido ao arredondamento

Qual é a melhor prática para evitar isso (mantendo a independência da resolução em termos de velocidade de movimento e assim por diante)? E onde seria o melhor lugar para resolver isso? Antes de passar os vértices para os sombreadores ou dentro do sombreador de vértices?

Eric
fonte
Como você está redimensionando e traduzindo para se ajustar à nova janela de exibição? Matrizes? Dimensionar e mover manualmente as posições dos objetos?
Emir Lima
@EmirLima Estou multiplicando as coordenadas por uma matriz combinada de modelo-visão-projeção dentro do meu shader de vértice. Todo o dimensionamento é feito pela matriz de projeção ortográfica.
Eric Eric
você poderia arredondar ou no chão as coordenadas, (talvez em vert shader)
T123
@ tm1rbrt Obrigado pelo seu comentário. Eu acho que teria que sempre andar no teto ou no teto para evitar 1 pixel mais ou menos em largura ou altura. Tentei fazer isso dentro do shader de vértice, mas a imprecisão nos cálculos lá torna isso difícil, se não impossível. Acabei pavimentando o que deveria ter sido números inteiros perfeitos para o número anterior.
Eric

Respostas:

1

Para chegar à sua pergunta principal, se deve ou não influenciar os vértices antes ou durante o sombreador, é preferível usar um sombreador. Se você sabe escrever uma rotina que pode levar em conta o visor e o sistema de coordenadas, é preferível usar um sombreador, pois permite que muitos sprites sejam ajustados em paralelo. Além disso, garante que as coordenadas "cosméticas" fiquem separadas das coordenadas do jogo no código da CPU, para que uma não influencie a outra.

Você pode fazer isso no vértice OU no pixel shader. No sombreador de pixels, é possível trocar texels para travá-los nos pixels na tela.

No DirectX9, eu precisava fazer isso com o HLSL para contornar a peculiaridade de que os cantos texel estavam localizados a 0,5, 0,5 em relação ao pixel , fazendo com que as texturas nítidas parecessem semi-embaçadas. Corrigir isso altera a localização física dos texels sem mover os vértices.

No seu caso, o deslocamento variará de quadro para quadro; portanto, passe as coordenadas reais do sprite para o sombreador para calcular o deslocamento decimal. Lembre-se de CLAMP a amostragem de textura para evitar quebra nas texturas.

ChrisC
fonte
3

Eu acho que armazenaria dois conjuntos de coordenadas.

  1. Um usado para desenhar seus objetos DISPLAY POSITIONe
  2. um segundo usado para manter um TRUE POSITION .

Dessa forma, você pode desenhar sprites com coordenadas arredondadas para eliminar a distorção causada pelo tamanho fixo da sua área de exibição.

Mas isso também permite que você mantenha a localização exata sem influenciar nenhuma lógica do jogo. por causa da natureza dos sub-pixels, também acho que você nem notará discrepâncias entre a visualização e a lógica do jogo.

Joe
fonte