Empreintes et Neige

Partagez avec vos amis!

Qu'est-ce qu'on fait ?

Après la fin du développement de MathMe, nous nous sommes retrouvés dans une période de semi-vide en attendant de discuter de nos futurs projets. Nous avons profité de ce temps libre pour nous exercer dans nos domaines respectifs. Suite à quoi, de nombreux tests technologiques sont en cours de réalisation.
Ainsi, vous verrez dans les prochains temps plusieurs postes semblables à celui-ci décrivant les différentes mécaniques, techniques et idées que nous essayons de mettre en place. À l'heure actuelle, aucun de ces tests n'a de lien avec un projet concret. Cependant, ils nous permettent de nous rendre compte de ce qu'il sera possible d'implémenter comme mécaniques de gameplay dans de futurs jeux.

Abordons le coeur du sujet !

Pour ce premier test technologique, je me suis mis en tête de créer mon propre système de trace de pas. L'idée peut sembler triviale au premier abord, mais peut se révéler beaucoup plus complexe lorsque l'on souhaite obtenir quelque un rendu réaliste. En effet, au lieu de simplement dessiner une trace de pas sur une surface, j'ai utilisé différentes techniques permettant déformer des objets en 3 dimensions et ainsi recréer une véritable sensation de profondeur à chaque pas de l'avatar. L'aperçu ci-dessous vous permet d'observer le résultat atteint au moment où j'écris ce poste. Des améliorations sont à prévoir, mais j'y reviendrai un peu plus tard.

Concrètement, que se passe-t-il sur la vidéo ci-dessus ? À chaque mouvement de la balle, une empreinte est dessinée, et c'est l'accumulation de nombreuses empreintes qui permet de reproduire cet effet de "trace" au sol. Ensuite, avec le temps, le chemin tracé par la boule se comble progressivement jusqu'à disparaître totalement. Cet effet à pour but de simuler l'accumulation de la neige au fil du temps.

Et ensuite ?

Le résultat actuel est déjà fortement intéressant, mais n'est bien sûr pas parfait. En effet un certain nombre de modifications et d'optimisations sont à prévoir pour s'en servir dans un jeu vidéo.

Dans un premier temps, je souhaite ajouter, en plus d'une trace continue, un système permettant de dessiner des traces seulement à un endroit précis. De cette manière il serait possible de simuler correctement les empreintes de pas d'un humanoïde ou d'un animal. Ce deuxième mode de fonctionnement permettrait entre autres un meilleur réalisme lorsque la couche de neige n'est pas très importante et serait, en termes de calculs, plus légers et donc plus fluides. La vidéo ci-dessous permet d'illustrer le résultat souhaité.

Une limitation de mon système implique l'utilisation de surface assez restreinte comme on peut le voir sur la vidéo avec la balle rouge. On peut agrandir l'espace jouable assez simplement en rajoutant des carrés de neige supplémentaires sur les côtés. Cependant, lorsque l'on passe d'une zone à l'autre, la trace n'est pas dessinée correctement et la transition est fortement visible (voir l'image ci-dessous). Il sera donc nécessaire de corriger ce problème pour obtenir un résultat propre.

Finalement, le dernier et principal souci concerne les performances. En effet, si on ne remarque que peu de conséquences avec l'utilisation de 2 ou 3 carrés de neige, on remarque de faibles ralentissements proportionnellement au nombre de zones de neige affichées à l'écran. J'ai plusieurs idées d'optimisation en tête pour améliorer grandement la vitesse de calcul. Pour ceux que ça intéresse, je rentrerai plus dans les détails techniques dans le chapitre correspondant. Pour résumer, tant que ce point-ci ne sera pas résolu, ce système ne pourra être utilisé librement dans un projet (j'entends par librement le fait de pouvoir utiliser cette mécanique sans avoir trop de questions à se poser sur l'impact au niveau des performances).

À quoi ça va bien pouvoir servir ?

Effectivement ! C'est bien beau de faire des tests techniques, mais est-ce qu'ils sont utiles ? Est-ce que l'on va pouvoir se servir du résultat dans un futur projet ? Et si oui, comment va-t-on l'utiliser ? Une mécanique de gameplay, un effet visuel ou autre chose ?

Comme je l'ai indiqué plutôt, dans l'immédiat on ne peut se servir de ce système comme on le souhaite. Cependant on peut déjà imaginer un certain nombre d'utilisations dans des projets. Au niveau esthétique, c'est un effet que l'on retrouve souvent qui amène réalisme et immersion à l'environnement dans lequel évolue le joueur. À titre d'exemple, on peut citer le sublime "Journey" :

Bien entendu, si j'ai implémenté ce système ce n'était pas seulement dans l'optique de "faire joli". L'effet a pour but d'apporter un plus dans des mécaniques de gameplay existantes, voir en créer de nouvelle. Prenons le cas d'un jeu de survie qui se déroulerait dans des zones enneigées (un peu comme "The long dark"), où l'environnement et la faune peuvent s'avérer très dangereux. En identifiant des empreintes, le joueur pourrait savoir s'il s'agit d'un animal inoffensif qu'il pourrait chasser pour se nourrir ou d'un prédateur qu'il devrait plutôt fuir.

On peut bien entendu imaginer beaucoup d'autres mécaniques de gameplay basée sur ce principe (dont celle qui m'a amené à développer ce système de traces dynamique, mais celle-là je vous en parlerai une autre fois !), mais je n'en évoquerai pas d'autres ici, laissez faire votre imagination.

En conclusion, il y a encore du travail à fournir pour arriver à un résultat que je jugerais "acceptable", mais c'est quelque chose de tout à fait réalisable ! Ce test à permis de mettre en lumière un certain nombre de mécaniques et d'idées que l'on pourrait intégrer dans nos futurs projets. Cependant, seul le futur sait si oui ou non cet effet nous sera utile un jour.

Pour les plus courageux, ou ceux qui s'intéressent au développement de jeu vidéo, une dernière partie vous attend pour expliquer comment j'ai implémenté tout ça.

 

Techniquement... Comment ça marche ?

Les empreintes

Tout le système repose sur l'utilisation de "heightmap". Pour ceux qui ne seraient pas familiers avec l'anglais, on peut traduire le terme "heightmap" par "carte de hauteur". Concrètement, il s'agit d'une image (généralement carrée) noire et blanche contenant des informations relatives à un relief. Son fonctionnement est assez simple. Lorsqu'un pixel est noir cela indique une altitude de 0 et lorsqu'il est blanc une altitude de 1 (bien entendu, le pixel peut aussi prendre n'importe quelle valeur de gris). L'image suivante permet de mieux comprendre comment fonctionne une "heightmap" (j'ai aussi rajouté quelques couleurs pour que ça soit plus sympa visuellement).

C'est bien sympa de pouvoir créer des montagnes super facilement grâce à une image en noir et blanc, mais ça n’explique pas vraiment comment mon système d'empreinte de pas fonctionne ! Et bien, ce qu'il faut comprendre avec les "heightmap" c'est qu’elles permettent de modifier un objet en 3 dimensions facilement, précisément et de manière optimisée.

Pour commencer, je génère une texture totalement blanche qui va me servir de "heightmap" dynamique (je sacrifie quelques millièmes de seconde au lancement du jeu pour économiser de l'espace mémoire). À côté de cette première texture, une seconde (plus petite) va me servir de pinceau (comme sur paint) avec lequel je vais dessiner sur ma "heightmap". Ainsi, en peignant ma "heightmap" à chaque mouvement de la balle, j'obtiens le résultat suivant :

En combinant les 2 principes décrits ci-dessus, on obtient un système permettant de gérer des empreintes en 3 dimensions. Je vous épargne toute la partie sur la récupération de la position de la boule par rapport au plan. L’algorithme utilisé étant un peu plus complexe et nécessite certaines connaissances avancées dans Unity.

Disparition progressive des traces

Actuellement, l'idée que j'ai implémentée pour effacer progressivement les traces de pas est particulièrement simple, mais pas vraiment optimale. En effet, j'éclaircis la "heightmap" plusieurs fois par seconde pour qu'elle devienne de plus en plus blanche. Ainsi, les empreintes laissées par la balle s'éclaircissent petit à petit et disparaissent progressivement. Si l'on reprend le principe de la "heightmap", plus un pixel est clair, plus son altitude sera grande. En ajustant correctement l'effet, celui-ci devient fluide et la trace revient progressivement à son état initial. Pour illustrer mes propos, je vais reprendre le dernier exemple, mais en ajoutant l'effacement des traces au fil du temps.

Le problème de cette technique est qu'elle demande de récupérer la "heightmap" (qui est construite dynamiquement) en mémoire à chaque fois. Le chargement d'une texture est une opération plutôt coûteuse en ressources CPU et peut fortement ralentir les configurations les plus faibles.

Néanmois plusieurs idées d'optimisation sont à l'étude en ce moment. La première consisterait à trouver un moyen d'éviter de chaque fois récupérer la "heightmap" depuis le GPU soit en la stockant dans une variable ou en trouvant une autre façon pour éclaircir l'image. Une seconde solution serait d'optimiser le nombre de pixels traités. En effet, actuellement, une opération est appliquée à chaque pixel de l'image alors que la seule partie qui nous intéresse vraiment est celle où les pixels ne sont pas blancs (ce qui correspond aux pixels où la trace a été dessinée).

Voilà pour cette partie technique, j'espère qu'elle aura permis à ceux qui s'y intéressent de comprendre plus ou moins comment j'ai mis en place ce système d'empreinte de pas dynamiques. Je prévois aussi d'écrire un second article sur les traces de pas dynamique lorsque j'aurai réussi à améliorer et optimiser le système actuel.

Pour ceux qui seraient encore là, d'autres articles sur nos divers tests technologiques vont bientôt paraître (peut-être que certains le sont déjà au moment où vous lisez ces lignes) donc rester attentifs et n'hésitez pas à nous poser des questions, faire des remarques et proposer des idées !


Partagez avec vos amis!

Leave a Reply

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