Shader n'est pas magique. Écriture de shaders dans Unity. Présentation

Bonjour à tous! Je m'appelle Grigory Dyadichenko et je suis le fondateur et directeur technique de Foxsys Studios. Aujourd'hui, je veux parler des shaders. La possibilité d'écrire des shaders (et généralement de travailler avec le rendu) est très importante lors du développement pour les plates-formes mobiles ou AR / VR, si vous voulez obtenir des graphiques sympas. De nombreux développeurs pensent que les shaders sont magiques. Qu'il y a peu de bonnes informations à leur sujet, et que pour les écrire, vous devez avoir, au minimum, le titre de candidat à la science. Oui, le développement des shaders par leurs principes est très différent du développement client. Mais l'essentiel est de comprendre les principes de base des shaders, ainsi que de connaître leur essence, pour qu'il n'y ait rien de magique et que la recherche d'informations sur ce sujet soit une tâche simple. Cette série d'articles est destinée aux débutants, donc si vous êtes bon en programmation de shaders, cette série ne vous intéressera pas. Quiconque veut comprendre ce sujet - bienvenue sous la coupe!



Ceci est un article introductif dans lequel je décrirai les principes généraux de l'écriture des shaders. Si le sujet est intéressant, nous analyserons plus en détail dans des articles distincts: vertex shaders, shaders géométriques, fragment / pixel shaders, triplanar shaders, screenspace effects et computer shaders (OpenCL, CUDA, etc.). Et en général, toute la magie que l'on peut faire sur le GPU. Cela sera trié dans le contexte du pipeline standard Unity. Donc, LWRP et HDRP me semblent un peu humides jusqu'à présent.

Qu'est-ce qu'un shader?



Source: www.shadertoy.com/view/MsGSRd

En fait, il s'agit d'un programme fonctionnant sur le GPU, dont la sortie est une information différente. Dans les vertex shaders, ce sont les paramètres des sommets du maillage. Les pixel shaders sont exécutés pixel par pixel.

Pour comprendre le fonctionnement des shaders, vous devez indiquer ce qu'est un pipeline graphique. Très souvent, les gens parlent de ce sujet avec des mots assez compliqués, mais nous le rendrons un peu plus facile à comprendre. Prenons l'exemple d'OpenGL. À cet égard, j'aime beaucoup cette photo.



Si vous omettez des pièces liées à l'éclairage, etc. En général, du point d'écrire les mêmes shaders Unlit sur hlsl, l'essentiel est le suivant. Nous avons un shader

#pragma vertex vert #pragma fragment frag 

où nous déterminons que la partie vertex du shader sera écrite dans la fonction vert, et la partie fragment dans la fonction frag.

Les structures que nous décrivons dans le shader déterminent les données que nous prendrons du maillage et après traitement avec le vertex shader qui sont suspendus à nos objets MeshRenderer et MeshFilter.

  struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; 

Ensuite, le vertex shader calcule en recevant les données d'application en entrée et donne le résultat sous la forme d'une structure v2f, qui va ensuite au fragment shader. Qui à son tour va déjà calculer la couleur du pixel. Étant donné que les informations v2f sont écrites uniquement sur les sommets (qui sont plus petits que les pixels), les données de la partie fragment sont interpolées. Tout cela peut être représenté comme le fait que vert est considéré indépendamment dans chaque sommet. Ensuite, le résultat est transféré à la partie fragment, où frag pour chaque pixel est considéré comme indépendant. Étant donné que les calculs sont effectués en parallèle, dans ces parties, il n'y a pas d'informations sur les voisins (si vous ne les transmettez pas intelligemment).

Plus en détail, toutes les nuances, ainsi que de nombreux exemples sont décrits dans la documentation d'Unity docs.unity3d.com/Manual/SL-Reference.html

Langages de programmation Shader



Source: www.shadertoy.com/view/WsS3Dc

Quoi d'autre est important de ne pas oublier. Le fait que les shaders soient maintenant écrits dans trois langages de programmation qui n'ont rien à voir avec l'unité. CG, GLSL et HLSL. La façon la plus simple d'écrire des shaders dans une unité est via HLSL, car c'est là que les fichiers de shaders avec l'autorisation .shader sont écrits. Et s'il y a relativement peu d'informations sur les shaders dans le contexte d'une unité, alors les informations séparément sur HLSL, GLSL et CG ne sont que des tonnes. La documentation des shaders décrit comment transférer ce qui est écrit dans ces langues vers Unity. Par conséquent, il s'avère que presque toutes les informations en général sur ces langages de programmation sont valides. Les trois langages sont très similaires au C, mais chacun a ses propres caractéristiques.

De plus, du point de vue de l'étude des shaders, lorsque ces langages ne posent plus de questions, vous pouvez voir quelles opportunités "UnityCG.cginc" et d'autres bibliothèques écrites par unité offrent en soi pour simplifier leur travail.

Pourquoi si dans les shaders, c'est mauvais?



Source: www.shadertoy.com/view/Md3cWr

Il est important de comprendre comment les shaders sont exécutés au niveau du fer et pourquoi ils sont si rapides qu'ils peuvent effectuer des millions d'opérations sans forcer.

L'idée principale des GPU est le parallélisme maximal des calculs. Ici, il est nécessaire d'introduire un tel concept de «front d'onde». En fait, c'est assez simple, le front d'onde est un groupe de shaders qui effectue la même séquence d'opérations. Autrement dit, du point de vue du GPU, la meilleure option est lorsque les mêmes instructions sont exécutées en même temps. La seule différence d'exécution est l'entrée. Le problème de la ramification est qu'une situation peut se produire lorsque dans un seul groupe de shaders, les shaders doivent appeler différentes opérations. Ce qui à son tour conduit à la création d'un nouveau front d'onde, à la copie de données, etc. Et c'est très cher.

Il y a des nuances et des exceptions, mais pour écrire en toute sécurité si, vous devez comprendre comment il se comporte sur la version cible de l'API graphique. Étant donné que les mêmes OpenGL ES 2 ou DX11 à cet égard sont très différents.

Pourquoi dois-je le savoir, car il existe des éditeurs de nœuds?




Il est important de comprendre que les éditeurs de nœuds sont avant tout un outil pour les artistes techniques. Ce sont des spécialistes qui ont une expertise en mathématiques, mais qui sont plus des designers. Les shaders de type filaire (où la compréhension des coordonnées barycentriques est requise) ou la transformation en coordonnées cartésiennes, qui est utilisée pour des projections délicates, est beaucoup plus facile à faire avec du code, comme de nombreux modèles mathématiques de matériaux physiques. Dans le même temps, du point de vue d'un programmeur de shaders, vous créez essentiellement des nœuds et des outils personnalisés pour que les artistes techniques créent une vraie magie. Les éditeurs de nœuds ont des fonctionnalités limitées de ce point de vue. Par conséquent, il est important de pouvoir écrire des shaders dans des langages comme hlsl. Comprendre comment fonctionne le rendu, etc.

Ressources utiles pour l'apprentissage



Source: www.shadertoy.com/view/4tlcWj

En termes d'apprentissage de la programmation des shaders, un bon exercice consiste à réécrire les shaders depuis www.shadertoy.com ou glslsandbox.com . De plus, il y a un profil sympa d'un spécialiste d'Unity, où vous pouvez voir beaucoup de github.com/keijiro intéressants

Tout le reste n'est que des mathématiques et une compréhension de la physique des effets. Ceci est quelque peu similaire au mélange des ingrédients, si le problème spécifique de la modélisation physique n'est pas résolu. Beaucoup de choses intéressantes peuvent être faites en mélangeant le bruit, la réfraction, la diffusion souterraine de la lumière, les caustiques, l'effet Fresnel, la réaction de diffusion et d'autres propriétés physiques des objets. En général, la programmation des shaders n'est certainement pas élémentaire, et il y a lieu de creuser en profondeur.

Si le sujet des shaders est intéressant, je vais essayer de publier une série d'articles sur ce sujet, déjà avec des exemples spécifiques et des tutoriels sur le sujet de la création d'effets différents. Suggérez dans les commentaires ce que vous aimeriez lire et quels sujets étudier. Merci de votre attention!

Tous les effets de l'article sont un enregistrement des effets de shader avec shadertoy.

Source: https://habr.com/ru/post/fr473638/


All Articles