{"id":602,"date":"2017-08-17T13:11:28","date_gmt":"2017-08-17T12:11:28","guid":{"rendered":"http:\/\/oneiricworlds.com\/fr\/?p=602"},"modified":"2017-08-17T19:47:08","modified_gmt":"2017-08-17T18:47:08","slug":"herbe-vegetation","status":"publish","type":"post","link":"https:\/\/oneiricworlds.com\/fr\/2017\/08\/herbe-vegetation\/","title":{"rendered":"Herbe &#038; V\u00e9g\u00e9tation"},"content":{"rendered":"<p>Bonjour \u00e0 tous,<\/p>\n<p>R\u00e9cemment, j&rsquo;ai essay\u00e9 d&rsquo;am\u00e9liorer la d\u00e9mo visuellement pour que le jeu ait un meilleur look. J&rsquo;ai pas mal travaill\u00e9 sur le rendu de l&rsquo;herbe et de la v\u00e9g\u00e9tation notamment, et\u00a0c&rsquo;est ce que je vais d\u00e9tailler dans cet article.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_121404.png\" rel=\"attachment wp-att-512\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-512\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_121404-1024x570.png\" alt=\"20170810_121404\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Hop, un\u00a0nouveau syst\u00e8me de v\u00e9g\u00e9tation.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h3>I &#8211; Le syst\u00e8me d&rsquo;herbe de Unity<\/h3>\n<p>Avant tout, j&rsquo;ai envisag\u00e9 d&rsquo;utiliser le syst\u00e8me de terrain et de v\u00e9g\u00e9tation de Unity, mais j&rsquo;ai \u00e9t\u00e9 confront\u00e9 \u00e0 2 probl\u00e8mes:<\/p>\n<p>Tout d&rsquo;abord, les terrains de mon jeu sont assez complexes, avec des \u00eeles volantes, des cavernes, des trous, des ponts, et autres formes non convexes. Unity propose uniquement des terrains de type \u00ab\u00a0height map\u00a0\u00bb, ce qui ne permet pas de g\u00e9n\u00e9rer de l&rsquo;herbe sur tous les c\u00f4t\u00e9s et au-dessous d&rsquo;une \u00eele volante par exemple.<\/p>\n<p>Ensuite, le syst\u00e8me de v\u00e9g\u00e9tation de Unity est con\u00e7u pour g\u00e9rer l&rsquo;affichage de l&rsquo;herbe sur des terrains immenses. Le batching est donc en grande partie dynamique. Cela g\u00e9n\u00e8re beaucoup de draw calls (sur le peu de test que j&rsquo;ai faits), et \u00e7a ralentit pas mal le\u00a0jeu.<\/p>\n<p>Voil\u00e0 pourquoi j&rsquo;ai choisi de cr\u00e9er mon propre syst\u00e8me de v\u00e9g\u00e9tation pour le jeu.<\/p>\n<p>&nbsp;<\/p>\n<h3>II &#8211; Le nouveau syst\u00e8me de v\u00e9g\u00e9tation<\/h3>\n<p>L&rsquo;id\u00e9e principale derri\u00e8re ce choix est de pouvoir cr\u00e9er facilement des champs d&rsquo;herbe en quelques clics, tout en gardant un bon contr\u00f4le sur la partie artistique. J&rsquo;utilise Blender comme outil pour le level design (entre autres), donc je dois trouver un moyen d&rsquo;exporter l&rsquo;herbe et les r\u00e9glages divers vers Unity via le format FBX. Je souhaite avoir quelque chose d&rsquo;assez l\u00e9ger en taille de fichier et qui puisse s&rsquo;adapter facilement aux diff\u00e9rents cas d&rsquo;utilisation que je vais rencontrer (v\u00e9g\u00e9tation \u00e0 la verticale sur les murs, ou mousse dessous les \u00eeles volantes, &#8230;). Voici ce \u00e0 quoi j&rsquo;ai abouti:<\/p>\n<h4>Dans Blender<\/h4>\n<p>Pour les raisons \u00e9voqu\u00e9es ci-dessus, j&rsquo;ai choisi d&rsquo;utiliser les couleurs associ\u00e9es \u00e0 chaque sommet sur des maillages\/meshes faits \u00e0 la main. Ca me permet de cr\u00e9er ces fameux meshes uniquement \u00e0 l&rsquo;endroit o\u00f9 je souhaite avoir de la v\u00e9g\u00e9tation. En outre, je peux utiliser les 3 canaux de couleurs pour cr\u00e9er 3 types de v\u00e9g\u00e9tation diff\u00e9rents sur un m\u00eame mesh. Pour peindre facilement chaque canal, j&rsquo;utilise les brosses \u00ab\u00a0Add\u00a0\u00bb et \u00ab\u00a0Sub\u00a0\u00bb de Blender avec des couleurs rouge, bleue et verte pures.<\/p>\n<p>Bien s\u00fbr, j&rsquo;utilise un nom sp\u00e9cial sur ce mesh avec des conventions sp\u00e9cifiques pour signaler \u00e0 Unity le type de v\u00e9g\u00e9tation que je d\u00e9sire.<\/p>\n<p>Je peux superposer plusieurs meshes les uns sur les autres, donc il n&rsquo;y a virtuellement pas de limite au nombre de v\u00e9g\u00e9tations diff\u00e9rentes que le syst\u00e8me\u00a0peut g\u00e9rer.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_vertexColorGrass.jpg\" rel=\"attachment wp-att-508\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-508\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_vertexColorGrass-1024x576.jpg\" alt=\"20170816_vertexColorGrass\" width=\"840\" height=\"473\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Voici le mesh avec les couleurs de sommets dans Blender. Pour ce mesh, j&rsquo;utilise le rouge pour l&rsquo;herbe, le vert pour la mousse, et le bleu pour des sortes de lianes tombantes.<\/em><\/p>\n<p>Bien s\u00fbr, c&rsquo;est un peu d\u00e9routant de \u00ab\u00a0peindre\u00a0\u00bb l&rsquo;herbe sans r\u00e9ellement la voir dans Blender (l&rsquo;herbe r\u00e9elle est g\u00e9n\u00e9r\u00e9e plus tard dans Unity). Mais c&rsquo;est le prix \u00e0 payer pour avoir des fichiers d&rsquo;export assez l\u00e9gers. Et puis&#8230; on finit par s&rsquo;habituer \ud83d\ude42<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_vertexColorRocks.jpg\" rel=\"attachment wp-att-511\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-511\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_vertexColorRocks-1024x576.jpg\" alt=\"20170816_vertexColorRocks\" width=\"840\" height=\"473\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Si je ne veux pas d&rsquo;herbe partout, je peux juste cr\u00e9er un petit mesh \u00e0 l&rsquo;endroit sp\u00e9cifique qui m&rsquo;int\u00e9resse. C&rsquo;est tr\u00e8s l\u00e9ger lorsqu&rsquo;on exporte en FBX.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h4>Dans Unity<\/h4>\n<p>Ensuite, lorsque j&rsquo;importe le niveau dans Unity, mes scripts d&rsquo;import vont g\u00e9n\u00e9rer la v\u00e9g\u00e9tation avec une densit\u00e9 fonction de l&rsquo;intensit\u00e9 de couleur des sommets du mesh. Chaque \u00e9l\u00e9ment de v\u00e9g\u00e9tation est g\u00e9n\u00e9r\u00e9 \u00e0 partir d&rsquo;un prefab. Le prefab est automatiquement \u00ab\u00a0coll\u00e9\u00a0\u00bb et orient\u00e9\u00a0de mani\u00e8re ad\u00e9quate sur la 1\u00e8re surface viable sous-jacente. Bien s\u00fbr d\u00e9finir une surface \u00ab\u00a0viable\u00a0\u00bb n&rsquo;est pas aussi simple que \u00e7a (je dois tester le type de surface&#8230;), mais vous avez saisi l&rsquo;id\u00e9e.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_154114.png\" rel=\"attachment wp-att-509\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-509\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_154114-1024x570.png\" alt=\"20170810_154114\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Parfois, le \u00ab\u00a0collage\u00a0\u00bb automatique de l&rsquo;herbe sur les surfaces am\u00e8ne de curieux r\u00e9sultats (l&rsquo;herbe sur le panneau ici, ce qui est plut\u00f4t rigolo, mais pas voulu). J&rsquo;ai donc du mettre en place plusieurs r\u00e8gles sp\u00e9cifiques pour emp\u00eacher ce genre de choses, ou, tout du moins, les contr\u00f4ler.<\/em><\/p>\n<p>J&rsquo;ai \u00e9galement mis en place une \u00e9tape de\u00a0randomisation, qui me permet de changer de mani\u00e8re al\u00e9atoire la taille, la rotation ou ce que j&rsquo;estime n\u00e9cessaire sur chaque prefab g\u00e9n\u00e9r\u00e9. Ceci permet de cr\u00e9er plus de variations.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_174518.png\" rel=\"attachment wp-att-515\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-515\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_174518-1024x570.png\" alt=\"20170810_174518\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Une capture d&rsquo;\u00e9cran pr\u00e9sentant les 3 types de v\u00e9g\u00e9tation: de l&rsquo;herbe au premier plan, de la mousse sur les parois verticales, et des lianes tombantes dessous.<\/em><\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170811_102213.png\" rel=\"attachment wp-att-514\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-514\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170811_102213-1024x570.png\" alt=\"20170811_102213\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Une autre image de la Guilde des Voleurs avec beaucoup d&rsquo;herbe.<\/em><\/p>\n<p>Ensuite, une fois que tous les prefabs ont \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9s, je les fusionne (\u00ab\u00a0batche\u00a0\u00bb) tous par mat\u00e9riau. Tout est rassembl\u00e9 dans des meshes de ~65000 sommets, qui est la limite impos\u00e9e par Unity. Evidemment, cela r\u00e9sulte en plusieurs meshes \u00ab\u00a0batch\u00e9s\u00a0\u00bb (g\u00e9n\u00e9ralement autour de 50, mais on peut monter \u00e0 plus que \u00e7a). Cela r\u00e9duit consid\u00e9rablement le nombre de draw calls.<\/p>\n<h3>III &#8211; Pour &amp; Contre<\/h3>\n<p>Comme d&rsquo;habitude, cette approche a de bons et de mauvais c\u00f4t\u00e9s:<\/p>\n<p>Le batching statique de tous les meshes d&rsquo;herbe tel que je le fais emp\u00eache d&rsquo;avoir un affichage dynamique permettant de montrer ou de cacher les brins d&rsquo;herbe en fonction de la distance, car tout est batch\u00e9 dans un ordre al\u00e9atoire. Cela signifie que chaque brin d&rsquo;herbe sur une \u00eele est visible de n&rsquo;importe o\u00f9 sur cette m\u00eame \u00eele. Mais comme les \u00eeles de mon jeu sont relativement petites, \u00e7a a l&rsquo;air OK pour l&rsquo;instant. A l&rsquo;avenir, si je devais optimiser encore, je pourrai toujours introduire une structure de type octree pour segmenter l&rsquo;herbe par r\u00e9gion et\/ou utiliser un shader intelligent qui pourrait \u00ab\u00a0clipper\u00a0\u00bb la geom\u00e9trie lointaine.<\/p>\n<p>Par contre, le batching statique avec ordre al\u00e9atoire a un avantage: je peux choisir de n&rsquo;activer que la moiti\u00e9 des meshes de v\u00e9g\u00e9tation, et cela divise la densit\u00e9 de l&rsquo;herbe par 2 partout de mani\u00e8re uniforme. Afficher de l&rsquo;herbe reste un processus assez co\u00fbteux pour la carte graphique, et il est bien pratique de pouvoir dynamiquement diminuer la densit\u00e9 de l&rsquo;herbe pour faire tourner le jeu sur des configurations plus modestes.<\/p>\n<p>Une autre bonne nouvelle est que, comme l&rsquo;herbe est g\u00e9n\u00e9r\u00e9e dynamiquement via des prefabs, ce syst\u00e8me de v\u00e9g\u00e9tation sait en r\u00e9alit\u00e9 g\u00e9rer les prefabs d&rsquo;une mani\u00e8re g\u00e9n\u00e9rale, et pas uniquement la v\u00e9g\u00e9tation; donc des rochers aussi par exemple. Je devrais donc plut\u00f4t l&rsquo;appeler \u00ab\u00a0syst\u00e8me de g\u00e9n\u00e9ration de d\u00e9tails\u00a0\u00bb en fait.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_222620.png\" rel=\"attachment wp-att-516\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-516\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_222620-1024x570.png\" alt=\"20170816_222620\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Quelques rochers g\u00e9n\u00e9r\u00e9s avec le nouveau syst\u00e8me de g\u00e9n\u00e9ration de d\u00e9tails.<\/em><\/p>\n<p>Un autre avantage est que je peux \u00e9galement positionner manuellement les prefabs d&rsquo;herbe si je le souhaite. Ils b\u00e9n\u00e9ficieront \u00e9galement du syst\u00e8me de batching. Je peux donc utiliser le syst\u00e8me de g\u00e9n\u00e9ration de v\u00e9g\u00e9tation pour les larges zones et faire du placement manuel pour les zones plus petites, ou plus sp\u00e9cifiques.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_232045.png\" rel=\"attachment wp-att-520\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-520\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_232045-1024x570.png\" alt=\"20170816_232045\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Quelques herbes positionn\u00e9es manuellement sur les rochers.<\/em><\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_231738.png\" rel=\"attachment wp-att-519\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-519\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170816_231738-1024x570.png\" alt=\"20170816_231738\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Une petite grotte avec beaucoup de lianes&#8230;<\/em><\/p>\n<h3>IV &#8211; Performances<\/h3>\n<p>Pour l&rsquo;instant, le jeu affiche 80 000 \u00e9l\u00e9ments de v\u00e9g\u00e9tations avec une fr\u00e9quence d&rsquo;affichage correcte (~30 fps) sur une configuration moyenne. Bien s\u00fbr cela d\u00e9pend du nombre de polygones sur chaque\u00a0prefab. Il faut donc \u00eatre tr\u00e8s pointilleux lors de la mod\u00e9lisation de chaque\u00a0\u00e9l\u00e9ment de v\u00e9g\u00e9tation.<\/p>\n<p>Et comme j&rsquo;avais d\u00e9j\u00e0 cod\u00e9 des shaders sp\u00e9cifiques pour la v\u00e9g\u00e9tation, je peux les r\u00e9utiliser pour ce nouveau syst\u00e8me. Du coup, l&rsquo;herbe r\u00e9agit toujours au vent et au d\u00e9placement du personnage.<\/p>\n<p><a href=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_180233.png\" rel=\"attachment wp-att-518\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-518\" src=\"http:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2017\/08\/20170810_180233-1024x570.png\" alt=\"20170810_180233\" width=\"840\" height=\"468\" \/><\/a><\/p>\n<p>Voil\u00e0, c&rsquo;est tout pour aujourd&rsquo;hui! J&rsquo;esp\u00e8re que ce n&rsquo;\u00e9tait pas trop technique. Ce syst\u00e8me de g\u00e9n\u00e9ration de v\u00e9g\u00e9tation est encore tout r\u00e9cent, donc j&rsquo;esp\u00e8re pouvoir l&rsquo;affiner dans les prochains mois pour le rendre plus efficace, et plus adapt\u00e9 aux probl\u00e8mes que soul\u00e8ve le jeu.<\/p>\n<p>A+!<\/p>\n<p>Paix!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bonjour \u00e0 tous, R\u00e9cemment, j&rsquo;ai essay\u00e9 d&rsquo;am\u00e9liorer la d\u00e9mo visuellement pour que le jeu ait un meilleur look. J&rsquo;ai pas mal travaill\u00e9 sur le rendu de l&rsquo;herbe et de la v\u00e9g\u00e9tation notamment, et\u00a0c&rsquo;est ce que je vais d\u00e9tailler dans cet article. Hop, un\u00a0nouveau syst\u00e8me de v\u00e9g\u00e9tation. &nbsp; I &#8211; Le syst\u00e8me d&rsquo;herbe de Unity Avant [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":609,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,7,10],"tags":[],"class_list":["post-602","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","category-dev","category-tutorial"],"_links":{"self":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/602","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/comments?post=602"}],"version-history":[{"count":11,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/602\/revisions"}],"predecessor-version":[{"id":614,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/602\/revisions\/614"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/media\/609"}],"wp:attachment":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/media?parent=602"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/categories?post=602"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/tags?post=602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}