OPTIMISATION MAPS HALF-LIFE 2Ce cours porte sur "comment optimiser sa map sous le moteur Source (Half-Life 2)" Ce cours a été entièrement écrit par moi, c'est à dire NykO18.
Si la page ne s'affiche pas correctement chez vous (résolution inférieure ou égale à 1024x768) cliquez ici. sous un contrat Creative Commons. Plan
IntroductionCe tutorial s'adresse à tous les gens qui vont se retrouver parmis les citations suivantes, toutes trouvées dans les forums de mapping-area : RoBoT a dit : brusnt a dit : CN_Mapoleon1er a dit : Nargzul a dit : mind a dit : Neernitt a dit : tuni a dit : J'aurais pu en prendre encore beaucoup comme ça, mais après on va me dire que j'essaie de combler ce tutorial avec du n'importe quoi. (je précise que j'ai corrigé les fautes d'orthographe des posts ci-dessus ) Je met à votre disposition la map que j'ai créée pour ce tutorial. Elle contient quelque uns des exemples que j'expose ici ainsi que les techniques pour les hints, areaportals, areaportalwindows, occluders, func_detail et autres.. Si au moins cela peut servir à quelque chose... faites en bon usage. I. La compilation90% des gens qui se plaignent d'une compilation beaucoup trop longue à leur goût on des problèmes avec VIS. (les autres ont une mauvaise idée de ce qu'est une heure de compilation à part un temps normal) Seulement voilà, dans ces 90% de plaignants, seulement 10 ou 20% savent réellement à quoi sert chaque étape de la compilation d'une map. Je vais donc tenter de vous expliquer cela rudimentairement (attention ce n'est pas non plus un cours sur la compilation, je fais avec mes connaissances et elles sont sommaires). I.1. BSPLors de la compilation, BSP possède le rôle le plus primitif. En effet, avant que n'importe lequel des autres outils puisse être utilisé, il faut au préalable "construire" la map. C'est le rôle de BSP. Il ignore d'abord toutes les entités MÊME les func_detail et créé les blocs qui formeront l'architecture basique de la map à l'aide de polygones. Dans le cas de Half-Life 2, tout objet est construit à partir de triangles, il faut donc 12 triangles pour faire un bloc rectangulaire. (2 par face rectangulaire) Son rôle est donc en premier lieu de découper la map en triangles. Half-Life 2 ne gêre pas les polygones de plus de 3 sommets, comme la majorité des moteurs 3D. Il est donc obligé de convertir un polygone de 4 ou 5 faces sous Hammer en 2 ou 3 triangles sous Half-Life 2, et ce même si Hammer semble persuadé qu'une forme à quatre côté puisse exister. Si elles sont représentées ainsi dans Hammer, c'est simplement pour que cela soit plus clair, plus intuitif et surtout plus simple pour s'y retrouver. BSP n'ignore pas réellement les entités, sinon il n'y en aurait tout simplement pas dans la map. Il faut bien différencier la "disposition des blocs" qui est le partitionnage de l'espace (découpage de la map et création de "pièces" ou "salles", ou Binary Space Partitioning [BSP]) de l'enregistrement de la position des entités. Les entités sont par la suite dynamiquement chargées par le moteur, à l'emplacement noté par BSP. Le partitionnage de l'espace consiste à déterminer la surface jouable et à traiter les endroits creux.. Hammer determine où sont les endroits où le joueur est susceptible de pouvoir se trouver.. Logiquement, il s'arrête aux "murs" qui bordent la map (le ciel par exemple). Tout ce qui se trouve en dehors de la map, ce vide étrange qu'aucun mappeur ne devrait laisser apparant, n'existe pas. Quand je dis "Logiquement" c'est parce que si votre map possède malgré tout un moyen d'accès vers le vide de l'extérieur (un trou en fait, et peu importe sa taille) et bien BSP ne va plus être capable de determiner où commence et où s'arrête votre map.. Il va, au bout d'un moment, se retrouver dans le vide et planter car il a "du vide" à calculer à l'infini... C'est ce qu'on appelle courramment un leak (littéralement "une fuite" en anglais). Une map qui possède un leak est impossible à optimiser, aussi veillez à ce que vos maps ne contiennent jamais de leaks. Les leaks se repèrent lors de la compilation de la map.. soyez attentifs aux messages de ce genre, qui indiquent un leak dans votre map : Pour en savoir plus sur BSP : I.2. VISC'est le deuxième outil à se lancer durant la compilation et c'est également celui qui a le plus d'importance au niveau de l'optimisation de votre carte. Explications : Prenons l'exemple ci-contre. Nous avons un couloir (numéro 5) reliant 4 salles (numéros 1, 2, 3 et 4) entre elles (vus de haut). Disons que l'on se trouve dans la salle 1. A votre avis, est-il nécessaire de calculer ce qui se trouve dans la salle 3 ? Je pense que non personnellement, et c'est exactement ce que le VIS va se dire. Dès qu'il n'y aura aucun moyen quel qu'il soit de voir le moindre pixel d'une autre salle, elle ne sera pas affichée, tout simplement. Je reviendrai un peu plus tard sur plusieurs moyen de ne pas calculer cette salle dont on ne voit "presque rien" mais aussi sur d'autres cas de figure plus ou moins complexes. Note: Compiler sa map en VIS FAST ne donne absolument pas un ordre de grandeur des FPS dans la map. Compiler en FAST c'est un peu comme ne rien faire du tout.. et c'est totalement déconseillé pour une compilation finale. Compiler en FAST c'est uniquement pour faire des tests sans altérer la qualité visuelle.. (à part RAD FAST qui altère les ombres) ch4ndl3r a dit : Définition : le PVS Voici 4 images qui vous aideront probablement à encore mieux comprendre ce qu'est un visleaf. Un visleaf est une "salle imaginaire" qui est représentée par les traits rouges sur les images ci-dessous. I.3. RADLe dernier outil qui se lance lors d'une compilation normale de Hammer c'est RAD. L'ami RAD a pour rôle de générer les ombres/lumières et de finaliser la map. Je ne sais pas grand chose sur lui, mais par contre, je sais qu'il n'intervient pas énormément pour optimiser une carte. Je vous expliquerai néanmoins quelques petits trucs qui font qu'il peut être utile tout de même. Comme vous avez pu le constater j'espère, VIS constitue une part très importante dans l'optimisation d'une map. Néanmoins, on va voir ensemble que BSP et RAD ont aussi leur rôle à jouer dans l'histoire. Des rôles secondaires certes, mais souvent, les rôles secondaires sont très important également. I.4. Temps de compilationJ'entend beaucoup de personnes (et j'ai été des leurs) dire qu'une map bien optimisée ne devrait pas se compiler en plus d'une heure, ou encore que c'est RAD qui prend le plus de temps, ou même qu'une map moche ne doit pas mettre longtemps à compiler. Tout ceci est absolument faux. Le temps de compilation d'une map est quelque chose de très variable. Cela dépend de facteurs tels que :
Il est également faux de penser que RAD est le plus long ou que c'est VIS le plus long.. Plus votre map aura d'effets de lumière complexes, plus RAD mettra de temps à compiler. Plus votre map sera complexe au niveau architectural et plus VIS mettra de temps à compiler. Il n'existe pas non plus de temps de référence pour chaque type de map.. tout dépend des facteurs énoncés plus haut. dm_tropic met environ 30min à se compiler avec le HDR, dm_mine met environ 2 ou 3h tandis que dm_escape met 10h. Il n'y a pas de règle de calcul pour cela ! II. Les TechniquesPassons tout de suite au vif du sujet. L'optimisation sous Half-Life 2. Certes, il parait beaucoup plus facile de faire des cartes sous Hammer que tout autre soft orienté modélisation 3D, et c'est vrai ! Le logiciel est très simple d'utilisation, ce sont malheureusement les méthodes qui sont très complexes. Autant il est facile de mapper pour Half-Life 2, autant il est difficile de BIEN mapper pour Half-Life 2. II.1. Le découpage de la mapCe qui suit est la règle d'or du mapping sous n'importe quel moteur utilisant le système BSP/VIS. II.1.A. Utilisation de VIS uniquementImaginons que tout à coup vous ayiez envie de créer trois salles, en angle droit, à ciel ouvert et raccordées par des couloirs. Pourquoi pas après tout ? Je vais vous montrer ce qu'il ne faut absolument pas faire sous aucune forme que ce soit ! Et pourtant, Dieu sait qu'on en voit souvent des maps comme ça ! Qu'est-ce qui ne va pas vont me dire certains.. "Non mais trois claques dans ta tête, quoi !" Le plus gros problème, même énorme, qui se pose ici, c'est le ciel (lees blocs bleu-ciel). Beaucoup d'entre nous ne peuvent imaginer le ciel autrement que comme "la plus grande chose qui nous entoure" et font donc un bloc tout autour de leur map pour le représenter. Il faut arrêter de penser comme cela ! Dans la réalité, c'est peut-être ainsi, mais pas dans Half-Life 2. Dans Half-Life 2, le ciel c'est simplement un bloc avec une texture spéciale qui donne une illusion de profondeur. Il n'y a donc aucun besoin de faire un bloc réellement profond ! Et voilà le travail ! Vous n'avez rien à redire sur VIS, il a fait son travail en suivant les directives de votre map, il a découpé en suivant le contour de vos blocs et on se retrouve avec un beau merdier sans nom composé de plusieurs dizaines de vis-leafs. (a prononcer "vicelifce", j'appellerai désormais comme ça les "salles hermétiques" dont je parle) Et où sont ces vis-leafs ? A des endroits vides qu'on ne peut de toute façon même pas atteindre, c'est-à-dire hors des trois salles du départ ! Voyez vous l'intêret ? Moi non. Pourquoi VIS a-t-il découpé de cette façon ? Mais tout simplement parce que nos trois salles n'ont pas de "plafond". VIS n'est pas censé savoir que nous ne pourrons pas passer par dessus les murs et, par conséquent, il fait son boulot partout.. même là où nous n'irons pas. C'est pourquoi cette technique dite du "Skybox Géant" est à proscrire immédiatement. Les blocs avec la texture tools/toolsskybox doivent être considérés comme des murs normaux. C'est juste leur apparence qui va changer. En conlusion, il n'est pas nécessaire de faire un skybox géant autour de sa map, il suffit de "boucher" les endroits où l'on voit le ciel avec des blocs portant la texture tools/toolsskybox. Comme ceci : Le résultat est le même, sauf que l'on ne peut pas passer par dessus les murs. Mais de toute façon, on en a jamais eu envie. On se retrouve avec 5 vis-leafs au lieu d'une bonne vingtaine ! Vous comprenez maintenant pourquoi je dis qu'il faut fermer "fermétiquement" ces "salles" ? Un autre exemple serait une banale fenêtre par laquelle on aurait jamais l'occasion de passer, mais qui donnerait sur l'extérieur.. pas besoin de faire toute une salle dehors, il suffit de boucher le trou de la fenêtre : II.1.B. Utilisation de VIS et des HintsII.1.B.a. Exemple 1C'est bien joli tout ça, mais du coup j'en entend déjà dire : "Si j'ai envie de passer par au dessus des murs pour aller d'une pièce à l'autre , ça me regarde." Et j'allais bien sûr y venir, car tout n'est pas toujours aussi rose dans la vie d'un mappeur Il est vrai que l'on a le droit de vouloir laisser au joueur la possibilité de passer au dessus des murs. Dans le cas de figure précédent, il se retrouve coincé contre le bloc du ciel. Heureusement il y a un moyen de faire la même chose autrement. Explications : Prenons une autre disposition, je me suis servi de celle fournie dans le SDK : sdk_hints.vmf Les blocs colorés en rouge, vert et bleu sont les vis-leafs que VIS va découper. Le problème est le suivant : lorsque l'on se trouve dans la salle 1, on ne peut logiquement pas voir ce qui se trouve dans la salle 2 car il y a un épais mur qui sépare les deux salles. On peut apercevoir ce qui peut se trouver SUR le mur, mais pas après le mur. Or, avec ce découpage de VIS, on a un problème. Regardez bien, n'importe où que l'on se trouve dans la salle 1, que ce soit au ras du sol (point bleu) ou au ras du ciel (point jaune), on se trouve dans le même vis-leaf coloré en vert. Du coup, VIS pense que c'est possible d'être collé au ciel et, par conséquent, de voir ce qui se trouve dans la salle 2 en regardant vers le bas. C'est ici qu'interviennent les Hints. Les hints, c'est assez obscur et peu de gens arrivent à les comprendre, mais je vais tenter de vous expliquer. C'est un bloc normal qui va servir à découper les vis-leafs. En gros, on va demander à VIS d'en créer plus que la normale (ici VIS a créé 3 vis-leafs spontanément, mais vous êtes d'accord que ça ne suffit pas puisqu'il y a un problème de visibilité). Bien utilisés, les hints ajoutent des vis-leafs mais font moins ramer le jeu, tandis que mal utilisés ils en rajoutent, font encore plus ramer le jeu et allongent le temps de compilation en prime. Dans notre cas à nous, ce que lon veut, c'est découper les vis-leafs des salles 1 et 2 en deux parties. Celle ou l'on va toujours se trouver (près du sol) et celle où l'on ne va jamais aller (vers le ciel). Voyez l'exemple : Le bloc vu du dessus (skip) : Le bloc vu du dessous (hint) : Le bloc vu de côté : Le résultat sur la découpe de VIS sera alors tout simple, il va fractionner les vis-leafs 1 et 2 en deux vis-leafs distincts dans le sens de la hauteur. Du coup, depuis le vis-leaf vert, on ne pourra voir que ce qui se passe dans le rouge (qui est vide, donc peu importe) mais plus dans le bleu, celui qui nous intéresse ! Comme ceci : Les Hints sont assez tordus, et il faut beaucoup de logique et des facilités à visualiser dans l'espace pour savoir où les placer efficacement. Mais une fois que l'on y est arrivés, cela peut drastiquement améliorer les performances d'une map. Extrait d'une conversation MSN avec MoroeS : Pour en savoir plus sur les hints : II.1.B.b. Exemple 2Partons maintenant sur un autre exemple pour comprendre les hints.. Il est un peu hors-sujet dans le contexte actuel de nos salles mais il vaut toujours mieux s'assurer d'avoir compris avec un deuxième exemple. Ce coup-ci, je vais prendre le cas classique du couloir courbé reliant deux salles entre elles. Pourquoi classique ? Parce que c'est l'exemple qui est toujours utilisé dans les cours sur les hints ! Bon, jusque là j'espère que vous aurez deviné que les deux gros carrés sont deux salles et que le petit truc qui les relie est un couloir. J'espère aussi que vous avez compris que de la salle du "haut", il est relativement inutile de savoir ce qui se passe dans la salle du "bas". Si BSP fait correctement son travail de découpe, il devrait créer quelque chose dans ce genre là, 4 vis-leafs représentant les 4 parties principales de la map. Seulement voilà, quel est le problème sur la découpe du dessus ? Il est assez simple a appréhender, VIS détermine la visibilité en se basant sur le fait qu'un vis-leaf est visible ou non depuis celui dans lequel on se trouve. Actuellement, on se trouve dans le vis-leaf numéro 1 sur le schéma ci-dessus. On a donc bien sûr une vue dégagée sur le numéro 2 ET une vue partielle sur le numéro 3. Concrètement qu'est-ce que ça signifie ? Ca signifie que peu importe l'endroit où l'on se trouve dans le vis-leaf numéro 1, tout ce qui se trouve dans les vis-leafs numéro 1, 2 et 3 sera calculé. Et ce, même si vous vous trouvez au niveau du chiffre 1 sur le schéma et que vous n'avez aucune visibilité sur le vis-leaf numéro 3. C'est un premier problème.. oui un premier car ce n'est que le premier. Souvenez de ce que j'ai expliqué quand j'ai présenté VIS au début de ce tutorial, il calcule la visibilité à 2 vis-leafs de distance. Concrètement cela signifie que les vis-leafs calculés sont non seulement ceux que vous voyez, mais également ceux que vous pourriez voir si vous vous situiez dans ceux que vous pouvez voir depuis l'endroit où vous êtes actuellement. Ouais c'est un peu confu, mais avec l'exemple vous allez comprendre. Toujours sur le schéma ci-dessus, depuis le vis-leaf numéro 1 on voit donc ce qui se passe dans le 2 et 3. Le problème c'est donc que VIS décide qu'il faut calculer également les vis-leafs qu'il est possible de voir si vous vous trouviez dans le 2 ou le 3. En conclusion, comme le vis-leaf numéro 4 est visible du vis-leaf numéro 3, il sera également calculé ! Résultat, depuis la salle du "haut" le moteur calcule absolument toute la map et donc la salle du "bas" avec (même si on ne la voit pas). Il va donc falloir trouver un moyen de dire à VIS qu'il arrête son délire et qu'il ne calcule plus cette salle d'aussi loin. Et pour cela, il va falloir modifier la façon dont BSP a découpé ces maudits vis-leafs pendant la compilation. Il va falloir faire en sorte qu'il y ai plus de 2 vis-leafs de distance entre la salle du "haut" et celle du "bas". Ce genre de chose se fait au moyen de hints. La seule façon de placer le hint dans cette situation c'est de le mettre en biais dans le couloir de façon à ce que l'on ne voie même plus le deuxième morceau du couloir. Et il n'y a que cette position qui convient (en jaune sur le schéma) : De cette façon, un 5ème vis-leaf est créé. La visibilité étant toujours calculée à deux vis-leafs de distance et le vis-leaf numéro 5 pouvant voir le numéro 3, le couloir sera bien sûr toujours calculé entièrement, mais le calcul s'arrêtera là. La salle du "bas" est maintenant à 3 vis-leafs de distance et VIS la considère désormais invisible depuis l'emplacement actuel. Voici en grande partie à quoi servent les hints. II.1.B.c. Exemple 3On vient de voir un exemple avec de belles découpes de BSP sur deux salles et un couloir, où tout est rose et fleuri dans le monde de BSP et de VIS. Maintenant, il est également probable que dès le départ BSP ne comprenne rien à rien à la situation et décide d'interpréter tout ça à l'arrache comme il peut. Imaginons que BSP ai décidé de découper l'espace de la façon suivante (et ne riez pas trop, c'est exactement la façon dont il découpe sur cette map de test chez moi, comme quoi...) : Il a tout simplement considéré les salles comme faisant partie intégrante du couloir.. juste une excroissance un peu plus large. Il a donc donné la priorité au couloir au lieu de la donner aux salles. Résultat, de n'importe où dans la map tout le reste est calculé. Le vis-leaf 1 voit le 3 qui voit le 4, le 3 voit le 4 qui voit le 5 et le 6, et ainsi de suite. La seule façon de calmer les choses dans ce cas de figure c'est de se prendre pour BSP et d'imaginer la "meilleur découpe qu'il aurait dû faire". Avec des hints il est ainsi possible de rétablir l'équilibre et de réparer les ignominies de BSP. Les hints seraient à placer de cette façon (en jaune sur le schéma) : Effectivement, cela fait de plus en plus de vis-leafs pour rien.. et c'est vrai que c'est gonflant ; mais BSP est concu comme cela et on n'y peut absolument rien. Avec cette nouvelle découpe, le vis-leaf 1, 2 et 3 voient le 4 qui voit le 5, le 4 voit le 5 qui voit le 6, 7 et 8. La salle du "bas" n'est plus non plus calculée depuis la salle du "haut" et tout le monde est content.. Il y a beaucoup plus de vis-leafs, mais au moins ca fonctionne. Évidemment, tous ces exemples paraîssent un peu dérisoire vu la taille des salles et le faible niveau de complexité utilisé. Mais imaginez que ces salles soient <>10 fois plus grandes et détaillées et on obtient de l'optimisation en bonne et dûe forme ! II.1.C. Utilisation de VIS et de murs invisibles (displacements)Si basiquement, vous n'avez pas envie de vous prendre la tête avec toutes ces histoires de hints, il reste malgré tout une solution qui marche très bien. Les murs invisibles, couverts de la texture tools/toolnodraw, ils sont invisibles, et pourtant ils bloquent la visibilité, si c'est pas magnifique ça ! Prenons une fois de plus un exemple. Le problème ici, c'est bien sûr que malgré le fait que l'on ne verra jamais ce qui se trouve de l'autre côté de ce mur (il est trop haut), tout y sera quand même calculé pour la raison au dessus.. (VIS voit à travers les displacements) L'astuce est donc de remodéliser ce mur avec un autre bloc qui sera lui traité par BSP mais qui sera invisible (et solide). La texture tools/toolnodraw est donc tout à fait adaptée ! Faites un bloc de cette manière en plein milieu de ce fichu mur de roche : De cette façon, la salle sera coupée en deux salles distinctes et BSP pourra faire son travail tout en ignorant toujours notre mur de roche. Lorsqu'il se heurtera au mur en nodraw, il considèrera que les limites de la salle se situent ici, et ignorera donc tout ce qui se trouve de l'autre côté ! Je veux bien vous accorder le fait que cela va empêcher vos grenades de passer de l'autre côté, mais on ne peut pas tout avoir en optimisation quand on utilise les méthodes du pauvre. Si maintenant vous vous décidez finalement à utiliser les hints, alors je vais vous montrer comment faire tout en gardant l'utilisation du bloc nodraw. Disons que, finalement, ça vous plairait bien que les grenades passent au dessus du mur. En gardant en mémoire que VIS voit à travers les displacements, il nous faut donc quelque chose à substituer à ce mur invisible pour empêcher tout ce qui est de l'autre côté d'apparaître. On va donc laisser le mur en nodraw, mais à l'intérieur du bloc displacé uniquement, comme ceci : On se met alors dans la peau de BSP, et on décoche dans les visgroups (sur le côté droit de Hammer) le groupe "Displacements" afin de voir uniquement ce que BSP voit. : On se retrouve alors tout "bêtement" dans le cas exposé au II.1.B (deux salles séparées par un mur mitoyen) et il nous suffit de disposer un hint sur le haut de ce mur et couvrant toute la salle, pour empêcher d'afficher ce qui se trouve de l'autre côté du mur. On obtient finalement le résultat suivant et notre optimisation est terminée : Pour en savoir plus sur la façon de construire sa map : II.1.D. Voir avec les yeux du compilateurDans le paragraphe précédent, j'ai rapidement abordé le fait que BSP et VIS ne voyaient pas le map de la même façon que nous, mais je ne me suis pas plus étendu sur le sujet que cela.. or, il me semble que c'est une chose très importante, et encore plus importante depuis que Hammer a été mis à jour afin de créer automatiquement des visgroups assez performants. J'ai donc décidé de m'attarder un peu plus là-dessus car c'est tout de même une "technique" que j'utilise relativement souvent lorsque je créé des maps. Les autovisgroups c'est simplement une façon de mieux s'y retrouver dans sa map quand cela commence à devenir un peu fouilli.. Lorsque vous construisez votre map, vous avez la possibilité de créer des groupes en selectionnant plusieurs objets et en les groupant. Et bien sachez qu'à côté de cela, Hammer créé lui même automatiquement des groupes très utiles au mappeur. Il rassemble lui même tout ce qui se ressemble afin de pouvoir les cacher/montrer à volonté. Il créé un groupe pour les props, un groupe pour les displacements, un groupe pour les func_detail, et ainsi de suite... Tout se retrouve bien organisé et cela va nous permettre de voir la map de la même façon que le compilateur. Prenons pour l'exemple un morceau d'une de mes maps, un petit village paisible. Voici comment vous voyez la map dans Hammer : Waaah, c'est joli () mais par contre ce n'est absolument pas comme ça que le compilateur voit la map.. Faisons une petite liste de ce que le compilateur (BSP+VIS) ne voit pas. BSP et VIS ne voient pas :
On va donc tout simplement aller dans le petit menu des autovisgroups et décocher tout ce qui nous intéresse pas, en premier lieu tous les props, puis les func_detail, puis les displacements, et toutes les entités : Il ne reste qu'à rajouter les hints et nous avons enfin une vision à peu près correcte de ce que voit vraiment le compilateur lorsqu'il traite la map. De là, il vous est beaucoup plus facile de voir où il risque d'y avoir des découpes, quels objets feraient mieux d'être mis en func_detail, quels autres ont besoin de hints, et ainsi de suite..
C'est une "technique" que j'utilise très souvent pour voir ce qui risque ou non de poser problème au compilateur. Sachez également que lorsque vous compilez en expert, une option -glview peut être ajoutée à BSP afin qu'il génère automatiquement une représentation de la map telle qu'il la voit, sous forme d'un petit fichier d'informations 3D lisibles avec glview.exe (fourni avec le SDK dans ..\sourcesdk\bin) Pour en savoir plus sur glview : II.2. L'économie de facesDans cette partie, nous allons parler d'optimisations uniquement liées à BSP. Il faut savoir quelques trucs avant de commencer, notamment que BSP effectue plusieurs tâches lors de la compilation, vous pouvez d'ailleurs les voir passer lors de sa compilation qui ne dure que quelques secondes grâce au fait que sa fonction est très primitive, transformer toute l'architecture Hammer en ensemble de triangles MAIS avec quelques options. Je vais vous expliquer quelques optimisations possibles par BSP. II.2.A. Les cylindres & archesJe vous rassure, je ne vais pas faire de roman sur les cylindres et les arches dans Half-Life 2, mais il y a néanmoins quelques petites choses à savoir notamment au niveau du nombre de faces ! (n'est-ce pas moroes :D) Faites donc un pilier dans une salle et compilez le tout.. Voilà la découpe de BSP pour former les vis-leaf. C'est exactement la même chose qu'en creusant avec un cylindre, quel merdier, un vis-leaf par face.. et évidemment, plus il y a de faces, et non seulement plus il y a de calculs à faire pour les afficher, mais en plus il y a également des calculs en plus pour VIS par la suite. Les cylindres ont la vie dure. Le problème est le même pour les arches, on a tendance, en vue de faire quelque chose le plus rond et beau possible, d'abuser sur le nombre de faces. Une arche à plus de 16 faces m'est personnellement inconnue, et je fais rarement d'arches/cylindres à plus de 10 ou 12 faces. Prenons l'exemple ci-dessous : Evidemment, l'arche la plus parfaite visuellement est celle le plus à gauche, mais est-ce vraiment voyant à ce point ? L'arche de droite me semble personnellement tout à fait acceptable non ? On compare une arche à 10 faces, avec une 8 faces, et une 6 faces. Il est tout à fait possible d'utiliser l'arche du milieu, mais 8 faces pour cela me semble déjà beaucoup. (pour une map multijoueurs tout du moins) Alors ne parlons pas d'une 10 faces ! Il faut savoir être avare en faces, et ne pas toujours privilégier la qualité visuelle aux performances. Vous pouvez également jouer avec les textures, une texture arrondie "lissera" l'arche par exemple. Et si par hasard l'arche est dans la pénombre, cela se verra moins. Pourquoi ne pas opter pour des arches/cylindres à moins de faces lorsqu'il fait sombre et à plus de faces lorsqu'il fait clair ? Cela serait déjà un bon commencement :) II.2.B. La fonction Carve et HollowII.2.B.a. CarveDirectement tiré de mon tutorial sur ce même sujet... Avec Carve : Comme vous pouvez le voir, j'espère, il y a un bloc de trop.. un des deux sités au dessus des portes.. C'est là qu'intervient l'outil "Clip" : Au lieu d'utiliser "Carve", utilisez "Clip" comme ceci : 1. Selectionnez le bloc à découper 2. Activez l'outil "Clip" 3. Dessinez une ligne sur le bloc selectionné, elle represente la ligne selon laquelle le bloc va être découpé. (on ne peut découper que sur 2 dimensions, donc selon un plan sur l'axe des x, des y ou des z) 4. En recliquant sur l'outil, vous activez plusieurs modes. Le premier mode découpe le bloc et supprime le deuxième morceau, le 2ème mode découpe le bloc et supprime le premier morceau et le 3ème bloc découpe uniquement. C'est ce mode qui nous intéresse. 5. Lorsque vous aurez la découpe voulue, appuyez sur Entrée, et le bloc est découpé. 6. Répêtez l'action autant de fois que nécessaire pour former le trou voulu.
7. Votre découpe est terminée ! Il ne vous reste plus qu'à supprimer le bloc bouchant ce trou pour qu'il soit opérationnel. Dans notre cas du début, on obtient facilement ceci : Il y a donc un bloc de moins, et il est beaucoup plus facile de retoucher ce mur après la découpe. Voyez le résultat avec l'outil Carve (à gauche) et avec l'outil Clip (à droite) :
Et imaginez ensuite qu'on veuille faire deux trous circulaires l'un a côté de l'autre. Voyez le résultat avec l'outil Carve : Voyez le résultat avec l'outil Clip: Il devient donc évident que l'outil Carve est une horreur dans la plupart des cas, voire tous les cas, et son utilisation est à bannir pour toute map qui se veut optimisée. Essayez donc un peu de changer la taille du mur creusé avec des cylindres.. Avec ma méthode il vous suffit d'agrandir les 4 blocs autour pour agrandir le mur sans toucher au trou. Vous pouvez même déplacer librement le trou lui-même si ça vous chante... ganondorf150 a dit : II.2.B.b. HollowSelon certaines personnes, l'utilisation de la fonction Hollow serait déconseillée. Je ne sais pas vraiment pourquoi, mais il est vrai que pour des blocs autres que des blocs rectangulaires, c'est absolument proscrit ! Cela fait un bordel inimaginable de faces et de blocs irréguliers.. Regardez le résultat d'un Hollow sur un cône : Zorg045 a dit : miliciste a dit : Il n'y a pas énormément de choses à dire sur la fonction Hollow, je conseille à tout le monde de plutôt construire ses salles bloc par bloc et ses canalisations, puits, galeries et autres endroits creux également. De même, n'essayez pas de "Hollower" des cylindres, il vous suffit de faire une arche de la même taille et de boucher chaque extrémité avec un bloc.. II.2.C. Les func_detailUn autre fondement de l'optimisation des maps est l'entité func_detail ! Et encore, si ce n'était qu'un fondement.. c'est la base même de l'optimisation sour le moteur d'Half-Life 2. C'est la technique la plus puissante, la plus utilisée et par chance, la plus facile à mettre en oeuvre.
Prenons une petite carte et mettons y quelques détails (poutres, piliers, cloisons, étagères, ...) pour voir ce qu'il se passe lorsque l'on arrive dans le jeu. Voici ce que cela donne dans Hammer : Mais voilà ce que ça donne dans le jeu une fois la map compilée : Comme vous pouvez le constater, il y a énormément de faces créées automatiquement autour des formes complexes qui constituent les détails. Je ne vous exliquerai pas pourquoi (ça prendrait un certain temps, sachez juste que BSP, pendant la compilation, fusionne les blocs qui se touchent). Il faut savoir que n'importe quel volume qui touche une surface génère un nombre de faces supplémentaires égal au nombre de côtés du volume qui touchent la surface. Le cylindre est donc le pire des cas car un cylindre de 12 faces touchant un plafond et un sol va générer 24 faces inutiles, 12 sur chacun des deux blocs. Et pour peu qu'il y ai plusieurs de ces cylindres, cela devient vite cataclysmique car les faces s'entre-découpent.. Pour éviter ce genre de désagréments, transformez un par un tout les blocs qui forment les détails en func_detail et voici le résultat obtenu dans le jeu : Alors certes, sur une petite map peu détaillée comme ça, les FPS ne changent pas.. mais imaginez sur une vraie map.. Imaginez bien que l'on vient d'économiser les deux tiers des faces sur cet exemple. Economiser deux tiers de polygones à afficher n'est en général pas de refus... Pour plus de commodité avec les func_detail, je vous conseille de régler, dans les options de Hammer, l'entité bloc par défaut sur func_detail. (Tools > Options > Default SolidEntity Class) Ainsi vous n'aurez qu'a faire CTRL+T ou "Tie To Entity" en selectionnant vos objets pour les tranformer en func_detail (cela va ainsi beaucoup plus vite). Vous vous demandez peut-être comment j'ai fait pour avoir cette vue avec des traits verts pour délimiter les polygones.. C'est très simple, pour repérer ces endroits anormaux où trop de faces apparaissent, activez la console de Half-Life 2 et tapez y "mat_wireframe 3". Pour cela, je pense que le mode développeur (developer 1) ou le mode de triche (sv_cheats 1) devront être activés. Alucard_DH a dit : Gardez en mémoire également qu'il ne faut pas trop abuser des func_detail, l'optimisation a ses limites et un abus de func_detail peut entraîner une détérioration drastique des performances. Regardez les cartes fournies avec le SDK pour savoir à peu près combien et où en utiliser. Néanmoins, je n'ai jamais eu de problème en transformant à peu près tout ce qui dépasse des murs et du sol sur mes maps. Usez-donc en et même abusez-donc en. Pour en savoir plus : II.2.D. La texture NodrawLe premier conseil que je tiendrais à donner à n'importe qui faisant des cartes est le plus simple : Toujours utiliser la texture tools/toolsnodraw lors de la création d'un objet. Toujours, toujours ! Cette texture spéciale permet de ne pas tenir compte lors de la compilation des faces sur lesquelles elle est appliquée, tout en considérant tout de même le bloc porteur comme solide. Pourquoi faire ? Simplement parce que lorsque vous créez une salle par exemple la plupart des faces n'ont absolument pas besoin d'être affichées et calculées. Prenons un exemple simple, une salle cubique avec 4 colonnes. Commençons par faire une salle, un pavé sur lequel on va appliquer l'outil Hollow. (c'est un pavé, hollow n'est donc pas un problème pour moi) Comme vous pouvez le voir, il y a un problème. (ah bon, vous ne le voyez pas ?) Si jamais vous n'utilisez pas la texture tool/toolnodraw il va y avoir des faces dessinées pour rien. Regardez, vous allez voir que toutes les faces colorées en rouge/orange n'ont aucun besoin d'être dessinées : Elles n'ont pas besoin d'être calculées soit parce qu'elles sont cachées darrière un autre bloc comme le plafond pour les faces du dessus ou un autre mur pour celles sur les tranches, mais aussi parce qu'on ne pourra pas voir cette salle de l'extérieur, donc pas besoin de dessiner les faces sur l'extérieur. Ca ne semble pas grand chose, mais l'on économise tout de même beaucoup de faces par cette méthode. Au lieu de 36 faces, le moteur n'en calcule plus que 6, les 6 que le joueur voit, les 4 murs, le sol et le plafond. Toujours pas convaincu(e) ? Alors regardez ce qui se passe lorsque je selectionne toutes les faces ayant la texture nodraw sur une de mes cartes : Ca vous parrait toujours aussi peu ? Sachant qu'il y a 18346 faces au total sur cette carte, on économise au moteur du jeu le calcul de 41% de ces faces, ce qui est énorme ! Il y a comme ça beaucoup de faces qu'il n'est pas nécessaire de calculer, voyez cette dernière image : Le dessus et le dessous des murs et des colonnes étant collés au sol et au plafond, il n'est pas nécessaire non plus de les faire calculer par le moteur. Voici ce que je pouvais dire sur la texture tools/toolnodraw, très très importante dans le mapping Source.
Le plus simple à faire pour ne pas trop vous embêter avec le nodraw c'est de créer tous vos nouveaux blocs avec cette texture puis ne texturer que les faces que le joueur pourra voir. Lorsque vous copiez un bloc déjà existant, retexturez-le en nodraw avant de changer ses textures afin d'être sûr de ne pas générer de faces inutiles. II.2.E. Le texturage en généralIl y a quelque chose de très logique dans le texturage, et dont presque personne ne se rend compte : l'alignement des textures c'est super super important. Imaginez que vous ayez construit un mur à partir de 4 blocs collés les uns aux autres. Ne me demandez pas où est l'intérêt, c'est juste pour vous expliquer. Voici notre mur, à chaque trait blanc correspond le bord d'un des blocs. Pour bien vous montrer, j'ai selectionné l'un d'entre eux : Maintenant, démolissons le bel alignement des textures que j'ai réalisé. C'est exactement ce qui se passe par exemple lorsque vous déplacez des blocs avec l'option Texture Lock > désactivée ! J'ai fait en sorte que les 4 textures ne soient plus du tout alignées les unes aux autres : Evidemment, ce qui était prévisible se produit, nous avons un mur composé de 4 blocs distincts. 8 triangles en facade. Mais imaginons maintenant que notre but était justement l'inverse. Un mur qui serait composé de 4 blocs mais qui, à première vue, ressemblerait à un seul bloc. Alors pourquoi avoir 4 faces différentes en facade alors qu'au fond le bloc ne ressemble qu'a une seule ? C'est exactement ce que j'essaie de vous faire comprendre. Aligner les textures TOUT LE TEMPS permet d'éviter ces désagréments, car afficher une texture alignée a côté d'une texture non alignée, c'est comme afficher une texture à côté d'une autre différente, et donc afficher une face à côté d'une autre. Tandis que si la texture est la même et qu'elle est alignée sur toutes les faces qui sont côte à côte, BSP va considérer toutes les faces comme "fusionnables" et va donc les rassembler pour n'en faire plus qu'une seule. Ci-dessous exactement le même mur composé de 4 blocs mais dont les 4 faces ont été fusionnées car la texture est alignée : Gain de faces, gain de calcul, gain de FPS. C'est tout simple, il faut absolument aligner vos textures. Le conseil du fûté : Autre petit détail vis-à-vis des textures c'est qu'à chaque fois qu'une texture "se repête" une nouvelle face est créée.. Je m'explique : si vous avez un mur de 1024 unités de long et 256 unités de haut et que vous apposez dessus une texture de 256x256 pixels, le mur sera découpé en 4 faces distinctes. Simplement parce qu'à chaque fois qu'on arrive au moment ou la texture se repête une nouvelle fois sur la même face, il faut une découpe.. II.2.F. La grille de HammerJe vais juste vous faire un petit speech sur la grille de Hammer. Juste pour vous dire que s'il y a une grille dans Hammer, ce n'est pas pour rien Je vois plein de mappeurs qui mappent sans la grille et je peux vous dire que ce n'est pas du tout du tout une bonne idée. Premièrement, il est tout à fait conseillé de garder cette grille pour aligner PARFAITEMENT chaque bloc avec chaque autre bloc. J'ai déjà vu plein de maps où tous les blocs étaient décalés d'une ou deux unités, enchevetrés les uns dans les autres, laissant des espaces entre chaque... l'anarchie pour une map Half-Life 2. Voici un exemple de décalage de moins d'un dixième d'unité qui suffit amplement à fausser les calculs de VIS : Sachez bien que lors de la compilation, VIS se contre-fout de savoir si, oui ou non, vous vouliez vraiment mettre des espaces entre vos blocs et s'il en trouve, il considèrera que votre salle se poursuit dans cet espace de quelques pixels, et adieu l'optimisation. Le pire ennemi du mappeur c'est le manque de précision.. le manque de rigueur dans la disposition des blocs.. l'envie de tout faire "comme ça vient" sans réfléchir à un "plan de construction" quelconque.. Autre chose, sachez que, quoi qu'il arrive, BSP va découper tous vos blocs toutes les 1024 unités. Peu importe si c'est au beau milieu d'un truc super détaillé, tout sera sauvagement découpé en suivant les lignes vertes (et les deux lignes bleues) de la grille de Hammer. C'est également pour cela qu'il est important d'afficher la grille, car construire un morceau d'architecture fort détaillé sur une telle ligne risque de doubler le nombre de faces.. et ça, c'est pas vraiment compatible avec l'optimisation. Regardez le travail : Faites donc bien attention à ces petits détails qui gachent la vie. II.3. Limiter la visibilitéPlutôt que directement simplifier la géométrie, il est également possible de tout simplement la cacher, quand on le désire. Evidemment, ça n'est pas toujours possible habilement, c'est pour cela qu'il vaut mieux appliquer un peu toutes les différentes méthodes. De mon côté, les méthodes suivantes fonctionnent plutôt bien. Nous allons parler de func_occluder, qui cache les props ; de func_areaportal et de func_areaportalwindow, qui cachent les props et les brushes.. etc.. II.3.A. Les func_occludersDirectement en relation avec la visibilité des props (prop_static, prop_physics, etc... aussi appelés models), voici venir les func_occluder. Les occluders sont des blocs qui permettent de contrôler la visibilité derrière eux. Ils ne jouent que sur l'apparition et la disparition des Props ne peuvent pas se situer en dehors du monde mais ont l'avantage de pouvoir être activés/désactivés durant une partie. Les func_occluder sont créés avec un brush de type block. Il doivent avoir la texture tools/toolsoccluder uniquement sur les faces qui doivent cacher les props et la texture tools/toolsnodraw sur celles qui n'ont aucun effet. Si des blocs possèdent cette texture sans être des func_occluder, cela dégradera les performances. Note: Trop d'occluders tue les occluders. Chaque func_occluder doit être placé de façon à cacher suffisemment de models. S'il s'avèrait qu'ils empêchent un grand nombre de props d'être affichés, alors ils amélioreraient les performances. Sinon, ils pourraient s'avérer plus gourmants en ressources que d'afficher tout simplement les props. Pour savoir si vos occluders sont utiles, affichez les FPS depuis la console (cl_showfps 2) et comparez la vitesse d'affichage avant et après avoir tapé r_occlusion 0 dans la console. Ceci désactive les occluders. (tapez "r_occlusion 1" pour les réactiver) Sur cette image, l'occluder permet de cacher tout le mobilier de la salle située derrière les deux portes. Lorsque les portes s'ouvrent, l'occluder est désactivé (par un output de la porte OnOpen > mon_occluder > Disable) et réactivé lorsque la porte se referme. (OnFullyClosed > mon_occluder > Enable). Un autre exemple, prenons la map dod_campazzo (magnifique map réalisée par MoroeS) dont je me suis chargé de l'optimisation (comme j'ai pu). La structure de la map fait qu'il est très compliqué d'utiliser les techniques conventionnelles (hints et découpage propre des leafs). J'ai alors allégé l'affichage de la map grâce à des func_occluder placés dans des endroits "stratégiques" de la map. Des endroits où il n'est pas vraiment possible de cacher la visibilité efficacement et où des dizaines de prop_static étaient affichés alors que non-visibles. C'est le cas des maisons qui bordent les rues. Il est très difficile de forcer VIS à ne pas calculer ce qui se trouve dans la rue suivant le coin d'un bâtiment, surtout quand les bâtiments en question sont de forme diverses et variées. J'ai alors "rusé" en plaçant des func_occluder à l'intérieur des bâtiments qu'il n'est pas possible de visiter. De cette façon, tout les models qui se trouvent derrière le bâtiment ne sont plus affichés. Et voici quel est le gain une fois dans le jeu. Tous les props dont le contour est affiché en vert ont été cachés par l'occluder.. ce qui en fait un certain nombre, comme vous pouvez le constater sur l'image suivante (le gain de performance est d'environ 10 FPS à cet endroit) : En règle générale, les occluders sont très utiles couplés à un mur en displacement, un mur partiellement détruit, ou à tout autre obstacle qui bloque partiellement la visibilité. Notez également qu'ils peuvent être également placés dans un sol ou/et un plafond d'un bâtiment de plusieurs étages pour cacher les models situés à l'étage du dessous/dessus, s'il s'averait que VIS ne s'en charge pas tout seul. Pour en savoir plus sur les occluders : II.3.B. Les func_areaportalLorsque vous construisez votre map, comme nous l'avons vu un peu plus avant, VIS découpe tout en vis-leafs pour calculer quelle pièce est visible d'un endroit à un autre. Le problème c'est que vous n'êtes pas sans savoir que tout ceci est très approximatif et que, par exemple, une toute petite ouverture donnant sur un extérieur giganstesque aura pour effet de faire calculer au moteur tout l'extérieur visible depuis la pièce courante.. autant dire, tout. Vous n'êtes pas non plus sans savoir que les portes par exemples ne sont pas considérées comme des solides par VIS mais comme des entités (logique me direz-vous). Ce qui fait qu'en vous trouvant devant une porte fermée, tout ce qui se trouve derrière est calculé quand même.. quel malheur. II.3.B.a Avec l'aide d'une porteEt bien, dites "Hourra" pour les func_areaportal car non seulement il vont résoudre le premier problème, mais également le second dans la foulée. Vous allez voir, en plus c'est super simple à mettre en oeuvre. J'ai repris notre jolie map du début, avec ces fameuses trois salles qui se suivent en "L" avec notre super ciel en guise de plafond. J'ai rajouté une porte pour séparer une salle d'une autre et j'ai fourré plein de models dans la deuxième salle pour tester. Lorsque le jeu s'est lancé, VIS a considéré que la porte n'existait pas, et donc, tout ce qui se trouvait derrière la porte fermée était calculé. Et c'est là que les func_areaportal sont super astucieux. En gros, un func_areaportal peut être utilisé de deux façons différentes. Avec la première, il doit toujours être couplé à une porte, doit faire la même taille qu'elle (conseillé) et avoir dans ses propriétés le champ Name of Linked Door contenant le nom de la porte. En fait, c'est une sorte de trigger qui va permettre deux choses très puissantes :
Je sais très bien que vu comme ça, ça n'est pas très parlant, alors je n'ai pas bien sûr pas oublié les petits screenshots qui vont avec : La porte et son func_areaportal de la même taille Le résultat quand la porte est fermée Et quand la porte est ouverte Et enfin quand on regarde seulement par un bout de l'ouverture II.3.B.b Sans l'aide d'une porteLa deuxième méthode, figurez-vous que c'est exactement la même, mais sans la porte. Comment ça ? Ben facile, mettez le même func_areaportal, ne mettez rien dans Name of Linked Door et positionnez Initial State sur Open, et la magie opère. Cela fait le même effet que s'il y avait une porte, mais tout le temps ouverte. Exactement la même chose que sur le quatrième screen ci-dessus. C'est très utile à placer par exemple au bout d'un couloir qui donne sur un grand espace. Sur l'image qui suit, on voit très bien comment cela fonctionne. Les deux traits blancs montrent le champ de vision du joueur (en bleu) à travers l'areaportal. Tout ce qui se situe dans le triangle bleu sera calculé car directement visible à travers l'ouverture tandis que tout le reste sera ignoré car hors de l'areaportal et situé derrière un mur.. II.3.B.c areaportal brush doesn't touch two areasIl existe évidemment des restictions à l'utilisation des func_areaportal, notamment le fait qu'ils doivent impérativement séparer 2 endroits clos. Pas 1, ni 3, ni 4, mais 2. De plus, ils ne sont pas transparents comme les hints qui sont traités une fois pendant la compilation et basta. Ils nécessitent des calculs de visibilité constants une fois dans le jeu. Heureusement, bien utilisés, ils sont beaucoup plus bénéfiques que le temps nécessaire à les calculer. Si par malheur vous n'aviez pas placé correctement vos func_areaportal, vous auriez un message d'erreur à la compilation ressemblant à quelque chose comme : Avec les func_areaportal, le truc c'est de faire en sorte que chaque côté de l'areaportal scelle des espaces clos.. hermétiques.. Explication avec des petits schémas. Sur le schéma suivant, on peut voir qu'il est possible de passer plusieurs fois par l'areaportal, dans le même sens.. Donc, chaque côté de l'areaportal n'est en fait composé que d'un seul espace clos. C'est contraire à l'esprit "areaportal". Sur ce deuxième schéma, nous sommes exactement dans le même cas de figure, sauf que nous avons désormais deux areaportal (areaportaux ?) distincts. Ces func_areaportal étant considérés comme solides, nous nous retrouvons avec deux espaces clos de chaque côté. Désormais, il n'y a plus aucun problème, chaque areaportal ne peut être traversé dans le même sens qu'une fois à la suite. (seulement si tout est fermé hermétiquement, et que les areaportal touchent les murs et le plafond/sol hermétiquement) Evidemment, sur ce dernier schéma, tout est clos dès le départ et nous n'avons donc aucun problème. Retenez juste que, si votre niveau décrit une boucle, vous devrez forcément utiliser au moins 2 func_areaportal pour créer 2 espaces clos. Si jamais vous obtenez l'erreur * Brush X: areaportal brush doesn't touch two areas, il vous suffira de charger le Pointfile (Map > Load Pointfile) et de regarder la boucle décrite par un trait rouge. Elle va vous montrer pourquoi votre func_areaportal foire, c'est à dire qu'elle va vous décrire par quel chemin il est possible de passer plusieurs fois dans votre areaportal dans le même sens.. Enfin, il existe une dernière solution à ce problème : vous avez mis un func_areaportal dans l'eau.. Oui je sais, c'est débile, mais on ne peut pas mettre d'areaportal qui traverse la surface d'un plan d'eau. Il faut alors le découper en deux areaportal distincts.. La partie au dessus de l'eau, et la partie au dessous de l'eau.. Sans ça, vous aurez des reflets très.. étranges.. à la surface de votre eau. II.3.B.d Mise en gardeTiré du site www.planetquake.com : "En utilisant les techniques d'optimisation dites "normales" de VIS, tout ce qui est dessiné à un moment et à un endroit précis est déjà connu par avance par le moteur. C'est une gestion statique. Avec les areaportals, le moteur doit calculer en temps réel quoi dessiner depuis chaque position du joueur à chaque fois qu'il croise la vue d'un func_areaportal. Quand vous avez plusieurs de ces areaportals, le moteur doit calculer encore plus dur pour afficher ce qu'il faut. Pour ceux qui sont assez logiques, le nombre de modes d'affichage différent est 2N où N est le nombre d'areaportals en vue. Donc, si une pièce possède 2 areaportals, cela fait 4 options différentes, et avec 4 areaportals cela fait 16... Comme vous pouvez le voir, cela devient vite très goumand en calculs pour le moteur dès qu'il commence à y avoir beaucoup d'areaportals. Dans nos tests, nous avons remarqué une augmentation notable de la charge du processeur du serveur sur les maps utilisant des func_areaportal. Nous avons également remarqué une perte de fluidité qui semble devenir de pire en pire avec plus de joueurs et avec la durée durant laquelle la carte est jouée. En imaginant ce que le serveur a à gérer, c'est tout à fait compréhensible.." [imaginez 16 joueurs dans une salle avec 4 areaportals.. ça fait 16x24 champs de visions à calculer.. soit 256 !] Autrement dit, lorsque vous êtes sur votre map solo avec vos 15 areaportals dans la même pièce (un à chaque fenêtre de maison, comme dans les maps "coast") c'est votre ordinateur qui supporte les calculs.. bien sûr pour lui il n'y a rien de plus simple.. et encore, parfois il a déjà du mal à s'en sortir. Alors maintenant, imaginez que votre PC doive gérer 8 fois Half-Life 2 en même temps ! Je ne pense pas qu'il aimerait trop, et bien c'est exactement la même chose pour le serveur qui hebergera votre map si elle est multijoueurs. Tidjey à dit : II.3.B.e Quelques commandesPour tester vos areaportal il y a plusieurs commandes console qui peuvent s'avérer très utiles (surtout en conjonction avec la commande mat_wireframe sinon ça n'a aucun interêt)
Pour en savoir plus sur les areaportal : II.3.C. Les func_areaportalwindowDans le même esprit que les func_areaportal voici les func_areaportalwindow. Le nom semble le même, mais l'utilisation est tout autre ! Voici l'idée. Imaginez que vous avez une salle avec des fenêtres donnant sur l'extérieur. Cet extérieur est assez lumineux vis-à-vis de l'intérieur de votre salle. Ce qui semblerait donc logique serait que ces fenêtres vous éblouissent.. facile a faire avec des env_lightglow.. mais tant qu'à faire, pourquoi ne pas faire également que, puisque vous êtes ébloui, ce qui est dehors ne soit pas dessiné ? Voilà un des intérêts de nos func_areaportalwindow. Tout comme les func_areaportal, ces derniers ont besoin d'un autre bloc pour fonctionner. Ce coup-ci, c'est d'un func_brush, bloc qui va servir de mur séparatoire. Le principe, c'est de faire apparaître/disparaître progressivement un mur selon la distance à laquelle le joueur se trouve. dans notre cas, nous avons tout intérêt à faire apparaître un mur blanc, blanc comme la lumière éblouissante. Evidemment, si dehors il fait nuit, on ne va pas faire apparaître un mur blanc.. mais un mur noir.. Nous allons donc créer un bloc de la taille de l'ouverture avec la texture qui nous intéresse puis le transformer en func_brush. Appliquez ensuite les options suivantes :
La deuxième étape, c'est de créer le bloc de la même taille qui va correspondre à notre func_areaportalwindow, faites donc déjà cela et mettre lui les propriétés suivantes :
Et voilà, vous aurez une fenêtre où, de loin, on verra un carré blanc éclatant et rien ne sera dessiné derrière, et plus vous vous en approcherez, plus le bloc blanc deviendra transparent et ce qui est derrière apparaîtra au fur et à mesure. Vous savez, c'est le même effet que dans Half-Life 2 sur la côte avec le buggy, dans on entre et sort des tunnels. Voilà comment optimiser un peu plus vos maps. Quelques images pour vous expliquer tout cela ? L'ouverture vue de loin. Un mur et rien de dessiné derrière Vue de plus près. Un mur translucide ou tout réapparaît derrière Vue de tout pret, l'ouverture est transparente II.4. D'autres techniquesImpossibles à classer dans une catégorie précise, il existe de nombreuses autres petites techniques qui peuvent ajouter de petites touches d'optimisation à vos maps. Certes, elles ne feront pas tout, mais un petit plus est toujours le bienvenu dans la course aux FPS ! Voici donc quelques unes des techniques que je connais : II.4.A. Les func_lodDans la même lignée de les func_detail, il y a également les func_lod. D'une certaine manière, c'est la même chose mais en version entité (donc ignoré par BSP) et dôté d'un système de disparition au bout d'une certaine distance. Ceci peut être à appliqué à n'importe quel bloc d'architecture de Hammer. Un comptoir, une torche, une grille ou autre petit objet créé à partir de brushes est un bon candidat pour devenir un func_lod. J'ai par exemple décidé de faire disparaitre les torches à l'intérieur d'un bâtiment ainsi que les bordures de fenêtres lorsque l'on est plutôt loin de celui-ci. Pensez-y, cela peut-être très salvateur. Gardez en mémoire également que, tout comme les func_detail, il ne faut pas trop abuser des func_lod. L'optimisation a ses limites et un abus de func_lod peut entraîner une détérioration drastique des performances. Regardez les cartes fournies avec le SDK pour savoir à peu près combien et où en utiliser. D'une manière générale, retenez que ce n'est pas conseillé pour l'architecture d'une map, mais plus pour de petits objets sans grande importance. II.4.B. Les PropsDepuis Half-Life 1, les petits objets comme les plus gros qui sont considérés comme plus détaillés que la normale ne sont plus composés de brushes (blocs dans Hammer : cubes, cylindres, etc.) Ce sont maintenant des modèles 3D créés depuis un autre logiciel tel que XSI, 3DSMax ou encore Maya.. Comme indiqué sur le Wiki de Valve, les Props devraient être utilisés pour les objets suivants :
Bien que tous ces objets nécessitent beaucoup moins de ressources que le reste des objets en brushes, il faut tout de même faire attention à ne pas dépasser certaines limites. On peut trouver sur les pages du VERC Collective de Valve les limites suivantes à respecter pour garder de bonnes performances :
Néanmoins, il y a des moyens d'augmenter ces limites, ou, tout du moins, d'en mettre plus que la normale sans faire pour autant ramer plus. Prenons pour cette partie une de mes cartes. Elle se déroule dans un bâtiment, mon IUT, et est composée de couloirs et de salles. Prenons pour exemple une des salles de classe et plus particulièrement, les néons au plafond : Ces néons au plafond sont fixes, ils ne peuvent pas tomber ni sortir de cette salle. Lorsque vous vous trouvez dans la salle d'à côté ou dans le couloir, il n'est absolument pas nécessaire de les afficher. Or, à cause de la largesse de VIS lors de son calcul de la découpe pour la visibilité, cela peut très bien arriver.. la salle mesure environ 280x280 et est entourée de murs et de portes donnant sur un couloir. Or, du couloir on a absolument pas besoin de voir les néons qui se trouvent dans cette salle, à part en se trouvant devant les portes. La distance maximale à laquelle on peut voir les néons du fond (fléchés) c'est le bord du couloir (fléché aussi). La distance séparant ces deux points est 340. On va alors régler plusieurs choses dans les propriétés des prop_static.
Cette méthode est assez efficace mais il en existe d'autres. Retenez juste que tout prop ne pouvant pas être atteint devrait être Non-Solide et tout prop ne se déplaçant pas devrait disparaître quand on ne le voit plus. Dans le même genre, les petits objets comme les papiers, canettes, bouteilles, etc.. devraient disparaître assez rapidement, comme à 512 unités et il n'est pas souvent nécessaire de leur faire projetter des ombres. Vous pouvez également utiliser le flag nommé Debris - don't collide with the player or other debris si c'est un petit prop_physics. Non seulement ça va éviter des calculs de collisions complexes entre ces petits objets, mais cela va également faire en sorte que le joueur passe à travers d'eux. Ce qui est plutôt pratique lorsque vous disposez des petits objets par terre, cela évite des blocages du joueur par une canette ou autres désagréments. Pour en savoir plus sur les props : II.4.C. La lightmapTiré directement du site officiel : Le moteur Source utilise des données de lightmap pour simuler la lumière et les ombres sur les brushes. L'augmentation de cette lightmap procure des ombres plus fines, mais demande plus de mémoire. La densité et la qualité de la lightmap peuvent être altérées pour améliorer les performances. Pour avoir un aperçu de la lightmap de votre carte, réglez le type de vue 3D sur 3D Lightmap Grid. Pour en savoir plus sur la lightmap : II.4.D. Les displacementsJe ne suis pas ici pour vous expliquer ce qu'est un displacement, néanmoins, je vous rapellerai certaines petites choses qu'il est bon de savoir sur eux.
Gectou4 a dit : Pour en savoir plus sur les displacements : II.4.E. Les prop_detailDe mon côté, je n'ai jamais vraiment réussi à insérer de prop_detail sur ma map, et je ne comprends pas vraiment en quoi ça consiste. Les seuls props_detail que je connaisse, sont ceux générés automatiquement par certaines textures pour former de l'herbe par exemple. Et c'est justement de ça que je comptais parler. Cette herbe, aussi sympa soit-elle, est parfois bien lourde à gérer pour le moteur. Et ce malgré le fait que ce ne soient que de vulgaires sprites dans la plupart des cas. Par exemple, la texture nature/benddirtdirt001a apposée sur un bloc qui n'est pas un displacement va générer énormément d'herbe au mètre carré. Voyez plutôt l'impact sur les FPS... (c'est compilé sans le VIS et le RAD je vous rassure) Alors certes, cela fait plutôt réaliste, mais en attendant, voyez les performances si je supprime cette herbe... (nous verrons comment la supprimer avec une commande console plus tard dans le tutorial) Comme vous pouvez le constater, il y a tout de même un bonne différence entre les deux screens. Certes, le premier est plus joli, mais le deuxième culmine à 18 FPS de plus tout de même.. Il faut donc apprendre à ne pas être trop gourmant avec l'herbe.. surtout sur de grandes étendues. Arrangez-vous pour en faire de petites taches par-ci par-là, le tout habillement maquillé derrière un peu de relief II.4.F. Les light_dynamicJe n'ai pas spécialement grand chose à dire sur les light_dynamic. Ce qu'il faut savoir, c'est que se sont des sources de lumières pour lesquelles les ombres seront calculées en temps réel, c'est à dire dans le jeu.. Ce qui signifie que cela sera particulièrement lourd à gérer pour le moteur, surtout au bout d'un certain nombre de lumières dynamiques.. J'ai d'ailleurs fait un petit test ci-dessous.. Une salle carrée, un displacement et 4 light_dynamic qui éclairent 4 NPCs (Eli, Alyx, Barney et Breen). Avec si peu de détail dans ma salle, je me retrouve a si peu de FPS : Et maintenant si j'éteint ces lumières dynamiques : Oui, 64 FPS pour afficher si peu de choses, c'est très peu. On voit bien que les light_dynamic c'est pas si terrible.. si au bout de 4 le moteur commence à flancher et perdre une quarantaine de FPS, c'est pas très recommandé niveau optimisation. Une autre chose à savoir également, et qui peut causer des ralentissements parfois incompris, c'est que les point_lightspot sont également des lumières dynamiques ! La seule chose qui diffère c'est le fait qu'avec cette entité-ci, un halo de lumière du plus bel effet est automatiquement ajouté à votre spot. Vous allez me dire, c'est dommage qu'ils n'aient pas prévu ça pour le light_spot tout bêtement.. et effectivement, c'est très idiot je trouve. Néanmoins, vous pouvez toujours coupler un point_lightspot et un light_spot puis, dans les flags du point_lightspot, cocher la case No Dynamic Light. Vous aurez ainsi uniquement ce joli halo de lumière et la lumière non dynamique du light_spot. (n'oubliez pas de régler les angles du point_lightspot similairement à ceux du light_spot ) J'ai également remarqué que faire clignoter des light ou light_spot basiques à des endroits assez complexes générait des pics d'utilisation du moteur et par conséquent, des saccades assez marquées et des chutes de FPS à chaque clignotement de la lumière. Certes, l'endroit était assez complexe, mais il n'y avait qu'une seule light aussi.. II.4.G. La texture blocklightExactement comme son nom l'indique, la texture tools/toolblocklight permet d'absorber toute lumière la touchant et l'empêche d'aller plus loin. Elle est très utile dans des situations où vous souhaitez jouer sur la lumière pour créer des effets que vous n'arrivez pas à faire naturellement. Mais elle est également très utile pour bloquer la lumière partout où elle n'est pas nécessaire. Cela évite à RAD de calculer de l'éclairage pour rien à des endroits où cela ne sert à rien.. Par exemple, vous voulez créer un trou très sombre, mettez donc un bloc texturé avec la texture tools/toolblocklight en plein milieu et la lumière n'ira jamais plus loin que ce bloc. Petit exemple du fonctionnement, placez tout simplement un bloc avec la texture blocklight dans un endroit lumineux, et voilà le résultat : Les displacements sont les meilleurs candidats pour ce type de traitement, du fait de leur propriété à laisser passer la lumière. C'est très con, mais c'est comme ça.. Pensez-y. II.4.H. L'overlap : à éviterL'overlap est tout simplement le nom anglais pour la superposition de blocs et leur inter-pénétration (ce mot vous fait rire ?). En théorie, il ne faut JAMAIS que deux blocs se retrouvent l'un dans l'autre ou que leurs faces soient superposées (quand cela arrive, on voit leur textures changer sans arrêt). L'overlap entraîne non seulement l'affiche de polygones supplémentaires et inutiles, mais peut également occasionnellement causer des problèmes dit de "Z-fighting" sur plusieurs faces dont le moteur a du mal à determiner laquelle montrer et laquelle cacher.. Ce n'est pas bien méchant à la base, mais en combinant ce problème mineur avec d'autres problèmes mineurs, on en vient à ralentir le travail de moteur du jeu, et par conséquent à perdre de précieux FPS. Voici l'aspect des overlaps dans Hammer : II.4.I. L'eau : un gouffre à FPSCe n'est un secret pour personne, l'eau sous le moteur d'Half-Life 2 est un gouffre à FPS. Non seulement elle prend énormément de temps à être affichée en temps qu'eau, mais elle prend également du temps pour dessiner ses shaders, pour dessiner ses reflets et en plus pour adapter le reste du monde à ses contours.. Autrement dit, moins il y en a, mieux c'est.
II.4.J. Start/End Fade PixelsUne technique que je n'ai remarquée qu'il y a peu en farfouillant un peu Hammer. Lorsque vous ouvrez une map et que vous allez dans Map > Map properties, vous avez deux options très pratiques dans la liste qui apparait : Start Fade Pixels et End Fade Pixels. Ces deux options servent à gérer la distance de disparition des models sur toute la map en même temps. Mais leur système diffère de celui intégré dans chaque prop de la map. En fait, ces deux options permettent de définir à partir de quelle taille un model va commencer à disparaître de l'écran. Si vous spécifiez 50 dans Start Fade Pixels et 20 dans End Fade Pixels, tous les objets de la map commenceront à disparaître à partir du moment où il feront moins de 50 pixels de diamètre à l'écran jusqu'à complètement disparaître lorsqu'ils auront atteint la taille de 20 pixels. Cela permet de faire disparaître très facilement les petits objets assez vite et les objets moyens un peu plus loin. C'est une méthode très simple pour donner un petit coup de pouce à une map qui craque un peu sous le poids des props. II.4.K. Quand tout le reste a échoué : l'env_fog_controllerQuand tout le reste de vos tests à échoué, il reste pourtant une solution. L'env_fog_controller est un entité qui permet de faire du brouillard, et qui dit brouillard dit distance de vision réduite. ça parait "dommage" d'en arriver là, mais on a parfois pas le choix.
Fog Enable : Yes Un exemple de brouillard : Toutefois, sur la capture d'écran ci-dessus, cela n'optimise en fait rien du tout, car après le brouillard, votre map ne disparait pas pour autant. Elle est simplement dans le brouillard, et même si vous ne distinguez plus les détails, ils sont quand même affichés dans le brouillard. Vous devez donc vous servir de l'option Far Z Clip Plane de cette même entité pour faire tout simplement disparaître la map à partir d'une certaine distance. En général, on l'utilise soit en intérieur, quand les espaces sont très réduits, soit en combinaison avec du brouillard visible. Toutefois, utiliser le Far Z Clip Plane sans le mettre en combinaison avec un brouillard quel qu'il soit rend assez moche car la map disparaît tout simplement après une certaine distance. Lorsque vous utilisez le Far Z Clip Plane, réglez-le sur la même distance que le "Fog End" de l'env_fog_controller. Un exemple de Far Z Clip Plane en n'utilisant pas de brouillard pour le masquer : Voici quelques commandes console permettant de manipuler le brouillard directement dans le jeu, cela permet de faire des tests facilement et sans avoir à recompiler à chaque fois votre map pour avoir le bon éclairage et le bon brouillard :
III. Comprendre une fois dans le jeuLa chose la plus utile dans ce tutorial probablement.. comment savoir, une fois dans le jeu, que vos optimisations sont utiles et même à la limite, si elles fonctionnent tout court. Voici donc tous les outils fournis par VALVe avec le moteur Source pour débugguer et développer sous Half-Life 2. III.1. Le +showbudgetShowbudget est un outil intégré au moteur Source qui permet de voir combien de temps Source passe sur chacune de ses tâches. C'est principalement un outil de détection des élements qui ralentissent trop le jeu. Ce passage traite de son usage à des fins d'optimisation. III.1.A. AccèsShowbudget est accessible depuis la console. Il n'est pas nécessaire d'activer le mode de triche pour l'utiliser. Ouvre la console et tapez : +showbudget Fermez ensuite la console. Il devrait normalement être apparu une fenêtre un peu intimidante sur votre écran, c'est le budget. Vous pouvez également taper -showbudget pour le faire disparaître. III.1.B. SignificationDans le coin en haut à droite, vous pouvez voir du texte traitant de "fps" et de "ms". Le premier nombre vous dit combien d'images par secondes sont actuellement dessinées. 60 et plus sont généralement considérés comme bon. Le second nombre est, lui, un meilleur indicateur en vous montrant combien de millisecondes (millièmes de secondes) cela prend au moteur pour dessiner une fois l'écran. Plus c'est bas, mieux c'est. Le texte apparaît en rouge lorsque Source pense que ce temps est mauvais, en jaune lorsque cela devient limite et plus trop adapté à plusieurs joueurs et en vert lorsque tout va bien. Ensuite, vous pourrez remarquer plusieurs barres de couleur dans la partie principale du graphique. Chaque barre représente combien de temps met Source pour effectuer chaque tâche. Quand ces barres sont petites (à gauche), votre ordinateur gère les choses plutôt bien. Si vous remarquez quelques barres flirtant avec la droite, c'est qu'il y a des endroits à retravailler dans votre map. Voici un résumé de ce que chaque barre signifie :
III.1.C. Assigner à une toucheSi vous avez prévu de beaucoup utiliser +showbudget, inserez ces lignes dans votre fichier config.cfg. Cela aura pour effet de réassigner la touche "J" pour afficher/cacher le budget. Vous devrez redémarrer le jeu pour que les changements prennent effet. alias showbudget_on "+showbudget; bind j showbudget_off" Vous pouvez également taper tout simplement bind j "+showbudget" dans la console pour assigner le budget à la touche "j" et faire en sorte qu'il s'affiche quand vous appuyez et disparaisse quand vous cessez d'appuyer sur la touche. III.1.D. Mise en gardeJ'ajouterais aussi qu'il faut vous méfier du showbudget et notamment des FPS qu'il affiche.. De plus, il est dit que le showbudget n'affiche réellement les bonnes valeurs que lorsque le jeu est lancé en mode plein écran et avec le moins possible d'applications tournant en arrière plan (désactivez les antivirus, antispywares, firewalls et autres bouffeurs de puissance). III.2. Les commandes consoleA côté du showbudget, il y a également pléthore de commandes console également très très utiles pour l'optimisation. En voici une liste, peut-être pas exhaustive, mais qui aura le mérite de vous présenter les plus utiles. Commandes génériques :
Commandes pour contrôler l'affichage :
Commandes pour contrôler la visibilité :
ConclusionJ'ai vraiment pas envie de faire de conclusion après avoir écrit tout ça.. mais alors, vraiment pas. Gardez également en mémoire que l'optimisation d'une map ne commence pas une fois que vous l'avez terminée, mais au contraire avant même de la commencer. Si la totalité de votre map peut être vue depuis un seul endroit, il n'y aura pas beaucoup d'optimisation possible... Essayez d'éviter les endroits très grands et très larges puisqu'il est pratiquement impossible de les optimiser. A la place, tentez de bloquer la distance de visibilité avec des immeubles, des murs, des arbres, je sais pas, peu importe.. Essayez également de construire votre map assez "labyrinthiquement" avec des angles, des couloirs qui tournent et des salles non-alignées avec les couloirs.. Un autre petite chose que je tiens à rappeler puisque vous êtes arrivés jusqu'ici. A aucun moment dans ce tuto je ne me vante de connaître tout sur l'optimisation. Au contraire, je ne connais certainement pas encore bon nombre de techniques. Celles dont j'ai la connaissance ne sont pas également forcément expliquées de la manière la plus efficace possible et il est également possible que certains d'entre vous aient une idée tout autre de telle ou telle entité. Sachez que j'ai testé plusieurs fois toutes les techniques présentes dans ce tuto, et je vous assure qu'elles fonctionnent toutes si vous faites tout dans les règles. Ne venez, s'il vous plait, pas vous plaindre parce que quelque chose ne fonctionne pas. L'erreur viendra forcément de vous. Vous pouvez néanmoins passer sur les forums de mapping-area.com et poser votre question en précisant que vous avez déjà lu ce cours. Et, une dernière chose.. il est évident que je me décharge de toute responsabilité si vous foutez en l'air votre map avec ce tuto C'est absolument pas mon problème. Quand vous comptez faire une grosse modification d'une map, gardez toujours une copie de sauvegarde sous la main. On est jamais assez loin d'une erreur. Si vous cherchez de plus amples imformations sur l'optimisation, voici quelques adresses :
http://www.mapping-area.com/forum/forum16.php En attendant, bon mapping et bonne optimisation ! Par NykO18
v1.0 (07/04/2005)
PS: Clin d'oeil à Asibasth qui a insisté pour apparaître en bas de cette page : Cette création est mise à disposition selon le Contrat Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique 2.0 France disponible en ligne http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ ou par courrier postal à Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. |
||