De Blender vers BabylonJS
11 commentaires(logiciels utilisés : Blender 2.79b, BabylonJS 3.3.0)
Cet article va prendre le prétexte d'une toute petite scène pour présenter un workflow simple de Blender vers BabylonJS, comprenant la gestion des lightmaps, afin de tendre vers un éclairage réaliste.
(cliquez pour lancer)
lien direct vers la démo
Les non-utilisateurs de Blender resteront peut-être intéressés par ce tutorial, puisque les grandes lignes de modélisation, unwrapping et gestion de la scène et ses objets restent les mêmes peu importe le logiciel, et aussi bien entendu la partie BabylonJS (BJS de son petit nom) qui est totalement indépendante du modeler utilisé.
Nous allons toucher des mains le webGL, donc pour les infographistes habitués des moteurs en vogue comme Unreal Engine ou Unity3D, autant vous prévenir maintenant, voici les gros points qui vont vous faire mal :
- les outils d'éditions et de réglages côté moteur 3D : beaucoup moins accessibles et ergonomiques
- la gestion de l'éclairage par les lightmaps : à l'ancienne, toute la chaine est à gérer par le graphiste
- le code ! Et oui, il va falloir pondre du javascript, en plus de quelques bouts de html/css (faire une appli webGL c'est faire un site web après tout)
Le workflow en quelques mots
Téléchargement des sources
Les sources du projet sont disponibles ici. Vous y trouverez :
- le dossier 3D, contenant les fichiers blend et les textures originales
- le dossier BJS, contenant l'espace de travail BabylonJS et les exemples du tutoriel
Les bases de la 3D temps réel
Je ne m'attarderais pas ici sur les méthodes de modélisation et de texturing, qui conservent les mêmes logiques peu importe le moteur qu'on utilise. Je pars du postulat que vous avez déjà ces notions de base (liste non-exhaustive) :
- unité de base au mètre
- modélisation orientée... temps réel évidemment
- textures en puissance de 2
- nommage correct et rigoureux de tous les assets
Il est bien sur conseillé d'avoir regardé et testé les Babylon 101 et les How to... de BabylonJS.
Standard vs PBR
Pour cet exemple je ne suis pas en workflow PBR mais Standard. Ceci vient du fait que l'exporteur officiel Blender-vers-BJS ne gère pas encore la conversion en PBR des matériaux. Il est aussi encore utile de savoir se débrouiller avec le Standard Workflow si l'on vise des machines utilisateurs peu puissantes (tout le monde n'a pas le dernier smartphone à la mode).
Il est cependant possible de travailler en PBR en exportant au format glTF, ce workflow est encore en phase expérimentale et soumis à quelques bugs, mais il fera l'objet d'une suite à ce tuto.
L'éclairage
Puisqu'il n'y a pas de moteur de rendu raytracing dans BabylonJS, je vais devoir faire mon éclairage sous un moteur précalc', comme Cycles. Cela m'oblige à créer deux versions de ma scène :
- la scène 3D temps réel, qui est en fait le fichier de travail principal et d'où la scène BJS est exportée, avec les matériaux standards Blender Render
- la scène 3D précalculée, qui va être dédiée à la création de lightmaps, avec les matériaux et les lights Cycles
L'édition de la scène BabylonJS
Les développeurs de BabylonJS nous proposent un éditeur, mais il possède des limitations qui ne me conviennent pas au quotidien, en particuler le fait que si je fais un nouvel export de ma scène Blender, il me faut recommencer tous mes réglages côté éditeur. Pourquoi pas lorsqu'il s'agit de jouer sur une micro-scène en one-shot, mais en production classique avec des exports & réexports permanents, ça n'est pas utilisable en l'état. Éditeur à surveiller tout de même, puisque souvent mis à jour.
J'effectuerais donc le plus de réglages possibles dans la scène Blender directement, puis une fois dans BJS j'utiliserais l'outil Inspector pour peaufiner tout ça, et reporterais les données... en javascript.
L'optimisation
Pour ce tutoriel je n'irais pas très loin dans les différents techniques d'optimisation, puisque ce n'est pas le sujet, je ferais donc le minimum nécessaire. Sur un scène complexe, la moindre optimisation peut avoir son importance (liste non-exhaustive) :
- maillage (et donc poids) des meshes
- taille des textures (peuvent se réduire en fin de projet)
- nombre de lampes dynamiques
- dépliage serré - avec parcimonie - des UV lightmaps
- jonction des objets & partage des matériaux
Côté Blender
Scène temps réel (Blender Render)
L'organisation de la scène
On est en temps réel, donc évidemment les objets doivent avoir un nom explicite, tachez de faire attention à ça, c'est important pour la suite lorsqu'on s'amusera avec du code.
Les objets sont séparés en calques pour rendre plus fluide nos opérations.
La modélisation
Rien d'exceptionnel ici. Pensez juste à préparer vos seams et sharp edges quand un mesh est terminé, pas besoin de s'y replonger après coup.
On devra évidemment enchainer non seulement sur le dépliage des UV classiques, mais aussi ceux dédiés aux lightmaps :
UVMap pour le texture tiling, UV2 pour les futures lightmaps
Ne pas perdre du temps à soigner les UV2 pour le moment, il s'agit juste de vérifier que le dépliage automatique se comporte bien (Unwrapping ou SmartUnwrap). Les UV1 peuvent être définitifs.
La préparation pour les lightmaps
Les objets vont être attachés ensemble selon la distribution désirée des lightmaps (là ça dépend vraiment de chaque projet), mais il va falloir réfléchir à plusieurs choses :
- si des objets partagent les mêmes matériaux, on tentera évidemment de les réunir
- certains objets n'auront pas besoin de lightmaps, et seront même gênants lors du rendu Cycles, on pourra donc les attacher ensemble, et veiller à utiliser un mot-clef permettant de les repérer par code une fois dans le moteur 3D
- notez que si l'on souhaite être absolument rigoureux sur la répartition de surface des lightmaps, on peut s'embêter à calculer les texels afin de conserver une harmonie entre tous les différents objets et la résolution de leur lightmap, mais pour cette scène je me le fais au feeling.
Il serait aussi possible de laisser détachés les objets et donc d'avoir des UV2 partagés, mais le workflow se compliquerait aussi bien du côté Blender que du côté Babylon.
- dans la planche UV, notez la face selectionnée : il s'agit de la surface arrière du tableau, scalée à 0.05 puisqu'il est inutile qu'elle utilise de la place sur la future ligthmap
- on peut remarquer qu'il reste un peu de vide : des plugins Blender aideraient à mieux répartir tout ça, mais dans une contrainte de rapidité de prod' en milieu pro', il n'est pas toujours évident d'atteindre la perfection. Ici le déplié reste satisfaisant.
mes deux objets exclus des lightmaps, utilisant le mot-clef noLM (pour no LightMap) : holdout.noLM.000 et furnitures.noLM.000
L'exportation de la scène
À ce stade, il est déjà possible de faire un premier export vers BabylonJS, même si nos lightmaps n'existent toujours pas. Vous pouvez déjà lire la doc' officielle à propos de l'exporteur (j'en ai écrit une partie, n'hésitez pas à me faire des retours et suggestions).
Si vous n'avez encore de setups BabylonJS sous la main, n'oubliez pas l'existence de l'éditeur, ou même de la sandbox, qui vous permettront de regarder votre 3D sous tous les angles en deux temps, trois mouvements.
L'export en lui-même n'est vraiment pas compliqué. Comme vous l'avez vu dans la doc' officielle, les réglages se situent dans les propriétés des meshes directement (ou du world, ou du material, etc).
Nous aurons alors un rendu moche, mais qui servira :
- à repérer d'éventuels bugs et à les corriger avant de commencer à jongler entre les scènes.
- à commencer du réglage, mais forcément très basique et succin puisque l'ambiance sera modifiée lors de l'ajout des lightmaps
export brut de Blender vers la Babylon Sandbox
Scène précalculée (Cycles)
Lorsque notre scène temps réel est prête, il est temps de s'occuper de notre ambiance lumineuse. Il va être question ici de se concentrer sur l'éclairage et non sur le peaufinage des matériaux. En fait, nous allons même écraser la plupart des matériaux en les remplaçant par un seul tout simple et tout basique.
Les objets
La première action à affectuer dans notre nouvelle scène Cycles vide est évidemment d'importer nos objets dedans.
Plusieurs type d'actions existent, dépendant de vos préférences :
- Ctrlc puis Ctrlv, rapide et efficace
- le
File > Append
, qui peut être intéressant - le
File > Link
qui serait le workflow parfait, mais je n'ai pas encore trouvé l'astuce idéale pour ça- pour les curieux, la piste la plus solide serait de lier les matériaux Cycles au niveau de l'objet plutôt que de ses data (ou vice-versa), mais mon plugin BakeTool n'a pas l'air d'apprécier.
Dans le cas où vous mettez à jour la scène Cycles, vous aurez déjà présentes les anciennes version d'objets. Avant d'importer les nouvelles versions, supprimez les anciennes et n'oubliez pas de supprimer les Orphan Data via l'Outliner.
Là encore, j'utilise soigneusement les calques, avec certains roles assignés :
- les objets lightmappés, qui seront potentiellement à mettre à jour de temps en temps
- les objets dédiés au rendu mais ne recevant pas de lightmaps (abat-jour par exemple)
- les lights et les caméras
Les matériaux
Puisqu'au baking seul l'impact lumineux nous intéresse, il n'est pas vraiment utile de se coltiner une conversion de tous nos matériaux Blender Render vers Cycles. Sur une petite scène comme ça, cela reste envisageable mais sur une scène avec plus d'une centaine de matériaux y'a de quoi s'arracher les cheveux - surtout s'il nous faut faire une mise à jour de toute la géométrie deux jours plus tard.
C'est pourquoi nous allons créer un matériau Cycles par défault, tout simple, nommé par exemple _cycles_default_ :
Afin d'éviter de le perdre lors d'un éventuel Orphan Data clean, on le met en Fake User.
Ensuite, il est possible - grâce au plugin Material Specials - d'écraser et d'assigner ce matériaux à tous nos objets : ShiftQ > Assign Material > _cycles_default_
Oui mais, et le color bleeding ? En effet on le perd totalement avec cette technique. On peut alors sélectionner les éléments d'importance et créer des matériaux particuliers. Dans ma scène, j'ai choisi de conserver mon parquet ; mais là encore le matériau est tres simple puisqu'il s'agit tout simplement de la diffuse connectée au shader Diffuse BSDF.
Une petite capture vidéo du process sera peut-être bienvenue :
lien direct vers la vidéo
L'éclairage
Le world output est on-ne-peut-plu' simple, mais suffisant pour cette scène :
La light est toute simple également :
En revanche, en ayant placé la light à son emplacement logique (à savoir au milieu de l'ampoule), nous nous confrontons à un problème évident : la lumière ne passe pas à travers l'ampoule et l'abat-jour.
Pour l'ampoule le problème est très simple à régler, il suffit de lui assigner un shader entièrement transparent. Pour l'abat-jour, le matériaux n'est finalement pas beaucoup plus complexe, on apporte juste une couleur unie proche du tissu de l'abat-jour :
notez l'activation du mode Fake User sur ces matériaux, afin de ne pas les perdre en cas de mise à jour des meshes
Pour réduire le bruit au rendu , se référer à la doc' Blender officielle.
On a maintenant un éclairage qui ressemble à quelque chose, on va pouvoir passer au baking des lightmaps.
Le baking
Ici j'utilise Baketool, qui n'est pas très compliqué à prendre en main. Si vous souhaitez utiliser le workflow par défaut, voir la doc' Blender officielle.
Préparez votre liste d'objets et bakez sur leur second canal UV.
Le point important ici est de sélectionner la passe de Diffuse sans sa Color. En effet, nous ne désiront que l'impact lumineux direct et indirect.
configuration du baking avec baketool
pour info, l'option de baking par défaut de Blender
Lancez le calcul.
admirez ce magnifique espace perdu pour la lightmap des murs, huez moi
Il est possible de tolérer un certain niveau de bruit au rendu (puisque le baking prend beaucoup plus de temps de calcul qu'un rendu classique), puis de faire une passe de denoise ensuite :
filtre Denoise sous Gimp
Enregistrez vos lightmaps finales dans votre dossier BJS/assets/lightmaps/
.
Côté BabylonJS
Comme vu plus haut, il vous est possible de ne pas vous prendre la tête avec du code en utilisant l'éditeur officiel. Soyez juste certain de ne pas avoir à mettre à jour votre fichier exporté.
Notez aussi qu'il vous faut avoir accès à un serveur web. Vous trouverez un peu d'aide sur cette page.
Mais pour ce tuto je vais utiliser la méthode en partant de zéro. Néanmoins même si vous n'êtes pas très à l'aise avec le code, le copier-coller est toujours possible. Notez que je ne suis pas développeur pro', et qu'il est possible que mon code soit à peaufiner (me faire des retours si c'est le cas ;) )
Préférez afficher votre scène en mode navigation privée, pour éviter les problèmes de cache, et sachez qu'avoir la console ouverte est quand même très utile (en allant dans les settings de celle-ci, vous pouvez forcer la non-mise en cache).
L'export/import de notre scène
Pour éviter de se retrouver avec un tas de fichiers en vrac à la racine de notre future application 3D web, on va organiser une petite arborescence :
Arborescence | Fonction |
---|---|
|
Vous pouvez déjà exporter le fichier babylon dans le dossier assets, les textures nécessaires y seront copiées automatiquement. Placez dans le dossier dédié les lightmaps.
Plutôt que de lier le moteur BabylonJS sur une version en ligne, je pense qu'il est toujours préférable de rapatrier une version en local (placée dans le dossier js). Le reste de notre javascript sera ici écrit directement dans notre fichier html principal, mais il serait plus propre de l'écrire dans un fichier dédié placé dans ce dossier js lui aussi.
L'index.html est l'endroit où tout va se passer. Commencez par créer un fichier texte vide nommé ainsi, puis éditez-le.
Toujours en s'aidant de la doc' BJS officielle, on arrive vite à notre premier chargement de scène 3D :
<!doctype html>
<html>
<head>
<title>From Blender to Babylon - standard workflow</title>
<meta charset="UTF-8">
<script src="https://nothing-is-3d.com/js/babylon.js"></script>
<style>
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: tahoma, arial, sans-serif;
color:white;
}
#canvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
// ArcRotateCamera doc, you can use FreeCamera if you prefer:
// http://doc.babylonjs.com/api/classes/babylon.arcrotatecamera#constructor
var arcRotCam = new BABYLON.ArcRotateCamera(
"arcRotateCamera", 1, 1, 4,
new BABYLON.Vector3(0, 1, 0),
scene
);
arcRotCam.attachControl(canvas, true);
// SceneLoader doc :
// http://doc.babylonjs.com/api/classes/babylon.sceneloader#append
BABYLON.SceneLoader.Append(
"assets/",
"scene-BJS.babylon",
scene
);
engine.runRenderLoop(function () {
scene.render();
});
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>
Dans les balises <head>
rien de particulier : on indique le chemin du moteur, et on informe le navigateur que l'on souhaite que la partie 3D (canvas) remplisse toute notre page.
Dans les balises <body>
ce qui nous intéresse particulièrement ici est la fonction BABYLON.SceneLoader.Append
qui nous permet d'intégrer notre 3D. Mais on aura auparavant :
- instancié le moteur 3D
var engine = new BABYLON.Engine(canvas, true);)
- créé une scène en utilisant ce moteur
var scene = new BABYLON.Scene(engine);
- créé une caméra
Les valeurs de positions caméra que j'ai renseigné ci-dessus méritent d'être peaufinées. Après avoir regardé du côté de la doc', je me débrouille pour que :
- ma vue initiale soit correcte :
var arcRotCam = new BABYLON.ArcRotateCamera("arcRotateCamera", 5.5, 1.2, 3.75, new BABYLON.Vector3(-0.8, 0.75, 0.8), scene);
- mes coups de molettes dézomment moins violemment :
arcRotCam.wheelPrecision = 200;
- mon clipping min soit adapté à la scène :
arcRotCam.minZ = 0.005;
( = 5 mm)
Nous voici donc avec notre premier chargement de scène !
voir tuto01.html
Avant de s'attaquer aux réglages matériaux, il nous reste à gérer les lightmaps et à les assigner de façon automatique à nos objets.
Les lightmaps
Ici on va monter d'un cran la complexité du code javascript, parce qu'il va nous falloir :
- boucler parmis nos objets et exclure ceux qui n'ont pas de lightmaps
- charger les lightmaps existantes
- assigner les bonnes lightmaps à chaque matériau
- effectuer du réglage de base des matériaux pour un affichage correct des lightmaps
Pour être certain que nos objets existent lorsqu'on appelera notre fonction décrite ci-dessus, il va falloir nous placer dans le onSuccess de notre SceneLoader. Exemple avec le code ci-dessous, où le file loaded!
ne s'affichera dans la console que lorsque tout le contenu de notre fichier .babylon sera chargé :
BABYLON.SceneLoader.Append(
"assets/",
"scene-BJS.babylon",
scene,
function(){
console.log("file loaded!")
}
);
voir tuto02.html (regardez la console)
On va donc faire nos bouts de code dans cette fonction. Mais avant le SceneLoader, j'ai besoin d'une fonction d'assignation de la lightmap à un material, qui sera appelée ici assignLightmapOnMaterial.
Voici donc la chose :
function assignLightmapOnMaterial(material, lightmap) {
material.lightmapTexture = lightmap;
// we want using UV2
material.lightmapTexture.coordinatesIndex = 1;
// our lightmap workflow is a darken one
material.useLightmapAsShadowmap = true;
}
BABYLON.SceneLoader.Append(
"assets/",
"scene-BJS.babylon",
scene,
function () {
/** LIGHTMAP ASSIGNATION PROCESS **/
// lightmapped meshes list
var lightmappedMeshes = ["wallz.000", "furnitures.000"];
// we start cycling through them
for (var i = 0; i < lightmappedMeshes.length; i++) {
var currentMesh = scene.getMeshByName(lightmappedMeshes[i]);
// lightmap loading
var currentMeshLightmap = new BABYLON.Texture(
"assets/lightmaps/" + currentMesh.name + "_LM.jpg",
scene
);
currentMeshLightmap.name = currentMesh.name + "_LM";
// we start cycling through each mesh material(s)
if (!currentMesh.material) {
// no material so skipping
continue;
} else if (!currentMesh.material.subMaterials) {
// no subMaterials
assignLightmapOnMaterial(
currentMesh.material,
currentMeshLightmap
);
} else if (currentMesh.material.subMaterials) {
// we cycle through subMaterials
for (var j = 0; j < currentMesh.material.subMaterials.length; j++) {
assignLightmapOnMaterial(
currentMesh.material.subMaterials[j],
currentMeshLightmap
);
}
}
}
/** END OF LIGHTMAP ASSIGNATION PROCESS **/
}
);
Si vous souhaitez faire usage du copier-coller sans analyse, ne vous concentrez que sur cette partie : var lightmappedMeshes = ["wallz.000", "furnitures.000"];
où il vous faut renseigner le nom de vos meshes à lightmapper.
Evidemment sur une scène avec des dizaines ou centaines d'objets il vous sera impossible de maintenir une telle liste manuellement, mais automatiser tout ça rendrait le code moins compréhensible pour un néophyte du javascript, j'ai donc fait ce choix pour ce tutorial.
voir tuto03.html
Bon alors on se rend vite compte ici qu'il manque un réglage sur notre rendu. Quand on a activé le paramètre useLightmapAsShadowmap
dans nos matériaux lightmappés, on a l'ambientColor de la scene qui agit en multiply. Ainsi, si cette couleur est grise, la plus haute valeur d'ambient de nos matériaux, même si celle-ci est blanche, sera grise aussi (clampée par la scene.ambientColor).
On passe donc cette ambient en blanc, dans notre sceneLoader :
scene.ambientColor = BABYLON.Color3.White();
voir tuto04.html
L'éclairage dynamique
Vous aviez peut-être déjà placer une pointLight dans Blender ? (Creez-en une si non) Celle-ci est bien exportée et agit déjà sur vos matériaux, sur les diffuse & specular color :
Blender | BabylonJS |
---|---|
Tout comme les matériaux, le plus vous préréglez dans Blender, le plus simple c'est. Pour des réglages plus avancés, vous devriez comprendre comment faire une fois la partie sur les réglages matériaux effectuée.
Les matériaux
Pour connaitre tous les paramètres qui nous sont accessibles, comme d'hab'... il faut regarder la doc'. N'oubliez pas que le plus simple est d'utiliser les paramètres accessibles directement via Blender.
Ainsi donc, comment accèder à un matériau en javascript ? Tout d'abord, nous allons lancer l'outil Inspector, qui va nous permettre d'accèder à des réglages de scène avec une UI.
On va donc placer l'appel de cet outil à la fin de notre fonction de sceneLoader :
[...]
}
/** END OF LIGHTMAP ASSIGNATION PROCESS **/
/* tools */
scene.debugLayer.show();
}
);
[...]
Mettons qu'il nous tienne à coeur de passer notre mur blanc en rose. Il nous suffit d'aller dans l'onglet Material, de trouver notre matériau (utiliser le Filter by name...), de trouver notre ambientColor et de la régler.
Vous rechargez alors votre page pour vérifier que ça soit bien pris en compte... et là c'est le drame : évidemment, notre réglage s'est perdu en route.
On va donc créer une variable javascript correspondant à notre matériau, et lui assigner en dur notre paramètre :
[...]
}
/** END OF LIGHTMAP ASSIGNATION PROCESS **/
var wall01Mtl = scene.getMaterialByName("scene_BJS.wall01.000");
wall01Mtl.ambientColor = new BABYLON.Color3(0.87, 0.2, 0.57);
/* tools */
scene.debugLayer.show();
}
);
[...]
Et hop ! on est bon.
voir tuto05.html
Alors vous me direz "Oui mais l'ambientColor on peut la régler sans s'emmerder directement dans Blender non ?", et vous aurez raison, c'était juste pour avoir un paramètre visuel pour le tuto.
La démarche est juste identique pour n'importe quel paramètre, ici en consultant l'API sur l'ambientColor j'ai pu voir que BJS me demandait de lui fournir une Color3, dont acte.
Imaginons que je veuille supprimer une lightmap sur un matériau d'un de mes objets lightmappé ?
scene.getMaterialByName("scene_BJS.wall01.000").lightmapTexture = null;
ici je n'ai carrement pas créé de variable contenant le matériau, c'est probablement une mauvaise pratique
Mes normalMaps ont été générées en norme DirectX et non OpenGL ?
for (var k = 0; k < scene.materials.length; k++) {
scene.materials[k].invertNormalMapY = true;
}
là on boucle carrement parmis tous les matériaux de la scène
Avant de finir ce tuto, une micro-astuce pour vous que vous puissiez facilement simuler un semblant de reflection sans pour autant pêter les perf' : l'utilisation d'une spheremap. C'est une technique qui date de Mathusalem en 3D temps réel et qui donnera vite un aspect cheap, mais sur des surfaces courbes (comme la céramique de notre lampe) aura un effet convenable. Prenez juste un screenshot de votre scène BJS et appliquez un effect de sphérisation :
filtre de sphérisation sous Gimp
Puis dans Blender, assignez votre texture sur votre matériau et passez le Mapping en Spherical.
Finitions
Support du tactile
Pour s'assurer une bonne compatibilité des dispositifs tactiles, ils nous faut ajouter une librairie javascript nommée PEP.
Téléchargez la version minifiée ici, placez-là dans le dossier BJS/js/
puis appelez-là dans la balise <head>
.
Il vous faudra aussi ajouter touch-action="none"
dans la balise <canvas>
<!doctype html>
<html>
<head>
[...]
<script src="https://nothing-is-3d.com/js/babylon.js"></script>
<script src="https://nothing-is-3d.com/js/pep.min.js"></script>
[...]
</head>
<body>
<canvas id="canvas" touch-action="none"></canvas>
Et voilà, vous avez le support du tactile.
Les post-processes
Si vous le souhaitez, vous pouvez ajouter des post-processes, je vous laisse lire la doc' officielle. Sur ma démo présentée en début de page, j'ai juste utilisé un glowLayer, en plaçant à la fin de ma fonction SceneLoader
ce bout de code :
var glowLayer = new BABYLON.GlowLayer("glowLayer", scene)
Résultat
Je ne vous ais pas mâché tout le travail dans ce tuto, ni détaillé chaques opérations effectuées, mais vous devriez pouvoir arriver à ce résultat sans trop de difficultés:
voir tuto-final.html
Bien entendu, jettez un oeil sur les sources fournies en début de tutoriel.
Aller plus loin
Voici quelques pistes & astuces en vrac pour tendre vers la classe ultime :
- ajouter du contraste sur les lightmaps avec une passe d'ambient occlusion
- ajouter des post-processes (mais attention : une scène 3D temps réel doit toujours être belle même avec ceux-ci désactivés)
- apprendre javascript : évidemment quand on parle de webGL, le plus on connait javascript, le mieux on va s'en sortir
- apprendre python afin de pouvoir automatiser des taches chiantes sous Blender, exemples :
- assignation auto du
_cycles_default_
on link obj, voir même autoconvert du material courant (pour avoir le naming conversé) - relink automatique des matériaux cycles configurés, utilisation de Data ou Obj pour l'assignation mat'
- possibilité d'automatiser des taches comme le baking (sans passer par un plugin externe)
- améliorer des addOns qu'on utilise (et y pousser ses suggestions et modifications bien entendu)
- assignation auto du
Crédits
Logiciels
Les logiciels et addOns utilisés sont :
-
Blender 2.79b, avec ces addons:
- exporteur BabylonJS 5.6.3
- le workflow du texture baking de base de Blender est tout pourri, c'est pourquoi je me suis acheté l'addOn Baketool, que j'ai utilisé ici. Notez qu'il est possible que les addOns gratuits suivants peuvent vous être utiles (je ne les aient pas tous essayés, n'hésitez pas à m'en suggérer d'autres) : TexTools, BRM-BakeUI, Principled-Baker.
- Materials Utils Specials (par défaut)
- Layer Management (par défaut)
-
BabylonJS 3.3.0
-
Gimp 2.10. Je trouve Photoshop bien plus pratique, mais je n'ai pas de licence personnelle. Donc pourquoi ne pas profiter de l'écriture de ce tuto' pour tenter de mieux le maitriser. Krita vaut son test aussi.
-
EasyPhp Devserver 17.0 pour le server web local
-
Quelques éditeurs de code en vrac :
-
et pour écrire et préparer ce tuto, en vrac :
- Typora, éditeur léger en markdown
- ScreenToGif, capture d'écran et éditeur de gif
- Greenshot, capture d'écran et édition rapide
- XnView, visualiseur d'images et traitements rapides
- OBS Studio, capture d'écran en vidéo
- Moukey, affichage des actions claviers & souris (d'ailleurs, si vous avez mieux ?)
Ressources
Changelog
- 2018-10-08:
- ajout du changelog
- ajout de la partie Finitions (tactile, post-processes)
- mise à jour du zip des sources