« Les cartes graphiques/Les Render Output Target » : différence entre les versions
Contenu supprimé Contenu ajouté
mAucun résumé des modifications |
|||
Ligne 7 :
[[File:GeForce 6800 Pixel blending.png|droite|thumb|R.O.P des GeForce 6800.]]
Un ROP est typiquement organisé comme illustré ci-contre. Il récupère les fragments calculés par les pixels shaders et/ou les unités de texture, via un
Notons que les circuits de gestion de la profondeur et ceux pour la transparence sont séparés dans des unités distinctes, par commodité. Il faut dire que la gestion de la profondeur et la gestion de la transparence sont deux opérations assez séparées, qui gagnent à être effectuées en parallèle l'une de l'autre. On gagne en performance si on effectue les deux opérations en même temps, au lieu de les faire une à la fois. On peut aussi noter que les circuits de gestion de la profondeur et de la couleur gèrent diverses techniques de compression pour économiser de la mémoire et de la bande passante mémoire. Ajoutons à cela que ces deux unités contiennent des caches spécialisés, qui permettent de réduire fortement les accès mémoires, très fréquents dans cette étape du pipeline graphique.
Ligne 13 :
==La gestion de la profondeur (tests de visibilité)==
Le premier rôle du ROP est de trier les fragments du plus proche au plus éloigné, pour gérer les situations où un triangle en cache un autre (quand un objet en cache un autre, par exemple). Prenons un mur rouge opaque qui cache un mur bleu. Dans ce cas, un pixel de l'écran sera associé à deux fragments : un pour le mur rouge, et un pour le bleu. Vu que le mur de devant est opaque, seul le fragment de ce mur doit être choisi : celui du mur qui est devant. Pour cela, chaque fragment a une coordonnée de profondeur, appelée la coordonnée z, qui indique la distance de ce fragment à la caméra. La profondeur est calculée à la rastérisation, ce qui fait que les ROP n'ont pas à la calculer, juste à trier les
: Petite précision : il est assez rare qu'un objet soit caché seulement par un seul objet. En moyenne, un objet est caché par 3 à 4 objets dans un rendu 3d de jeu vidéo.
Ligne 23 :
[[File:Z-buffer no text.jpg|vignette|Z-buffer correspondant à un rendu]]
Pour savoir quels fragments sont à éliminer (car cachés par d'autres), notre carte graphique va utiliser ce qu'on appelle un '''tampon de profondeur'''. Il s'agit d'un tableau, stocké en mémoire vidéo, qui mémorise la coordonnée z de l'objet le plus proche pour chaque pixel. Par défaut, ce tampon de profondeur est initialisé avec la valeur de profondeur maximale. Au fur et à mesure que les objets seront calculés, le tampon de profondeur
[[File:Z-buffer.svg|centre|vignette|upright=2.0|Illustration du processus de mise à jour du Z-buffer.]]
Ligne 37 :
====La z-compression====
Une première solution pour économiser la bande passante mémoire est la technique de '''z-compression''', qui compresse le tampon de profondeur. Les techniques de ''z-compression'' découpent le tampon de profondeur en ''tiles'', en blocs carrés, qui
Précisons que cette compression ne change pas la taille occupée par le tampon de profondeur, mais seulement la quantité de données lue/écrite dans le tampon de profondeur. La raison à cela est simple : les ''tiles'' ont une place fixe en mémoire. Par exemple, si une ''tile'' non-compressée prend 64 octets, on trouvera une ''tile'' tous les 64 octets en mémoire vidéo, afin de simplifier les calculs d'adresse, afin que le ROP sache facilement où se trouve la ''tile'' à lire/écrire. Avec une vraie compression, les ''tiles'' se trouveraient à des endroits très variables d'une image à l'autre. Par contre, la z-compression réduit la quantité de données écrite dans le tampon de profondeur. Par exemple, au lieu d'écrire une ''tile'' non-compressée de 64 octets, on écrira une ''tile'' de seulement 6 octets, les 58 octets restants étant pas lus ou écrits. On obtient un gain en performance, pas en mémoire.
Ligne 47 :
====Le cache de profondeur====
Il faut savoir que les autres unités de la carte graphique peuvent lire le tampon de profondeur, en théorie. Cela peut servir pour certaines techniques de rendu, comme pour le ''shadowmapping''. De ce fait, il arrive que le cache de profondeur contienne des données qui sont copiées dans d'autres caches, comme les caches des processeurs de shaders. Le cache de profondeur n'est pas gardé cohérent avec les autres caches du GPU, ce qui signifie que les écritures dans le cache de profondeur ne sont pas propagées dans les autres caches du GPU. Si on modifie des données dans ce cache, les autres caches qui ont une copie de ces données auront une version périmée de la donnée. C'est souvent un problème, sauf dans le cas du cache de profondeur, pour lequel ce n'est pas nécessaire. Cela évite d'implémenter des techniques de cohérence des caches couteuses en circuits et en performance, alors qu'elles n'auraient pas d'intérêt dans ce cas précis.
Ligne 57 :
[[File:Texture splatting.png|centre|vignette|upright=2.0|Application de textures.]]
Le ROP peut aussi ajouter des effets de brouillard dans une scène 3D. Les premières cartes graphiques calculaient le brouillard dans les ROP, en fonction de la coordonnée de profondeur du fragment. De nos jours, il est calculé par les ''pixel shaders'' et les ROP n'incorporent plus de technique de brouillard spécialisés. Pour calculer le brouillard, on mélange la couleur
===Le circuit de gestion de la transparence===
Ligne 69 :
==L'antialiasing==
Le ROP prend en charge l'
[[File:Anti-aliasing demo.svg|centre|thumb|Anti-aliasing demo]]
Ligne 77 :
===Le supersampling===
La plus simple de ces techniques, le SSAA - '''Super Sampling Anti Aliasing''' - calcule l'image à une résolution supérieure, avant de la réduire. Par exemple, pour rendre une image en
Le rendu de l'image se fait à une résolution 2, 4, 8, 16 fois plus grande. La résolution n'apparait qu'après le rastériseur, et
{|
Ligne 88 :
====La position des sous-pixels====
Un point important concernant la qualité de l'antialiasing concerne la position des sous-pixels sur l'écran. Comme vous l'avez vu dans le chapitre sur la
* La solution la plus simple consiste à placer nos sous-pixels à l'endroit qu'ils occuperaient si l'image était réellement rendue avec la résolution simulée par l'antialiasing. Cette solution gère mal les lignes pentues, le pire cas étant les lignes penchées de 45 degrés par rapport à l'horizontale ou la verticale.
* Pour mieux gérer les bords penchés, on peut positionner nos sous-pixels comme suit. Les sous-pixels sont placés sur un carré penché (ou sur une ligne si l'on dispose seulement de deux sous-pixels). Des mesures expérimentales montrent que la qualité optimale semble être obtenue avec un angle de rotation
* D'autres dispositions sont possibles, notamment une disposition aléatoire ou de type Quincunx.
Ligne 105 :
Le '''Multi-Sampling Anti-Aliasing, abrévié en MSAA''' est une amélioration du SSAA qui économise certains calculs. Pour simplifier, c'est la même chose que le SSAA, sauf que les pixels shaders ne calculent pas l'image à une résolution supérieure, alors que tout le reste (rastérisation, ROP) le fait. Avec le MSAA, l'image à afficher est rendue dans une résolution supérieure, mais les fragments sont regroupés en carrés qui correspondent à un pixel. L'application des textures se fait par pixel et non pour chaque sous-pixel, de même que le pixel shader manipule des pixels, mais ne traite pas les sous-pixels. Avec le SSAA, chaque sous-pixel se verrait appliquer un morceau de texture et un pixel shader, alors qu'on applique la texture sur un pixel complet avec le MSAA.
Le calcul de la couleur finale du pixel se fait dans le ROP. Pour cela, le ROP a besoin d'une information quant à la position des sous-pixels. Le pixel final est associé à un triangle précis par la rastérisation. Cependant, cela ne signifie pas que tous les sous-pixels sont associés à ce triangle. En effet, les sous-pixels ne sont pas à la même place que le pixel dans la résolution inférieure. La position des sous-pixels est une chose dont nous parlerons plus en détail ci-dessous. Toujours est-il que l'étape de rastérisation précise si chaque sous-pixel est associé au triangle du pixel. Il se peut que tous les sous-pixels soient sur le triangle, ce qui est signe qu'on est pile sur l'objet, que les sous-pixels sont tous l'intérieur du triangle.
Une fois calculé par l'unité de rastérisation, le masque de couverture est transmis aux pixels shaders. Les pixels shaders peuvent utiliser le masque de couverture pour certaines techniques de rendu, mais ce n'est pas une nécessité. Dasn la plupart des cas, les pixels shaders ne font rien avec le masque de couverture et le passent tel quel aux ROP. Le ROP prend la couleur calculée par le pixel shader et le masque de couverture. Si un sous-pixel est complétement dans le triangle, sa couleur est celle de la texture. Si le sous-pixel est en dehors du triangle, sa couleur est mise à zéro. Le ROP fait la moyenne des couleurs des sous-pixels du bloc comme avec le SSAA. La seule différence avec le SSAA, c'est que la couleur du pixel calculée par le pixel shader est juste pondérée par le nombre de sous-pixels dans le triangle. Le résultat est que le MSAA ne filtre pas toute l'image, mais seulement les bords des objets, seuls endroit où l'effet d'escalier se fait sentir.
Niveau avantages, le MSAA n'utilise qu'un seul filtrage de texture par pixel, et non par sous-pixel comme avec le SSAA, ce qui est un gain en performance notable. Le gain en calculs niveau pixel shader est aussi très important, tant que les techniques de rendu utilisant le masque de couverture ne sont pas utilisées. Le gain est d'autant plus important que la majorité des pixels sont situés en plein dans un triangle, les bords d'un
====L'antialiasing sur les textures transparentes====
Pour les textures partiellement transparentes, l’antialiasing de type MSAA ne donne pas de bons résultats. Les textures partiellement transparentes servent à rendre des feuillages, des grillages, ou d'autres objets du genre. Prenons l'exemple d'un grillage. La texture de grillage est posée sur une surface carrée, les portions transparentes de la texture correspondant aux trous du grillage entre les grilles, et les portions opaques au grillage lui-même. Dans ce cas, les portions transparentes sont
Tout cela a poussé les fabricants de cartes graphiques à inventer diverses techniques pour appliquer l'antialiasing à l'intérieur des textures transparentes. L'idée la plus simple pour cela est d'appliquer le MSAA sur toute l'image, mais de passer en mode SSAA pour les portions de l'image où on a une texture transparente. Cela demande cependant de détecter les textures transparentes au niveau du pixel shader, et de les rendre à plus haute résolution façon SSAA. Cette technique a été utilisée sur les cartes NVIDIA sous le nom de ''transparency adaptive anti-aliasing'' (TAAA) et sur les cartes AMD sous le nom d'''adaptive anti-aliasing''.
====Les optimisations du ''multisampling''====
Ligne 123 :
Avec l'antialiasing, l'image est rendue à une résolution supérieure, avant de subir un redimensionnement pour rentrer dans la résolution voulue. Cela a des conséquences sur le ''framebuffer''. Le ''framebuffer'' a la taille nécessaire pour la résolution finale, cela ne change pas. Mais il faut trouver un moyen de rendre l'image à la résolution supérieure. Pour cela, pas le choix : on doit créer une sorte de ''framebuffer'' temporaire dans lequel on mémorise l'image intermédiaire à haute résolution. L'antialiasing rend l'image de haute résolution dans ce second ''framebuffer'', puis la redimensionne pour donner l'image finale dans le ''framebuffer'' normal. De plus, le z-buffer et les autres tampons utilisés par le ROP sont agrandis, afin de rendre l'image de résolution supérieure. Si on prend un antialiasing 4x, soit avec 4 fois plus de pixels que la résolution initiale, le z-buffer prend 4 fois plus de place, le ''framebuffer'' temporaire aussi.
Évidemment, cela prend beaucoup de mémoire vidéo, sans compter que rendre une image à une résolution supérieure prend beaucoup de bande passante. et diverses optimisations ont été inventées pour limiter la casse. Avec le multisampling, il n'est pas rare que plusieurs sous-pixels aient la même couleur. Autant les pixels situés sur les bords d'un objet/triangle ont tendance à avoir des sous-pixels de couleurs différentes, autant les pixels situés à l'intérieur d'un objet sont de couleur uniforme. Cela permet une certaine forme d'optimisation, qui vise à tenir compte de ce cas particulier. L'idée est de compresser le ''framebuffer'' de manière ne pas mémoriser la couleur de chaque sous-pixel pour un pixel uniforme. Au lieu d'écrire quatre couleurs identiques pour 4 sous-pixels, on écrit une seule fois la couleur pour le pixel entier. D'autres techniques de compression similaires à celles utilisées pour les textures sont aussi utilisées, mais je ne reviendrais pas dessus.
Notons cependant qu'il existe un type de GPU pour lesquels ce genre d'optimisation n'est pas nécessaire. Rappelez-vous qu'il existe deux types de GPU : ceux en mode immédiat, sujet de ce cours, et ceux en rendu à tile. Avec ces derniers, l'écran est découpé en tiles qui sont rendues séparément, soit l'une après l'autre, soit en parallèle. Le traitement d'une tile fait qu'on a besoin que l'on a pas besoin d'un z-buffer pour toute l'image, mais d'un z-buffer par tile. Même chose pour le ''framebuffer'' temporaire, qui doit mémoriser la tile, pas plus. Les deux sont tellement petits qu'ils peuvent être mémorisés dans une SRAM intégrée aux ROP, et non en mémoire vidéo. L'antialiasing est donc
[[File:Carte graphique en rendu par tiles.png|centre|vignette|upright=2|Carte graphique en rendu par tiles]]
Ligne 133 :
L''''antialiasing par ''post-processing''''' regroupe plusieurs techniques d'antialiasing différentes du SSAA et du MSAA. Avec elles, l'image n'est pas rendue à plus haute résolution avant d'être redimensionnée. A la place, l'image est calculée normalement, à sa résolution finale. Une fois l'image finale mémorisée dans le ''framebuffer'', on lui applique un filtre d'antialiasing spécial. Le filtre en question varie selon la technique utilisée, mais l'idée générale est la même. C'est donc des techniques dites de ''post-processing'', où on calcule l'image, avant de lui faire subir des filtres pour l'embellir.
Le '''''Fast approximate anti-aliasing''''' (FXAA), et le '''''Subpixel Morphological Antialiasing''''' (SMAA) sont les premières techniques d'antialiasing par ''post-processing'' à avoir été intégrées dans les cartes graphiques modernes. Pour le FXAA, le filtre détermine les zones à filtrer en analysant le contraste. Les zones de l'image où le contraste évolue fortement d'un pixel à l'autre sont filtrées, alors que les zones où le contraste varie peu sont gardées intactes. La raison est que les zones où le contraste varie rapidement sont généralement les bords des objets, ou du moins des zones où l'effet d'escalier se fait sentir. l'algorithme
Les cartes graphiques récentes utilisent des techniques basées sur des réseaux de neurones pour effectuer de l'antialiasing. La première d'entre elle est le '''''Deep learning dynamic super resolution''''' (DLDSR), qui consiste à rendre l'image en plus haute résolution, puis à lui appliquer un filtre pour en réduire la résolution. C'est un peu la même chose que le ''supersampling'', sauf que le ''supersampling'' est réalisé dans les ROP, alors que le DLDSR est effectué avec une phase de rendu complète, suivie par l’exécution d'un shader qui redimensionne l'image. Une technique opposée est le '''''Deep learning super sampling''''' (DLSS), qui rend l'image à une résolution inférieure, mais applqiue un filtre qui redimensionne l'image à une plus haute résolution. La première version utilisait un filtre de ''post-processing'', mais les versions suivantes utilisent de l''antialising temporel. Quoique en soit, toutes les versions de DLSS appliquent une forme d'antialiasing, même si elles ''upscalent'' aussi l'image.
|