Explorer les possibilitées actuelles !
Table des matières
+ Référence rapide — chaque problème courant et où le résoudre sur le site.
→ Arguments de l'application .app
→ Objective-C++ vs C++ : synthaxe
→ Couleurs prévisualitation RGB (web isn't P3)
→ Lecture documentation Objective-C
→ Configuration d'un header en haut de tes fichiers *_*
→ Informations sur les licences des dépendances externes
→ Les modes de stockage des textures : setStorageMode()
→ Usage flags textures : setUsage()
→ Les fonctions de comparaison de profondeur Z+ : setDepthCompareFunction()
Récapitulatif
Vous arrivez au bout de la partie Prise en main. À ce stade, vous savez ouvrir une fenêtre et y accrocher une CAMetalLayer, obtenir un MTLDevice et une MTLCommandQueue, compiler un fichier .metal en MTLLibrary, construire un MTLRenderPipelineState, encoder une passe de rendu, envoyer des sommets au GPU via un MTLBuffer, échantillonner une MTLTexture, et enchaîner les matrices de simd jusqu'à obtenir une scène 3D avec une caméra contrôlable.
Cela fait beaucoup de notions en peu de chapitres. Avant de continuer, prenez le temps de manipuler ce que vous avez écrit : changez les formats de pixels, cassez volontairement le descripteur de vertex pour voir ce que le validateur vous dit, remplacez un setVertexBytes par un vrai buffer, ajoutez un deuxième objet à la scène. Les erreurs que vous provoquez vous-même sont celles que vous saurez diagnostiquer plus tard.
Trois pièges qui reviennent souvent
- Le NDC de Metal a un z compris entre 0 et 1, pas entre -1 et 1. Une matrice de projection recopiée d'un tutoriel OpenGL donnera une profondeur fausse.
- L'origine des coordonnées de texture est en haut à gauche. Si vos textures apparaissent à l'envers, c'est presque toujours ça.
- Les ressources sont liées par numéro de slot ([[buffer(1)]]), jamais par nom. Décaler un index d'un cran ne produit aucune erreur de compilation, seulement un rendu absurde.
Quand vous vous sentez à l'aise avec l'ensemble, passez à la partie Éclairage.
Glossaire
Fondations
- Metal : l'API graphique et de calcul bas niveau d'Apple. Contrairement à OpenGL, ce n'est pas une spécification implémentée par des pilotes tiers, mais un framework fourni directement par le système.
- metal-cpp : les en-têtes C++ officiels qui exposent Metal sans passer par Objective-C. C'est ce que nous utilisons dans tout le cours.
- MTLDevice : l'objet qui représente le GPU. C'est la fabrique de toutes les ressources : buffers, textures, bibliothèques de shaders, états de pipeline.
- CAMetalLayer : la couche Core Animation dans laquelle Metal présente ses images. C'est le point de contact entre le GPU et la fenêtre.
- CAMetalDrawable : la texture présentable récupérée à chaque image. Conceptuellement l'équivalent du back buffer, mais il faut la demander explicitement et la relâcher vite.
Soumission du travail
- MTLCommandQueue : la file dans laquelle on soumet le travail. Créée une fois pour toute la durée de vie de l'application, jamais par image.
- MTLCommandBuffer : un conteneur de commandes destiné au GPU, rempli par des encodeurs puis validé avec commit. Objet jetable : un nouveau à chaque image.
- MTLRenderCommandEncoder : l'objet qui traduit vos appels de dessin en commandes GPU. Un encodeur correspond exactement à une passe de rendu, et se termine par endEncoding.
- MTLBlitCommandEncoder : l'encodeur des opérations de copie : transferts entre buffers et textures, remplissages, génération des mipmaps.
- MTLRenderPassDescriptor : la description des attachements d'une passe — couleur, profondeur, stencil — et de ce qu'il faut en faire.
- loadAction / storeAction : ce que le GPU fait du contenu d'un attachement à l'entrée de la passe (charger, effacer, ignorer) et à la sortie (conserver, jeter). Sur une architecture à tuiles, ces deux champs pèsent lourd sur les performances.
- Frames in flight : le nombre d'images que le CPU a le droit de préparer d'avance. On le borne avec un sémaphore pour éviter d'écrire dans un buffer que le GPU est en train de lire.
Pipeline et état
- Pipeline graphique : le trajet complet d'un sommet — assemblage des attributs, vertex shader, rastérisation, fragment shader, tests de profondeur et de stencil, écriture dans les attachements.
- MTLRenderPipelineState : l'objet immuable qui fige d'un bloc les deux shaders, les formats de pixels des attachements, le descripteur de vertex et le blending. Sa construction est coûteuse, sa liaison est presque gratuite : c'est le grand principe de Metal, payer au chargement plutôt qu'à chaque image.
- MTLDepthStencilState : la fonction de comparaison de profondeur et l'autorisation d'écriture, dans un objet séparé du pipeline state.
- MTLViewport : la région de la cible de rendu où l'on dessine, avec ses bornes de profondeur.
- Validation layer : le mode de vérification activable au lancement. Il transforme la plupart des rendus noirs inexplicables en un message d'erreur précis.
Ressources
- MTLBuffer : un bloc de mémoire accessible au GPU. Il sert indifféremment de tampon de sommets, d'indices ou de constantes — Metal ne distingue pas les types de buffers.
- MTLStorageMode : l'emplacement de la ressource. shared est visible du CPU et du GPU, private réservé au GPU, memoryless n'existe que le temps d'une passe. Sur Apple Silicon, la mémoire unifiée rend shared quasi gratuit.
- MTLVertexDescriptor : la description du format des sommets — format, décalage et index de buffer de chaque attribut, pas d'avancement de chaque flux. C'est l'équivalent le plus proche d'un VAO, à ceci près qu'il est figé dans le pipeline state.
- MTLTexture : une image structurée destinée au GPU, avec son type (2D, cube, tableau), son nombre de niveaux de mip et son usage déclaré.
- MTLPixelFormat : le format d'un texel ou d'un attachement. Il doit correspondre exactement entre la texture, le descripteur de passe et le pipeline state.
- MTLSamplerState : l'objet qui décide comment lire une texture — filtrage d'agrandissement et de réduction, filtrage entre mips, mode d'adressage. Il est séparé de la texture : un même sampler sert pour plusieurs images.
- Mode d'adressage : le comportement du sampler hors de l'intervalle [0, 1] — répétition, miroir, blocage sur le bord, couleur de bordure.
- Mipmaps : les versions réduites successives d'une texture, choisies selon la surface couverte à l'écran. On les génère avec un blit encoder.
Shaders et MSL
- MSL : le Metal Shading Language, un dérivé de C++14. Templates, surcharge et structures s'y écrivent normalement, ce qui permet de partager un même en-tête entre le code CPU et le code GPU.
- MTLLibrary : l'ensemble des fonctions shader compilées, généralement un fichier .metallib produit à la compilation du projet.
- MTLFunction : un point d'entrée nommé extrait d'une bibliothèque, désigné par un qualificateur vertex, fragment ou kernel.
- Espaces d'adressage : la mémoire visée par un pointeur en MSL. device pour les gros tampons en lecture-écriture, constant pour les données lues identiquement par tous les threads, thread pour le privé, threadgroup pour le partagé au sein d'un groupe.
- Qualificateurs d'attribut : les annotations entre doubles crochets qui relient le shader au monde extérieur — [[buffer(n)]], [[texture(n)]], [[position]], [[stage_in]].
- stage_in : le mécanisme par lequel un vertex shader reçoit ses attributs déjà assemblés d'après le vertex descriptor, plutôt que de les lire à la main dans un buffer.
- setVertexBytes / setFragmentBytes : l'envoi direct d'une petite structure au shader sans passer par un MTLBuffer. C'est le remplaçant le plus direct des uniforms de GLSL, limité à quelques kilo-octets.
Mathématiques et espaces
- simd : la bibliothèque vectorielle d'Apple, disponible des deux côtés de la frontière CPU/GPU. Elle joue le rôle que GLM tient chez OpenGL, mais elle est déjà là.
- Vecteur : une grandeur qui porte une direction et une longueur, et qu'on emploie aussi bien pour une position que pour un déplacement.
- Matrice : un tableau de nombres qui encode une transformation. Chez Metal comme chez simd, la convention est en colonnes.
- Espace local : les coordonnées d'un modèle relatives à son propre point d'origine, telles qu'elles sortent du logiciel de modélisation.
- Espace monde : les coordonnées relatives à l'origine commune de la scène, une fois la matrice de modèle appliquée.
- Espace vue : la scène exprimée depuis la caméra, qui se retrouve à l'origine et regarde selon un axe fixe.
- Espace de découpe : le résultat de la projection, avant division perspective. C'est ce que le vertex shader doit écrire dans [[position]] ; le matériel se charge du reste.
- NDC : les coordonnées normalisées après division perspective. Chez Metal, x et y vont de -1 à 1, mais z de 0 à 1.
- Espace écran : les coordonnées en pixels dans la cible de rendu, origine en haut à gauche.
- LookAt : la matrice de vue construite à partir d'une position, d'une cible et d'un vecteur vertical de référence.
- Angles d'Euler : le lacet, le tangage et le roulis, dont on tire un vecteur de direction pour orienter la caméra.