OpenGL - bords blancs sur les cubes

12

Dans un jeu de type minecraft que je fais, j'obtiens des bords blancs sur mes cubes:

entrez la description de l'image ici

Il est beaucoup plus visible dans les textures plus sombres. Les textures sont configurées comme ceci: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

De l'aide?

Luis Cruz
la source
3
Pouvez-vous montrer du code sur la façon dont vous rendez chaque cube et comment vous placez les cubes?
joncodo
1
Envelopper les textures fait-il quelque chose de différent? À quoi ressemble la texture / la taille à laquelle vous vous liez?
Chuck D
Je voulais juste souligner que j'ai également vu cela se produire dans de grands atlas de texture, qui utilisent de petites tuiles. Par exemple, disons que vous avez un ensemble de tuiles / atlas 1024 * 1024, et que vous utilisez des tuiles de 32 * 32. Vous obtenez des erreurs d'arrondi car le point décimal qui mappe à ladite tuile est un très petit double. Cela rend la précision presque impossible. Une solution? Divisez l'atlas de tuiles en tuiles individuelles. C'est ce que fait ou faisait Minecraft. Ils avaient un gros jeu de tuiles, et à l'exécution, ils l'ont découpé en textures individuelles.
Krythic

Réponses:

19

Il existe deux causes possibles pour ce type de problème, selon exactement de quel problème il s'agit. Je vais énumérer les deux:

1. Vous voyez d'autres couleurs de votre texture le long des bords des carreaux.

Cela me semble être le problème dans ce cas, car tous les pixels de bord sont l'une des trois couleurs qui sont plausiblement dans votre texture: blanc, noir et marron.

Si vous utilisez plusieurs images de tuiles côte à côte dans une seule texture (un atlas de texture), comme je suppose que vous le faites, cela est inévitable. Cela se produit parce que le GPU ne correspond pas parfaitement à l'interpolation le long du bord d'un triangle avec l'interpolation le long de la texture, et vous obtenez de petits morceaux de la texture adjacente.

Il y a plusieurs choses que vous pouvez faire.

  • Utilisez une texture de tableau au lieu d'un atlas de texture. Une texture matricielle est constituée d'une pile d'images 2D de même taille et vous spécifiez une troisième coordonnée pour en sélectionner une; il est destiné exactement à remplacer les atlas de texture sans problème de filtrage. Cependant, les textures de tableau sont une fonctionnalité plus récente qui peut ne pas être disponible dans la version d'OpenGL que vous utilisez.
  • Générez une bordure de 1 pixel dans chacune de vos tuiles de texture, qui reproduit la couleur du pixel régulier adjacent. (Il s'agit essentiellement de réimplémenter les GL CLAMP[_TO_EDGE], mais d'une manière qui est consciente des atlas de texture - votre utilisation de ceux-ci n'a aucun effet parce que la plupart de vos bords de carreaux ne sont pas au bord de la texture.) C'est la solution que j'utilise dans ma propre entrée dans le genre, Cubes . Je ne connais aucun inconvénient particulier, sauf qu'il utilise plus de mémoire de texture.
  • Insérez très légèrement vos coordonnées de texture, afin qu'elles n'aillent pas jusqu'au bord de la tuile texture. En faire trop entraînera une minceur notable des bords de la texture par rapport aux pixels du milieu.
  • Utilisez une seule texture par type de tuile. Cela impose des coûts de changement de texture.

2. Vous voyez à travers les écarts entre les tuiles.

Je ne pense pas que ce soit le problème dans ce cas, car il n'y a pas de terrain vert vu à travers les lacunes, mais je l'inclus pour être complet.

Cela peut se produire lorsque vous ne fournissez pas exactement les mêmes coordonnées pour les sommets des bords de réunion des tuiles adjacentes, ce qui se produit généralement en raison d'une erreur en virgule flottante. Par exemple, si vous avez des tuiles de taille 0,6 et calculez le bord droit de la tuile à x=100avec (100*0.6) + 0.6, et le bord gauche de la tuile à x=101avec (100*0.6), vous n'obtiendrez pas la même réponse exacte, et la différence peut être visible sous forme de petites taches de lacunes.

La solution est de s'assurer que votre arithmétique est cohérente; voici quelques façons de procéder:

  • Assurez-vous que vous ne calculez pas (même indirectement) index*size + size, mais seulement (index+1)*size.
  • Assurez-vous que votre arithmétique est exacte; la façon la plus simple de le faire est de rendre votre taille de tuile exactement 1,0, ce qui se traduira par une arithmétique entière exacte même si vous effectuez vos calculs avec des flottants 32 bits (jusqu'à 16 millions de blocs de l'origine, de toute façon).
  • Utilisez des entiers réels pour les calculs de coordonnées de sommets; cela vous donne encore plus de portée.
Kevin Reid
la source
Cela ressemble à des lacunes pour moi - pas de saignement de texture (à moins que ce ne soit une texture assez haute résolution) compte tenu des petits morceaux pointus.
Mario
Merci, le fait d'insérer un peu les coordonnées de la texture semble le corriger.
Luis Cruz
@Mario Je suppose que c'est avec le grossissement LE PLUS PROCHE - notez la bordure nette à l'intérieur de la tuile. Donc pour cette perspective, c'est une texture à résolution infinie.
Kevin Reid
Vous pouvez également utiliser un tableau de textures pour éviter les coûts de commutation.
danijar