Tamanho ideal de sprite para rotações

8

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.

Panda Pajama
fonte
3
Esta não é uma resposta útil, mas li a pergunta e disse: "Ah, isso é fácil!", Fui escrever uma resposta, franzi a testa, li novamente e depois pensei muito nisso por alguns minutos antes de concluir que de fato, não é fácil. Dito isto, meu instinto é "o dobro da resolução em cada eixo é perfeito ou definitivamente bom o suficiente", mas não tenho nenhuma evidência disso. Finalmente, eu suspeito que isso depende muito do kernel de redução de escala com o qual você está comparando - um simples kernel com média de pixels pode ser fácil de analisar e replicar, mas um kernel de Lanczos pode ser impossível.
ZorbaTHut
Eu acho que sua suposição de que 1/256 é o limite do delta de diferença de cores aceitável está errada porque o espaço de cor tradicional (sRGB) é não linear.
Sam Hocevar
@ sam Pode não ser linear quando comparado com o espectro de luz real, mas a quantização é linear. No entanto, depende realmente do algoritmo de interpolação, e os resultados podem ser muito diferentes para interpolação linear e, digamos, bicúbica. Mas mesmo sem interpolação, deve haver uma maneira de calcular o tamanho ideal.
Panda Pajama
@zorbathut A resposta é definitivamente diferente dependendo do algoritmo de downsampling. Mas deve ser relativamente simples encontrar uma solução geral para interpolação linear ou vizinha mais próxima. Ainda estou trabalhando nisso, mas acho que em 8 direções, sqrt (2), a área é ótima. Deixe-me saber onde você chegou
Panda Pyjama

Respostas:

7

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 Nque a imagem intermediária tenha tamanho N×Nmaior que 64×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.

construindo imagem intermediária 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 original 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 não trabalhadaImagem 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, tente N = 256 etc. até obter o tamanho correto.

sam hocevar
fonte
Ver esse problema como um arredondamento duplo é uma abordagem bastante interessante, mas eu gostaria de discordar da sua hipótese de que é impossível, já que você está vendo isso numericamente, não como um problema de sinal. Vamos considerar um sinal unidimensional. Ao amostrá-lo em n pontos, reteremos todas as informações com frequências de até 1 / 2n . Usando o teorema de Nyquist, é possível amostrar o sinal em m> n pontos, e depois reamostrá-lo em n pontos e chegar ao mesmo resultado como se o tivéssemos originalmente amostrado em n pontos. Isso pode ser facilmente estendido para n-dimensões.
Panda Pyjama
11
@PandaPajama, infelizmente, ao invocar o Nyquist, você assume que o sinal pode ser feito estritamente com banda limitada, o que não acontece quando nossas amostras estão em um domínio discreto. É isso que o meu contra-exemplo explora e porque está relacionado ao arredondamento.
18712 Samo Hocevar
Se a imagem original for arbitrariamente grande, ela pode ser considerada como se estivesse em um domínio contínuo. No entanto, em uma discussão mais prática, seu argumento é válido quando se considera um algoritmo muito específico para redução de escala com um tamanho muito específico (2x). Interpolações bilineares e bicúbicas do vizinho mais próximo fornecerão resultados diferentes. Especificamente para o vizinho mais próximo, acredito que é possível construir geometricamente uma solução geral, mas isso terá que esperar pelo fim de semana.
Panda Pyjama
11
@PandaPajama, você está correto novamente, imagens muito grandes podem ser consideradas contínuas, mas o problema é que a imagem intermediária ainda está em um domínio discreto. Além disso, o vizinho mais próximo não sofrerá o problema de arredondamento por definição, mas, além de casos triviais, sofrerá de 1) problemas relacionados ao teorema da equidistribuição que tornarão o tamanho mínimo próximo de 6400 × 6400, ou seja. bastante impraticável e 2) problemas graves de apelido.
18712 Sam 13:40