Tutorial Managed DirectX/Direct3D : Les lumières

Les Lumières et les matériaux

Les lumières et les matériaux constituent les deux éléments principaux de tout jeu en 3D pour créer une ambiance. Sans eux, un jeu est morne, terne sans saveur. Ils sont la clé de voûte pour tout jeu misant particulièrement sur l’ambiance.


Figure 1 — Tomb Raider : Ici l’ambiance fait tout


Ce tutorial aborde tout ce qui tourne autour des lumières et des matériaux sous DirectX. Nous allons créer comme programme d’exemple un système astronomique avec comme source lumineuse le soleil, une comète, et un interrupteur pour allumer le tout ! Pour illustrer de manière plus complète les matériaux, un autre exemple (beaucoup plus simple) sera réalisé pour mettre en valeur les différent type de réflexion possible face à une source lumineuse. 


1 Et la lumière fut …

Plusieurs types de lumières peuvent être créées sous DirectX pour créer un monde plus réaliste. Malheureusement toute effet lumineux créé par lui ne sera jamais aussi réaliste que celui du monde réel. Un lumière est soumise à plusieurs contraintes : l’atténuation avec la distance (une bougie ne peut être vue a 1 kilomètre), la réflexion, un objet illuminé peut être lui-même source d’illumination ‘regardez comme la lune éclaire la nuit). De même un objet qui réfléchit la lumière peut atténuation sa valeur avant de la renvoyer. Tous les objets que nous côtoyons ne renvoient pas la lumière de la même manière, un manteau de velours noir absorbera toute source lumineuse, une porcelaine blanche vernie, en renverra une grande partie. DirectX ne peut donc pas prendre tous ces paramètres en compte au risque de créer des applications d’une lenteur toute rédhibitoire mais il arrive toutefois, grâce à d’excellentes approximations à créer des univers lumineux tout à fait réalistes.

Jusqu’ici les programmes d’exemple ne géraient absolument pas la lumière et étaient parfaitement éclairés sous tous les angles. En fait avec l’instruction :

         dev.RenderState.Lighting = false;


Dans les programmes précédents, tout élément de la scène était éclairé parfaitement, sans nuances dans les même proportions. Lorsque cette propriété vaut true, on demande à Direct3D de nous laisser la gestion du module d’illumination.  On peut ainsi prendre la gestion ou refuser la gestion avant l’affichage de certains objets dans la méthode Render.

Remarque : Faite le test suivant : donnez true à cette instruction dans les programmes 3D précédent. Al’affichage tous les objets sont noirs : ne connaissant pas la gestion des lumières, nous n’avons créé aucune source lumineuse.


 
1.1 Qu’est ce qu’une lumière pour Direct3D ?


  


Une lumière pour Direct3D est un ensemble de propriétés que le programmeur peut modifier. Tous les types de lumières ne les utilisent pas forcément tous.


 


 


Position


Position dans l’espace de la source de lumière.


 


Direction


Direction vers laquelle la lumière est émise.


 


Portée (Range)


Distance maximum à partir de la source lumineuse que la lumière peut parcourir. Tout objet dont la distance à la source est supérieure à cette distance ne sera pas éclairé par la source.


 


Atténuation


Indique la variation de luminosité sur la distance. La lumière peut s’éteindre brusquement passé la distance Range ou bien diminuer progressivement, ou bien encore s’accentuer


 


Lumière diffuse


C’est la couleur principale émise par une lumière. La lumière diffuse est une lumière qui a été dispersée, mais elle a toujours une direction par opposition à la lumière ambiante qui n’en a pas.


 


Lumière ambiante


C’est la couleur de la lumière ambiante. La lumière ambiante est lumière générale de fond. La lumière ambiante a été tellement dispersée qu’elle n’a aucune direction ou source. Elle produit la même intensité lumineuse en tout point de la scène.


 


Lumière spéculaire


C’est la couleur de la lumière spéculaire qui est émise par la lumière. La lumière spéculaire est l’opposé de la lumière diffuse. La lumière spéculaire n’est pas dispersée du tout, vous peut employer la lumière spéculaire pour créer des points culminants sur vos objets.

Toutes ces caractéristiques peuvent être paramétrées via les propriétés d’un objet de type Light.


 


1.2 Quels types de lumières ?


  


Il y a quatre types de lumières qui peuvent être créée dans une scène. Chaque type utilise une partie des propriétés définies dans le point précédent.


Toutes les lumières ajoutent des frais généraux processeurs à votre application. La lumière ambiante est la plus simple à mettre en place, suivie des lumières directionnelles, puis les lumières ponctuelles et enfin les lumières spot.


Pensez à ceci quand vous décidez quelles lumières à employer dans votre application.


  


Lumière ambiante


Cette lumière n’a ni position ni direction. L’intensité qu’elle génère est constante en tout point de la scène.


 


dev.RenderState.Ambient = Color.Green;


 


 


Ici la lumière ambiante donnée est verte.


  


Lumière ponctuelle


Il s’agit là de la même source de lumière qu’une ampoule. Il y’a certes une source, l’ampoule, mais pas de direction : la lumière est émise dans tous les sens. Un exemple d’une lumière de point est une ampoule. Il a également les attributs de couleur, de gamme et d’atténuation qui peuvent être placés. Figue 7.1 ci-dessous, expositions comment la lumière est émise d’une lumière de point.


Une lumière ponctuelle se paramètre grâce à une position, une direction, une atténuation, une portée, une couleur et une couleur réfléchie.


  



Figure 2


 


Lumière Directionnelle


Les lumières directionnelles ont la direction et colorent mais ne disposent d’aucun source.  Un peu comme la lumière du soleil (s’il n’y avait pas le soleil de visite). Grâce à ce type de lumière, tous les objets dans la scène reçoivent la lumière de la même direction. Les lumières directionnelles n’ont pas des attributs de gamme ou d’atténuation. Figue 7.2 ci-dessous, expositions comment la lumière est émise d’une lumière directionnelle.


Une lumière directionnelle se paramètre grâce à une direction, une couleur et une couleur réfléchie.


 



Figure 3


 


Spot / Projecteurs


Pas besoin de décrire cette lumière, son nom la définit. On voit dans la vie réel ce genre de source lumineuse sur les réverbères, ou les spots de théâtres qui, en haut d’une scène, éclairent l’acteur.


Les projecteurs se paramètrent grâce à une position, direction, couleur, couleur de réflexion, l’atténuation et portée. Pour un projecteur vous pouvez définir en plus un cône intérieur et externe par l’intermédiaire de deux angles. Una variable nommée FallOff indique alors avec quelle intensité la lumière va tendre de 0 depuis le bord du cône interne jusqu’au bord du cône externe. Le cône interne est la lumière puissante sans atténuations


L’angle du cône intérieur est connu comme thêta et l’angle du cône externe est connu comme phi.


 


Figure 17.4


 


2 Matériaux


 


L’utilisation d’une source de lumière n’a aucune raison d’être si le point qui se trouve illuminé sur un objet n’est pas doté de propriétés qui décrivent son comportement face à la lumière. Cet ensemble de propriété est nommé matériau (material).


 


2.1 Qu’est ce qu’un matériau?


  


Un matériau décrit comment la lumière est réfléchie sur objet (polygone). Vous pouvez indiquer la quantité de lumière réfléchie, faire briller l’objet ou le rendre mat ou encore donner une couleur.


Ces arrangements sont énumérés ci-dessous :


  


La réflexion diffuse


Quantité de lumière diffuse que l’objet réfléchira. C’est une valeur de couleur. Il est possible d’indiquer que l’objet réfléchira seulement la lumière diffuse du rouge. Ceci fera paraître l’objet en rouge.


  


La réflexion ambiante


Quantité de lumière ambiante que l’objet réfléchira. C’est une valeur de couleur qui permet d’indiquer que l’objet réfléchit ou non la lumière ambiante. Il est ainsi possible de cacher l’objet à moins qu’il reçoive un autre type de lumière telle que la lumière diffuse.


  


La réflexion spéculaire et sa puissance


Quantité de lumière spéculaire qui est réfléchie. Vous pouvez employer la réflexion et les puissances spéculaires pour créer les points spéculaires qui feront briller l’objet.


  


Émission


Possibilité de rendre un objet émetteur de lumière. Si l’objet semble émettre de la lumière il n’en émet pas réellement ;  les autres objets dans la scène ne seront pas affectés par cet arrangement.


 


3 La Normale


  


La normale en un point est un vecteur de norme 1 dont les coordonnées quantifient son orientation dans l’espace 3D.Cette notion étonnante (orienter un point ?!) permet de calculer la capacité de ce point à absorber la lumière, suivant l’angle d’arrivée de celle-ci sur le point.


Etudions le schéma suivant :


 

Figure 5 —Une surface, un point, une normale, une lumière et un angle


 


 


L’angle a que fait le rayon lumineux L avec la normale N de cette surface permet de calculer l’intensité lumineux en ce point. L’intensité lumineuse décroît lorsque a croît.


 



Figure 6 —Modulation de l’intensité résultante suivant l’angle a.


 


 


C’est le même principe que lorsqu’on est face à un soleil couchant ou se levant : nos yeux peuvent le regarder sans protections. Au zénith, il veut mieux éviter.


  


4 Premier exemple : Lumière Spot, Directionnel et Point


  


Toutes les notions liées à la gestion de la lumière ayant été acquises un exemple s’impose pour mettre en application sous DirectX ce que nous venons d’apprendre.


   


4.1 Quid exemplum ?


  


Quel meilleur exemple pour parler de lumière que de recréer une partie du système solaire?


 


Les cinq premières planètes et la lune (mercure, vénus, terre, mars, jupiter) ainsi que le soleil.


Nous ferons partir une lumière directionnelle et/ou lumière point du soleil pour comparer. Un spot sortira de la terre pour éclairer toutes planètes se trouvant à proximité.


Bien entendu, comme d’habitude, plusieurs touches clavier permettront de modifier divers paramètres dans le jeu.


Ouvrez le programme d’exemple intitulé « Direct3D Lumières ». Au lancement du programme nous avons l’écran suivant :


 



Figure 7 —Vers l’infini et au dela !


Rien qu’à voir cet écran, on comprend mieux le terme « ambiance » employé dans l’introduction de ce chapitre. On se croirait presque dans l’espace ! Il ne manque plus que les étoiles (nous verrons cela avec les particules à la fin de cet ouvrage).


 


Une terre et 4 autres planètes apparaissent gravitant autour du soleil. Une lune peut être aperçue autour de la terre.


Toutes les planètes sont éclairées par le soleil. Seule une partie de leur surface est donc éclairée (tout comme la lune).


 


Remarque : Le programme ne respecte pas scrupuleusement les dimensions et distances réelles. Que les puristes pardonnent cet exemple modifié pour simplifier la vue. Une simple visite sur les nombreux sites astrologie permettra de corriger le programme. [1]. Néanmoins il respect les degrés d’obliquité, les temps de révolution et les temps de rotations.


  


Le programme fonctionnera principalement sur les matrices et les calculs qui en découlent. Chaque rotation autour d’un axe de planète, chaque rotation autour d’une planète, chaque translation, obliquité, demandera une matrice et un calcul ceci multiplié par le nombre de matrices.


 


Dans les nouveautés nous aurons ici :


  


·        Une gestion de lumières.


·        Une gestion de matériaux.


·        Une nouvelle classe pour la forme 3D sphérique


·        La classe cube modifié pour pouvoir être associée à un matériau.


 


4.2 Les matrices pour mettre en mouvement


  


Avant de regarder comment les lumières sont gérées, il nous faut commencer par la gestion des objets graphiques.


Il existe dans le code source plus d’une trentaine de matrices. Nous étudierons seulement celles qui donnent un mouvement à la terre. La gestion des matrices a été simplifiée au maximum pour rendre le programme simple à lire (que les puristes me pardonnent :) ).


 


La déclaration se fait en tout début de fichier :


 


 


      Matrix matriceTerre, matriceDéplacementTerre, matriceTerrePivot, matriceRotationTerreAutourDeSonAxe, matriceRotationTerreAutourSoleil, matriceTerreNuages;


 


La matrice nommée matriceTerre est la résultante de tous les calculs à effectuer pour donner un mouvement réaliste à notre planète. Les matrices suivantes servent à calculer (dans l’ordre) : la distance de la terre par rapport au soleil, l’ubiquité de la terre (elle penche), la rotation de la terre autour de son axe, la révolution qu’elle effectue autour du soleil et, enfin une matrice pour la masse nuageuse qui entoure la planète.


Les calculs sont réalisés très simplement dans SetupMatrice :


  


 


//Calculs de différentes échelles de temps


float tempsJour = -this.vitesseTemps;


float tempsAnnée = tempsJour * 365.0f;


float tempsMois = tempsAnnée / 12.0f;


 


 


//////////////////////////////////////////////////////////


//mise en place des matrices de transformation pour la terre


matriceRotationTerreAutourDeSonAxe = Matrix.RotationY(Environment.TickCount/tempsJour);//une rotation par jour


matriceRotationTerreAutourSoleil = Matrix.RotationY(Environment.TickCount/tempsAnnée);//365 rotation par an


matriceDéplacementTerre = Matrix.Translation(20.0f,0.0f,0.0f);//km de distance du soleil


matriceTerrePivot = Matrix.RotationYawPitchRoll(0.0f,0.0f, 23.44f* (float)Math.PI/180);//obliquité de l’axe de rotation


matriceTerre = Matrix.Scaling(1f, 1f, 1f)*matriceRotationTerreAutourDeSonAxe*matriceTerrePivot;//création d’une seule matrice pour tous ces calculs


matriceTerre *= matriceDéplacementTerre;


matriceTerre *= matriceRotationTerreAutourSoleil;


 


 


Pour plus de clarté nous allons énumérer instruction par instruction ce qui est fait :


Les trois premières sauvegarde pour une utilisation ultérieure des temps précis sur lesquels se baseront les calculs futurs.


Le premier calcul de matrice réalise une rotation d’une durée d’un jour (rotation autour de l’axe de la terre). Le second calcul effectue ue autre rotation mais pour le temps d’une année. Une translation de 20 en abscisse par rapport à l’origine est effectuée. L’ubiquité est sauvegardée dans une nouvelle matrice. Nous avons à ce stade 4 matrices initialisées décrivant chacune un mouvement précis de la terre. La dernère matrice nommée matriceTerre va être calculée à partir d’elles. Un scalling est réalisé : la taille de la terre fait 1 en standard ici multiplié par la rotation autour de son axe et l’ubiquité. Le résultat est multiplié dans l’instruction suivante par la distance au soleil et enfin dernière phase, prise en compte de la rotation de la terre.


  


Remarque : on voit bien ici que l’ordre des multiplications de matricesdoit être scrupuleusement respecté : si nous avions fait une translation de matriceDéplacementTerre après la dernière rotation au lieu d’avant, nous aurions eu une terre qui tournerai plus vite que la normale sur elle-même et qui n’effectuerait pas de révolution autour du soleil. Dans ce code par contre, la seconde rotation est effectuée après la translation, c’est donc un cercle d’une distance de 20 que la terre parcours !


 


 Chaque matrice finale de chaque planète, satellite ou enveloppe nuageuse est affectée à la matrice World avant l’affichage de la forme correspondante dans Render :


 


 


//afficher la terre


device.Transform.World = matriceTerre;


this.sphereTerre.Render(device);


   


4.3 Gérer les matériaux


  


Autre étape importante : la gestion des matériaux. Pour une bonne luminosité, donner une matériau à sa forme éclairée est une bonne chose ! Leur gestion est enfantine. Nous avons une classe Cube et Sphere qui acceptent un materiau en entrée dans le contructeur :


  


                       


ColorValue rgbaDiffuse  = new ColorValue(0, 0, 0, 0);


ColorValue rgbaAmbient  = new ColorValue(0, 0, 0, 0);


ColorValue rgbaSpecular = new ColorValue(0, 0, 0, 0);


ColorValue rgbaEmissive = new ColorValue(0,0, 0, 0);


            


this.DéfinirMaterial(rgbaDiffuse, rgbaAmbient, rgbaSpecular, rgbaEmissive, 200);


 


 


DéfinirMaterial se présente ainsi dans Cube et Sphere :


 


 


public void DéfinirMaterial(Color rgbaDiffuse, Color rgbaAmbient, Color rgbaSpecular, Color rgbaEmissive, float rPower)


{


            this.material.Diffuse = rgbaDiffuse;


            this.material.Ambient = rgbaAmbient;


 


            this.material.Specular = rgbaSpecular;


            this.material.SpecularSharpness = rPower;


 


            this.material.Emissive = rgbaEmissive;


}


 


  


Rien de compliqué si on a lu le point 17.2 de ce chapitre.
 


4.4 Créer des normales


  


Avant dernière étape avant les lumières, la gestion des normales permet de rendre visible un objet. Ajouter une normale à une surface / vertex est une opération compliquée si l’on souhaite créer un vecteur spécial. Dans le cas contraire, c’est une opération simple.


 


Il faut d’abord modifier le format de vertices pour ajouter les normales :


 


 


public struct SphereVertex


{


     public float X, Y, Z;


 


     public float Nx, Ny, Nz;


 


     public int Couleur;


 


     public float tu, tv;


 


     public const VertexFormats Format = VertexFormats.Position | VertexFormats.Normal | VertexFormats.Diffuse | VertexFormats.Texture1;


};


 


  


Les trois flottants ajoutés (Nx, Ny, Nz) définit par le drapeau VertexFormats.Normal spécifient un format de vertices acceptant un vecteur normal.


L’initialisation se fait dans la méthode qui rempli de vertex buffer (OnCreateVertexBuffer) dans la classe Cube ou Sphere:


 


 


Vector3 vNormal;


 


vNormal.X = x0;


vNormal.Y = y0;


vNormal.Z = z0;


   


vNormal = Vector3.Normalize(vNormal);


 


 


C’est la méthode Normalize de Vector3 qui créé une normale dans le point donné de coordonnées (x0, y0, z0).


  


4.5 Gérer les lumières


  


Tout est maintenant prêt pour la gestion des lumières !


La première étape est de supprimer la lumière artificielle qui éclaire toute la scène.


Deux aspects graphiques sont aussi ajoutés via render stage :


 


 


dev.RenderState.Lighting = true;


 


 


Suit alors, dans Render la création des lumières.


 


 


 


if (this.typeLumière == TypeLumière.Directionnelle)


{


      this.device.Lights[0].Diffuse= Color.FromArgb(255,255, 255);


      this.device.Lights[0].Type =LightType.Directional;


      this.device.Lights[0].Direction = Vector3.TransformCoordinate(Vector3.Empty,  Matrix.Translation(15.0f,0.0f,0.0f)*matriceRotationTerreAutourSoleil);


}


else if (this.typeLumière == TypeLumière.Ponctuelle)


{


      this.device.Lights[0].Diffuse= Color.FromArgb(255,255, 255);


      this.device.Lights[0].Type =LightType.Point;


      this.device.Lights[0].Range = this.portéeLumière;


}


else


{


      this.device.Lights[0].Diffuse= Color.FromArgb(255,0, 0);


      this.device.Lights[0].Type =LightType.Spot;


      this.device.Lights[0].Direction = Vector3.TransformCoordinate(Vector3.Empty,  Matrix.Translation(15.0f,0.0f,0.0f)*matriceRotationTerreAutourSoleil);


      this.device.Lights[0].Falloff = 0.0f;


      this.device.Lights[0].InnerConeAngle = 0.025f*tailleCone;


      this.device.Lights[0].OuterConeAngle = 0.05f*tailleCone;


}


this.device.Lights[0].Position = Vector3.Empty;


this.device.Lights[0].Attenuation0 = 1.0f;


this.device.Lights[0].Attenuation1 = 0.0f;


this.device.Lights[0].Attenuation2 = 0.0f;


this.device.Lights[0].Enabled = true;


 


 


 


Généralement la création de lumière se fait une fois, mais dans notre cas elle peut avoir à être mise à jour à chaque nouvelle frame, son emplacement dans Render se trouve donc nécessaire.


TypeLumière est une énumération que nous avons créé nous même pour définir le choix de l’utilisateur quand à l’éclairement de la scène.


Lights est un tableau de Light appartenant à l’objet device dont la taille est infinie. Nous utilisons ici l’index 0 mais nous aurions pu utiliser 400. Null besoin d’initialiser un objet Light. Il faut juste valider la lumière paramétrée avec un Enable = true comme pour la dernière instruction. Il est possible dans le programme d’utiliser trois types de lumière : directionnel, ponctuel et Spot. Ponctuel est la lumière standard du soleil qui éclaire dans toutes les directions à partir d’un point source. Directionnel va au contraire donner un sens à la lumière : la droite passant par l’origine et par le centre de la terre. Toutes les planètes dans ce cas se verront éclairée dans le sens soleil-terre. Enfin Spot va diriger la lumière vers une planète prise (ici la terre). L’utilisateur pourra chaner la taille du cone du Spot pour n’éclairer qu’une partie de la terre, toute la terre ou une vaste zone de l’espace. Un if else est donc obligatoire pour paramétrer différemment ces trois lumières. Pour la directionnel une direction est donnée :


 


 


Matrix.Translation(15.0f,0.0f,0.0f)*matriceRotationTerreAutourSoleil


 


 


C’est à dire la position de la terre,  L’expression :


 


 


Vector3.Empty


est le vecteur origine (0, 0, 0). Vector.TransformCoordinate transforme un vecteur dans l’espace en se basant sur le calcul matriciel passé en second argument.


Dans le else suivant, point de direction mais une portée pour la lumière directionnelle : définie par l’utilisateur à l’aide du clavier.


Enfin le dernier else pour le Spot définit le fallOff, l’innerCone, l’outerCone[2].


Suit un paramétrage commun pour la position et l’atténuation. Les trois valeurs d’atténuation présentes ici (0, 1 et 2) sont des facteurs différents pour une atténuation :


 


 


Attenuation0

Facteur d’atténuation linéaire.

Attenuation1

Facteur d’atténuation au carré.

Attenuation2

Facteur d’atténuation Exponentiel.


 


  


La propriété Enable active la lumière.


  


4.6 La ou la lumière n’éclaire rien …


  


Bien des points dans cet exemple peuvent sembler encore obscurs. Voyons les en détails.


 


Effet sur les planètes?


  


Deux beaux effets viennent couronner ce programme d’aide. La terre est entourée d’une atmosphère, le soleil semble se consumer. Ces deux effets sont réalisés à l’aide de l’alphablending[3].


La terre est entourée d’une sphere légèrement plus grosse qu’elle sur laquelle est plaquée la texture suivante :


  



 


Lorsque la forme sphérique est affichée avec le blending suivant :


  


this.device.RenderState.AlphaBlendEnable = true;


this.device.RenderState.SourceBlend = Blend.SourceAlpha;


this.device.RenderState.DestinationBlend = Blend.One;


 


Le noir ajouté aux couleurs de la terre disparaît et le blanc efface les couleurs de la terre, les couleurs se marient donc parfaitement


La même opération est réalisée pour le soleil, mais avec deux sphères. L’opération de blending est légèrement différente.


  


this.device.RenderState.AlphaBlendEnable = true;


this.device.RenderState.DestinationBlend = Blend.DestinationColor;


this.device.RenderState.SourceBlend = Blend.SourceColor;


  


Ombres?


  


Les rayons de Direct3D sont tellement puissants qu’ils traversent les objets ! Trève de plaisanterie, le module d’illumination traite les points qu’on lui adresse sans jamais se référer aux formes auxquels ils appartiennent. Si une forme est cachée derrière une forme éclairée, elle sera elle aussi éclairée. La gestion des ombres incombe donc au programmeur …


 


La lune peut être ainsi vue éclairée lorsqu’elle se trouve derrière la terre


 



Figure 17.8 —Vieux dicton : Lune éclairée à la novembre, terre transparente !


 


  


De même on peut d’apercevoir que la terre dans sa partie sombre est visible parceque les nuages de son atmosphère ne sont pas cachées :


 


 


 Figure 17.9


 


L’alpha blending donne pour pixels colorés en sortie le résultat d’une opération qui prend en compte les texels de la texture de la sphère de nuage et ceux de la surface de la sphère terre. Dans la mesure où la sphère terre est noire car non touchée par la lumière, et que la couleur noire est l’élément neutre dans le blending exécuté ici, on obtient la restitution parfaite de la texture nuage… Dommage mais facilement réparable. « Tatillonnez » vous trouverez.


 


 Fil de fer ?


 


Le mode fil permet l’affichage d’une forme 3D sous la forme d’un grillage complexe. Afficher les modèles dans ce mode est simple et ne demande qu’une instruction :


  


this.device.RenderState.FillMode = FillMode.WireFrame;


  


L’instruction permettant un affichage classique étant


  


this.device.RenderState.FillMode = FillMode.Solid;


 


Dither ?


Méthode pour afficher des données graphiques avec une palette de couleurs limitée. Chaque Pixel de l’image source est étalé  (habituellement une zone de 2×2) sur l’image de destination.


A distance, l’oeil mélange les pixels dans une couleur qui offre plus de nuances que la palette originale. La technique a comme conséquence un meilleur aspect visuel que la suppression arbitraire de pixels.


Pour l’activer :


  


dev.RenderState.DitherEnable = true;


  


4.7 Touches de l’exécutable


   


Page Haut/Bas : Déplacement en hauteur.


Flèches haut/bas : avancer/reculer.


+/- : Vitesse temporelle du système


F1 : Modification de la couleur de fond.


F2 : Annuler/ajouter les lumières.


F3 : Prendre place sur la lune pour observer la terre.


F4/F5 : affichage en fil de fer ou en mode solide.


F6 : Une lumière directionnelle dans le sens soleil/terre  ou  lumière ponctuelle avec pour centre le soleil


F7/F8 : Modifier le matériau de la terre (lumière spéculaire ou non)


F9/F10 : augmenter la portée de la lumière ou la diminuer de 1 (si lumière ponctuelle)


F11/F12 : diminuer ou augmenter la taille du cône de la lumière en mode Spot


 


5 Second exemple : Matériaux


  


Dernier exemple du chapitre portant sur les matériaux. Le programme sur les matrices faisant tournoyer des cubes va être repris. Une lumière ponctuelle sera utilisée pour les éclairer. L’aspect intéressant résidera dans le fait que chaque cube aura un matériau propre qui lui donnera un aspect différent face à une source de lumière :


  


Le code source de cet exemple (intitulé Direct3D Lumières (2) ) s’avère fort simple. Quatre sphères créées avec une forme rudimentaire, 4 calculs de matrices pour les faire tournoyer, une lumière ponctuelle créée et, enfin 3 matériaux ajoutés au trois premières sphères.


La première sphère à gauche sera mat et renverra une lumière douce.


 


sphere1.material.Diffuse = Color.FromArgb(255, 128, 64, 255);


  


Seule la couleur diffuse est donc précisée.


La troisième sphère à droite sera brillante.


 


sphere2.material.Diffuse = Color.FromArgb(0, 255, 255, 0);


sphere2.material.Ambient = Color.FromArgb(128, 255, 128, 255);


sphere2.material.Specular = Color.FromArgb(128, 255, 128, 255);


  


Une lumière diffuse évidemment mais aussi une lumière ambiante (réfléchie) et une lumière spéculaire (brillante).


La troisième sphère en haut sera réfractant et semblera être une source lumineuse en renvoyant une vive lumière.


 


sphere3.material.Diffuse = Color.FromArgb(128, 128, 128, 255);


sphere3.material.Ambient = Color.FromArgb(255, 255, 255, 255);


sphere3.material.Emissive = Color.FromArgb(24, 24, 24, 255);


sphere3.material.Specular = Color.FromArgb(255, 255, 255, 255);


  


Ici une lumière spéculaire est définie pour rendre l’objet lumineux.


La dernière sphère enfin sera éclairée complètement afin de pouvoir faire une comparaison.


  


6 Conclusion


Les deux exemples de ce tutorial l’ont bien montré : les lumières sont une composante primordiale de tout jeu. Elles interviennent principalement dans l’ambiance du jeu mais aussi dans son réalisme au même titre que les textures. Leur utilisation étant triviale rien ne saurait empêcher quiconque de les utiliser dans ses productions ! Dans tous les cas toujours bien étudier le sens même de tous les objets créés dans une scène afin de leur octroyer un matériau propre à sa finalité.


 


telecharger Vous pouvez télécharger les samples ici.




[1] Notamment le site http://www.ens-lyon.fr/Planet-Terre/Infosciences/Planetologie/Description/Articles/planetcompar.html.

[2] Voir la figure 4 pour comprendre l’utilité de ces 3 paramètres.

[3] Voir le post …

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>