Después de agregar velocidad a mi juego, siento que mis texturas se contraen. Pensé que solo eran mis ojos, hasta que finalmente lo capturé en una captura de pantalla:
El de la izquierda es lo que aparece en mi juego; el de la derecha es el sprite original, pegado. (Esta es una captura de pantalla de Photoshop, ampliada 6x).
Observe que los bordes tienen un alias: parece casi una representación de subpíxeles. De hecho, si no hubiera forzado a mis sprites (que tienen posición y velocidad como ints) a dibujar usando valores enteros, juraría que MonoGame está dibujando con valores de punto flotante. Pero no lo es.
¿Cuál podría ser la causa de que estas cosas parezcan borrosas? No sucede sin la velocidad aplicada.
Para ser precisos, mi SpriteComponent
clase tiene un Vector2 Position
campo. Cuando llamo Draw
, esencialmente uso new Vector2((int)Math.Round(this.Position.X), (int)Math.Round(this.Position.Y))
para el puesto.
Tuve un error antes de que incluso los objetos estacionarios temblaran, eso se debió a que usé el Position
vector recto y no redondeé los valores ints
. Si uso Floor
/ en Ceiling
lugar de redondo, el sprite se hunde / se desplaza (una diferencia de píxel en ambos sentidos) pero aún se dibuja borroso.
Respuestas:
Bueno, esto es vergonzoso.
Resulta que no estaba dibujando usando posiciones enteras, sino posiciones flotantes. Archy me señaló el camino correcto con su comentario
@ashes999 did you debug this call and checked this.X, this.Y and this.origin?
Tan pronto como agregué una declaración de seguimiento, noté que no se trazó nada. Resulta que mi
SpriteComponent
clase usaba correctamente valores enteros, peroSpriteSheetComponent
todavía usaba valores flotantes sin procesarVector2 Position
.Aunque no probé el filtrado y la sujeción de texturas, sospechaba que no se trataba del cambio correcto, porque estaba dibujando una imagen 2D con el mismo ancho y alto que la imagen de origen (sin escala).
fuente
XNA usa DirectX9 que usa el centro del píxel como su ubicación. Esto es notable cuando se usan las sobrecargas basadas en Vector2 de la clase de dibujo. Creo que restar (.5, .5) debería solucionar su problema.
Más información aquí.
fuente
int, int
los argumentos. Además de eso, las cosas se ven perfectamente bien cuando no tengo ningún objeto en movimiento.SpriteComponent
tiene unaVector2
posición, que se incrementa como flotadores dependiendo de la velocidad; cuando dibujo, creo un nuevoVector2
con versiones enteras (redondeadas) de miposition
X e Y. Este no es el problema, ya que los objetos estacionarios sin velocidad parecen estar bien.p += v
duranteUpdate
y renderizo connew Vector2((int)Math.Round(p.X), (int)Math.Round(p.Y)))
.El renderizado no sabe nada sobre su velocidad, por lo tanto, la posición, el tamaño o cualquier otra cosa que pase a SpriteBatch.Draw es diferente o el error estaba presente antes de agregar velocidad. ¿Cómo se llama a SpriteBatch.Draw exactamente?
¿Depuró esta llamada y comprobó this.X, this.Y y this.origin? ¿En qué está configurado this.origin? Básicamente no hay forma de que el resultado del renderizado con velocidad sea diferente cuando esta llamada de Draw es la misma.
fuente
El problema es probable que el filtrado de textura esté activado. Si no está seguro de lo que eso significa, considere una situación en la que tiene una imagen que tiene 2 píxeles de ancho: el primer píxel es negro, el segundo píxel es blanco. Si amplía esta textura, si el filtro de textura está activado, verá que se vuelve borroso y que el área entre el píxel blanco y negro usa un color gris degradado.
Un ejemplo clásico de juegos con y sin filtro son Super Mario 64 que tenía un filtro mientras que Doom no.
Cuando no usa la velocidad, es probable que su Sprite esté posicionado de manera que el centro de la textura esté en el punto de muestra en el que XNA (o cualquier api subyacente que se esté usando) tome el color. Cuando te mueves con una velocidad de flotación, entonces la posición de tu Sprite cambia, por lo que el punto de muestra puede no alinearse directamente con el centro de un píxel, por lo que el resultado final es que se está obteniendo un color que es un promedio de los píxeles más cercanos solía renderizar.
Puede verificar que el filtrado esté activado simplemente haciendo que su Sprite sea realmente grande en la pantalla. Si está borroso, entonces ese es el problema.
Si debe tener una precisión de píxel perfecta en el renderizado, querrá tener un valor flotante para la posición almacenada en algún lugar, pero use valores enteros para la posición del objeto que está renderizando ... o, por supuesto, simplemente puede desactivar el filtrado si tu juego no lo necesita.
Quizás también quieras leer esto .
fuente
Draw
. Así que no estoy seguro de cómo podría ser el caso, pero intentaré renderizar a gran escala y ver si ayudar a desactivar el filtrado de textura.Intente configurar su SamplerState en SamplerState.PointClamp en la llamada SpriteBatch.Begin.
fuente