Pourquoi les textures sont-elles toujours des puissances carrées de deux? Et s'ils ne le sont pas?

53

Pourquoi la résolution des textures dans les jeux est-elle toujours une puissance de deux (128x128, 256x256, 512x512, 1024x1024, etc.)? Ne serait-il pas judicieux d’enregistrer la taille du fichier du jeu et d’adapter la texture au modèle UV non enveloppé?

Que se passerait-il s'il y avait une texture qui n'était pas une puissance de deux?

Serait-il incorrect d'avoir une texture de quelque chose comme 256x512 ou 512x1024? Ou est-ce que cela causerait les problèmes que peuvent causer des textures non puissantes?

Keavon
la source
9
Vos autres exemples sont également des puissances de deux, mais pas la même puissance de deux. La puissance de deux optimise la texture pour le matériel graphique.
MichaelHouse
1
@ Byte56 Je pense qu'il signifie 2 ^ nx 2 ^ n texture, où n varie de 1 à l'infini. (Pas vraiment infini.)
Robin
Notez également que les puissances des deux ont l’avantage de rendre les mipmaps triviales.
Pubby
Étant donné que la texture enveloppe normalement (bien que vous puissiez choisir cette option dans un shader personnalisé), vous n'avez pas besoin de perdre de l'espace. Enroulez simplement les coordonnées uv de vos polygones sur les bords et vous pourrez utiliser l'espace beaucoup plus facilement. Si vous n'avez pas besoin de presser, il est plus sûr de vous en tenir à la largeur = hauteur = 2 ^ n textures, car cela permettra une plus large gamme de matériel au détriment d'une mise en page UV légèrement plus compliquée.
Daniel Carlsson
Ils ne sont pas toujours des puissances de deux.
Almo

Réponses:

49

Pourquoi la résolution des textures dans les jeux est-elle toujours une puissance de deux (128x128, 256x256, 512x512, 1024x1024, etc.)?

Comme Byte56 l'a laissé entendre, la "puissance de deux" restrictions de taille sont (étaient) que chaque dimension doit être, indépendamment, une puissance de deux, et non que les textures doivent être carrées et avoir des dimensions qui sont une puissance de deux.

Cependant, sur les cartes modernes et les API graphiques modernes, cette "restriction" a été assouplie de manière à ce que les dimensions des textures puissent être, dans des limites raisonnables, tout ce que vous voulez. Pourtant:

Ne serait-il pas judicieux d’enregistrer la taille du fichier du jeu et d’adapter la texture au modèle UV non enveloppé? Que se passerait-il s'il y avait une texture qui n'était pas une puissance de deux?

En garantissant que les dimensions de la texture sont une puissance de deux, le pipeline graphique peut tirer parti des optimisations liées à l'efficacité de l'utilisation de puissances de deux. Par exemple, cela peut être (et il y a plusieurs années déjà avant que nous ayons des GPU dédiés et des compilateurs optimaux extrêmement intelligents) plus rapide à diviser et à multiplier par deux. Travailler dans des puissances de deux également simplifié les opérations au sein du pipeline, telles que le calcul et l'utilisation de mipmaps (un nombre qui est une puissance de deux se divisera toujours de manière égale en deux, ce qui signifie que vous n'avez pas à faire face à des scénarios où les dimensions de votre mipmap en haut ou en bas).

Il est vrai que vous «gaspillez» un peu d’espace de cette façon, mais l’espace supplémentaire en vaut généralement la peine, en contrepartie du rendu. De plus, il existe des techniques, telles que la compression ou le regroupement de plusieurs images dans un seul espace de texture, qui peuvent réduire une partie des pertes de stockage.

Josh
la source
11
"C’est vrai que vous" gaspillez "un peu d’espace de cette façon, mais l’espace supplémentaire en vaut généralement la peine, en contrepartie de la performance de rendu." - Il y a environ dix ans, je travaillais dans un studio qui transférait un jeu PS2 vers la XBox. Bien que, techniquement, la PS2 ne prenne pas en charge les textures non puissantes, vous pouvez, dans certains cas, le forcer à le faire avec une manipulation astucieuse et aucune perte de vitesse. La XBox, par contre, ne les supportait pas complètement . Le résultat final est que malgré le fait que la XBox dispose de presque deux fois plus de RAM que la PS2, nous avons dû sous-échantillonner certaines textures pour les adapter.
ZorbaTHut
J'ai de la difficulté à trouver une citation, mais j'ai lu précédemment que les images JPEG devraient être multipliées par 8 pour une efficacité maximale, car tout ce qui est en dehors nécessite encore un bloc 8x8.
salmonmoose
1
@salmonmoose: correct; JPEG compresse chaque bloc de 8x8 indépendamment et tamponne les blocs sur le bord. Mais cela n'a rien à voir avec cette question.
MSalters
1
Les JPEG sont encodés en blocs 8x8, oui. Ce n'est pas vraiment une considération d'efficacité cependant. Et ce n'est pas nécessairement une puissance de 2 non plus. :)
Kylotan
Un exemple est sur Android, où souvent des textures non puissantes produisent des textures blanches.
user717572
17

Pourquoi les textures sont-elles toujours des puissances carrées de deux?

Les textures ne sont pas toujours carrées, ni toujours deux . La raison pour laquelle ils ont tendance à être des puissances de deux est généralement d'accroître la compatibilité avec les anciennes cartes vidéo qui imposaient cette restriction. En ce qui concerne les textures non carrées, ce n'est généralement pas un problème. Résumer:

  • Les textures n'ont généralement pas besoin d'être carrées - bien que DirectX ait une D3DPTEXTURECAPS_SQUAREONLYcapacité, mais j'ai travaillé avec des textures non carrées, même avec du matériel ancien, sans aucun problème.
  • Les textures doivent avoir une puissance de deux, car de nombreuses cartes graphiques plus anciennes en ont encore besoin. La raison de cette restriction était qu'ils pouvaient effectuer certaines optimisations des opérations de mappage de texture. La plupart des cartes graphiques modernes n'ont pas cette restriction non plus.
David Gouveia
la source
12
Il convient de noter que par "anciennes cartes graphiques", il signifie des éléments fabriqués avant 2006 ou à peu près.
Nicol Bolas
1
@ NicolBolas Merci, j'essayais en fait de trouver des références sur ce point.
David Gouveia
7

Cela concerne l'optimisation des cartes graphiques. Ils ont été conçus pour les traiter de cette manière. La plupart des cartes ces jours -ci vont vous permettre de charger des textures avec des dimensions qui ne sont pas des puissances de deux, mais il aura probablement un impact négatif sur la performance. Il y a de fortes chances que lors de son chargement, il sera converti, ce qui vous coûtera du temps de chargement sans économiser de mémoire. Les textures non carrées sont généralement acceptables, à condition que leurs deux dimensions soient des puissances de deux.

Un moyen de traiter les textures de taille impaire consiste à utiliser un Atlas de textures . Fondamentalement, vous regroupez plusieurs textures en une seule texture et utilisez les coordonnées de texture de vos sommets pour référencer l'image dont vous avez besoin. Cela apporte également des avantages supplémentaires en termes de performances, car cela permet d'éviter les changements d'état. Une utilisation courante de ceci consiste à placer tous les éléments de l'interface dans une seule texture, ce qui signifie que si vous avez regroupé les sommets de vos interfaces dans un seul objet tampon, vous pouvez dessiner le tout avec un seul appel, plutôt que de changer de texture. plusieurs fois et en faisant un appel de tirage distinct pour chacun.

Jason Morales
la source
6

Le problème est que certains matériels n'offrent qu'un support limité pour les textures n'ayant pas une puissance de deux dimensions.

Par exemple, reportez-vous au bas de http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876%28v=vs.85%29.aspx et lisez les notes de bas de page 3 et 4.

3 Aux niveaux de fonctionnalité 9_1, 9_2 et 9_3, le dispositif d'affichage prend en charge l'utilisation de textures 2D avec des dimensions qui ne sont pas des puissances de deux dans deux conditions. Tout d'abord, un seul niveau de carte MIP peut être créé pour chaque texture, et deuxièmement, aucun mode d'échantillonnage en boucle n'est autorisé pour les textures (c'est-à-dire, les membres AddressU, AddressV et AddressW de D3D11_SAMPLER_DESC ne peuvent pas être définis sur D3D11_TEXTURE_ADDRESS_WRAP).

4 Aux niveaux de fonctionnalité 10_0, 10_1 et 11_0, le dispositif d'affichage prend en charge de manière inconditionnelle l'utilisation de textures 2D avec des dimensions qui ne sont pas des puissances de deux.

Adam
la source
6

Le matériel graphique est optimisé pour les opérations de matrice, les opérations de fragment et les opérations de vecteur. Les matrices carrées sont simplement plus faciles à manipuler, car les calculs peuvent être faits en blocs (appelés fragments), le matériel est optimisé pour les opérations de bloc, c'est pourquoi il existe des choses comme les tampons de fichiers, le blit de RAM ne blit pas sur le disque a été peuplé. La même chose est vraie de la mémoire graphique.

Le tampon de trame est composé de fragments qui sont carrés. Par exemple, dans un écran avec une résolution de 800x600 et un espace colorimétrique RVB (0-255), il y a 800x600 points avec 3 octets par canal, un total général de 3x800x600 = 1 440 000 octets à adresser dans le tampon de trame. Cela signifie qu'il existe 1 875 fragments adressables de 256x256x3 octets. Parce que les données de texture sont carrées, il est beaucoup plus facile de mapper de la matrice GRAM à la matrice de tampon d’écran en utilisant une mise à l’échelle bicubique, où, comme si ce n’était pas le cas, le biais pour le côté le plus long prendrait plus de temps à calculer être mis à l'échelle.

De nombreuses API graphiques acceptent les données de texture non carrées, car elles acceptent les coordonnées de mappage UV en tant que données à virgule flottante. Cependant, une fois envoyées au GPU, un remplissage est ajouté aux données de texture, car les proportions réelles de l'image ne modifient pas le mappage. semble ne pas être affecté, mais un remplissage est ajouté aux données de texture, car le GPU aime l’adresser comme un carré parfait.

Donc, si une image 100x1024 est utilisée et une image de 1024x1024 est utilisée, ce qui signifie que 946.176 octets sont perdus. D'autant plus si la composition doit être faite, car un canal alpha devra être ajouté afin d'indiquer que les données de remplissage ne doivent pas affecter la texture composée.

awiebe
la source
C’est une explication intéressante (qui concerne les matrices carrées) qui ne se trouve pas dans la puissance habituelle de 2 réponses (+1) - pourriez-vous fournir des citations si possible?
Samaursa
1

Notre monde numérique fonctionne avec une numération binaire, puis pour jouer en multijoueur ou pour diviser par 2 une valeur, vous pouvez "déplacer" une valeur à gauche ou à droite, par exemple.

<<  Left shift      x = 5 << 1    0101 << 1     1010     10
>>  Right shift     x = 5 >> 1    0101 >> 1     0010      2

Travailler avec des valeurs "puissance de deux" est plus facile pour un processeur.

Esdebon
la source
0

Matériel moderne peut (enfin) faire face à l' activation des modes de wrap sur la non-puissance de deux textures à base, mais non le pouvoir de deux textures ont encore tendance à perdre la mémoire GPU car ils ont tendance à se rembourré jusqu'à le long de la largeur par une certaine quantité de matériel spécifique (soit tuile ou arrondi à la puissance suivante de deux tailles contenant la texture).

Étant donné que cela dépend du matériel et que les fournisseurs n'entrent généralement pas dans les détails de ces détails, la chose la plus sûre à faire est de continuer à utiliser la puissance à deux dimensions pour les textures, afin de ne pas gaspiller la RAM du processeur graphique.

Zoner
la source