Select Page

Time Travellers – WIP 20

Jan 21, 20243D, Modelling, WIP

Before sharing the progress on the artwork, let’s talk about optimization on pre-calculated projects.

Those of you following my work since Versus: The way to shadows know I’m used to find solutions to avoid crashes at render time, specially on animated or intensive VFX projects like Unexpected Gifts or Christmas in Alsace.

This time, as my current artwork is full of details in the models and textures, I’m at a point I need to drastically optimize my entire scenes. Even if you’re working on killer rendering machines, for big projects I encourage you to optimize your scenes and files using the following steps. Of course, everything depends on the scale of your project, as for mine, here are the processes I  used:

Avant de partager l’avancement de l’illustration, parlons optimisation de projets pre-calculés.

Ceux qui suivent mon travail depuis Versus: The way to shadows savent que je cherche constamment des solutions pour éviter les crashes au moment du rendu, spécialement sur les projets animés et aux VFX intensifs comme Unexpected Gifts ou Christmas in Alsace.

Cette fois, comme mon projet est une illustration aux modèles et textures détaillées, j’en suis rendu au point d’optimiser drastiquement mes scènes. Même si vous travaillez sur des machines de guerre, pour des gros projets je vous encourage à appliquer les étapes suivantes. Bien-sur, tout dépend de l’échelle de votre projet. Par rapport au mien, voici les procédés que j’ai utilisé:

Convert textures

Using jpegs over tga ou png takes less time to load the textures when you launch the render. Same for using 8bits vs 16bits images. Of course you can keep 16 or 32 bits for your normal and displacement maps if you want fine details and avoid stair stepping look.

Converting your images texture files as TX files will also reduce loading times when renders are launched.

Utiliser des Jpegs au lieu des TGA, PNG ou autre prendra moins de temps lors du chargement des textures. Il en va de même concernant l’utilisation du 8bits vs 16bits. Bien entendu, vous pouvez gardez du 16 ou 32 bits pour vos normales et displacement maps pour éviter l’effet escalier.

Convertir vos images au format TX réduira aussi les temps de chargement au moment du rendu.

Jpeg 11,8Mo vs Png 100Mo
Png textures took 4min03 VS Jpeg textures took 3min16 to load and render
3ds Max – Arnold – CPU

Normal VS Displacement

Keep medium/fine details for normal maps only

Unless you have extremely closeup shots on a detailed mesh, keep the low and medium details for the displacement maps and high/fine details in your normal maps = you won’t need to subdivide your meshes so high at render time, or try to smartly subdivide your model to get higher polygones density on detailed displacement map areas. You can also use extremely fine details from a 2D bump map.

Gardez les détails moyens/fins pour vos normal maps

A moins d’avoir des plans très proches d’un mesh détaillé, gardez les détails légers et moyens pour la displacement et les détails fins/hauts pour les normal maps = vous n’aurez pas à autant subdiviser vos meshes au moment du rendu. Ou alors tentez de subdiviser intelligemment vos maillages pour obtenir plus de densité dans les zones demandant plus de détails. Vous pouvez aussi ajouter les détails extrêmement fins via du bump 2D.

Stair stepping in the 16 bits (left) VS Smooth results with the 32 bits displacement map (right)
Be smart when using these texture maps to avoid exaggerated results

Decimation VS Subdivision

On static meshes (not deforming with skin modifier) do you really need to subdivide your mesh 7 or 8 times at render time? I don’t, therefore here is the destructive workflow I used on most of my static meshes:

Using a shoe from my scene as example, I manually subdivided the meshes with edge loops to get an homogeneous topology on the surfaces, added a few subdivisions with turbosmooth or opensubdiv (subdivision in Blender) then I imported the mesh Zbrush with GoZ, subdivided the mesh a couple more of time. I applied my displacement map and finally used Decimation master plugin to drastically reduce the amount of polygones while keeping a certain density to feel the displaced effect. Of course you must keep the UVs during this process to be able to use your already created base color, roughness and normal maps.

This way, you physically create the entire rendering process on your mesh but the decimation process give you a lighter mesh. For all the hands in my scene, the subdivision process cranked the polygones count to 47.5 million, the result has been reduced to 2,8 million polygones. The missing details will come at render time with roughness and normal maps.

Sur les maillages statiques (non déformés par un skin modifier) avez-vous réellement besoin de 7 ou 8 subdivisions au moment du rendu? Pour ma part non,j’ai donc utilisé ce procédé destructif sur mes maillages:

En prenant une chaussure comme exemple, j’ai manuellement subdivisé le maillage avec des edge loops pour obtenir une topologie homogène, d’autres subdivisions ont été appliquées via un turbosmooth ou opensubdiv (subdivision dans Blender), j’ai importé le tout dans Zbrush via GoZ, et je l’ai encore subdivisé quelques fois. J’ai appliqué la map de displacement et j’ai utilisé le plugin Decimation master pour réduire au maximum le nombre de polygones tout en gardant un volume acceptable qui montre l’effet du displacement. Bien-sur il faut garder les UVs dans ce procédé afin d’appliquer les textures déjà créées (le cas dans mon projet), les détails additionnels provenant de la base color, roughness et normal maps.

Ainsi, on applique dans la viewport ce qui se passe au moment du rendu sauf que la décimation nous offre un mesh beaucoup plus léger. Pour toutes les mains de ma scène, la subdivision originale faisait monter le nombre des polygones à 47.5 millions. Le résultat a été réduit à 2.8 millions. Les détails additionnels arrivent au moment du rendu via les roughness et normal maps.

Rendered in 3ds Max and Arnold – CPU mode

UV Optimization

A brief word about unwrapping. As my project is a still image, I focused on the parts that will be visible in the camera, meaning the non visible parts have tinier UV spaces, this way I could get more details on my textures.


Un petit mot sur les UVs. Mon projet étant un rendu d’image fixe, je me suis donc concentré sur les parties visibles à la caméra, c’est à dire que les parties non visibles ont été logées dans des plus petits îlots d’UVs = plus de détails dans les textures.

Meshes Optimization

The more modifiers you’ll add on top of your mesh, the more time it will take to handle it at render time. Try to collapse/apply the modifier on your meshes as much as possible. This is the last step before rendering the final scene. In 3ds Max, if you have a non animated noise applied on a mesh, collapse it to an editable poly, same for unwrapping, etc.

Also, if some of your meshes go out of frame and they don’t have a particular impact on what you see in the camera, like a projected shadow or light bounce affect, reduce the poly count by deleting the non visible polygones. This is what I did on the hands, walls and floor meshes because of the decimation process used earlier. If you want to keep the non visible meshes, drastically lower their poly count, keeping the basic volume.

Plus vous aurez de modifiers dans votre maillage, plus il mettra du temps à être géré au moment du rendu. Essayer d’écraser/appliquer au maximum les modifiers dans vos meshes. Il s’agit de la dernière étape avant le rendu final. Dans 3ds Max, dans le cas d’un rendu image fixe, si vous avez un modifier Noise appliqué au mesh, écrasez le tout dans un editable poly, de même pour l’unwrapp, etc.

Aussi, si certains de vos maillages sortent du cadre et qu’ils n’ont aucune incidence sur ce qu’on voit à la caméra, comme une ombre projetées ou un effet de rebond de lumière, réduisez le nombre de polygones en supprimant les parties non visibles. C’est ce que j’ia fait sur les murs, sols et mains dans ma scène, suivant le procédé de décimation. Si vous désirez garder les meshes non visibles, simplifiez les au maximum.

All that won’t be seen in frame is either deleted (arms) or decimated (walls)
The non visible part of the bed (covered by the blanket) was cut and heavily decimated


Less time loading before the render finally starts because there is less subdivision processes on each meshes. Textures load faster (and depending on your specs: you run out of memory less often) = overall shorter render times.

Les temps de chargements seront moins longs car moins de subdivisions à appliquer. Les textures chargeront plus rapidement et selon vos machines: moins de message d’erreur liés au manque de mémoire = Rendus plus rapides. Et je n’entends pas par là le rendu en lui même mais bien toute la partie de chargement/préparation précédent le rendu.


With all that said, I began applying these ideas to be able to launch renders using Cycles. Since my current GPU is too weak, I’m now turning to CPU rendering for various advanced rendering tests. Good news, it works, and only one major element is missing in the final scene: the hair of the female character, which I’ll come back to at the end of this article.

Since the beginning of these optimizations, new models have been created: headphones, fully modeled and unwrapped in Blender to push myself to learn the software a bit more. Everything was quickly textured along with other props. Other models have also been adjusted, like all the bedding, including the duvet, on which I spent a lot of time working on the base material to achieve a tangible fabric.

Tout cela étant dit, j’ai donc commencé à appliquer ces idées pour être capable de lancer les rendus sous Cycles. Mon GPU actuel étant trop faible, je me tourne à présent vers le rendu CPU pour les différents tests de rendus avancés. Bonne nouvelle, ça fonctionne et il ne manque qu’un gros élément dans la scène finale: les cheveux du perso féminin sur lesquels je reviendrai à la fin de cet article.

Depuis le début de ces optimisations, de nouveaux modèles on été créés: des écouteurs, entièrement modélisés et unwrappés sous Blender pour me forcer à apprendre un peu plus le soft. Le tout a été rapidement texturé avec d’autres props. D’autres modèles ont encore été ajustés, comme toute la literie dont la couette sur laquelle j’ai passé énormément de temps à travailler le material de base pour obtenir un tissu tangible.

The decimation workflow has been applied to the book pages as well
Cloth pull brush FTW

However, the female character was rigged, skinned, and posed in 3ds Max, then the body was adjusted in certain areas in Zbrush to fix some skinning issues. Several poses were experimented with before returning to the initial intention

Cependant le personnage féminin a été riggé, skinné et mis en pause dans 3ds Max, puis le corps a été ajusté par endroit dans Zbrush pour régler certains soucis de skinning. Plusieurs poses ont été expérimentées avant de revenir à l’intention initiale.

As mentioned in the optimization section of this article, the hands were optimized through a process in Zbrush to obtain a lighter model that takes less time to load during rendering. The same applies to the hands of the main character.

Comme dit dans la partie optimisation de cet article, les mains ont été optimisées via un passage par Zbrush pour obtenir un modèle plus léger et mettant moins de temps à charger au moment du rendu. De même pour les mains du perso principal.

47.5 Million polygons to 2.8 Million polygons
The material mix for arms + hands was more complex to create in Blender than in 3ds Max

The final challenge of this illustration. I would have loved to use Ornatrix to create the hair for the second character, but I’ll have to work with Geo nodes instead. I regret that some basic functions, like managing the frequency of a frizz hair, are not directly accessible in the modifier, and that you have to dive into the node graph to find the right value to modify, similarly for applying the effect along the hair. At the moment, I’m at the stage of defining the main volume using curves that will serve as guides for the creation of the hair, strand by strand.

Le dernier challenge de cette illustration. J’aurais aimé utiliser Ornatrix pour créer les cheveux du second personnage mais je vais devoir faire avec les Geo nodes. Je regrette que certaines fonctions de bases comme la gestion de la fréquence d’un frizz hair ne soit pas accessible directement dans le modifier et qu’il faille fouiller dans le node graph pour trouver la bonne valeur à modifier, de même pour l’application de l’effet le long du cheveux. J’en suis pour le moment rendu à l’étape de définition du volume principale via des curves qui serviront de guides pour la création même des cheveux, mèches par mèche.

Pin It on Pinterest