Estoy haciendo un juego basado en sprites, y tengo un montón de imágenes que obtengo en una resolución ridículamente grande y las escalo al tamaño de sprite deseado (por ejemplo, 64x64 píxeles) antes de convertirlas en un recurso de juego, así que cuando dibuje mi sprite dentro del juego, no tengo que escalarlo.
Sin embargo, si giro este pequeño sprite dentro del juego (motor agnóstico), algunos píxeles de destino se interpolarán y el sprite se verá manchado.
Por supuesto, esto depende del ángulo de rotación, así como del algoritmo de interpolación, pero independientemente, no hay suficientes datos para muestrear correctamente un píxel de destino específico.
Así que hay dos soluciones en las que puedo pensar. El primero es usar la gran imagen original, rotarla a los ángulos deseados, y luego reducir todas las variaciones resultantes, y ponerlas en un atlas, que tiene la ventaja de ser bastante simple de implementar, pero ingenuamente consume el doble de sprite espacio para cada rotación (cada rotación debe estar inscrita en un círculo cuyo diámetro es la diagonal del rectángulo del sprite original, cuya área es el doble de ese rectángulo original, suponiendo sprites cuadrados).
También tiene la desventaja de tener solo un conjunto predefinido de rotaciones disponibles, lo que puede estar bien o no dependiendo del juego.
Entonces, la otra opción sería almacenar una imagen más grande, y rotar y reducir la escala mientras se renderiza, lo que lleva a mi pregunta.
¿Cuál es el tamaño óptimo para este sprite? Significado óptimo de que una imagen más grande no tendrá efecto en la imagen resultante.
Esto definitivamente depende del tamaño de la imagen, la cantidad de rotaciones deseadas sin pérdida de datos hasta 1/256, que es la diferencia de color mínima representable.
Estoy buscando una respuesta teórica general a este problema, porque probar varios tamaños puede estar bien, pero está lejos de ser óptimo.
Respuestas:
Creo que lo que está tratando de hacer es el espacio de imagen 2D equivalente al doble redondeo . Puedo construir una prueba flexible de que es imposible encontrar un tamaño tan intermedio, al menos en el caso de algoritmos simples de reducción de escala como la interpolación lineal.
Supongamos que encontramos
N
que la imagen intermedia tiene un tamañoN×N
mayor que64×64
. Supongamos que ni siquiera estamos aplicando rotación todavía (el ángulo es cero).Ahora construyamos una imagen que no funciona.
Construyendo la imagen intermedia
Considere una imagen intermedia completamente negra. Obviamente, la imagen final también será completamente negra. Luego, agregue un píxel gris de intensidad mínima (R¸G, B = 1,1,1). La imagen final aún debe ser completamente negra. Agregue otro píxel gris tocando el primero. Continúe construyendo un círculo hasta que la imagen final ya no sea completamente negra.
Imagen 1
Ahora, un píxel en la imagen final es gris (si continuamos para siempre, la imagen resultante sería completamente gris, por lo que obviamente en algún momento un píxel se vuelve gris), y si eliminamos ese último píxel, volverá a ser completamente negro.
Construyendo la imagen original
Considere la hipotética imagen original que condujo a nuestra imagen intermedia. No puedo demostrar que existe, pero tengo el fuerte presentimiento de que existe. Por ejemplo, si la imagen original tiene tamaño
2N×2N
, esto podría ser:Imagen 2
Al reducir la imagen 2 al tamaño intermedio, obtenemos la imagen 1.
Y por hipótesis, al reducir la escala a
64×64
, obtenemos un punto gris en la imagen final.Ahora separemos el último píxel que agregamos y dispersémoslo por el clúster original:
Imagen 3
Este es nuestro contraejemplo.
Cuando se reduce al tamaño final, esta imagen debería darnos un píxel gris, porque los píxeles que dispersamos están aún más cerca del clúster, por lo que la intensidad global es al menos tan alta.
Cuando se reduce al tamaño intermedio, esta imagen debe perder el píxel especial porque se han dispersado, por lo que obtenemos una imagen completamente negra al hacer el cambio de tamaño de dos pasos.
Conclusión y pensamientos futuros.
Espero que esto te convenza de que lo que estás tratando de lograr no funcionará en el caso general.
Mi enfoque para su problema sería calcular el mejor tamaño por imagen : comience con la imagen original y, por ejemplo.
N = 128
, pruebe todos los ángulos posibles y calcule el error máximo. Si el error máximo no es satisfactorio, intente,N = 256
etc., hasta obtener el tamaño correcto.fuente