La 3D sous XNA Campus-Booster ID : **XXXXX Copyright © SUPINFO. All rights reserved La 3D sous...
-
Upload
frederique-billy -
Category
Documents
-
view
113 -
download
1
Transcript of La 3D sous XNA Campus-Booster ID : **XXXXX Copyright © SUPINFO. All rights reserved La 3D sous...
La 3D sous XNACampus-Booster ID : **XXXXX
www.supinfo.com
Copyright © SUPINFO. All rights reserved
La 3D sous XNA
Objectifs de ce module
Découvir la 3D. Que faut il connaître pour faire de la 3D ?
Afficher votre objet en 3D. Afficher un simple triangle puis un modèle en 3D.
Comprendre et utiliser les transformations. Modifier la position, l’orientation et la taille d’objets 3D.
En suivant ce module vous allez :
La 3D sous XNA
Plan du module
Introduction à la 3D. coordonnées, caméra, vertex…
Affichage d’un triangle. Comment afficher un simple triangle ?
Transformations. Modifications de l’état de nos objets 3D.
Affichage d’un modèle 3D. Utilisation de modèles 3D.
Billboarding. De la 2D en 3D.
Lumière. Gestion de l’éclairage
Optimisations. Optimiser l’affichage.
Voici les parties que nous allons aborder :
La 3D sous XNA
Introduction à la 3D
coordonnées, caméra, vertex…
La 3D sous XNA
Plan de la partie
Le système de coordonnées.
La Caméra.
Le vertex.
Voici les chapitres que nous allons aborder :
Introduction à la 3D
Le monde de jeu se situe dans un repère 3D orthonormé.
Chaque objet sera positionné dans le monde suivant ses coordonnées X, Y et Z.
Il s’agit d’un repère « main droite »
Introduction à la 3D
Système de coordonnées
La caméra est caractérisée par :
Une position X,Y,Z
Un champ de vision :
Cette méthode permet d’obtenir la projection matrix
Une direction :
Cette méthode permet d’obtenir la view Matrix
Afin d’observer le monde la caméra est nécessaire
Introduction à la 3D
Camera
Matrix.CreatePerspectiveFieldOfView(float fieldOfView,float aspectRatio,float nearPlaneDistance,float farPlaneDistance)
Matrix.CreateLookAt(Vector3 cameraPosition, ref Vector3 cameraTarget,ref Vector3 cameraUpVector);
Un vertex est un point auquel on associe différentes propriétés comme :
Une couleur
Des coordonnées de texture
Une normale
Une tangente
Etc…
Au pluriel : Vertices
Un vertex = un point, un sommet
Introduction à la 3D
Vertex
Affichage d’un triangle
Comment afficher un simple triangle ?
La 3D sous XNA
Plan de la partie
Pourquoi un triangle ?
Création du VertexBuffer
Affichage du VertexBuffer
Effets
BackFace culling
Application d’une texture
Affichez votre premier triangle pas à pas
Voici les chapitres que nous allons aborder :
Affichage d’un triangle
Tout objet 3D est composé essentiellement de triangles :
Affichage d’un triangle
Pourquoi un triangle ?
Il est donc essentiel de savoir dessiner un triangle
Créer un tableau de vertices :
VertexBuffer = zone mémoire pour vertices
Affichage d’un triangle
Création du VertexBuffer
VertexPositionColor[] vertices = new VertexPositionColor[3];
Affectation des positions :vertices[0] = new VertexPositionColor(new Vector3(-0.5f, 0.5f, 0), new Color(10, 120, 200, 255));vertices[1] = new VertexPositionColor(new Vector3(-0.5f, 0, 0), new Color(10, 120, 200, 255));vertices[2] = new VertexPositionColor(new Vector3(0, 0, 0), new Color(10, 120, 200, 255));
Assignation au VertexBuffer :
vertexBuffer = new VertexBuffer(this.graphics.GraphicsDevice, VertexPositionColor.SizeInBytes * 3, ResourceUsage.WriteOnly);vertexBuffer.SetData(vertices);
Spécifier le type de Vertex utilisé:
Etapes de l’affichage :
Affichage d’un triangle
Affichage du VertexBuffer
graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration( graphics.GraphicsDevice, VertexPositionColor.VertexElements);
Spécifier le VertexBuffer à afficher :graphics.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);
Afficher le vertexbuffer:
graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
Un effet permet de spécifier à la carte graphique comment afficher les triangles en appliquant des modifications d’affichage telles que :
Eclairer l’objet
Modifier la couleur des pixels
Appliquer un effet de Bump mapping
Etc…
Un effet est normalement issu d’un fichier .fx programmé en HLSL
Le framework XNA met à disposition un effet simple qui ne nécessite pas de fichier .fx : le BasicEffect
Tout affichage en XNA doit utiliser un effet
Affichage d’un triangle
Effets
Initialisation :
Propriétés de l’effet :
Affichage du triangle à l’aide de l’effet :
BasicEffect
Affichage d’un triangle
Effets
effect = new BasicEffect(graphics.GraphicsDevice, null);
effect.VertexColorEnabled = true;
effect.Begin();foreach (EffectPass pass in effect.CurrentTechnique.Passes){ pass.Begin();
effect.View = mViewMatrix; effect.Projection = mProjectionMatrix;
graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
pass.End();}effect.End();
Affichage d’un triangle
Back Face culling
Il faut spécifier les points dans le sens trigonométrique par rapport à la camérasinon le triangle ne sera pas visible.
Par défaut une seule face du triangle est dessinée pour des raisons de performance
Ce comportement peut être modifié en changeant le culling mode :
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
Une texture ?
Affichage d’un triangle
Texturer un triangle
Une texture est tout simplement une image appliquée à un triangle.
XNA gère par défaut les formats PNG, TGA, JPEG, DDS et BMP.
Il n’y a pas de différence de performance suivant le format utilisé : la texture est convertie en format interne à Direct3D et sa taille adaptée à une puissance de 2
Cependant plus la résolution de la texture est élevée plus son affichage sera gourmand en temps.
Affectation de la texture :
Affichage d’un triangle
Texturer un triangle
Afin de texturer un triangle il suffit de donner les coordonnées de la texture au vertex
Mise en place de la texture :
Utilisation de VertexPositionTexture comme type de vertex
Chargement de la texture :
Assignation de la texture à l’effet :mTexture = content.Load<Texture2D>( "Glass" );
basicEffect .TextureEnabled = true;basicEffect .Texture = texture;
Créez votre projet et ouvrez le fichier Game1.cs
Ajoutez les champs suivants à votre classe :
Dans la méthode Initialize, initialisez la caméra :
Création du projet et initialisation de la caméra
Affichage d’un triangle
Pas à pas
Matrix viewMatrix;Matrix projection;VertexBuffer vertexBuffer;BasicEffect effect;
viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 1), new Vector3(0, 0, 0), Vector3.Up);projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height, 1.0f, 100.0f);
Dans la méthode LoadGraphicsContent déclarez vos vertices et assignez les au vertexBuffer :
A la suite, initialisez votre effet :
Vertices et effet
Affichage d’un triangle
Pas à pas
VertexPositionColor[] vertices = new VertexPositionColor[3];vertices[0] = new VertexPositionColor(new Vector3(0,0,0),Color.Blue);vertices[1] = new VertexPositionColor(new Vector3(0.5f,0.5f,0),Color.Red);vertices[2] = new VertexPositionColor(new Vector3(0.5f,0,0),Color.Green);
vertexBuffer = new VertexBuffer(graphics, VertexPositionColor.SizeInBytes * 3, ResourceUsage.WriteOnly);vertexBuffer.SetData<VertexPositionColor>(vertices);
effect = new BasicEffect(graphics, null);effect.VertexColorEnabled = true;
Dans la méthode Draw affichez votre triangle :
Affichage
Affichage d’un triangle
Pas à pas
graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionColor.VertexElements);graphics.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);
effect.Begin();foreach (EffectPass pass in effect.CurrentTechnique.Passes){ pass.Begin();
effect.View = viewMatrix; effect.Projection = projectionMatrix;
graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
pass.End();}effect.End();
Résultat :
Affichage d’un triangle
Pas à pas
Transformations
Modifications de l’état de nos objets 3D
La 3D sous XNA
Plan de la partie
Matrices
Rotation
Homothétie
Translation
Voici les chapitres que nous allons aborder :
Transformations
Pourquoi utiliser des matrices ?
Transformations
Matrices
Les objets ne sont pas affichés « tel quel » ils peuvent être :
Orientés
Agrandis / Réduis
Déplacés
Ces transformations sont effectuées à l’aide de matrices
Qu’est-ce qu’une matrice ?
Transformations
Matrices
Une matrice est un outil représenté par un tableau à 2 dimensions permettant d’effectuer les transformations
Il suffira de multiplier les coordonnées d’un point par une matrice de translation pour le faire déplacer.
Les matrices peuvent être associées (une matrice peut à la fois effectuer une rotation, une translation et un redimensionnement)
Transformations
Matrices
La multiplication des matrices n’est pas une opération commutative : effectuer une rotation suivie d’une translation ne donne pas le même résultat qu’effectuer une translation puis une rotation.
Les méthodes de la classe matrice permettent :
Transformations
Rotation
D’obtenir une rotation à partir d’un axe du repère :
D’obtenir une rotation à partir d’un axe quelconque
D’obtenir une rotation à partir d’un angle de Yaw/Pitch/Roll :
Matrix.CreateRotationX(float radians)
Matrix.CreateFromAxisAngle(Vector3 axis, float angle)
Pour effectuer un redimensionnement :
Transformations
Homothétie
Utilisation de la méthode CreateScale :
Possibilité d’un redimensionnement non homogène grâce aux surcharges
Matrix.CreateScale(float scale)
Matrix.CreateScale(float xScale,float yScale, float zScale)
Pour déplacer un objet :
Transformations
Translation
Utilisation de la méthode CreateTranslation :
Contenu de la Matrice de translation (1,2,3)
Matrix.CreateTranslation(float xPosition, float yPosition , float zPosition )
1 0 0 0
0 1 0 0
0 0 1 0
1 2 3 1
Effectuer une translation sur un objet :
Effectuer un redimensionnement et une rotation :
La matrice world définit la transformation qui sera effectuée sur l’objet.
Effectuer une rotation sur le triangle dessiné précédemment, placez ce code après l’affectation de la view et de la projection Matrix:
Transformations
Exemples
effect.World = Matrix.CreateTranslation( 1, 0 , 0);
effect.World = Matrix.CreateScale(2) * Matrix.CreateRotationX(MathHelper.PiOver4);
effect.World = Matrix.CreateRotationX(-MathHelper.PiOver4);
Affichage d’un model 3D
Utilisation de modèles 3D
La 3D sous XNA
Plan de la partie
Qu’est-ce qu’un modèle 3D ?
Affichage d’un modèle 3D.
Voici les chapitres que nous allons aborder :
Affichage d’un model 3D
Un modèle 3D c’est simplement un ensemble de vertices stockés dans un fichier sous un format prédéfinit.
La création d’un modèle triangle par triangle est fastidieuse c’est pourquoi des logiciels de modélisation existent.
Ils permettent d’exporter dans les formats .X et .FBX que XNA peut lire par défaut.
Affichage d’un model 3D
Qu’est-ce qu’un modèle 3D ?
Affichage d’un model 3D
Affichage d’un modèle 3D
Chargement du modèle :
Affichage d’un modèle :
Model model = content.Load<Model>( "media\\ship" )
foreach (ModelMesh mesh in model.Meshes){ foreach (BasicEffect effect in mesh.Effects) { effect.View = mViewMatrix; effect.Projection = mProjectionMatrix; effect.EnableDefaultLighting(); } mesh.Draw();}
Billboarding
De la 2D en 3D
La 3D sous XNA
Plan de la partie
Pourquoi ?
Comment ?
Voici les chapitres que nous allons aborder :
Billboarding
Billboarding
Pourquoi ? Il est parfois nécessaire d’afficher un objet 2D dans une
scène 3D sans que le joueur s’en aperçoive il faut donc orienter un carré vers la camera : il s’agit de billboarding.
Effets spéciaux Pour des raisons de performance
Création d’un billboard :
Billboarding
Comment ?
Afin d’afficher un billboard il suffit d’utiliser la matrice adéquate sur un carré :
Matrix.CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3? cameraForwardVector);
Lumière
Eclairez vos jeux
La 3D sous XNA
Plan de la partie
Fonctionnement
Mise en pratique
Voici les chapitres que nous allons aborder :
Affichage d’un model 3D
Fonctionnement
Lumière
Eclairage des surfaces
XNA peut gérer l’éclairage des surfaces automatiquement
Comment XNA sait-il qu’une surface doit être plus éclairée qu’une autre ?
Il est donc nécessaire pour chaque vertex de spécifier sa normale
On remarque que plus une surface est face au soleil plus elle est éclairée
Spécifier les normales
Lumière
Eclairage des surfaces
Afin de spécifier les normales il faut utiliser un type de vertex contenant les normales comme VertexPositionNormalTexture par exemple :
VertexPositionNormalTexture v = new VertexPositionNormalTexture(Position, Normal, textureCoordinate);
Mise en place de l’effet de lumière
Lumière
Eclairage des surfaces
Lors de l’affichage de l’objet avec un BasicEffect il suffit d’utiliser les méthodes et propriétés adéquates.
effect.LightingEnabled = true;effect.DirectionalLight0.Enabled = true;effect.DirectionalLight0.Direction = LightDirection;effect.DirectionalLight0.DiffuseColor = new Vector3(Red, Green, Blue);
effect.DirectionalLight0.SpecularColor = new Vector3(Red, Green, Blue);effect.SpecularPower = 10;
Optimisations de l’affichage
Soulagez votre GPU…
La 3D sous XNA
Plan de la partie
Indices
LOD
Frustum culling
QuadTree
Mipmapping
Voici les chapitres que nous allons aborder :
La 3D avancée sous XNA
Un vertex contient de nombreuses informations(position, coordonnées texture, normal, etc…)
Plus le nombre de vertices envoyés à la carte graphique est important, plus l’envoie à celle-ci prends de temps et moins l’affichage sera rapide.
Un carré est composé de 2 triangles soit 6 vertices : or il n’y a que 4 vertices différents.
Les indices vont nous permettre de n’utiliser que le nombre de vertices strictement nécessaire.
Ou comment réutiliser un même vertex…
Optimisation de l’affichage
Indices
Création de l’indexbuffer :
Les triangles ne seront plus formés dans le vertexbuffer : celui-ci ne contient que des vertices différents à la suite.
Formation des triangles grâce aux indices :
Affectation de l’indexBuffer :
Implémentation
Optimisation de l’affichage
Indices
indexBuffer = new IndexBuffer(graphics.GraphicsDevice, typeof(short), NumberOfIndices, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
short[] indices = new short[TrianglesNumber * 3] { 0, 1, 2 , 1, 3, 2 … };indexBuffer SetData<short>(indices);
graphicDevice.Indices = indexBuffer;
Les points représentent les vertices crées :
Exemple
Optimisation de l’affichage
Indices
Avec les indices il faut former les triangles :
VertexPositionColor[] vertices = new VertexPositionColor[4];vertices[0] = new VertexPositionColor(new Vector3(-0.5f, 0.5f, 0f), Color.Black);vertices[1] = new VertexPositionColor(new Vector3( 0.5f, 0.5f, 0f), Color.Black);vertices[2] = new VertexPositionColor(new Vector3( 0.5f,-0.5f, 0f), Color.Black);vertices[3] = new VertexPositionColor(new Vector3(-0.5f,-0.5f, 0f), Color.Black);vertexBuffer.SetData<VertexPositionNormalTexture>(vertices);
Les points représentent les vertices crées :
Exemple
Optimisation de l’affichage
Indices
Avec les indices il faut former les triangles :
Indices du premier triangles : 0 , 1 , 3
short[] indices = new short[] { 0, 1, 2 ,
Les points représentent les vertices crées :
Exemple
Optimisation de l’affichage
Indices
Avec les indices il faut former les triangles :
Indices du premier triangles : 0 , 1 , 3
Indices du second triangle : 1 , 2 , 3
short[] indices = new short[] { 0, 1, 2 , 1, 2, 3 };indexBuffer.SetData<short>(indices);
Moins il y a de vertices affichées à l’écran mieux le GPU se porte
Plus un objet est éloigné moins l’on voit ses détails
Il est donc possible d’afficher un objet moins détaillé lorsque celui-ci est éloigné et afficher l’original lorsque la caméra est assez proche
Cette technique s’appelle Level Of Detail
Level Of Detail
Optimisation de l’affichage
LOD
Si vous appelez la méthode Draw et que l’objet n’est pas visible vous ferez tout de même appel à votre GPU et donc consommerez des ressources.
Il faut donc n’afficher que ce qui est dans le champ de vision de la caméra
Afficher uniquement ce qui est visible
Optimisation de l’affichage
Frustum culling
Il suffit de tester si notre objet se trouve entre ces 6 plans
Creation d’une sphère englobant l’objet
Creation de la sphère englobante de l’objet à partir du model :
Implémentation sous XNA
Optimisation de l’affichage
Frustum culling
BoundingSphere boundingSphere = new BoundingSphere();boundingSphere.Radius = radius;BoundingSphere.Center = new Vector3(x,y,z);
BoundingSphere boundingSphere = new BoundingSphere();
foreach (ModelMesh mesh in mShipModel.Meshes) { BoundingSphere sphere = mesh.BoundingSphere; BoundingSphere.CreateMerged(ref boundingSphere, ref sphere, out boundingSphere);}
boundingSphere.Center *= scale;boundingSphere.Radius *= scale;
Creation du Frustum de la caméra :
Teste si la sphère englobante est dans le frustum :
ContainmentType est une énumération :
Implémentation sous XNA
Optimisation de l’affichage
Frustum culling
BoundingFrustum frustum = new BoundingFrustum(viewMatrix * projectionMatrix);
ContainmentType containment = frustum.Contains(boundingSphere );
Schéma
Optimisation de l’affichage
QuadTree
N = 2
Une fois le découpage effectué il suffit de tester si le carré se trouve dans le frustum culling.
Si celui-ci se trouve complètement dans le frustum culling tous les éléments contenus dans le carré peuvent être dessinés
Si celui-ci ne se trouve pas dans le frustum culling aucun élément contenu dans le carré ne sera affiché.
Si celui-ci est en parti en dehors et dedans il faudra alors effectuer récursivement le même teste avec les 4 carrés contenus dans ce carré.
Découpage en zone
Optimisation de l’affichage
QuadTree
Plus la texture affichée est grande plus le GPU sera sollicité
Il est inutile d’afficher une texture plus grande que son affichage à l’écran : la conversion vers une texture plus petite sera couteuse en GPU et l’affichage approximatif.
Afin de résoudre de problème il est possible d’utiliser la technique du mipmapping
Pourquoi ?
Optimisation de l’affichage
Mipmapping
Exemple sans mipmapping
Optimisation de l’affichage
Mipmapping
Exemple avec mipmapping
Optimisation de l’affichage
Mipmapping
Afin d’utiliser le mipmapping il suffit de créer plusieurs fois la même texture à des tailles différentes : l’on divise à chaque fois la taille par 2.
XNA se chargera d’afficher la texture adaptée
Comment ?
Optimisation de l’affichage
Mipmapping
Les images .dds peuvent contenir les différents niveaux de mipmapping.
Comment ?
Optimisation de l’affichage
Mipmapping
Afin de les générer il est possible d’utiliser le DirectX Texture Tool issu du SDK.
TransformationsTransformations
Afficher un triangle
Afficher un triangle Introduction à
la 3DIntroduction à
la 3D
Les MatricesLes Matrices
Résumé du module
OptimisationsOptimisations
La 2D sous XNA
Pour aller plus loin…
Publications
Sites web
http://www.labo-dotnet.com/
Si vous voulez approfondir vos connaissances:
http://www.xna.com/
La 3D sous XNA
http://creators.xna.com/
XNA Game Studio Express: Developing Games for Windows and the Xbox 360 par Joseph B Hall
Professional XNA Game Programming: For Xbox 360 and Windows par Benjamin Nitschke
Félicitations
Vous avez suivi avec succès le module de cours n°02
La 3D sous XNA