Introduction au développement de Shader pour Realm Crafter
Transcription
Introduction au développement de Shader pour Realm Crafter
Introduction au développement de Shader pour Realm Crafter Table des matières: _ Introduction _ Qu‟est ce qu‟un shader et qu‟est ce que ça signifie? _ Les Vertex Shaders L‟espace Objet (Object Space) L‟espace Univers (World Space) L‟espace Vue (View Space) L‟espace écran (Screen Space) _ Les Pixel Shaders _ Les effets de structure (Effect Structure) Les Constantes Déclaration de Vertex Code de Shader Techniques et Passes _ Et maintenant? Introduction C‟est à la fois un tutorial et une page d‟information qui traite principalement de Realm Crafter. Certaines parties peuvent être, et, sont, issues d‟autres softwares. Aussi, ce tutorial ne vous apprendra pas grand chose en math; Realm Crafter a la gentillesse de nous proposer gratuitement de petites fonctions pour nous aider avec l‟éclairage et le fog (brouillard, flou). Maintenant que ce petit Avertissement est passé, passons aux choses sérieuses… Qu‟est ce qu‟un shader et qu‟est ce que ça signifie? Un shader c‟est juste un tout petit programme/code qui agira directement sur le GPU (carte graphique). Il y a 3 types de shader; vertex, geometry et pixel. Je n‟évoquerai pas les geometry shaders, du fait qu‟ils ne fonctionnent qu‟avec D3D10+. Quand un objet est représenté, le GPU travaille énormément pour retranscrire toutes vos informations 3D (groupes de triangles/faces et les textures) vers une image en 2D sur votre moniteur. Il y a une foule d‟étape à traverser avant que chaque vertex et pixel ne soit mis en “rendu” (affiché en 3d); ici, seule les étapes dites « programmables » sont les seules à nous intéresser pour le moment. Un mesh est constitué d‟une grosse liste de triangles qui eux-mêmes sont composés de 3 sommets (3 vertices = vertex au pluriel). Un vertex aura, au moins, une position; même s‟il pourra contenir également d‟autres informations (comme la couleur). Le vertex shader consiste à capturer le rendu de chaque vertex et à transformer ses coordonnées 3D en coordonnées 2D à l‟écran. Ensuite, nous pourrons appliquer d‟autres effets au vertex comme l‟éclairage et le fog. Prenons un triangle, imaginez chaque point qui passerait par le vertex shader. L‟étape suivante consisterait donc à remplir le triangle avec une couleur ou avec une texture. Un pixel shader consiste à texturer chaque pixel du triangle. Ça peut être encore plus poussé; nous pourrons ensuite travailler sur un éclairage plus avancé en utilisant une normal map ou un parallax mapping. Les Vertex Shaders La fonction principale du vertex shader, c‟est de transformer la position du vertex, depuis l‟espace object (object programmables) vers l‟espace écran (programmables programmables). La prochaine partie est plus mathématique, attention. L‟espace Objet (Object Space) Quand vous créez un model, vous centralisez tous ses sommets (vertices) autour d‟un point d‟origine. Ces sommets sont dans “L‟espace Objet” et ces mêmes sommets sont renvoyés dans le vertex shader. L‟espace Univers (World Space) Vous aurez probablement plusieurs copies de votre mesh dans une même scène. Le mesh lui-même ne change pas; les sommets sont toujours contenus dans l‟espace objet. Toutefois, Le moteur retiendra la transformation de l‟objet par rapport à son origine dans l‟univers. La 1ère tâche de votre vertex shader consistera à combiner les sommets de l‟espace objet avec la transformation depuis le moteur. Résultat, les sommets seront inclus dans l‟espace univers. L‟espace Vue (View Space) Parfois on le nomme également “L‟espace caméra” (Camera Space), il définit le rapport du vertex (sommet) à la caméra. La camera peut avoir n‟importe quelle position dans une scène; donc tous vos vertex doivent être déplacés correctement de façon à toujours lui faire face. Dans l‟espace univers, nous pouvons déterminer à quelle distance un vertex se situe par rapport à la scène d‟origine. Dans l‟espace vue, nous pouvons désormais trouver où le vertex se situe par rapport à la caméra réelle. L‟espace écran (Screen Space) La transformation finale traduit les sommets et leurs positions de l‟espace vue vers l‟écran 2D . L‟espace vue nous indique que les sommets sont faces à la caméra, donc nous n‟avons plus qu‟à générer une position 2D à partir de ces derniers. C‟est à partir de ce point que le champs de vision et son ratio aspect sont pris en considération; les triangles seront étirés pour s‟adapter en conséquence. C‟est le processus final dans la transformation du vertex. Cette donnée est alors utilisée pour l‟étape suivante… Les Pixel Shaders Une fois que tous nos triangles/faces ont été rendu; nous devons les remplir de couleur, pour ainsi dire. Au plus bas niveau, vous pouvez vous contenter de fournir une couleur à un pixel. Mais au plus haut, vous pouvez gérer des réflexions complexes, des réfractions et différents éclairages. En général, le pixel shader aura une coordonnée de texture. C‟est une valeur qui sera utilisée pour “rechercher” une texture. La coordonnée aura une valeur X et une Y qui, pour chacune d‟elle, sera comprise entre 0 et 1 (il est possible que les valeurs soient plus hautes, mais en règle générale elles restent comprises entre 0-1). Le shader ne tient pas compte des dimensions de votre texture, à partir des coordonnées de la texture, il se réfère à une distance relative. Ainsi sur une texture 256x256 , une valeur de “0.5” fera référence au pixel 128. De même, sur une 512x512, la même valeur fera référence au pixel 256. On couvrira l‟ensemble des usages actuels des textures dans la partie pratique de ce tutorial. Les effets de structure (Effect Structure) Les fichiers utilisés par Realm Crafter sont des fichiers Microsoft DirectX Effect (.fx). Ces derniers nous offrent tout un éventail de fonctions à utiliser. Dans les derniers jours de D3D8 et au début de D3D9, vous deviez conserver vos codes séparés, et vous ne pouviez pas avoir un système de rendu automatisé égale à celui que les moteurs modernes vous fournissent. Les chapitres suivants vous expliqueront les différentes sections d‟un fichier .FX. Les Constantes Nos programmes de shader ont besoin de recevoir des données depuis l‟application. Cela inclut: Les informations de Transformation _ Textures _ lumières _ Fog _ Bones (pour l‟animation) Ces variables sont à l‟extérieur du code principal et sont appelés constantes; Elles sont semblables aux „globals‟ en programmation. Cependant, les constantes ne peuvent pas être attribuées à partir d'un shader. HLSL fournit plus de types de données que les autres langages. Je n‟inclurai pas la liste complète, mais je vais répertorier quelques uns des types les plus importants: float – c’est une valeur numérique qui peut avoir un point décimal; c’est la base des constantes les plus fréquentes. float2 – C’est un float à 2 dimensions. Qui comprend les 2 valeur de ‘x’ et ‘y’. float3 – c’est un float à 3 dimensions. Qui comprend les valeurs de ‘x’, ‘y’ et ‘z’. float4 – C’est un float à 4 dimensions. Qui comprend les valeurs de ‘x’, ‘y’ et ‘z’, mais également une valeur ‘w’. float4x4 – C’est la plus utilisée pour les matrices (les types de transformation). Elles contiennent 16 variables de floating point (imaginé comme une grille 4x4). texture – Une simple texture issue du moteur. Les types Integer (programmables) sont supportés, mais ne sont pas recommandés. Les GPUs calculent les valeurs du floating point plus rapidement que celles des programmables Une constante peut être donnée comme un paramètre spécial connu en tant que semantic. Realm Crafter utilise des semantics pour connaître quelles variables sont nécessaires pour contrôler et fournir. Les constantes peuvent aussi être contenu dans un tableau (défini par des crochets). Quelques exemples de constantes: float ObjectAlpha : Alpha; float3 CameraPos : CameraPosition; float4x4 WVP : WorldViewProjection; float4x4 Bones[50] : Bones; Declaration de Vertex Une déclaration de Vertex est une structure qui décrit les propriétés d‟un simple vertex. La plupart des shaders contiennent 2 structures. La 1ére c‟est la vertex input structure; c‟est le format que le moteur fournit au shader et qui sera utilisé pour le vertex. Le second c‟est la vertex output structure; elle contient toutes les données qui seront envoyées du vertex shader au pixel shader. Une déclaration de vertex peut indiquer au GPU quelle sorte de propriétés elle utilise. Par exemple, nous avons quasiment toujours besoin d‟une variable de position (et le GPU a besoin que nous lui sortions toujours une position). De plus, nous souhaiterions utiliser les coordonnées de texture et les couleurs de vertex. Les types de propriétés sont de simples semantics (comme pour les constantes). Voici une liste des semantics que vous rencontrerez: Position – Une position de vertex Normal/Tangent/BiNormal – Un vertex normal/Tangent/BiNormal; TexCoordn – Une coordonnée de texture. N fait référence à un index compris entre 0 et 7, ce qui signifie que vous pouvez avoir jusqu’a 8 coordonnées de texture par vertex. Colorn – Une couleur, l’index fonctionne de la même façon que pour les textures ci-dessus. Nous pouvons avoir jusqu'à 8 sémantics “TexCoord”. Ça peut sembler beaucoup, mais en réalité nous les utiliserons plus que de simples coordonnées de textures. Vous verrez toute à l‟heure qu‟elle sert également à extraire les informations de lumière. Quelques exemples de structure: // Input structure of a normal vertex struct VSStandard { float4 Position : POSITION; float3 Normal : NORMAL; float4 Color : COLOR0; float2 TexCoord : TEXCOORD0; }; // Output structure. Notice how we’re using texture coordinates // for other things. struct VSOut { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; float4 Lights : COLOR1; float4 Fog : TEXCOORD1; float3 Normal : TEXCOORD2; float4 Light0Dir : TEXCOORD3; float4 Light1Dir : TEXCOORD4; }; Code de Shader Il s‟agit du code de nos vertex et pixel shader. Ceux sont 2 fonctions auxquelles nous ferons appel plus tard. Techniques et Passes La plus importante, et indispensable, partie du shader c‟est la technique. Une technique décrit une liste de passes dans le shader. La plupart des shaders de Realm Crafter auront une seule technique et une seule passe. Une passe c‟est une instance dans laquelle l‟objet est affiché en rendu. Si vous avez de multiples passes, l‟objet sera “rendu” (donc) plusieurs fois; il y aura très peu d‟instances où vous en aurez besoin, ou même pour lesquelles vous voudriez le faire. A l‟intérieur d‟une passe, nous stockons les noms de fonctions des 2 vertex shader et pixel shader. Nous stockons également la version du shader dont les fonctions seront compilés (en général, il s‟agit de la version 2.0). La partie finale de la pass est une liste des états de rendu. Un état de rendu (render state) est un paramètre que le GPU pourra utiliser dans les parties dites non programmables du pipeline de rendu. Je ne les décrirai pas in dans ce tutorial parce qu‟elles ne sont pas nécessaires pour le moment. Un exemple de pass: technique MyTechnique { pass Pass0 { // Shaders VertexShader = compile vs_2_0 vs_main(); PixelShader = compile ps_2_0 ps_main(); // Render states alphablendenable = true; srcblend = srcalpha; destblend = invsrcalpha; zenable = true; zwriteenable = true; } } Et maintenant ? Maintenant, nous allons essayer de créer notre premier shader que nous utiliserons dans RCP. Rendez-vous dans le Tutorial 2. Realm Crafter is a registered trademark of Solstar Games, LLC. Tutorial content may not be copied without permission. Traduit par Giuliani (Terrier) avec l‟aimable autorisation de Solstar Games, LLC.