IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Blender pour le jeu vidéo


précédentsommairesuivant

XIII. Lumières et ombres

Maintenant que nous avons les éléments de base de notre jeu, nous pouvons aller plus loin dans la création de l'univers qu'il va faire explorer à nos joueurs. La première chose à prendre en compte est l'éclairage.

Un espace est perceptible grâce à sa géométrie, mais également par les ombres et lumières qui en dessinent les volumes et y apportent une ambiance. Nous allons voir dans ce chapitre comment illuminer notre espace et y dessiner des ombres.

Nous ne rentrons pas ici en détail dans l'apprentissage de l'éclairage puisqu'il s'agit d'une spécialité en soi qui n'est pas l'objet principal de ce livre.

XIII-A. Différents types d'éclairage

L'éclairage par défaut du mode jeu est basé sur les vertices : chaque vertex prend une teinte en fonction de sa distance par rapport aux lampes environnantes. La couleur des faces est déduite par interpolation. Cette technique montre ses limites assez rapidement, car l'interpolation est faussée ou rend visibles certaines arrêtes.

Il s'agit du mode d'éclairage le plus simple et historiquement le plus ancien. Il est aussi appelé éclairage Gouraud, du nom de son inventeur.

Cette technique ne permettra pas non plus de produire des ombres portées.

Image non disponible

Pour ces raisons, il est souvent préférable de changer de technique de shading. L'option se trouve dans le panneau Render, sous l'onglet Shading. On peut choisir entre Multitexture (par défaut) et GLSL. Ce dernier dévoile plus de boutons, pour activer et désactiver certaines options (les lampes, les ombres, etc.).

Image non disponible

En mode GLSL, l'éclairage n'est plus calculé à partir des vertices, mais sur la face tout entière, pixel par pixel. Cela permet de révéler des dégradés plus fins et des reflets spéculaires fidèles à la forme d'origine. Les changements sont aussi bien visibles dans la 3D View que dans le jeu.
Dans l'exemple ci-contre, nous avons placé une lampe au niveau d'un des angles du cube (légèrement décalée) et nous avons pris deux points de vue différents de manière à bien voir le reflet. Le résultat est parlant : en multitexture, le rendu est extrêmement triangulé et les spéculaires sont faibles, ce qui n'est pas le cas en GLSL.

Image non disponible
Multitexture
Image non disponible
GLSL

Pour profiter du mode GLSL, il faut penser à configurer la vue 3D en mode Textured.(raccourci : Alt+z)

Image non disponible

XIII-B. Options des lampes

Pour ajouter une lampe, il suffit de passer par le menu Add (Maj + A), sous l'option Lamp. Le seul mode non supporté actuellement est la lampe de type Area. Une fois une lampe ajoutée, on peut modifier son type ainsi que diverses options dans le panneau Lamp. Les options disponibles ne présentent pas de différence majeure avec le mode Blender Render, mais nous allons les passer en revue brièvement.

Les options communes à tout type de lampe sont tout d'abord la couleur et l'intensité (Energy). Negative permet d'avoir une lampe dont l'éclairage va en diminuant (idéal pour fausser une ombre, mais non physiquement réaliste).

En cochant l'option This Layer Only, une lampe se trouvant dans un calque n'éclaire que les objets présents dans ce même calque. Cette option peut être utile si d'autres layers sont activés simultanément : on peut avoir une lampe qui éclaire un objet, mais pas les autres.

Image non disponible

Enfin, Specularet Diffuse spécifient si la lampe produit des reflets spéculaires et de la lumière ambiante.

XIII-B-1. Lampe Point

Ce type de lampe est utile pour imiter les sources lumineuses qui diffusent de la lumière dans toutes les directions depuis un point fixe et central, comme une torche ou une bougie, avec une rapide diminution d'intensité. Il n'y a pas d'ombre portée avec ce type de lampe.

La manière dont diminue l'intensité peut être changée avec l'option Falloff. L'option par défaut, Inverse Square, correspond à la diminution réaliste d'une lampe ponctuelle. L'option Distance indique la distance à laquelle il faut se situer pour être exposé à la moitié de l'intensité maximale, elle-même définie dans Energy.

Image non disponible

XIII-B-2. Lampe Sun

Le type Sun est une lampe directionnelle, permettant de simuler un point éclairant la scène depuis une très grande distance et avec des rayons parallèles, comme le ferait le soleil. Seule la rotation de l'objet lampe permet de changer la provenance de la lumière, sa position n'est pas prise en compte. L'onglet Shadow permet de régler la projection d'ombre. Ce point sera traité spécifiquement dans la suite de ce chapitre. Le calcul de l'ombre est limité à un certain angle, défini par Frustum.

Image non disponible

XIII-B-3. Lampe Spot

Le spot limite l'éclairage à un cône et permet de projeter les ombres portées. La forme du cône est paramétrable sous l'onglet Spot Shape. Comme pour le Sun, l'option Shadow est disponible.

Image non disponible

XIII-B-4. Lampe Hemi

Le type Hemiest un autre type de lampe directionnelle, sans possibilité de produire des ombres. Elle est différente de la lampe de type Sun, car la lumière provient de tous les côtés d'une demi-sphère englobant la scène. Elle peut par exemple simuler l'éclairage diffus produit par un ciel nuageux.

Image non disponible

XIII-B-5. Texturer une lampe

Comme pour les matériaux, il est possible d'affecter des textures à chaque paramètre en lien avec la lumière. Nous pouvons modifier le World qui sert de couleur de fond et agit aussi sur la couleur ambiante des matériaux, mais également sur les lampes qui peuvent ainsi varier d'intensité pour simuler l'ambiance d'un environnement.
L'application des textures sera détaillée aux chapitres suivants.

Image non disponible

XIII-C. Les ombres portées

Commune aux lampes Spot et Sun, les options d'ombres sont importantes à comprendre pour une bonne qualité d'éclairage et de bonnes performances graphiques. En effet, le calcul des ombres portées dynamiques peut vite devenir gourmand en ressources, et doit être utilisé avec parcimonie. Cela reste malgré tout une option de choix pour ajouter réalisme et ambiance à une scène.

Image non disponible

On peut modifier la couleur de cette ombre pour simuler une ambiance. Ce qui est à l'ombre de la lampe est éclairé par une lumière d'ambiance colorée.

Image non disponible

L'option This Layer Only permet de limiter la production d'ombre aux seuls objets présents sur le même calque que la lampe.

L'option Shadow Only permet de produire une ombre sans ajouter de lumière à la scène. En fait, la lampe ne produit que les ombres. Dans l'exemple ci-dessous, nous avons dû ajouter une autre lumière pour l'éclairage général en complément du spot qui produit des ombres bleues, selon son rayon d'éclairage.

Image non disponible

L'option Buffer Type est importante : elle détermine le mode de production de l'ombre. Une ombre est en fait une texture ajoutée par-dessus les autres. Elle a donc une définition. Le type Buffer Simple produit simplement une texture à partir de la scène, le type Variance produit lui une texture adoucie, plus floue, qui permet d'obtenir des ombres douces, au prix d'un calcul supplémentaire.

Image non disponible

L'option Quality : Size est importante également : c'est elle qui détermine la taille de la texture utilisée pour l'ombre (toujours carrée). Ceci est particulièrement visible dans le cas d'une ombre de type Simple. Une ombre de petite taille (ex. 128) produira une ombre pixelisée alors qu'une ombre plus détaillée (512 ou 1024) sera plus précise et aura des bords plus nets.

Pour la taille des images, il est préférable d'utiliser des puissances de 2 pour optimiser le calcul. 128, 256, 512, 1024 ou 2048 sont les échelles habituellement utilisées.

Cette option est à considérer avec attention, parce qu'elle joue un rôle aussi bien sur la performance que sur l'esthétique. Des ombres de grandes tailles, en grand nombre, risquent de réduire fortement le taux de rafraichissement de l'image, augmentant donc la qualité du rendu, mais diminuant la qualité de l'animation.

Variance semble être une bonne option, permettant d'utiliser plus de lampes avec un rendu adouci tout en conservant une fréquence élevée de l'affichage.

Image non disponible
Image non disponible

En ajoutant, une texture à une lampe, il est possible de lui demander d'agir sur une ombre. Suivant l'effet souhaité, cela peut être nécessaire de jouer avec le positionnement des objets et des lampes sur plusieurs calques de la scène. Ici, il s'agit d'une distorsion : un objet fixe (Suzanne) ayant une ombre tout à fait différente de l'ombre attendue.

Image non disponible

Multiplier les lampes pour améliorer l'éclairage ou ajouter des effets peut être tentant. Il faut cependant résister à cette envie lorsque des ombres dynamiques sont utilisées et bien réfléchir à l'importance d'avoir une ombre dynamique pour chaque lampe. Il est possible de produire un éclairage de bonne qualité et de figer (baker) des ombres dans les textures des objets statiques. Ceci sera détaillé dans la section Travailler le rendu du jeu dans le chapitre Précalcul des textures et de la lumière.

L'espace dans lequel les ombres seront produites peut également être limité, en contrôlant la distance de leur apparition (Clipping). Clip Start et Clip End sont respectivement les distances minimales et maximales entre lesquelles l'objet doit se trouver pour produire une ombre. La distance des objets sur lesquels l'ombre sera éventuellement projetée peut sortir de cet intervalle. En limitant cette distance, les interactions entre lampes facilitent ainsi les calculs du moteur de jeu. Ces distances sont représentées dans la vue 3D par un segment de droite affiché dans l'axe de la lampe, ce qui aide à les régler finement.

XIII-D. Scrypthon !

Interagir avec les lumières en Python est également possible. L'objectif va être de faire varier l'intensité de la lumière en fonction de la hauteur d'un objet 3D qui va rebondir sur le sol.

Les captures d'écran ci-dessous montrent la scène dans sa situation de départ ainsi que le code Python que nous allons utiliser. Vous pouvez également voir les deux briques logiques que nous utilisons pour la mise en place de la scène. La première est la brique Always. Elle est configurée en mode pulse, ce qui permet de s'assurer que l'on aura une génération d'événements constants. Attaché à cette génération d'événements, nous exécutons le script python Lamp.

Image non disponible

Étudions maintenant en détail le script Python que nous utilisons.

 
Sélectionnez
from bge import logic 
cont = logic.getCurrentController() 
ball = cont.sensors[0].owner 
light = cont.owner 
light.color = [ 0.8, 0.3 , 0.6 ] 
light.energy = min(ball.position.z + 0.4, 0.5)

La première ligne correspond, comme toujours, à l'import des modules recevables.
On récupère ensuite le contrôleur qui est relié à ce script Python. Ici le contrôleur est rattaché à notre lampe, or nous avons besoin de connaître la position en z de notre boule.

 
Sélectionnez
ball = cont.sensors[0].owner

Avec cette ligne de code, nous allons récupérer notre boule par l'intermédiaire de notre sensors Always(premier et unique sensor attaché à notre controller) que nous avons opportunément accroché à notre objet. Chaque contrôleur possède une liste appelée sensors qui répertorie la totalité des sensors qui lui sont rattachés. Ici, il n'y a qu'un seul sensor, on peut donc sans problème utiliser la notation [0] pour récupérer le premier élément de la liste.

 
Sélectionnez
light = cont.owner

Nous récupérons la lumière de la manière classique, en récupérant le owner du contrôleur courant.

 
Sélectionnez
light.color = [ 0.8, 0.3 , 0.6 ]

Ici, nous nous amusons à modifier la couleur de la lumière pour la rendre violette.
La ligne suivante est un peu plus compliquée. On va ici modifier la puissance de notre lumière.

 
Sélectionnez
light.energy = min(ball.position.z + 0.4, 0.5)

Pour cela, on change la valeur de l'attribut energy de notre spot. La fonction min en Python nous permet de récupérer la plus petite valeur d'un ensemble, qui se limite ici à la valeur de la coordonnée en z de notre balle rebondissante à laquelle on ajoute 0.4 ou à 0.5). On va donc obtenir un effet 'jour , nuit, jour , nuit' tant que la balle rebondit. Lorsqu'elle finira par s'arrêter, notre scène sera alors plongée dans le noir.

XIV. Introduction aux matériaux et textures

Les matériaux et leurs textures sont les futures couleurs du monde de notre jeu ! Et, puisque nous devons limiter le nombre de polygones pour des raisons de performance du moteur de jeu, les matériaux et textures seront donc très importants pour habiller nos objets et personnages. Nous allons voir dans ce chapitre deux approches pour donner à nos surfaces des aspects variés et enrichir l'aspect global de notre environnement.

De manière générale, matériaux et textures sont intimement liés. Il est possible d'avoir des matériaux sans textures, mais cela limite fortement les effets visuels possibles. Par contre, il n'existe pas de texture visible sans qu'elle soit au moins attachée à un matériau.

Il est important de noter aussi que la gestion des matériaux et textures pour le Game Engine se fait différemment qu'en mode de rendu Blender classique. Les différences sont tant dans la gestion des nodes, pour ceux qui ont l'habitude d'aborder cette pratique sous cet angle, que dans les possibilités offertes par le mode de texture plus ancien, sans utilisation de nodes.

XIV-A. Les deux façons de créer des matériaux

Les matériaux dans le Game Engine peuvent être définis de deux manières différentes, qui se complètent d'une certaine façon. Ceci est dû à l'historique du logiciel.

  • La méthode ancienne, héritant de la méthode des versions 2.4x, est de définir le matériau dans les panneaux des onglets matériaux et textures. C'est aussi la seule méthode qui fonctionnera lorsque nous serons en mode de rendu Multitextures.
  • La méthode actuellement développée utilise le système des nœuds de matériaux, qui tire utilement parti des capacités de calcul des cartes graphiques modernes. Pour utiliser ce dernier système, il faudra néanmoins initialiser certains paramètres dans les panneaux de matériaux et textures. Cette méthode est la méthode conseillée, permettant de construire des textures complexes et dynamiques au besoin. Cette méthode ne fonctionne que si le mode de rendu GLSL est activé.

XIV-B. Les paramètres d'affichage des matériaux

Nous allons décrire dans cette partie les différents panneaux présents dans l'onglet Material de la fenêtre Properties.

Les options Diffuse, Specular et Shading  sont a priori connues. Rien de mystérieux concernant leurs utilisations, car elles ne diffèrent pas de Blender Internal ou de Blender Cycle.

Une des spécificités du mode Game Engine, c'est que nous avons maintenant un panneau Game Settings avec quelques options importantes.

Image non disponible

LeBackface Culling sert uniquement à calculer les faces dont la normale pointe vers la caméra. Techniquement, si l'on coche cette option, si une normale est dans le même sens que la caméra elle n'est pas affichée et donc l'objet devient transparent. On peut utiliser cette méthode pour le cas où la caméra entre dans un objet afin de ne pas avoir un écran noir.

Le paramètre Invisible, quant à lui, fait disparaître totalement le matériau en jeu et tous les objets auxquels il est appliqué.

Le bouton Text sert uniquement à afficher le matériau sur un objet texte, mais seuls les objets textes sont concernés.

Les modes d'Alpha Blend indiquent de quelle manière gérer la transparence :

  • Opaque : c'est l'option par défaut. Dans ce mode, toutes les faces sont opaques ;
  • Add : la transparence de la face dépend de sa couleur, plus elle est proche du blanc, plus le matériau est opaque et plus elle est proche du noir, plus il est transparent ;
  • Alpha clip : ce mode supporte un canal de transparence Alpha (RGBA). On l'utilise pour avoir de la transparence quand on utilise les textures. Cependant, la transparence est limitée : on a soit complètement transparent (0), soit complètement opaque (1) :
  • Alpha : sûrement le mode le plus adapté pour la transparence, car il gère les textures qui ont une transparence avec un canal alpha et supporte la semi-transparence (de 0 à 255). Par contre, ce mode demande plus de calculs, et n'est pas conseillé pour des faces trop nombreuses.

XIV-C. Les paramètres des textures

Comme nous le disions plus haut, il est très rare d'avoir un matériau qui n'est pas lié à une texture. De manière générale, une texture donnera toujours au minimum une couleur plus complexe à notre objet, que simplement la présence de l'option Diffuse dans l'onglet Material.

Notez que les textures procédurales ne sont pas supportées par le Game Engine. Si vous les avez utilisées pour modifier l'apparence de votre objet, il vous faudra passer une technique nommée baking qui permet de faire la conversion de ces textures en images bitmap. Cette technique est d'ailleurs décrite au chapitre Pre-calcul des textures et de la lumière de la section Travailler sur le rendu.

Vous l'aurez compris, le travail se fera donc uniquement avec des textures image ou par une programmation plus complexe en GLSL.

Concernant les images et pour des raisons de performance, il sera toujours préférable de limiter le nombre de textures utilisées ainsi que leur taille. Par défaut, une image dans Blender est un carré de 1024 pixels de côté. Le Game Engine n'est cependant pas restreint à l'affichage d'images carrées pour les textures. Mais il est recommandé de prendre cette habitude pour faciliter les calculs liés à leur affichage. Une texture idéale sera donc un carré dont la longueur de côté, en pixel, sera une puissance de 2 (exemple: 128x128, 256x256, 512x512…).

XIV-C-1. Créer une nouvelle texture

La création des textures de type Image liées à un matériau pour le Game Engine est identique au Blender Internal, mais nécessite la connaissance de quelques subtilités pour qu'elle s'affiche correctement dans le jeu.

Pour les utilisateurs de Cycles, une petite explication s'impose. Par défaut, les matériaux du Blender Internal et du Game Engine n'utilisent pas de nodes. Donc, contrairement à Cycles, il n'y a pas un système nodal commun aux textures et aux matériaux. Dans le Node Editor, les nœuds des textures et les nœuds de matériaux sont donc différents. Ils ont chacun leur propre onglet. Le nœud Texture permet d'introduire une texture créée de façon traditionnelle et de la lier avec un nœud matériau. Il est donc impératif d'initialiser une texture à la manière de Blender Internal (avec l'onglet Texture de la fenêtre Properties) avant de pouvoir l'utiliser dans les nodes de matériaux.

De façon traditionnelle (à la manière de Blender Internal), les textures sont donc disposées dans une liste où l'ordre détermine la priorité d'une texture par rapport à une autre. Ci-dessous, voici la méthode pour ajouter une texture à cette liste :

  1. Sous cette liste, cliquez sur le bouton New pour créer une nouvelle texture image. À la place du bouton New, apparaît son nom ;

    Image non disponible
  2. En dessous du nom, il faut préciser le type Image ou Movie. Ce sont les seuls types fonctionnels dans le Game Engine. Comme on vous le disait plus haut, les textures procédurales ne sont pas supportées ;

    Image non disponible
  3. Cliquez alors sur le bouton Open dans l'onglet Image placé en dessous de manière à pouvoir charger une image.

XIV-C-2. Définir le mode de projection

Le panneau Mapping est configuré par défaut en mode coordonnées automatiques Generated pour mapper la texture selon une projection plane (Flat), mais une bonne pratique est d'utiliser systématiquement des coordonnées UV pour tout mesh (volume ou plan). Seule la projection de type Flat fonctionne dans le Game Engine, les autres types de projections ne sont pas supportés.

Image non disponible

XIV-C-3. Définir l'influence

Le panneau Influence indique comment la texture va influencer les paramètres du matériau. Ceci ne fonctionne que si on n'utilise pas le mode node pour gérer notre matériau.

Dans notre capture d'écran, nous avons activé le slider Color et Alpha. Ce qui veut dire que notre image de texture influence l'apparence colorée de notre objet et joue aussi sur sa transparence. Nous aurions pu activer uniquement l'influence Alpha. La couleur n'aurait alors pas été affectée, juste la transparence de l'objet. Il est ainsi possible d'activer ou de désactiver un seul ou tous les réglages du panneau. Il n'est pas rare aussi d'affecter la géométrie de manière à utiliser les variations de luminosité de notre image pour simuler du relief et rendre le résultat plus réaliste. Image non disponible

Les autres panneaux de l'onglet Texture sont des notions supposées connues.

Lors de l'utilisation de textures répétées, il est important de bien travailler l'image initiale de manière à ce que les raccords ne soient pas visibles dans le jeu. La fonction Filtres > Mappage > Rendre raccordable de Gimp permet d'aider et marche parfaitement sur les textures de matériaux. Dans Krita, appuyer sur V après une sélection fera un remplissage automatiquement raccordé de la sélection sur toute sa surface.

XIV-D. Les nœuds matériaux

Pour gérer nos matériaux et textures, nous pouvons aussi utiliser les nodes : une pratique qui tend à se généralise peu à peu dans l'ensemble de Blender. Nous vous encourageons d'ailleurs à utiliser cette méthode parce que nous pensons que les nœuds de matériaux exposent une arborescence de matériau et textures plus simple à comprendre que les relations établies par l'ordre de la liste et les panneaux Influence de chaque texture (méthode plus attachée à une pratique de Blender 2.4x).

Nous tenons à rappeler que cette façon de travailler ne fonctionne que si vous avez GLSL activé.

XIV-D-1. Un matériau simple avec des nœuds

Voici un exemple simple de matériel fait avec les nodes.

Image non disponible

Ici, un nodeRGB envoie une donnée de couleur vers l'entrée couleur du matériau, dont la sortie nourrit un nodeOutput qui donnera le résultat sur l'objet.

XIV-D-2. Matériau avec une texture dans le Node Editor

Voici, en détail, la procédure pour créer des nodes de matériaux et les lier avec des textures.

  1. Affichez les nœuds de matériaux dans leNode Editor.
  2. Activez les nœuds de matériaux en cochant la case Use Nodes dans le Header du Node Editor. Une fois réalisé, l'objet devient complètement noir et les panneaux changent dans le panneau Material.Image non disponible
  3. Cliquez sur le bouton New pour donner un nouveau matériau au nœud Material. L'objet n'est plus noir. Si le matériau à utiliser avait déjà été créé, il suffit de le choisir dans la liste des matériaux du Material.Image non disponible
  4. Appuyons ensuite sur Maj+A pour créer un nœud Input > Texture. Assignons-lui une texture créée au préalable en la choisissant dans la liste.
    Référez-vous au sous-chapitre Créer une texture décrit plus haut si vous ne savez pas comment faire, mais ne tenez pas compte du panneau Influence qui n'aura effectivement aucune influence ici.Image non disponible
  5. Une fois que nous avons créé notre nœud Texture et que nous lui avons assigné notre bloc de données Texture, nous devons supprimer ce bloc de donnée de la liste qui se trouve dans l'onglet Texture de la fenêtre Properties, sinon la texture sera appliquée de façon traditionnelle en plus de son utilisation par les nodes.
  6. Le paramétrage de notre nœud texture est accessible dans l'onglet Textures à chaque fois que vous sélectionnez le nœud correspondant. L'absence de liste indique bien que la texture affichée est celle d'un nœud Texture. Image non disponible
  7. Pour appliquer votre texture en mode UV sur votre objet, vous devez maintenant connecter au minimum un nœud Geometry à partir de sa sortie UV dans l'entrée Vector de notre nœud Texture. Comme dans Cycles, nous pouvons aussi utiliser un nœud Mapping qui permet de modifier la taille, la rotation et les décalages de la projection de la texture. Les coordonnées de Mapping sont précisées grâce au nœud Geometry. Image non disponible
    L'information essentielle est que les textures doivent avoir une des coordonnées UV pour s'afficher. Les autres modes de Mapping ne fonctionnent pas dans le Game Engine.

XV. Matériaux et textures avancés

Dans ce chapitre, nous verrons quelques effets avancés liés aux matériaux et textures. Il s'agit principalement de jouer sur des effets de relief, de transparence ou de brillance de nos objets afin de donner plus de réalisme ou de corps à notre environnement. Ces effets sont généralement utilisés pour pallier la simplification de la géométrie due à notre besoin de performance. C'est aussi un des canaux importants de l'expression du style graphique du jeu.

Nous verrons trois aspects importants combinant propriétés des matériaux et usages avancés des textures : les effets de brillance, de relief et de transparence.

Vous devez avoir compris le chapitre précédent, Introduction aux matériaux et textures, pour pouvoir suivre celui-ci.

XV-A. Gérer la brillance ou les reflets de lumière sur notre matériau

Le canal spéculaire décrit la brillance. Il peut s'agir d'une couleur uniforme (pour un matériau à la surface régulière, plus ou moins brillante), ou d'une image en niveaux de gris servant à distinguer les zones mates (caoutchouc, tissu…) des zones brillantes (métal, verre, graisse…), avec toutes les nuances intermédiaires (caoutchouc mouillé, métal sale…).

On peut l'obtenir généralement en se basant sur la texture de couleur, que l'on modifie dans un éditeur d'images comme Gimp ou Krita.

Dans l'exemple suivant, une texture agit sur le canal spéculaire pour que le cube brille uniquement dans certaines zones.

Image non disponible

En méthode Blender Internal (pas d'utilisation de nodes), il faut définir dans l'onglet Texture de notre matériau, ajouter une texture dans notre liste qui n'a d'influence que sur les options sous Specular dans le panneau Influence.

En mode node, ajoutez un nœud Texture qui se connectera uniquement à notre entrée Specular de notre nœud Material.

XV-B. Donner du relief

Comme nous travaillons sur une application temps réel, les performances sont une question cruciale. Nous utiliserons donc des maillages composés de peu de faces (low poly), et par conséquent peu détaillés. Pour pallier ceci, nous pouvons simuler un faible relief à l'aide d'une texture de relief. C'est un effet très intéressant, car il utilise peu de ressources, pour un résultat qui peut être saisissant s'il est bien utilisé.

Une texture de relief (Bump map) est une image en niveau de gris qui contient des informations de profondeur : si les pixels sombres sont des « creux », les pixels clairs sont des « bosses ». L'effet convient bien à des reliefs peu prononcés et dont la précision n'est pas fondamentale (une route goudronnée, du tissu…).

On l'obtient généralement en se basant sur la texture de couleur, que l'on modifie dans un éditeur d'image comme Gimp .

Image non disponible

À gauche, la texture Bump. Elle est utilisée dans le menhir de gauche et est absente dans le cas du menhir de droite.

Une Normal Map est un peu plus complexe. Elle décrit de manière très précise le relief de l'objet, elle permet vraiment de donner l'illusion d'un maillage dense. On l'obtient généralement en comparant un modèle low poly et un modèle high poly (cette technique est traitée dans le chapitre Optimisation de la texture et de la lumière : Baking), ou à défaut, à partir d'une bump map et d'un outil comme Insane Bump (plugin Gimp).

Dans le BGE, elles s'utilisent de la même manière que pour un matériau de rendu, soit en utilisant un node texture nourrissant une entrée Normals d'un matériau, soit de manière traditionnelle en cochant la case Normal (panneau Textures / Influence / Geometry) et en réglant la puissance de l'effet. Pour une normal map, il faudra également, dans Textures / Image Sampling, cocher Normal Map.

Image non disponible

La Normal Map est ici récupérée par baking de plusieurs objets sur l'objet actif (le plan) grâce à l'option Selected to Active du panneau Baking dans l'onglet Render.

XV-C. L'utilisation de la transparence

Outre l'usage évident de transparence pour imiter des matériaux de type eau, verre, etc., la transparence est utilisée dans les jeux vidéo pour simplifier la géométrie. On peut par exemple simuler une forme complexe plane par un plan carré et une texture partiellement transparente.

C'est une façon d'éluder la création de géométries pour définir une forme. Dans un décor naturel, les arbres, les feuilles, les grillages, par exemple impliqueraient de créer une géométrie très lourde, mais ramené à des plans texturés avec de la transparence, un projet d'un décor familier devient réalisable avec beaucoup moins de faces.

Image non disponible

Le terme Alpha (en référence à la couche ou au canal Alpha d'une image) où qu'il soit mentionné dans l'interface de Blender est relatif à de la transparence. Dans l'UV/Image Editor, vous pouvez afficher une image avec sa transparence, sans sa transparence ou uniquement sa couche Alpha. Vous pouvez la modifier avec les outils de peinture. Plutôt que de dédier une image en noir et blanc à la transparence, l'usage le plus fréquent est d'utiliser la couche Alpha de l'image. Le réglage de la transparence de façon traditionnelle n'est pas évident, car les options par défaut n'aident pas ou sont disséminées dans différents recoins de l'interface. Pour information, la méthode traditionnelle implique de cocher la case du panneau Transparency dans l'onglet des matériaux. Les boutons pour les différents types de transparence sont relatifs au Blender Internal. Seule, la glissière Alpha a une importance sur la transparence globale du matériau. Passez sa valeur à 0.

Dans l'onglet des textures, pour qu'une texture modifie la transparence, il faudra activer également une glissière Alpha dans le panneau Influence. Par défaut, le blend mode de ce panneau est Mix. La valeur de la glissière Alpha du matériau est à adapter au blend mode utilisé. Avec un blend mode Mix, la valeur à indiquer est zéro, car les valeurs de la couche alpha de l'image vont s'ajouter à la valeur Alpha nulle du matériau. Mais pour un blend mode Multiply, il faudra cocher l'option RGB to Intensity et utiliser une valeur Alpha du matériau égale à 1. (Si vous ouvrez de très vieux fichiers créés avant l'apparition du blend mode Mix, il est probable que le blend mode utilisé soit Multiply). La méthode nodale permet de faire abstraction du blend mode et d'une activation du panneau de la transparencedans l'onglet du matériau. Il suffit simplement d'utiliser un nœud Extended Material possédant un socket d'entrée Alpha au lieu du nœud Material par défaut qui ne comprend qu'une sortie Alpha.

Pour créer un nouveau matériau pour ce nœud, cliquez sur le bouton New du nœud Extended Material. Déterminez les coordonnées de la texture en connectant la sortie UV d'un nœud Geometry à l'entrée Vector du nœud Texture. Faites agir la texture sur la transparence du matériau. Dans le cas où vous souhaitez utiliser la couche alpha d'une image, connectez la sortie Value du nœud Texture à l'entrée alpha du nœud Extended Material. Dans le cas où vous utilisez la texture comme un masque noir et blanc à partir d'une image sans couche alpha, connectez la sortie Color du nœud Texture à l'entrée alpha du nœud Extended Material.

Image non disponible

Attention : pour que la transparence du matériau soit effective, il faut absolument que la sortie alpha du nœud Extended Material soit connectée à l'entrée alpha du nœud Output.

Bien que l'effet de transparence soit effectif dans la prévisualisation (preview) du matériau, il n'est pas flagrant dans le viewport. C'est à cause du réglage par défaut de l'option alpha blend du panneau Game Settings sur le choix Opaque (ignorant volontairement la transparence pour garder toutes les faces du mesh opaques).

Image non disponible

Dans l'onglet du matériau, ce panneau Game Settings possède un paramètre Alpha blend mode à modifier pour adapter la superposition d'objets semi-transparents.

Image non disponible

Passez ce réglage sur le choix Alpha Blend pour avoir une transparence correspondante à la texture.

Image non disponible

Ce choix respecte les transitions douces. Contrairement à celui-ci, le choix Alpha Clip n'accepte pas les valeurs intermédiaires et force une transition abrupte entre une partie totalement transparente ou totalement opaque. Lorsque des surfaces se chevauchent, le choix Alpha Sort donnera un effet de profondeur, d'épaisseur en éclairant plus fortement les éléments les plus proches. Pour générer des effets lumineux comme du feu, des sprites lumineux peuvent se superposer et alors le choix Add permettra d'augmenter l'intensité lumineuse d'après la transparence aussi appelée de la transparence additive.

À présent, il reste une différence entre le résultat visible dans la vue 3D et le résultat dans le viewport du jeu. La surface n'est visible que d'un côté pour accélérer l'affichage. Par défaut, l'option Backface Culling du matériau est activée. Il faudra alors la désactiver pour créer un élément de décor fixe visible des deux côtés comme un grillage. Pour accorder la vue 3D au choix fait pour un matériau, la même option Backface Culling est accessible dans le panneau Shading des propriétés de la vue 3D.

Les autres paramètres de ce panneau ne sont pas directement en relation avec la transparence. Cependant lorsque l'on crée un plan texturé, c'est soit pour faire un sprite soit un billboard toujours dirigé dans la même direction (souvent vers la caméra). Le menu Face Orientations offre plusieurs choix de direction automatique.

XVI. Matériaux dynamiques et textures animées

Dans ce chapitre, nous allons voir trois méthodes pour faire varier les matériaux et textures dans le temps. Ces trois méthodes sont très différentes les unes des autres, mais sont regroupées ici parce qu'elles concernent la modification en direct de l'apparence de nos objets.

Nous verrons premièrement une technique bien connue des créateurs de jeux 2D, c'est l'utilisation de sprites pour rendre des effets d'animation. La deuxième passe par un processus de remplacement, à la volée, dans la carte graphique elle-même, des images attachées aux textures. Et la dernière méthode concerne la fabrication d'un matériau qui se modifie en fonction d'un événement particulier activé en cours de jeu.

Image non disponible

XVI-A. Textures animées par sprites

L'effet de transparence est souvent utilisé avec les sprites animés. Il s'agit de réduire  les ressources en utilisant une seule image regroupant les quelques frames d'une animation courte.

Il vous faut considérer l'image comme une texture normale au niveau du matériau.

Le réglage de l'animation se fait dans l'UV/Image Editor.

Texturez un simple plan avec l'image correspondant à collection des étapes de l'animation.

Elle doit être formée de tuiles de taille identique. Chaque tuile correspondant à une frame de l'animation.
Affichez l'image dans l'UV/Image Editor.

Les UV de la face du plan doivent recouvrir l'ensemble de l'image.

Faire un reset des UV est un moyen simple de s'en assurer.

Image non disponible

Affichez le panneau Game Properties dans la colonne des propriétés de l'image. Afin de recouper le nombre et la disposition des tuiles, dans la colonne des propriétés de l'image, il faut définir un nombre de colonnes avec la valeur x et de lignes avec la valeur y de l'encart Tiles.
Cochez le Clamp en x et en y selon l'aspect de votre image, mais laissez l'option Tiles désactivée pour l'animation. Pour indiquer la tuile de départ et celle de la fin de l'animation, précisez les valeurs Start et End de l'encart Animated. Les tuiles sont indexées de gauche à droite, de haut en bas. Pour que l'animation se lance dans le Game Engine, cochez la case Animated du panneau Game Properties. L'animation tourne en boucle lorsque vous pressez la touche P. À ce stade, il reste à adapter la vitesse de défilement des tuiles lorsque vous lancez le jeu. Pour cela, le plus simple est de faire des allers-retours successifs entre le lancement du jeu et modification de la valeur Speed.

XVI-B. Textures animées par remplacement

La technique présentée dans cette partie est très différente. Nous allons remplacer une texture dans la carte graphique par une image ou un flux d'image de provenance variée : fichier image, fichier vidéo, webcam, bloc mémoire ou un mélange de ce qui précède. Le terme fichier est à prendre au sens large : il peut s'agit d'un fichier ou d'un flux vidéo accessible sur Internet. Il suffit pour cela de spécifier une URL plutôt qu'un nom de fichier.

En plus nous pouvons appliquer un effet sur l'image avant qu'elle ne soit envoyée au GPU : incrustation vidéo de type écran vert, gamme de gris, normal map. Cette technique avancée n'est accessible que par Python via le module bge.texture. La magie derrière ce module est la bibliothèque libre FFmpeg. La plupart des formats et des codecs supportés par FFmpeg sont utilisables dans ce module. En voici une liste non exhaustive :

  • AVI ;
  • Ogg ;
  • Xvid ;
  • Theora ;
  • dv1394 camera ;
  • carte d'acquisition compatible avec video4linux (cela inclut de nombreuses webcams) ;
  • jpg ;
  • flux RTSP.

Le principe est simple. Nous identifions une texture sur un objet existant en utilisant la fonction bge.texture.materialID. Ensuite nous créons un objet texture dont le contenu sera modifié dynamiquement suivant l'une ou l'autre méthode évoquée plus haut et nous échangeons les deux textures dans le GPU. Le moteur graphique du BGE n'est pas averti de la substitution et continue à afficher les objets comme d'habitude, sauf que nous avons maintenant le contrôle de la texture. Quand l'objet texture est détruit, l'ancienne texture est restaurée.

XVI-B-1. Image fixe

Ce script Python change la texture d'un objet par une image fixe.

 
Sélectionnez
import bge 
from bge import texture 
from bge import logic 
def createTexture(cont):
    obj = cont.owner
    # Obtention de l'index de la texture initiale 
    ID = texture.materialID(obj, 'IMoriginal.png') 
    # Creation de la nouvelle texture 
    object_texture = texture.Texture(obj, ID) 
    # il faut garder une reference permanente 
    obj.attrDict["tex"] = object_texture 
    # chemin complet vers le fichier image 
    url = logic.expandPath("//newtex.png") 
    # chargeons la texture en memoire 
    new_source = texture.ImageFFmpeg(url) 
    # swap de texture 
    object_texture.source = new_source 
    # remplacement dans le GPU 
    object_texture.refresh(False)

def removeTexture(cont):
    obj = cont.owner
    try:
        del obj.attrDict["tex"] 
    except: 
        pass

Voyons ligne par ligne le fonctionnement de ces fonctions.

 
Sélectionnez
import bge 
from bge import logic 
from bge import texture

Ces trois lignes nous permettent d'accéder aux modules bge.logic et bge.texture par leurs noms. Nous avons besoin de texture pour créer la texture animée et de logic pour des fonctions d'intendance.

 
Sélectionnez
def createTexture(cont):
    obj = cont.owner

La fonction createTexture sera appelée par un controller Python, l'argument est donc la référence du controller. Nous avons besoin de l'objet, car c'est lui qui possède la texture que nous voulons modifier.

 
Sélectionnez
# Obtention de l'index de la texture initiale 
    ID = texture.materialID(obj, 'IMoriginal.png')

Nous supposons dans cet exemple que l'objet possède un matériel qui utilise une texture original.png. Le préfixe IM signifie que nous cherchons une image et pas un matériel. Nous pouvons directement rechercher un matériel par son nom en utilisant le préfixe 'MA'.

 
Sélectionnez
# Création de la nouvelle texture
    object_texture = texture.Texture(obj, ID)

Une fois le matériel identifié nous créons un objet Texture en spécifiant l'identifiant de matériel trouvé précédemment. Le premier canal de texture du matériel sera automatiquement remplacé par cette nouvelle texture.

 
Sélectionnez
# il faut garder une référence permanente
    obj.attrDict["tex"] = object_texture

L'objet texture doit impérativement rester en mémoire tant que nous voulons utiliser la nouvelle mémoire, sinon le garbage collector de Python supprimera l'objet dès la fin de la fonction et la texture sera supprimée. La méthode que nous utilisons ici est de conserver la référence l'objet logic en l'ajoutant au dictionnaire attrDict de l'objet qui persiste tant que l'objet n'est pas détruit (ce qui se produit au plus tard à la fin du jeu). Nous aurions pu sauver la référence dans le dictionnaire global de l'objet logic (logic.globalDict) pour le conserver tout au long du jeu même si l'objet est détruit.

 
Sélectionnez
# chemin complet vers le fichier image 
    url = logic.expandPath("//newtexture.jpg")

Nous avons besoin du chemin complet de la texture. Cette ligne suppose qu'une image « newtexture.jpg » est présente dans le répertoire du fichier blend. Les '//' sont remplacés par le chemin complet du blend.

 
Sélectionnez
# chargeons la texture mémoire
    new_source = texture.ImageFFmpeg(url)

La fonction ImageFFmpeg() du module bge.texture permet de charger une image fixe. Nous utiliserions une autre fonction pour charger une vidéo ou pour créer un bloc mémoire.

 
Sélectionnez
# swap de texture
    object_texture.source = new_source

Jusqu'à présent, notre texture était vide. En lui donnant une source, on lui donne du contenu, ici notre image préalablement chargée.

 
Sélectionnez
# remplacement dans le GPU
    object_texture.refresh(False)

Le chargement de la nouvelle texture dans le GPU se fait par la fonction refresh. L'argument de refresh est un booléen qui indique si la texture doit être recalculée (et donc réenvoyée au GPU) au prochain refresh. Dans le cas d'une image fixe, ce n'est pas nécessaire, mais pour une vidéo, ce serait indispensable, de même qu'il serait indispensable d'appeler refresh très fréquemment pour que les différentes images de la vidéo soient extraites et envoyées au GPU (tout se passe dans refresh). Pour utiliser ce script nous aurons besoin de deux briques controllers qui appellent la fonction createTexture au début du jeu pour effectuer le remplacement. Et une à la fin qui appelle la fonction removeTexture pour restaurer la texture.

La fonction removeTexture est optionnelle, car la  texture sera d'office restaurée à la fin du jeu grâce au fait que nous utilisons le dictionnaire de l'objet pour sauver la référence: ce dictionnaire est effacé à la fin du jeu ou dès que l'objet est détruit.

Comme vous le voyez sur la capture d'écran, nous avons choisi la méthode Module et non pas la méthode Script pour ajouter notre fonctionnalité python. Cela implique donc que nous devions utiliser la syntaxe NomModule.NomFonction pour indiquer à Blender où se trouve le code python à utiliser.

Image non disponible

XVI-B-2. Image vidéo

Dans cet exemple que nous ne détaillerons pas autant, nous remplaçons la texture d'un objet par une vidéo, ici une vidéo en ligne.

 
Sélectionnez
import bge 
from bge import texture 
from bge import logic 
def createTexture(cont):
    obj = cont.owner
    # Obtention de l'index de la texture initiale 
    ID = texture.materialID(obj, 'IMoriginal.png')
    # Creation de la nouvelle texture
    object_texture = texture.Texture(obj, ID)
    # il faut garder une référence permanente
    obj.attrDict["tex"] = object_texture
    # chargeons la texture en memoire
    new_source = texture.VideoFFmpeg("http://mirrorblender.top-ix.org/movies/sintel-1024-surround.mp4") 
    # swap de texture
    object_texture.source = new_source
    # démarrons la vidéo new_source.play()
    # remplacement dans le GPU object_texture.refresh(True)
def runTexture(cont): 
    obj = cont.owner 
    if "tex" in obj: 
        obj.attrDict["tex"].refresh(True) 
        print("1") 
def removeTexture(cont): 
    obj = cont.owner 
    try: 
        del obj.attrDict["tex"] 
    except: 
        pass

Ce script se distingue du précédent par deux points :
1. L'objet source est de type VideoFFmpeg au lieu de ImageFFmpeg (si nous avions utilisé ImageFFmpeg nous n'aurions obtenu que la première image du film). Cet objet a une API adaptée à la lecture de fichier vidéo (play, pause, stop). Ici nous utilisons play() pour lancer la vidéo ;

2. Nous devons rafraichir la texture fréquemment pour que les images du film soient successivement envoyées au GPU. Pour cela, la fonction runTexture doit être appelée fréquemment. Nous utiliserons pour cela un sensor Always en mode tick :

Image non disponible

XVI-C. Matériaux dynamiques avec les nodes

Utiliser les nodes ouvre la porte à une multitude d'effets poussés basés sur des paramètres d'entrée (inputs) qui seraient normalement inaccessibles. Comme exemple, fabriquons un matériauqui devient transparent s'il est observé de près : cela peut servir par exemple à voir à travers une partie du décor si la caméra se rapproche trop. En partant du material basique vu sous forme de node que nous avons préparé précédemment, il n'y a que très peu de changements à effectuer.

Pour commencer, il faut activer la transparence du material en cochant l'option Transparency dans l'onglet Render Pipeline Options du material.

Image non disponible

Ensuite, dans le Node Editor, il suffit de jouer avec le paramètre Alpha du node Output. Dans notre cas, nous devons relier cet Alpha à la distance de la caméra, disponible via le node Camera Data, en exploitant l'entrée View Distance. Lorsque cette distance atteint ou dépasse 1, l'alpha prendra sa valeur maximale (opaque). Pour un réglage plus fin, insérer un node Math en mode Multiply permet de modifier cette distance critique. L'option Clamp est une bonne pratique pour limiter les valeurs de sortie entre 0 et 1, puisque l'alpha va ignorer des valeurs extérieures à cet intervalle.

Image non disponible

XVII. Ajouter du son

Image non disponible

À côté de l'aspect visuel, un jeu vidéo (ou une application interactive) a souvent besoin d'un univers sonore pour être complet. Nous allons voir dans ce chapitre comment ajouter du son et de la musique dans notre univers visuel.

XVII-A. Les formats audios

Considérons deux cas de figure concernant les sons dans un jeu, les sons d'ambiance et les sons générés par des actions. Pour les sons courts, les petits bruitages, nous choisirons des fichiers au format .wav ou .aif, non compressés, qui seront plus rapides à lancer pour le Game Engine et assureront une bonne synchronisation avec les interactions. Par contre, si les fichiers sont plus gros (par exemple des musiques d'ambiance), nous pourrons prendre un autre format compressé (.ogg ou .mp3) pour éviter d'alourdir le .blend. Concernant le fichier, les formats supportés par le BGE sont wav, mp3, ogg, aif et flac.

XVII-B. Logic brick

Il est très simple de jouer un son via les briques logiques, pour réagir à un événement du jeu. Pour lancer des sons via les Logic brick, nous devons utiliser l'actuator Sound. Dans cet actuator, nous avons donc le fichier à lire, le mode de lecture, le volume du son, qui varie de 0 à 2 et le Pitch qui sert à modifier la fréquence du son.

Image non disponible

XVII-C. Les modes de lecture

Selon les cas, il peut être intéressant de jouer un son de différentes manières : une seule fois si le personnage se cogne contre un mur, plusieurs fois en boucle tant qu'il marche sur un sol bruyant, une seule fois sauf si on l'arrête, etc.

XVII-C-1. Jouer le son en entier

En utilisant Play End à la première impulsion, le son se lance et se joue complètement. En cas de seconde impulsion pendant que le son est encore en train de se jouer, il recommencera à 0. Cela correspond bien pour des sons d'événements comme les chocs ou les actions du personnage.

XVII-C-2. Jouer le son en entier, sauf si on l'arrête

En mode Play Stop, tant que l'entrée de la brique est active, le son est joué. Mais dès que l'entrée n'est plus active, le son s'arrête. En cas d'arrêt (fin du son ou entrée inactive), le prochain lancement se fera au début du son. Attention toutefois, même si l'entrée reste active, le son ne se relancera pas de lui-même à la fin de sa lecture.

XVII-C-3. Jouer le son en boucle, pour toujours

Avec Loop End, le son joue complètement et va se relancer en boucle après une impulsion. En cas de seconde impulsion, le son recommence à 0. Cette approche est parfaite pour une musique d'ambiance.

XVII-C-4. Jouer le son en boucle, sauf si on l'arrête

En mode Loop Stop, c'est le même principe que le Play Stop sauf que le son se jouera en boucle tant que l'entrée n'est pas relâchée. Idéal pour des sons fonctionnels ou de processus, comme des bruits de machine et moteur, de l'eau qui coule, etc.

XVII-C-5. Jouer le son dans les deux sens

Le Loop Bidirectional joue le son du début jusqu'à la fin et si l'entrée est encore active à la fin du son, celui-ci est alors joué à l'envers.

XVII-C-6. Jouer le son dans les deux sens, sauf si on l'arrête

Le Loop BidirectionalStop joue le son tant que l'entrée est active, mais s'arrête dès lors que l'entrée est inactive. Et comme le Loop Bidirectional, si l'entrée est active jusqu'à la fin du son, alors celui-ci se joue à l'envers, jusqu'à ce que l'entrée logique soit mise à Faux.

XVII-D. Effet 3D

Image non disponible

Ajouter un peu de profondeur et d'espace aux sons permet de créer une meilleure immersion dans le jeu. Par exemple si un ennemi se trouve loin du personnage, on l'entendra à peine ; mais s'il surgit juste derrière le personnage, le son sera très fort !

Nous devons en premier changer le type du Listener de la scène (dans l'onglet Scene > Audio > Listener), choisir la valeur Linear Clamped (le modèle de distance pour le calcul des atténuations). Occupons-nous de la brique logique Sound : cochons la case 3D Sound. Les valeurs de Reference Distance (distance de référence), Maximum Dist (distance maximale) et Rolloff sont les paramètres définissant la diffusion du son.

À partir de la distance de référence, le son commence à diminuer. La distance maximale est la distance à laquelle on pourra entendre le son. Le Rolloff est le paramètre de la courbe d'atténuation du son. Avec la valeur 1 la diminution du son est linéaire suivant la distance entre la distance de référence et la distance maximum. Pour ceux que ça intéresse, l'audio est gérée par OpenAL et selon la documentation de la bibliothèque, on a :

 
Sélectionnez
distance = max(distance, AL_REFERENCE_DISTANCE)
distance = min(distance, AL_MAX_DISTANCE)
gain = (1 - AL_ROLLOFF_FACTOR * (distance - 
            AL_REFERENCE_DISTANCE) /
             (AL_MAX_DISTANCE - AL_REFERENCE_DISTANCE))

Ce graphique présente la diffusion du son pour des valeurs données.

Image non disponible

Avec une valeur de 200 pour le Rolloff nous avons à peu près une valeur de 2000 pour le Maximum Distance, ce qui correspond +-10 Unités Blender (donc si nous passons le Maximum Distance à 4000, le son sera entendu jusqu'à 20 Unités Blender, etc.). Par contre, cela ne marche plus très bien avec des valeurs trop petites (< 1).

On peut aussi jouer avec le Reference Distance pour définir quand effectuer l'effet d'atténuation du son.

Pour conclure, dans une scène on change Scene > Audio > Listener en mode Linear Clamped

On place un cube avec l'actuator sound :

  • Maximum Distance= 2000 (donc une décroissance sur 10 Blender Units !) ;
  • Rolloff = 200 ;
  • Reference Distance = 20.

Voilà ce qui se passera :

  • à 1 Blender Unit : on entendra normalement le son (100 %) ;
  • à 10 Blender Units : on entendra normalement le son (100 %) ;
  • à 15 Blender Units : on entendra normalement le son (100 %) ;
  • à 20 Blender Units : on entendra normalement le son (100 %) ;
  • à 23 Blender Units : on entendra le son un peu moins fort ;
  • à 28 Blender Units : on entendra le son très bas ;
  • à 30 Blender Unites : on n'entendra pratiquement plus le son.

XVII-E. Scrypthon !

Concernant la gestion du son, le Python amène vraiment une nouvelle palette de fonctionnalités pour traiter les sons. Cette fois, nous utilisons un autre module Python : aud. Pour ajouter du son lors d'une collision entre deux objets, nous utilisons la configuration suivante.

Image non disponible

Rappelons que nous avons choisi la méthode Module et non pas la méthode Script du contrôleur pour appeler le script son.py suivant.

 
Sélectionnez
import aud
from os import chdir
from bge import logic 
# on n'oublie pas de se placer dans le bon repertoire 
chdir(logic.expandPath("//")) 
device = aud.device() 
def play1():
     factory = aud.Factory('music1.mp3')
     factory = factory.limit(0.0, 5.0)
     handle = device.play(factory) 
def play2():
     factory = aud.Factory('music1.mp3')
     factory = factory.fadein(0.0, 5.0)
     factory = factory.fadeout(7.0, 9.0)
     handle = device.play(factory) 
def splitch():
     factory = aud.Factory('splitch.mp3')
     factory = factory.limit(0.0, 5.0)
     handle = device.play(factory)
     handle.loop_count = 2

Les trois premières lignes nous permettent d'importer nos modules et les trois suivantes servent à bien définir le répertoire courant (voir le chapitre Bien préparer son projet).

Nous commençons par créer une variable device qui nous permettra d'agir sur la carte son. Ensuite nous déclarons trois fonctions, play1, play2 et splitch. Dans la capture d'écran, nous demandons à Blender d'utiliser la fonction play1, mais nous pourrions très bien utiliser les autres fonctions à d'autres moments dans notre projet. Les trois fonctions commencent par la création d'une aud.Factory, un lien vers un fichier son que l'on va pouvoir configurer, avant de le jouer grâce à la méthode play() de notre device.

Regardons donc cette fonction play1. Une fois la Factory créée, nous allons utiliser sa méthode limit() pour sélectionner uniquement une plage de temps du fichier son. La fonction limit() prend deux paramètres float : start et end, qui définissent en secondes le début et la fin de notre sélection. Une fois que l'on a configuré ce que l'on veut, on demande à notre device (qui, rappelez-vous est un lien vers la carte son) : ici la carte son va jouer les 5 premières secondes de notre fichier audio.

Dans la fonction play2(), nous souhaiterions aller plus loin en ajoutant des fondus, pour rendre plus fluides le début et la fin de la lecture. Une fois la Factory créée, nous allons la configurer en appelant successivement deux fonctions (lignes 2 et 3 de play2()) : fadein() pour un fondu en ouverture, puis fadeout() pour un fondu en fermeture. On peut en effet mettre en place plusieurs effets en enchaînant les appels à des fonctions de configuration. Il ne nous reste qu'à jouer le son avec device.play().

Terminons maintenant avec la fonction splitch(). Vous aurez remarqué que lorsque nous utilisions la méthode play(), nous récupérions un handle. Voyons comment en tirer profit. On peut par exemple modifier son attribut loop_count, qui permet de jouer plusieurs fois le son. Ici nous avons donné 1 comme valeur, il sera donc joué 1 fois à la 4e ligne de la fonction.

Petite précision intéressante, si vous donnez une valeur négative à loop_count, votre son se répétera continuellement. Le handle que vous renvoie la fonction play() permet d'agir sur la lecture du son une fois celle-ci en cours. Vous pouvez par exemple la mettre en pause (avec la fonction pause()), la reprendre (avec la fonction resume()) ou arrêter définitivement la lecture (avec la fonction stop()). Concernant la fonction stop(), elle arrête bien totalement la lecture. On ne peut la reprendre qu'en relançant la fonction play() de notre périphérique.

XVIII. Filtres de rendu

Jusqu'à présent, nous avons étudié un ensemble de techniques qui permettent d'agir sur le contenu de l'image avant son rendu. Nous verrons dans ce chapitre qu'il est possible d'agir après le rendu, afin de personnaliser le style visuel du jeu, ou d'agir de manière très pointue sur l'affichage.

XVIII-A. Filtre 2D 

La brique logique 2D Filter Actuator permet d'ajouter facilement un shader d'affichage, afin d'obtenir des effets comme du flou, ou une coloration sépia par exemple. Il s'agit de filtres 2D (comparables à ceux d'un éditeur d'image comme Gimp) qui s'appliquent sur chaque frame, après leur rendu et avant leur affichage. Voici un exemple de jeu BGE sans filtre 2D.

Image non disponible

Le même avec un filtre Sepia.

Image non disponible

Ou un filtre Dilatation (voir le détail des textures).

Image non disponible

La mise en place est très simple, puisqu'il suffit d'ajouter un actuator 2D Filter et de sélectionner un filtre. On peut insérer cette brique logique dans un objet quelconque comme la caméra.

Image non disponible

Les options Enable et Disable permettent de contrôler les filtres dynamiquement. On peut par exemple imaginer un flou de mouvement qui ne s'active qu'au-delà d'une certaine vitesse de déplacement, ou encore un filtre que le joueur peut désactiver dans un menu pour améliorer les performances. Ici, deux touches du clavier permettent d'activer ou de désactiver le filtre.

Image non disponible

L'option Pass Number permet de contrôler les filtres de manière indépendante. Ici, le clavier permet d'agir sur le filtre Sepia défini sur la passe 1, mais pas sur le filtre Blur défini sur la passe 0.

Image non disponible

Quelques filtres simples sont fournis avec le BGE, mais ils ne répondront sans doute pas à tous vos besoins. Il est naturellement possible d'utiliser des filtres personnalisés (via l'option Custom Filter et un simple fichier texte) que l'on aura téléchargés ou écrits soi-même.

Image non disponible

Le filtre Chromatic Bloom visible sur cette capture est disponible ici : http://mattline1.blogspot.co.uk/2012/08/blender-2d-filters.html

Il existe un Add-on regroupant un belle collection de ces filtres (parmi d'autres shaders utiles pour le BGE) : http://urfoex.blogspot.be/2013/03/bge-glsl-glsl-shader-repository-addon.html

Cette série de tutoriels explique les bases nécessaires pour écrire vos propres shaders : http://solarlune-gameup.blogspot.co.uk/search/label/GLS.


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 flossmanuals. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.