Si les GPU prennent de plus en plus de place dans le monde du rendu 3D, ce n'est pas le seul changement d'importance qui touche ce secteur. L'intégration de denoiser toujours plus rapides et efficace change également la donne. Jusque dans des produits open source tels que Blender.
Ces dernières années, le monde du rendu 3D est bousculé par plusieurs révolutions, notamment en ce qui concerne le ray tracing. On pense bien entendu à l'accélération matérielle apportée par les GPU, bien plus rapides que n'importe quel CPU sur le marché. Surtout depuis l'architecture Turing de NVIDIA et ses RT Cores.
Des unités de calcul particulières devant accélérer le test des bounding box et des intersections entre un triangle et un rayon via des structures arborescentes dites Bounding Volume Hierarchy (BVH).
- NVIDIA : architecture Turing, nouvelles Quadro RTX, solutions de ray tracing et prochaines GeForce
- TU102, TU104 et TU106 : que cachent les nouveaux GPU Turing de NVIDIA ?
Mais cela concerne également la façon de calculer les images. En effet, il n'est plus nécessaire de lancer des milliers de rayons et de les suivre à la trace pour obtenir une image parfaite. Désormais, une pratique commune consiste à en limiter le nombre ce qui donne une image imparfaite, « bruitée ». Puis d'y appliquer un filtre de denoising.
Un exemple de denoising de l'OID d'Intel, le traitement d'une image sur Turing et l'accélération matérielle du ray tracing via les BHV
C'est ce qui permet d'obtenir des performances bien plus élevées, avec un rendu de type ray tracing appliqué en temps réel. Chaque constructeur pour cela une solution maison, consistant en général à appliquer un modèle issu d'un apprentissage profond (deep learning), avec des optimisations pour son matériel.
Si une telle méthode est adaptée aux jeux, elle l'est aussi dans des environnements où un débit d'images rapide est nécessaire comme le viewport d'une application de rendu 3D. De quoi cumuler un rendu accéléré avec un denoising efficace. C'est le pari fait par les développeurs de l'outil open source Blender avec sa branche 2.8x.
Mais dans la pratique, comment en profiter et quel est le résultat ?
Intel OID et NVIDIA OptiX : deux approches assez différentes
Blender 2.81, 2.82 et la prochaine 2.83 ont apporté un lot important de nouveautés sur ces sujets. En effet, la première a introduit la bibliothèque Open Image Denoise (OID) d'Intel, qui fait partie de son oneAPI Rendering Toolkit. Un denoiser basé sur un modèle issu d'un apprentissage profond, exploitant la Math Kernel Library for Deep Neural Networks (MKL-DNN) et tirant parti de jeux d'instructions tels que SSE4, AVX2 et AVX-512. Bref, des CPU récents d'Intel.
Blender 2.81 intégrait également un premier support d'OptiX de NVIDIA, permettant de préférer un tel rendu à CUDA sur les GeForce/Quadro RTX et donc de l'accélération matérielle des RT Cores. Mais cette solution dispose également d'un denoiser, exploitant lui aussi un modèle issu de l'intelligence artificielle depuis sa version 5.0.
Il est basé sur une publication de plusieurs chercheurs du constructeur effectuée en collaboration avec Derek Nowrouzezahrai de la McGill University. Sa mise en œuvre est accélérée par un autre type d'unités spécifiques aux architectures récentes de NVIDIA (Volta, Turing), spécialisées dans les calculs matriciels : les Tensor Cores.
Ce sont elles qui sont exploitées pour obtenir un résultat efficace et rapide. Blender 2.82 permet l'utilisation d'OptiX avec son accélération matérielle pour le rendu d'une scène sur GPU. La prochaine version 2.83, actuellement en alpha, permettra également d'en profiter avec un rendu CPU et au sein du viewport.
Notez que tant l'approche d'Intel que de NVIDIA, consiste à s'intégrer au moteur Cycles de Blender avec une gestion native (même si l'implémentation diffère comme nous allons le voir). Une situation différente de ProRender chez AMD qui est un plugin externe devant être utilisé comme un moteur à part entière, avec un rendu qui lui est propre.
Nos conditions de test et résultat d'un rendu par défaut
Pour mieux comprendre l'intérêt du denoising, il faut un peu se plonger dans les paramètres de Blender. Pour cela, nous utilisons la dernière version 2.83a en date, sous Windows 10.
La scène que nous utilisons est le fichier de démo Spring de Pablo Vazquez, qui se compose de deux personnages : Andy et son chien Nacho, courant dans l'herbe. On y trouve donc une multitude d'éléments complexes. Par défaut le rendu est effectué sur CPU, avec des tuiles de 16x16 pixels (nous en reparlerons dans un prochain article) et le denoiser par défaut de Blender. L'image est générée à une définition de 2004 x 1000 pixels (en réalité 1002 x 500 pixels à 200%).
Voici le résultat :

Le rendu de la scène Spring sous Blender 2.83a sur CPU avec ses paramètres par défaut
Le denoiser pour réduire le temps de rendu
Dans les paramètres de la scène, un élément est particulièrement important : le sampling (voir la documentation). On peut y trouver qu'il s'agit d'un rendu de type path tracing, avec 300 rayons par pixel. Un nombre élevé, mais on a vu pire dans certaines scènes régulièrement utilisée pour des benchmarks.
Cela s'explique par un point précisé précédemment : le denoiser par défaut de Blender est actif dans les paramètres de cette scène. Malgré cela, un Core i5-9600K (6C/6T de 3,7 à 4,6 GHz) nécessite 1 739 secondes, soit 28 minutes et 59 secondes pour effectuer le calcul complet.
Si on désactive le denoiser et qu'on demande un rendu avec 1 000 rayons par pixels, il faut alors 5 340 secondes soit... 1h29. On le voit, l'utilisation d'un rendu avec moins de rayons mais le denoiser permet de réduire par trois le temps de rendu, tout en disposant d'un résultat bien plus correct :
Rendu avec 300 rayons et 1 000 rayons sans denoiser puis 300 rayons et le denoiser par défaut
L'action du denoiser étant assez rapide (quelques secondes pour passer de l'image « bruitée » au rendu final), il s'agit d'un élément essentiel pour gagner un temps précieux. Il est d'ailleurs possible d'aller plus loin. On peut en effet imaginer encore réduire le nombre de rayons, tout en gardant un résultat tout aussi convenable.
L'utilisation d'un bon denoiser est alors nécessaire. C'est d'ailleurs sur ce critère qu'ils se distinguent les uns par rapport aux autres, plus que sur leur rapidité d'exécution : être capable de finaliser précisément le rendu d'une image même avec peu de rayons. Et de l'aveu même des équipes de Blender, celui qu'ils proposent par défaut est encore incomplet et imparfait dans de telles conditions. C'est là qu'Intel et NVIDIA entrent en scène.
Comment activer le denoiser OptiX de NVIDIA ?
Pour activer celui d'OptiX, c'est assez simple. En effet, il se trouve dans les propriétés des couches de la scène, comme celui utilisé par défaut. Il suffit donc de le choisir à sa place, ainsi que les passes sur lesquelles on veut qu'il soit actif, de manière cumulative : Color, Albedo, Normal. Plus vous en sélectionnez, plus ce sera précis prévient Blender.
Pour connaître son niveau de qualité, nous avons opté pour un rendu sur CPU (ce qui n'est pas encore possible avec Blender 2.82), en utilisant les trois passes du denoiser Optix « AI-Accelerated ». Voici le résultat avec un rendu avec 50, 150 et 300 rayons par pixel, nécessitant 6, 17 ou 29 minutes envion.
Notez que ces conditions ne sont pas idéales pour le denoiser de NVIDIA, les GPU étant plus à l'aise avec de grandes tuiles plutôt que de petites de 16x16 pixels (nous y reviendrons dans un prochain article).
Sans denoising - 50 rayons, 150 rayons et 300 rayons
Denoiser Blender - 50 rayons, 150 rayons et 300 rayons
Denoiser NVIDIA OptiX - 50 rayons, 150 rayons et 300 rayons
Comme on peut le voir, le denoiser de Blender affiche un résultat assez médiocre avec peu de rayons. C'est d'ailleurs encore pire si l'on fait un test avec un chiffre moindre (comme 10 par exemple). Systématiquement, la solution de NVIDIA offre un résultat meilleur, mais cela a un prix : à y regarder de près on perd en finesse de détail.
Un rendu sur GPU avec Denoiser IA : le bon compromis ?
Ainsi, les dents du personnage ou les plis de son col sont moins visibles. Un problème que l'on peut régler en exploitant un autre avantage d'OptiX : le rendu accéléré sur GPU.
Ainsi, il n'est plus nécessaire d'attendre 1h30 si l'on effectue un rendu avec 1 000 rayons ou plus. Nous avons d'ailleurs fait un essai pour le vérifier : avec 3 000 rayons, 18 minutes sont nécessaires au rendu (sur une GeForce RTX 2080 Ti), avec un résultat bien plus net sur de nombreux détails :

Rendu sur GPU et denoising via OptiX, avec 3 000 rayons
Comment activer le denoiser OID d'Intel ?
Activer Open Image Denoise est un peu plus compliqué. Cela passe par l'ajout d'un filtre sous la forme d'un nœud dans la fenêtre de compositing. Il faut pour cela activer les métadonnées de réduction du bruit, ajouter le nœud, y brancher les différentes sources de données et la sortie au reste de la phase de rendu.
Une manipulation qui complexifie la mise en œuvre ou même l'essai pour l'utilisateur, qu'il soit initié ou non. Pour vous simplifier la vie, nous avons adapté la scène Spring en gardant ses paramètres par défaut, désactivant le denoiser de Blender, ajoutant l'Open Image Denoise d'Intel.
Voici le résultat avec 50, 150 et 300 rayons :
Denoiser Intel OID - 50 rayons, 150 rayons et 300 rayons
Ici, on constate le même phénomène qu'avec OptiX, chacun ayant ses avantages et ses défauts. La solution d'Intel est meilleure sur la précision de certains éléments, notamment les ombres, mais on perd en détails sur d'autres, comme la texture des vêtements par exemple. Tout dépendra donc de vos besoins et préférences.
Si vous souhaitez faire vos propres comparaisons sur différents éléments de la scène, de manière plus complète, nous mettons à votre disposition l'ensemble des rendus calculés :
Comment profiter d'OptiX dans le viewport de Blender ?
OptiX dispose néanmoins d'un autre avantage que sa plus grande facilité de mise en œuvre, il est également plus flexible, pouvant être utilisé désormais sur CPU, GPU, pour un rendu ou dans le viewport.
Ce dernier cas n'est pas géré par l'Open Image Denoise d'Intel. Pour la solution de NVIDIA il faut disposer de la version 2.83 de Blender, actuellement distribué dans la section des builds expérimentales, mais aussi d'un pilote à jour (440.59+ sous Linux, 441.87+ sous Windows) et d'une GeForce RTX.
Pour vérifier comment cela fonctionne, nous avons utilisé la démo Procedural (Blenderman) distribuée par Blender. Nous y avons activé les scripts Python, en chargement automatique via l'onglet Save & Load des paramètres (Menu, > Edit > Prefereces). Puis l'utilisation d'OptiX pour le rendu.
Nous obtenons alors une fenêtre découpée en trois : un viewport à gauche, un second en haut à droite et les paramètres en bas à droite. On active un rendu complet, le calcul commence après quelques secondes, un nuage de points s'affinant peu à peu. Si on passe par OptiX, on note que l'image est vite assez nette, commençant sous la forme de blocs très compressés qui s'affinent là aussi ensuite, mais donnant un résultat probant plus rapidement.
Pour vous permettre de mieux vous en rendre compte, voici une vidéo réalisée sur notre machine de test (la capture étant effectuée depuis le port HDMI, sans impact sur les performances) :