Aller au menu - Aller au contenu

Icône Optimisation (A : lois de HLvis)

Mise à jour : 22/07/2009
Difficulté : Facile Facile
1 414 visites depuis 7 jours, dont 6 sur ce chapitre classé 94/786
Le chapitre sur l'optimisation est découpé en 2 parties, exactement comme je l'avais fait pour la compilation : j'expliquerai dans ce chapitre comment fonctionne HLvis, puis je vous aiderai à résoudre les nombreux problèmes qu'il vous cause (r_speeds notamment).

Nous n'allons pas vraiment parler de mapping pur et dur. En réalité, on va carrément jouer sur une map, faire des constats puis en déduire le fonctionnement du compilateur HLvis (raisonnement scientifique quoi ;) )

Ce chapitre peut vous paraître simple au premier abord, mais détrompez-vous ! Il s'agit de mapping avancé et de problèmes qui touchent même les mappeurs professionnels de chez Valve !

J'ai voulu traiter le sujet différemment des autres sites afin de vous amener en douceur à comprendre un sujet complexe tel que les r_speeds (c'est un peu ça la méthode du Zér0 ;) ).
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Découpage des polygones

Lorsque vous faites une map, vous la travaillez dans un premier temps sous Worldcraft, puis vous la donnez aux compilateurs afin de pouvoir jouer dessus.

La grosse erreur serait de croire que vous êtes en train de jouer sur la même map que celle que vous avez faite sous Worldcraft...
Pardon ??? Ma map n'est plus la même lorsque j'y joue ???
En effet ! Lorsque vous l'avez donnée aux compilateurs, il ne fallait pas croire bêtement que ceux-ci allaient juste la rendre jouable sous Half-Life !
Les compilateurs ont en réalité complètement modifié votre map et elle n'est carrément plus la même...
  • Première étape : HLcsg va diviser vos blocs (appelés polygones lorsqu'on joue), pour faire en sorte que tous les blocs aient la forme la plus simple possible. Ainsi le moteur de Half-Life aura moins de mal à les interpréter, mais du coup le nombre de polygones aura été multiplié !!!
  • Deuxième étape : HLbsp va se charger de déterminer les limites de votre map (lorsqu'il y a un Leak, il n'y a plus de limites ce qui le fait planter). Tous les blocs situés en dehors de ces limites sont donc totalement supprimés dans le *.bsp !
  • Troisième étape : HLvis doit calculer la visibilité, c'est-à-dire déterminer quel polygones doivent être calculés en fonction de la position du joueur. Vous vous en doutez, c'est un très gros travail.


Ceci est juste à titre récapitulatif pour bien mettre les choses au clair.
Je ne vous parle pas de HLrad ici parce qu'il n'intervient pas beaucoup dans les problèmes d'optimisation...
Ce qui nous intéressera dans un premier temps, c'est le travail qu'a effectué HLcsg (première étape). Concrètement, quelles différences peut-on voir entre la map sous Worldcraft et celle sous Half-Life ?

Eh eh, cette différence n'est pas visible en réalité... du moins pour un oeil d'humain ! Je vais vous montrer un exemple typique du découpage des polygones...
Je crée une map toute bête : une salle avec une caisse au milieu (la caisse est un bloc et non pas une entité). Je vous conseille de faire la même chose que moi, vous allez voir c'est assez surprenant !

Voici ce que l'on devrait voir dans la vue "Camera" de Worldcraft :

Image utilisateur

Si l'on met de côté la laideur de cette salle, combien de blocs pouvez-vous y compter ?
Le sol, les 4 murs, le plafond et la caisse. On peut voir par ailleurs 2 entités : une light et un info_player_start. Le départ du joueur est tout vert parce que je fais une map pour Half-Life, mais si vous faites pareil pour Counter-Strike ne vous en faites pas, il n'y a aucune différence.
Bon, en tout on a à peu près 7 blocs.

Je compile la map avec le GUI et... zou ! Je lance Half-Life dessus.
Pour que vous puissiez effectuer les manipulations que je vais vous proposer, il faut IMPERATIVEMENT que vous lanciez votre map en mode "Solo" et non pas Multijoueurs.
Le fonctionnement reste le même dans les 2 cas, mais certaines commandes ne fonctionnent pas en mode Multijoueurs...
Voici un screenshot que j'ai pris sous Half-Life :

Image utilisateur

Apparemment, la map est strictement identique à celle de Worldcraft. Vous pouvez compter les mêmes blocs : le sol, les murs, le plafond et la caisse...

Mais êtes-vous bien sûr qu'il y a 7 polygones dans votre map ?

Pour le vérifier, nous allons activer le mode "fil de fer" de Half-Life. Il ne fonctionne qu'en mode "Solo", c'est pour cela que je vous ai demandé de lancer votre map de cette manière.

Ouvrez la console en tapant sur la touche "²", et tapez la commande suivante :

gl_wireframe 1
Cette commande ne fonctionne que si vous êtes dans une partie Solo ET que vous êtes en mode "OpenGL". Elle ne marche pas avec DirectX ! Il va donc peut-être falloir effectuer le changement dans les options de Half-Life...
Fermez la console en tapant de nouveau sur "²", et observez le résultat :

Image utilisateur

Surprenant non ?

Comme vous pouvez le voir, ce mode affiche les lignes qui séparent les polygones. Il est très facile de les compter ainsi. Amusez-vous à compter les polygones maintenant ;)
Mais pourquoi y a-t-il autant de polygones ?!
Il y a 2 raisons :
  • La caisse a découpé le sol sur lequel elle était posée. En effet, HLcsg a martyrisé votre pauvre bloc et l'a découpé en plusieurs parties (4 normalement). C'est ça le découpage des polygones !
    Quel en est l'intérêt ? C'est pour Half-Life que l'on fait ça... On doit lui simplifier au maximum les polygones, au risque d'en augmenter le nombre.

    Schématiquement, ça pourrait donner ça sur une vue de dessus :

    Image utilisateur
    La caisse (en rouge) a divisé le sol (en orange) en 4 parties. Et c'est comme ça que ça fonctionne pour tous les blocs de votre map !!!

    Je vous laisse imaginer si, à la place de la caisse, on avait mis un tonneau, ou n'importe quel objet cylindrique... Le sol aurait été découpé encore plus de fois et bien bizarrement.
    Je vous laisse retenter l'expérience avec un objet cylindrique !
  • Pour la deuxième raison, on peut se demander pourquoi le plafond a lui aussi été affecté... C'est curieux, on n'avait posé aucun objet dessus et pourtant il a été découpé !?

    L'explication tient dans les flats. Ce n'est pas évident de définir un flat. Disons à notre niveau que c'est une division d'un bloc à cause de sa texture. Oui, c'est la texture qui est en cause.
    Je vous rappelle la définition de texture ? ;) C'est une image qui est répétée en mosaïque... eh bien, à chaque fois que l'on répète la texture, un nouveau flat est créé.
    Sur le screenshot que nous avons vu, vous pouvez maintenant discerner la taille de la texture et le nombre de fois qu'on a dû la répéter en mosaïque...
    Schématiquement, ça doit donner quelque chose comme ça :

    Image utilisateur

    Chaque partie représente un flat, une répétition de la texture.

    Cela veut donc dire que si vous créez un très grand bloc, il n'y aura pas qu'un seul polygone, mais plusieurs car la texture aura été répétée de nombreuses fois !
Voilà, c'est à peu près tout ce que vous deviez savoir sur le découpage des polygones :)

Travail du moteur de Half-Life

On enchaîne maintenant avec un autre aspect de l'optimisation très très important... On va y étudier le fonctionnement du moteur de Half-Life.
Ne négligez surtout pas ce passage car vous y apprendrez des connaissances in-dis-pen-sables à la compréhension des r_speeds.

Rappelons-nous. Que fait HLvis ? Il détermine les blocs qui sont calculés ou pas par le moteur de Half-Life... C'est très important, car si vous vous trouvez à un bout de votre map, vous n'allez quand même pas devoir calculer la position des polygones situés à l'autre bout puisque vous ne les voyez pas !!!

Le travail de HLvis a pour but de dire à Half-Life : "A cet endroit, on va calculer ces polygones et pas ceux-là".
Moins on calcule de polygones, plus le calcul de l'image va vite... et donc, en jouant sur votre map on aura des fps élevées (images par seconde).
Plus les fps sont élevées, moins votre map risque de "ramer". Car c'est bien là le problème : Half-Life est un vieux jeu, mais il peut sans problème faire ramer une carte graphique récente si vous n'y prenez pas garde !
Jusque-là, tout irait bien. Sauf que, la plupart du temps, HLvis va "supposer" que le joueur peut voir certains polygones alors que ce n'est pas le cas. Half-Life va donc faire un travail inutile en calculant des blocs que l'on ne voit pas...

Et ça, c'est très agaçant pour le mappeur, même si ce mappeur est un habitué de Worldcraft. Half-Life calcule trop de polygones pour rien...

Prenons un exemple typique assez impressionnant. Dans une de mes maps, je me trouve à l'intérieur d'une maison derrière la porte d'entrée qui est fermée... Je vois ceci :

Image utilisateur

Tout simple : des murs, un plafond, des escaliers... bref, peu de blocs sont calculés à priori.

Je vais vous prouver qu'en fait, Half-Life calcule 50 fois plus de blocs que ça (et je n'exagère pas) !

Pour cela, tapez dans la console la commande suivante :

gl_wireframe 2

Je vous rappelle que cette commande ne fonctionne que si vous avez lancé votre map en mode "Solo" et que vous êtes en OpenGL...

Le mode gl_wireframe 2 est encore plus avancé que celui que nous avons étudié tout à l'heure. Il affiche non seulement tous les polygones découpés et les flats, mais aussi TOUS les polygones calculés par le moteur (on les voit par transparence).

Voici donc tous les polygones que Half-Life calculait comme un fou alors que ça ne servait à rien :

Image utilisateur

Vous avez beau vous frotter les yeux, vous verrez bien la même chose : Half-Life calculait entièrement la pièce qui se trouvait derrière la porte et qu'on ne voyait pas !
Ca fait un sacré paquet de polygones tout ça ;)
Pourquoi, mais pourquoi Half-Life fait-il tous ces calculs inutiles ?
Il anticipe. En effet, la porte que vous voyez là est susceptible de s'ouvrir à n'importe quel moment, par vous ou par un autre joueur... Half-Life se tient prêt et calcule donc déjà les polygones qui se trouvent derrière.
Et si vous avez déjà fait connaissance avec les Leaks, vous savez que Half-Life a horreur de montrer du vide au joueur (c'est le pire cauchemar du mappeur ça, lol ;) )

Contre ce problème, il existe des solutions. Certaines sont préventives (ce sont celles que je préfère), d'autres sont assez bourrines (on force Half-Life à ne pas calculer des polygones, mais alors là gare aux bêtises !).

Les portals



Un portal est une information (et une seule) que HLvis a calculée. Cette information est destinée au moteur de Half-Life et lui indique quels polygones il doit calculer à un endroit précis de la map.

C'est au départ HLbsp qui, après avoir écrit le fichier *.bsp, se charge de transmettre un fichier d'informations sur la map à HLvis pour qu'il puisse faire les calculs nécessaires dessus.
Vous devriez d'ailleurs lire la ligne suivante :

BSP generation successful, writing portal file 'c:\maps\nom_de_la_map.prt'

C'est sur ce fichier *.prt que HLvis va travailler. Il va déterminer les portails (en anglais "portals").

Prenons l'exemple de ma map que vous avez vue tout à l'heure. Il y a un portal qui dit : "SI le joueur se trouve derrière la porte d'entrée, ALORS il faut caluler tous les polygones qui se trouvent dans la pièce derrière".
Il est intéressant de noter que les blocs ne sont pas calculés s'ils sont séparés du joueur par plus d'1 portal. Les entités-blocs tel que le func_wall ne sont pas calculées si elles sont séparées par au moins 2 portals.
Cela veut dire qu'il faut éviter de mettre beaucoup de func_wall parce qu'ils sont beaucoup plus souvent calculés que les blocs normaux. On aura l'occasion de reparler de tout ça...

Les r_speeds

Pour commencer, je tiens à préciser qu'il est impératif d'avoir lu le début de ce chapitre pour comprendre les r_speeds. Sinon, vous risquez d'être complètement largués (déjà que c'est pas un chapitre évident, alors si vous sautez les étapes...).

Bien, ceci étant précisé, on va pouvoir se poser la question traditionnelle :

Beuh, c'est quoi les r_speeds ? :)
Les r_speeds sont des informations que le moteur de Half-Life vous donne en temps réel, c'est-à-dire pour chaque image calculée.
Sachant que notre ordinateur doit afficher au moins 24 images par seconde pour que ça reste fluide à nos yeux d'humains, eh bien il va être difficile de lire 24 r_speeds en une seconde ! Rassurez-vous, ça reste malgré tout très lisible parce que les informations sont quasiment les même d'une r_speed à une autre étant donné que votre ordinateur est très rapide...
Comment afficher les r_speeds ?
Si vous utilisez ZHLT Compile GUI pour compiler, les r_speeds sont déjà sur votre écran. Eh oui, ce sont les lignes qui apparaissent en haut à gauche de l'écran !

Sinon, vous devez taper cette commande dans la console :

r_speeds 1

Puis celle-ci afin que les r_speeds apparaissent en haut de l'écran :

developer 1

Voilà, les r_speeds sont là :)
Quelles informations donnent les r_speeds pour chaque image ?
Les r_speeds donnent à chaque fois 4 informations différentes par ligne :

Image utilisateur

Il y a ici 4 lignes, donc ce sont les r_speeds de 4 images calculées par le moteur de Half-Life.
On va s'intéresser à une seule image : la première ligne. Elle contient les informations suivantes :

69fps 5 ms 440 wpoly 256 epoly

Ces 4 informations sont toutes différentes, et certaines sont plus ou moins importantes. Nous allons les étudier dans l'ordre :

  • 69fps : comme nous l'avons vu plus haut, les fps (frames per second) représentent le nombre d'image par seconde qui s'affichent sur votre écran. En théorie, 24fps suffisent pour que le jeu soit fluide. On a ici 69fps, c'est donc largement plus qu'il ne nous en faudrait ;)
    Cette information dépend de la puissance de votre ordinateur. En effet, pour une même map, un ordinateur rapide aura des fps élevées alors qu'un ordinateur plus lent (de l'âge de pierre) aura des fps plutôt basses.
    Si vous voyez tout le temps 8fps sous Half-Life, alors il serait peut-être temps de changer votre ordinateur, vous ne croyez pas ? ;)
  • 5 ms : c'est le temps qu'a mis votre ordinateur pour calculer cette image. Ici, cette image a été calculée en 5 millisecondes (elle est rapide ma bécane hein ? ;) )
    Petit calcul : combien ça fait d'images par seconde si toutes les images sont calculées en 5 ms ? Ca fait 1000 ms / 5 ms = 200fps !!!

    Alors pourquoi a-t-on "seulement" 69fps au lieu de 200fps ?
    max_fps 90
    Eh bien, Half-Life limite volontairement le nombre d'images par seconde pour éviter de fatiguer votre écran, voire de le déteriorer (Valve voulait peut-être éviter des procès de fabriquants d'écran !)
    Pour info, vous pouvez augmenter la limite des fps à vos risques et périls. Servez-vous de la commande max_fps. Par exemple, si on veut limiter le nombre de fps à 90, on doit taper :

    max_fps 90

    Mais ça n'a strictement aucun intérêt ! Enfin, pour la frime peut-être... ;)
  • 440 wpoly : cette information est la plus intéressante des 4. Pourquoi ? Parce qu'elle ne dépend pas de la puissance de votre PC ! Cette valeur sera la même pour tout le monde.
    Les wpoly (World Polygons) sont le nombre de polygones que Half-Life a dû calculer pour cette image. Comme vous avez pu le constater, même pour une petite map le nombre de polygones augmente très vite ! Ici, 440 polygones ont été calculés pour cette image (c'est une valeur très correcte)...
    Il faut donc prendre en compte les polygones découpés, les flats, et les polygones que l'on ne voit pas mais que Half-Life calcule quand même !

    Comme nous l'avons vu plus haut, Half-Life sait quels polygones il doit calculer grâce aux portals. Ce sont eux qui lui indiquent s'il doit calculer tel ou tel polygone.

    Pourquoi les wpoly sont-ils aussi importants ?

    Eh bien, étant donné que cette valeur sera la même pour tous les ordinateurs, vous pouvez ici juger si votre map risque de ramer ou pas.
    Plus il y a de wpoly, plus il y a des chances que votre map commence à ramer. On dit à tort que l'on a "des r_speeds élevées" (c'est une erreur parce que ce sont seulement les wpoly qui sont élevés, mais bon que voulez-vous ;) )

    Les wpoly prennent en compte non seulement les blocs, mais aussi tout ce qui ressemble à un bloc : les entités func_wall par exemple sont elles aussi comptabilisées et contribuent à augmenter vos wpoly !

    Il y a des valeurs à ne pas dépasser. Pour une map multijoueurs (Counter-Strike par exemple), 800 wpoly c'est déjà beaucoup... mais la limite fatidique serait autour de 1000 wpoly. Si vous avez plus que ça, c'est vraiment beaucoup trop et votre map est à revoir !
    Les valeurs "idéales" se situent autour de 500 wpoly. Là, on peut se fragger en toute tranquilité :)

    Vous verrez dans le prochain chapitre comment diminuer vos wpoly, car il existe des méthodes pour "arranger" votre map.
  • 256 epoly : moins importants dans une partie multijoueurs, les epoly (Entities Polygons) représentent en fait le nombre de polygones liés aux entités (généralement des entités-point).

    Les func_wall, tout comme les func_illusionary et autres, ne sont pas comptabilisés dans les epoly, mais bel et bien dans les wpoly !!!


    Que reste-t-il alors qui apparaît dans les epoly ?
    Il s'agit des "sprites" (explosions, fumigènes...) et des "models" (armes, joueurs, ennemis...).

    Pour une map multijoueurs, ces valeurs ne sont généralement pas très élevées. C'est surtout dans les maps "Solo" que ça risque de flamber... En effet, il y a beaucoup plus de models dans ces maps, principalement à cause des ennemis !
    Il faut alors prendre en compte les wpoly ET les epoly.

    Généralement, les epoly sont beaucoup plus élevées que les wpoly. C'est tout à fait normal d'avoir plusieurs milliers de epoly : l'échelle n'est pas la même que pour les wpoly.
    En effet, les epoly sont une toute autre affaire et il y en a généralement beaucoup...

    Si vous avez des wpoly élevés, il vaut mieux faire en sorte de réduire un peu les epoly pour que votre map rame moins, et vice versa.


    Mais bon, en règle générale on retiendra que les epoly sont "moins importants" pour une map multijoueurs, mais qu'il faut commencer à les prendre en compte si on fait une map "Solo" avec des ennemis.


Voilà. Vous savez tout ce qu'il faut savoir sur les r_speeds, et je reconnais que ce n'est pas une notion évidente. Il ne tient plus qu'à vous d'y faire attention et de vous en méfier...
Dans le prochain chapitre, je vais vous aider à diminuer vos r_speeds... et ce sera assez facile car, maintenant que vous savez comment tout cela fonctionne, vous n'aurez aucun mal à comprendre les méthodes que j'emploie pour réduire les r_speeds !
Chapitre précédent Sommaire Chapitre suivant

Partager

1 commentaire pour "Optimisation (A : lois de HLvis)"
Note moyenne : 3.81 / 4 (47 votes)
Pseudo Commentaire
Hors ligne MisterJ # Posté le 28/03/2009 à 13:32:32
Le pro de l'édition de post!
Avatar

Ville : Lévis
Pays : Canada

Pour la commande gl_wireframe 2, il serait intéressant de dire pour ceux qui n'ont pas Half-Life 1 que BSPViewer peut faire le même rendu. Ouvrir la map et se rendre dans le menu Render et cochez "Edges" et "Clip Edges".

En plus on ne parle même pas des autres utilités des Hint-Skip.

Voir tous les commentaires