Bonjour à tous. Mes articles précédents étaient et Programmation réactive dans le développement de jeux : spécificités de Unity . Développer des jeux sur Unity : examiner les approches de l'organisation de l'architecture Aujourd'hui, je voudrais aborder un sujet tel que le rendu et les shaders dans Unity. Les shaders (en termes simples) sont des instructions pour les cartes vidéo qui leur indiquent comment rendre et transformer des objets dans le jeu. Alors, bienvenue au club, mon pote. Avertir! Cet article faisait un kilomètre de long, je l'ai donc divisé en deux parties ! Comment fonctionne le rendu dans Unity ? Dans la version actuelle de , nous avons trois pipelines de rendu différents : intégré, HDRP et URP. Avant de traiter du rendu, nous devons comprendre le concept des pipelines de rendu que nous propose Unity. Unity Chaque pipeline de rendu exécute certaines étapes qui effectuent une opération plus importante et forment un processus de rendu complet. Et lorsque nous chargeons un modèle (par exemple, .fbx) sur la scène, avant qu'il n'atteigne nos moniteurs, il parcourt un long chemin, comme s'il voyageait de Washington à Los Angeles sur différentes routes. Chaque pipeline de rendu a ses propriétés avec lesquelles nous allons travailler. Les propriétés des matériaux, les sources de lumière, les textures et toutes les fonctions à l'intérieur du shader affecteront l'apparence et l'optimisation des objets à l'écran. Alors, comment ce processus se déroule-t-il ? Pour cela, nous devons discuter de l'architecture de base des pipelines de rendu. Unity divise tout en quatre étapes : les fonctions d'application, l'utilisation de la géométrie, la rastérisation et le traitement des pixels. Fonctions applicatives Le traitement des fonctions commence sur le CPU et se déroule dans notre scène. Cela peut inclure : Traitement physique et erreur de calcul de collision Animations de textures Entrée clavier et souris Nos scénarios C'est là que notre application lit les données stockées en mémoire pour générer davantage nos primitives (triangles, sommets, etc.). A la fin de l'étape d'application, tout cela est envoyé à l'étape de traitement de la géométrie pour travailler sur les transformations de sommets à l'aide de transformations matricielles. Traitement de la géométrie Lorsque l'ordinateur demande via le CPU les images que nous voyons à l'écran, cela se fait en 2 étapes : à notre GPU Lorsque l'état de rendu est configuré et que les étapes du traitement de la géométrie au traitement des pixels ont été franchies Lorsque l'objet est rendu à l'écran La phase de traitement de la géométrie se déroule sur le GPU et est responsable du traitement de la sommets de notre objet. Cette phase est divisée en quatre sous-processus : ombrage des sommets, projection, découpage et affichage à l'écran. Lorsque nos primitives ont été chargées et assemblées avec succès lors de la première étape d'application, elles sont envoyées à l'étape de vertex shading. Il a deux tâches : Calculer la position des sommets dans l'objet Convertir la position en d'autres coordonnées spatiales (des coordonnées locales aux coordonnées mondiales, par exemple) afin qu'elles puissent être rendues à l'écran De plus, au cours de cette étape, nous pouvons également sélectionner les propriétés qui seront nécessaires pour les prochaines étapes de dessin des graphiques. Ceux-ci incluent les normales, les tangentes, ainsi que les coordonnées UV et d'autres paramètres. La projection et le découpage fonctionnent comme des étapes supplémentaires et dépendent des paramètres de la caméra dans notre scène. Notez que l'ensemble du processus de rendu est effectué par rapport au Camera Frustum. La projection sera responsable de la perspective ou du mappage orthographique, tandis que le découpage nous permet de couper la géométrie en excès à l'extérieur du tronc de caméra. Rastérisation et travail avec les pixels La est la rastérisation. Elle consiste à trouver des pixels dans notre projection qui correspondent à nos coordonnées 2D à l'écran. Le processus de recherche de tous les pixels occupés par l'objet écran est appelé pixellisation. Ce processus peut être considéré comme une étape de synchronisation entre les objets de notre scène et les pixels à l'écran. prochaine étape du travail de rendu Les étapes suivantes sont effectuées pour chaque objet à l'écran : Triangle Setup est chargé de générer des données sur nos objets et de les transmettre pour la traversée. Triangle Traversal énumère tous les pixels qui font partie du groupe de polygones ; dans ce cas, ce groupe de pixels est appelé un fragment. La dernière étape suit lorsque nous avons collecté toutes les données et que nous sommes prêts à afficher les pixels à l'écran. À ce stade, le fragment shader est lancé, qui est responsable de la visibilité de chaque pixel. Il est responsable de la couleur de chaque pixel à rendre à l'écran. Ombrage direct et différé Comme nous le savons déjà, Unity dispose de trois types de pipelines de rendu : Built-In, URP et HDRP. D'un côté, nous avons Built-In (le plus ancien type de rendu qui répond à tous les critères Unity). À l'inverse, nous avons les HDRP et URP (appelés Scriptable RP) plus modernes, optimisés et flexibles. Chaque pipeline de rendu a ses chemins de traitement graphique, qui correspondent à l'ensemble des opérations nécessaires pour passer du chargement de la géométrie au rendu à l'écran. Cela nous permet de traiter graphiquement une scène éclairée (par exemple, une scène avec une lumière directionnelle et un paysage). Des exemples de chemins de rendu incluent le chemin direct, le chemin différé et les sommets hérités différés et hérités allumés. Chacun prend en charge certaines fonctionnalités et limitations, ayant ses performances. Dans Unity, le chemin vers l'avant est la valeur par défaut pour le rendu. En effet, le plus grand nombre de cartes vidéo le prend en charge. Mais la voie vers l'avant a ses limites en matière d'éclairage et d'autres fonctionnalités. Notez que URP ne prend en charge que le chemin direct, tandis que HDRP a plus de choix et peut combiner à la fois les chemins directs et différés. Pour mieux comprendre ce concept, considérons un exemple où nous avons un objet et une lumière directionnelle. La façon dont ces objets interagissent déterminera notre chemin de rendu (modèle d'éclairage). De plus, le résultat sera influencé par : Caractéristiques du matériau Caractéristiques des sources d'éclairage Le modèle d'éclairage de base correspond à la somme de 3 propriétés différentes : couleur ambiante, réflexion diffuse et réflexion spéculaire. Le calcul de l'éclairage se fait dans le shader. Cela peut être fait par sommet ou par fragment. Lorsque l'éclairage est calculé par vertex, il est appelé éclairage par vertex et est effectué à l'étape du vertex shader. De même, si l'éclairage est calculé par fragment, il est appelé shader par fragment ou par pixel et se fait à l'étape du shader de fragment (pixel). L'éclairage Vertex est beaucoup plus rapide que l'éclairage Pixel, mais vous devez considérer que vos modèles doivent avoir de nombreux polygones pour obtenir un beau résultat. Matrices dans l'unité Revenons donc à nos étapes de rendu, plus précisément à l'étape de travail avec les vertex. Les matrices sont utilisées pour leur transformation. Une matrice est une liste d'éléments numériques qui obéissent à certaines règles arithmétiques et sont souvent utilisées en infographie. Dans Unity, les matrices représentent les transformations spatiales. Parmi eux, on peut retrouver : UNITY_MATRIX_MVP UNITY_MATRIX_MV UNITY_MATRIX_V UNITY_MATRIX_P UNITY_MATRIX_VP UNITY_MATRIX_T_MV UNITY_MATRIX_IT_MV unité_ObjectToWorld unity_WorldToObject Ils correspondent tous à des matrices quatre par quatre (4x4). Chaque matrice comporte quatre lignes et quatre colonnes de valeurs numériques. Un exemple de matrice peut être l'option suivante : Comme cela a été dit précédemment - nos objets ont deux nœuds (dans certains éditeurs graphiques, ils sont appelés transformation et forme), et les deux sont responsables de la position de nos sommets dans l'espace objet. L'espace objet définit la position des nœuds par rapport au centre de l'objet. Et chaque fois que nous modifions la position, la rotation ou l'échelle des sommets de l'objet, nous multiplions chaque sommet par la matrice du modèle (dans le cas de Unity - UNITY_MATRIX_M). Pour transférer des coordonnées d'un espace à un autre et y travailler, nous travaillerons constamment avec différentes matrices. Propriétés des objets polygonaux Poursuivant le thème du travail avec des objets polygonaux, je peux dire que dans le monde des graphiques 3D, chaque objet est constitué d'un maillage polygonal. Les objets de notre scène ont des propriétés ; chacun contient toujours des sommets, des tangentes, des normales, des coordonnées UV et une couleur. L'ensemble forme un maillage. Tout cela est . géré par des shaders Avec les shaders, nous pouvons accéder et modifier chacun de ces paramètres. Nous utiliserons généralement des vecteurs (float4) lorsque nous travaillerons avec ces paramètres. Ensuite, analysons chacun des paramètres de notre objet. Sommets Les sommets d'un objet correspondent à un ensemble de points qui définissent la surface dans l'espace 2D ou 3D. Dans les éditeurs 3D, les sommets sont généralement représentés comme des points d'intersection entre le maillage et l'objet. Les sommets sont caractérisés, en règle générale, par 2 points : Ce sont des composants enfants du composant de transformation Ils ont une certaine position selon le centre de l'objet commun dans l'espace local Cela signifie que chaque sommet a son composant de transformation responsable de sa taille, de sa rotation et de sa position, ainsi que des attributs qui indiquent où ces sommets sont relatifs au centre de notre objet. Normales Les normales nous aident intrinsèquement à déterminer où se trouve la face de nos tranches d'objet. Une normale correspond à un vecteur perpendiculaire à la surface d'un polygone, qui est utilisé pour déterminer la direction ou l'orientation d'une face ou d'un sommet. Tangentes En se référant à la documentation Unity, on obtient la description suivante : Une tangente est . Les tangentes dans Unity sont représentées par Vector4, avec des composants x, y, z définissant le vecteur, et w utilisé pour inverser la binormale si nécessaire - Unity Manual un vecteur de longueur unitaire qui suit la surface du maillage le long de la direction de texture horizontale (U) Qu'est-ce que je viens de lire ? En langage simple, les tangentes suivent les coordonnées U en UV pour chaque forme géométrique. Coordonnées UV Beaucoup de gars ont regardé les skins dans et peut-être, comme moi, ont même essayé de dessiner quelque chose qui leur était propre. Et les coordonnées UV sont exactement liées à cela. Nous pouvons les utiliser pour placer une texture 2D sur un objet 3D. GTA Vice City Ces coordonnées agissent comme des points de référence qui contrôlent quels texels de la carte de texture correspondent à chaque sommet du maillage. La zone des coordonnées UV est égale à une plage comprise entre 0,0 (flottant) et 1,0 (flottant), où "0" représente le point de départ et "1" représente le point final. Couleurs des sommets En plus de la position, de la rotation et de la taille, les sommets ont également leurs couleurs. Lorsque nous exportons un objet à partir d'un logiciel 3D, celui-ci attribue une couleur à l'objet qui doit être affectée par l'éclairage ou la copie d'une autre couleur. La couleur de vertex par défaut est le blanc (1,1,1,1,1,1) et les couleurs sont encodées en RGBA. À l'aide des couleurs de sommet, vous pouvez, par exemple, travailler avec le mélange de texture, comme indiqué dans l'image ci-dessus. Petite conclusion C'est la fin de la 1 partie. Dans la 2 partie, j'aborderai : Qu'est-ce qu'un shader Langages de shaders Types de shader de base dans Unity Structure de nuanceur ShaderLab Mélange Tampon Z (tampon de profondeur) Abattage Cg/HLSL Graphique d'ombrage Si vous avez des questions, laissez-les dans les commentaires !