Après avoir ajouté de la vélocité à mon jeu, j'ai l'impression que mes textures se contractent. Je pensais que ce n'était que mes yeux, jusqu'à ce que je le capture enfin sur une capture d'écran:
Celui de gauche est ce qui rend dans mon jeu; celui de droite est le sprite d'origine, collé dessus. (Il s'agit d'une capture d'écran de Photoshop, agrandie 6x.)
Notez que les bords sont des alias - cela ressemble presque à un rendu sous-pixel. En fait, si je n'avais pas forcé mes sprites (qui ont la position et la vitesse en pouces) à dessiner en utilisant des valeurs entières, je jurerais que MonoGame dessine avec des valeurs à virgule flottante. Mais ce n'est pas le cas.
Quelle pourrait être la cause de ces choses floues? Cela ne se produit pas sans la vitesse appliquée.
Pour être précis, ma SpriteComponent
classe a un Vector2 Position
domaine. Lorsque j'appelle Draw
, j'utilise essentiellement new Vector2((int)Math.Round(this.Position.X), (int)Math.Round(this.Position.Y))
le poste.
J'ai eu un bug avant où même les objets stationnaires tremblaient - c'était dû à moi en utilisant le Position
vecteur droit et sans arrondir les valeurs à ints
. Si j'utilise Floor
/ Ceiling
au lieu de rond, le sprite coule / plane (une différence de pixel dans les deux sens) mais reste toujours flou.
Réponses:
Hum, ceci est embarrassant.
Il s'avère que je ne dessinais pas en utilisant des positions entières, mais des positions flottantes. Archy m'a indiqué le bon chemin avec son commentaire
@ashes999 did you debug this call and checked this.X, this.Y and this.origin?
Dès que j'ai ajouté une déclaration de trace, j'ai remarqué que rien n'était tracé. Il s'avère que ma
SpriteComponent
classe utilisait correctement les valeurs entières, mais mesSpriteSheetComponent
valeurs flottantes toujours utilisées à partir du brutVector2 Position
.Bien que je n'ai pas essayé le filtrage et le serrage de texture, je soupçonnais que ce n'était pas le bon changement, car je dessinais une image 2D à la même largeur et hauteur que l'image source (pas de mise à l'échelle).
la source
XNA utilise DirectX9 qui utilise le centre du pixel comme emplacement. Cela est visible lors de l'utilisation des surcharges basées sur Vector2 de la classe draw. Je pense que la soustraction (0,5, 0,5) devrait résoudre votre problème.
Plus d'infos ici.
la source
int, int
comme arguments. En plus de cela, les choses semblent parfaitement bien quand je n'ai aucun objet en mouvement.SpriteComponent
a uneVector2
position, qui augmente en tant que flotteurs en fonction de la vitesse; quand je dessine, je crée un nouveauVector2
avec des versions entières (arrondies) de mesposition
X et Y. Ce n'est pas le problème, car les objets stationnaires sans vitesse semblent bien.p += v
pendantUpdate
et rend avecnew Vector2((int)Math.Round(p.X), (int)Math.Round(p.Y)))
.Le rendu ne sait rien de votre vitesse, donc soit la position, la taille ou tout autre chose que vous passez à SpriteBatch.Draw est différent ou l'erreur était présente avant d'ajouter la vitesse. Comment appelez-vous SpriteBatch.Draw exactement?
Avez-vous débogué cet appel et vérifié this.X, this.Y et this.origin? À quoi est ce fichier this.origin? Il n'y a fondamentalement aucun moyen que le résultat du rendu avec la vélocité soit différent lorsque cet appel Draw est le même.
la source
Le problème est probablement que le filtrage de texture est activé. Si vous n'êtes pas sûr de ce que cela signifie, envisagez une situation où vous avez une image de 2 pixels de large: le premier pixel est noir, le second pixel est blanc. Si vous zoomez sur cette texture, si le filtrage de texture est activé, vous verrez qu'elle devient floue et que la zone entre le pixel noir et blanc utilise une couleur gris dégradé.
Un exemple classique de jeux avec et sans filtrage est Super Mario 64 qui avait un filtrage alors que Doom n'en avait pas.
Lorsque vous n'utilisez pas la vélocité, votre Sprite est probablement positionné de sorte que le centre de la texture se trouve au point d'échantillonnage où XNA (ou toute autre API sous-jacente utilisée) saisit la couleur. Lorsque vous vous déplacez avec une vitesse flottante, la position de votre Sprite change, donc le point d'échantillonnage peut ne pas s'aligner directement avec le centre d'un pixel, donc le résultat final est qu'une couleur qui est une moyenne des pixels les plus proches est utilisé pour le rendu.
Vous pouvez vérifier que le filtrage est activé en rendant simplement votre Sprite vraiment grand à l'écran. Si c'est flou, c'est bien le problème.
Si vous devez avoir une précision au pixel près dans le rendu, vous voudrez avoir une valeur flottante pour la position stockée quelque part, mais utilisez des valeurs entières pour la position de l'objet que vous rendez ... ou bien sûr, vous pouvez simplement désactiver le filtrage si votre jeu n'en a pas besoin.
Vous pouvez également lire ceci .
la source
Draw
. Je ne sais donc pas comment cela pourrait être le cas - mais je vais essayer de rendre à grande échelle et de voir si la désactivation du filtrage de texture aidera.Essayez de définir votre SamplerState sur SamplerState.PointClamp dans l'appel SpriteBatch.Begin.
la source