Estou criando um jogo baseado em sprite e tenho um monte de imagens em uma resolução ridiculamente grande e as dimensiono para o tamanho desejado de sprite (por exemplo, 64x64 pixels) antes de convertê-las em um recurso do jogo. sprite dentro do jogo, não preciso escalá-lo.
No entanto, se eu girar esse pequeno sprite dentro do jogo (mecanismo agnóstico), alguns pixels de destino serão interpolados e o sprite parecerá borrado.
Obviamente, isso depende do ângulo de rotação e do algoritmo de interpolação, mas, independentemente disso, não há dados suficientes para amostrar corretamente um pixel de destino específico.
Portanto, existem duas soluções em que posso pensar. O primeiro é usar a imagem enorme original, girá-la para os ângulos desejados e, em seguida, reduzir todas as variações resultantes e colocá-las em um atlas, que tem a vantagem de ser bastante simples de implementar, mas ingenuamente consome o dobro de sprite espaço para cada rotação (cada rotação deve ser inscrita em um círculo cujo diâmetro é a diagonal do retângulo original do sprite, cuja área é duas vezes maior que o retângulo original, supondo sprites quadrados).
Ele também tem a desvantagem de ter apenas um conjunto predefinido de rotações disponíveis, o que pode ser bom ou não, dependendo do jogo.
Portanto, a outra opção seria armazenar uma imagem maior e girar e reduzir a escala durante a renderização, o que leva à minha pergunta.
Qual é o tamanho ideal para este sprite? Ótimo significado que uma imagem maior não terá efeito na imagem resultante.
Definitivamente, isso depende do tamanho da imagem, da quantidade de rotações desejada sem perda de dados até 1/256, que é a diferença mínima de cor representável.
Estou procurando uma resposta geral teórica para esse problema, porque tentar vários tamanhos pode ser bom, mas está longe de ser o ideal.
Respostas:
Eu acho que o que você está tentando fazer é o espaço de imagem 2D equivalente ao arredondamento duplo . Posso construir uma prova solta de que é impossível encontrar um tamanho intermediário, pelo menos no caso de algoritmos simples de redução de escala, como a interpolação linear.
Suponha que tenhamos achado
N
que a imagem intermediária tenha tamanhoN×N
maior que64×64
. Suponha que ainda não estamos aplicando rotação (o ângulo é zero).Agora vamos criar uma imagem que não funciona.
Construindo a imagem intermediária
Considere uma imagem intermediária totalmente preta. Obviamente, a imagem final também ficará totalmente preta. Em seguida, adicione um pixel cinza de intensidade mínima (R¸G, B = 1,1,1). A imagem final ainda deve estar totalmente preta. Adicione outro pixel cinza tocando o primeiro. Continue construindo um círculo até que a imagem final não fique mais preta.
Imagem 1
Agora, um pixel na imagem final é cinza (se continuássemos para sempre, a imagem resultante seria totalmente cinza, então, obviamente, em algum momento, um pixel ficará cinza) e, se removermos o último pixel, ele estará totalmente preto novamente.
Construindo a imagem original
Considere a imagem original hipotética que levou à nossa imagem intermediária. Não posso provar que existe, mas tenho um forte pressentimento de que existe. Por exemplo, se a imagem original tiver tamanho
2N×2N
, pode ser:Imagem 2
Ao reduzir a imagem 2 para o tamanho intermediário, obtemos a imagem 1.
E por hipótese, ao reduzir para
64×64
, obtemos um ponto cinza na imagem final.Agora vamos separar o último pixel que adicionamos e espalhá-lo pelo cluster original:
Imagem 3
Este é o nosso contra-exemplo.
Quando reduzida para o tamanho final, essa imagem deve nos dar um pixel cinza, porque os pixels que dispersamos estão ainda mais próximos do cluster, portanto a intensidade global é pelo menos tão alta.
Quando reduzida para o tamanho intermediário, essa imagem deve perder o pixel especial porque eles foram espalhados, para obter uma imagem totalmente preta ao redimensionar em duas etapas.
Conclusão e pensamentos futuros
Espero que isso o convença de que o que você está tentando alcançar não funcionará no caso geral.
Minha abordagem para o seu problema seria calcular o melhor tamanho por imagem : comece com a imagem original e por exemplo.
N = 128
, tente todos os ângulos possíveis e calcule o erro máximo. Se o erro máximo não for satisfatório, tenteN = 256
etc. até obter o tamanho correto.fonte