Unity 2018 : Prise en main du Lightweight Render Pipeline

L’année 2018 est très importante pour le moteur Unity 3D qui évolue vers quelque chose de nouveau. Une des ces nouveautés est évidemment la nouvelle pipeline de rendu programmable, aka Scriptable Render Pipeline (SRP). Le but du SRP est de vous permettre de créer votre propre boucle de rendu, et ainsi avoir le rendu que vous voulez. Créer son propre Renderer est tout de même un peu compliqué (pas tant que ça en réalité, mais ça sera l’objet d’un autre article), c’est pour cela qu’Unity propose deux nouveaux Renderers, le Lightweight et le HD Render Pipeline. Dans cet article nous verrons comment exploiter le Lightweight Render Pipeline. La version HD sera quant-à elle traitée un peu plus tard, le temps que certaines fonctionnalités se stabilisent.

Un peu de théorie

Mais au final qu’est ce qu’un Renderer ? C’est une partie du moteur qui va définir comment les objets sont envoyés sur la carte graphique. Voici un morceau de pseudo code qui illustre le fonctionnement d’un Foward Renderer.

public void RenderScene(Camera camera, Scene scene)
{
    foreach (var mesh in scene.Meshes)
        foreach (var ligth in scene.Lights)
            GraphicsDevice.Draw(camera, mesh, light);
}

Suivant l’API graphique utilisée (OpenGL, Direct3D, Vulkan…) on appelle une méthode qui permet d’envoyer les vertices avec les informations des matériaux (textures, paramètres, etc…) sur la carte graphique. Une fois sur la carte graphique, ce sont les Shaders qui prendront le relais pour arriver au final à une image sur votre écran.

Oui je sais… Vous voulez simplement utiliser le nouveau Lightweight Render Pipeline 😉 Mais la théorie était à mon avis utile à connaitre.

Le Lightweight Render Pipeline

Ce nouveau renderer est là pour remplacer le « vieux » Forward Renderer qui est activé par défaut. Il a quelques fonctionnalités en moins, mais d’autres en plus. Je vous recommande de vous rendre sur ce lien pour étudier le comparatif détaillé. Le Lightweight Render Pipeline est plus léger et surtout plus optimisé, en réalité c’est une toute nouvelle architecture taillée pour répondre à deux besoins : Celui des GPU mobiles et des applications AR/VR.

Le HD SRP ne prend pas encore en charge la VR, rassurez vous c’est prévu. Mais à l’heure d’aujourd’hui, si vous avez besoin d’un Deferred Renderer, il faut utiliser le « vieux » Deferred Renderer, ou alors attendre que le HD Render Pipeline devienne compatible. Ce n’est qu’une histoire de mois..

Les nouveautés

Il y a plusieurs nouveautés vraiment intéressantes, je vais juste en décrire quelqu’une ici. Premièrement vous allez pouvoir créer des Shaders avec un éditeur de graphe, exactement comme dans Unreal Engine 4. L’avantage est que ces Shaders fonctionneront aussi bien sur Lightweight que sur HD Render Pipeline (après une recompilation de l’Asset évidemment).

C’est un Forward Renderer simple, donc le nombre de lumières en temps réel est toujours limité. Par contre les lumières sont toutes rendues en une seule passe. Avant il y avait un draw call par lumière sur chaque objets, là il n’y a qu’un seul draw call. Le Shader est un peu plus gros, mais beaucoup plus efficace ! Vous ne devez pas avoir peur d’utiliser plus d’une source de lumière en temps réel désormais.

Dans les points plus négatifs, il n’est pas possible d’utiliser l’illumination global en temps réel (Precomputed GI) et vous ne pourrez backer vos Lightmaps qu’en mode Subtractive. Si vous avez besoin d’éclairage spéculaire, il faudra utiliser une lumière supplémentaire en temps réel.

Note sur la compatibilité

Si vous partez d’un projet existant, sachez que vous devez mettre à jour tous vos matériaux car ce ne sont plus les mêmes shaders. Unity propose un outil intégré pour le faire automatiquement. Cependant si vous utilisez des shaders non standards (téléchargés sur l’AssetStore par exemple) qui ne sont pas Unlit (fonctionnant avec la lumière), ils ne fonctionneront plus. Il faudra soit trouver un équivalent, soit utiliser ShaderGraph pour les refaire, soit vous en passer.

De même, il n’est pas possible d’utiliser des post-process en dehors de la stack Post Processing v2. Certains créateurs d’effets comme Amplify vont render leurs effets compatibles avec la stack Post Processing v2, par contre ce n’est pas le cas de tous, alors attention.

Enfin, la plateforme WebGL n’est pas prise en charge car elle ne permet pas de faire de multi-threading efficace.

Pour résumer, si vous utilisez beaucoup de post-process en provenance de l’asset store, ou que vous utilisez tout un set de shaders custom, ou que votre production cible WebGL, ou que vous ne voulez pas modifier vos matériaux, alors ne mettez pas à jour votre projet vers aucun Scriptable Render Pipeline pour le moment. Vous pouvez essayer de le faire pour le fun, mais s’il vous plait, faites des sauvegardes !

Installation

Il y a plusieurs manières d’installer le Lightweight Render Pipeline, la façon la plus simple et de passer par la création d’un projet grâce au nouveaux templates. Il est aussi possible d’ajouter de l’ajouter à la main (github) ou depuis le gestionnaire de paquet embarqué.

Que vous partiez d’un projet vide, d’un template ou d’un projet existant, faites moi plaisir et activez le Linear Color Space, ainsi que .Net 4.x. Les Scriptable Render Pipeline sont fait pour fonctionner en Linear Color Space. C# 4.x est activé par défaut sur les nouveaux projets.

A partir d’un nouveau projet

Vous avez deux possibilités pour utiliser le Lightweight SRP, la première est de créer un nouveau projet dans Unity en utilisant le template Lightweight SRP. La différence avec la version VR est que le post processing est un peu allégé (certains effets n’ont pas leur place en VR) et que le prefab du joueur est configuré différemment.

Création d'un nouveau projet avec le temps Lightweight Render Pipeline
Création d’un nouveau projet avec le temps Lightweight Render Pipeline

C’est la méthode la plus simple pour démarrer car votre projet sera automatiquement configuré. Le post-processing sera par exemple activé par défaut ! Vous aurez donc un joli rendu dès le début ! Cependant je vous conseil pour ce tutoriel de le faire manuellement, afin de comprendre exactement à quoi tout correspond.

Installation manuelle

Il est tout à fait possible d’installer le Lightweight SRP sur un projet existant. Pour cela il suffit d’ouvrir le package manager et de sélectionner le package Lightweight Render Pipeline. Depuis le menu Window > Package Manager, sur l’onglet All. Il n’est pas nécessaire d’ajouter les package Shader Graph ou Post Processing car ils sont automatiquement ajoutés avec le Lightweight Render Pipeline. Vous pouvez cependant les ajouter quand mêmes, vous aurez ainsi un contrôle sur la version que vous utilisez.

Il faut choisir le paquet Lightweight Render Pipeline et cliquer sur installer
Il faut choisir le paquet Lightweight Render Pipeline et cliquer sur installer

Une fois ajouté, le Lightweight Render Pipeline n’est pas pour autant actif ! Il y a 2 voir 3/4 étapes supplémentaires. La première chose est de créer un Lightweight Render Pipeline Asset. Pour se faire, faites un clic droit le dossier Assets et sélectionnez Create > Rendering > Lightweight Pipeline Asset.

Création du Lightweight Pipeline Asset
Création du Lightweight Pipeline Asset

Réglage de l’asset

Un fichier d’asset est crée, celui-ci dispose de plusieurs options que nous allons détailler tout de suite. Avant beaucoup de réglages de qualité étaient fait depuis les QualitySettings. Tous les Scriptable Render Pipeline, Lightweight, HD ou ceux qui verront le jour plus tard, utilisent un fichier Asset pour définir son fonctionnement. Sachez que vous êtes libre d’en créer autant que vous voulez pour définir des profils de qualité/performance. Il est temps de faire un point sur tous ces paramètres.

Les paramètres du Lightweight Pipeline Asset
Les paramètres du Lightweight Pipeline Asset

Le paramètre Render Scale défini l’échelle de l’image. Par exemple si votre résolution est de 1920×1080 que le paramètre Render Scale a une valeur de 0.5, alors la résolution à l’écran sera de 1920 * 0.5, 1080 * 0.5, soit 960×540. Vous pouvez changer ce paramètre pendant l’exécution du programme, c’est donc super pratique sur mobile par exemple pour gagner quelques FPS ! En AR/VR, l’échelle se contrôle toujours depuis la classe  XRSettings, le paramètre Render Scale ne fonctionnera donc pas en VR.

Pixel Lights et Vertex Lights sont deux paramètres très important si vous travaillez sur un jeu qui utilise plus d’une lumière en temps réel. Le calcul d’une lumière par pixel est plus couteuse que par vertex, cependant le résultat est plus joli quand elle est calculée par pixel. Vous pouvez monter jusqu’à 8 lumières par pixel en temps réel et 4 supplémentaires par vertex, pour un nombre total de 12 lumières en temps réel sur un Forward Renderer ! Evidemment vous pouvez blinder votre scène de lumières, Unity va simplement afficher les lumières les plus proches de la caméra.

Par exemple si vous avez 20 lumières et que votre renderer est réglé pour en affiché 2 par pixel et 4 par vertex. Unity va chercher les 2 lumières les plus proches de la caméras et les affichera par pixel. Ensuite le moteur va chercher les 4 lumières suivantes et va les afficher par vertex. Toutes les autres lumières ne seront pas traitées ! Si par contre vous avez besoin d’utiliser plus de lumière en même temps… Alors il faut passer sur le HD Render Pipeline ou alors sur le « vieux » Deferred Renderer.

Si vous utilisez du Post-Processing avancé je vous recommande de cocher Depth Texture, cela vous permettra d’utiliser plus d’effets. La texture de profondeur a un petit coût sur les performances, même si heureusement le shader est très simple.

Le paramètre HDR doit à mon avis être coché tout le temps, sauf si vous êtes sur mobile et que le GPU est vraiment faible. Une texture dispose de 4 composantes couleurs RGBA qui vont de 0 à 1. Activer le HDR permet de dépasser la valeur maximum de 1. A quoi ça sert ? A plusieurs effets comme le Bloom, l’Eye Adaptation, mais aussi le Tone Mapping (qui est à mon avis l’effet incontournable sur une stack de post processing) ! Si vous visez un beau rendu, ce paramètre est incontournable.

Le paramètre AntiAliasing défini le taux de filtrage du MSAA. Si vous utilisez la stack Post Processing avec du FXAA, vous n’avez pas besoin de ce paramètre. Sinon vous pouvez le monter à 2x voir 4x sur Android (attention aux performances), et entre 4x et 8x sur PC ou console.

Enfin le réglage de l’ombre permet de définir le type d’ombre, la taille de la shadow map, le nombre de cascade. Les ombres de type Soft sont les plus belles (car elle sont filtrées) mais consomment plus. De même plus la taille de la shadow map sera grande et plus les ombres seront belles (même pour une hard shadow), cependant cela a un coût non négligeable sur les performances. Suivant le réglage de vos lumières (temps réel, mixte, backed)  vous pourrez pousser ou pas ces paramètres. Il n’y a pas de réglage magique, mais je dirais que sur mobile, il faut éviter les cascades, les soft shadows et les shadow map de plus de 1024. Sur PC vous êtes vraiment libre, par contre sur console il faudra faire de essais car ça dépendra vraiment aussi de votre éclairage.

Activation, mise à jour et utilisation

Il faut maintenant dire à Unity d’utiliser le fichier que nous venons de configurer, ce qui surchargera le « vieux » Renderer. Depuis le menu Edit > Project Settings > Graphics, puis glissez votre fichier Asset sur le Scriptable Render Pipeline Settings ou sélectionnez le depuis l’explorateur après avoir cliqué sur le petit rond.

Activation du Scriptable Render Pipeline Asset
Activation du Scriptable Render Pipeline Asset

A partir de maintenant le Lightweight Render Pipeline est actif ! Si vous l’avez ajouté sur un projet existant, tous vos matériaux sont violet. Il va falloir les reconfigurer pour utiliser les shaders du Lightweight Render Pipeline. Par chance, si vous utilisez les shaders de base (Standard, Legacy) Unity pourra le faire pour vous en allant dans le menu Edit > Render Pipeline > Upgrade Project Materials to Ligthweight Materials. Les shaders de type Unlit et Skybox n’ont pas besoin d’être mis à jour. Si vous utilisez des shaders spécifiques, il faudra par contre faire la conversion à la main. Mais vous ne devriez pas avoir de soucis.

  • Lightweight Pipeline/Standard (PBR) est l’équivalent du shader Standard avec des options en plus (double sidded par exemple)
  • Lightweight Pipeline/Standard (Simple Ligthing) est l’équivalent du Legacy/Diffuse avec des options en plus (double sidded par exemple)
  • Lightweight Pipeline/Terrain pour les terrain (no kidding!)
  • Lightweight Pipeline/Particles/ Pour les particles, avec là encore des options en plus

Activer le Post Processing

Si vous démarrez sur un projet existant il est possible que le Post-Processing ne soit pas activé. On va corriger ça en un rien de temps car c’est important que cette fonctionnalité soit activée pour tirer parti au mieux des nouveaux SRP.

La première étape est d’ajouter sur la caméra du joueur, le script PostProcess Layer.

Ajout du PostProcess Layer sur la caméra
Ajout du PostProcess Layer sur la caméra

Vous devez choisir le Layer sur lequel le PostProcess Volume se trouve. Unity propose maintenant par défaut un Layer nommé PostProcessing. Si vous ne l’avez pas, vous pouvez simplement le créer, puis le sélectionner sur ce composer.

Maintenant nous allons créer un GameObject vide sur la scène et y attacher un script PostProcess Volume. Changez le Layer du GameObject et mettez le sur PostProcessing. Vous êtes maintenant prêt à ajouter les effets qui rendront votre scène encore plus vivante.

Activation du PostProcess Volume
Activation du PostProcess Volume

Comme sur la capture d’écran ci-dessus, cliquez sur le bouton New, ça va créer et ajouter un nouveau PostProcess Profile, c’est un fichier Asset, exactement comme le Lightweight Pipeline Asset. Vous allez pouvoir lui ajouter des effets, voici la configuration que je vous recommande.

  • Color Grading : Mode ACES
  • Bloom : Intensité à 2 et Threshold à 1, il est important de ne pas trop descendre cette valeur car votre rendu sera plus flou. Un bon réglage des matériaux émissif sera suffisant à avoir un bon Bloom. Si vous voulez un peu de Flare, vous pouvez activer Anamorphic Ratio avec une valeur supérieur ou inférieur à 0.
  • Vignette : Intensity / Smoothness / Roundness à 0.5

Et rien qu’avec ça vous aurez un rendu de bien meilleur qualité ! Par contre en VR, je vous recommande de désactiver la Vignette car ça va masquer un peu le champs de vision. Vous pouvez par contre l’activer lors d’un déplacement forcé 😉

Un rendu de base sans aucun Post-Processing
Un rendu de base sans aucun Post-Processing
Un rendu de base avec juste trois effets
Un rendu de base avec juste trois effets

Votre premier Shader graphique avec ShaderGraph

Maintenant que tout est configuré, vous allez pouvoir profiter de toute la puissance d’Unity 2018. Sachez que vous n’êtes pas obligé d’utiliser ShaderGraph, vous pouvez utiliser les Shaders livrés avec le Lightweight Render Pipeline. De même, vous n’avez pas à créer un shader par material, ne tomber pas dans le piège que certains font avec d’autres moteursL’idée est de créer un shader qui répond à un besoin et de le réutiliser !

On va commencer par créer un cube, puis un nouveau material, que l’on va mettre sur ce cube. De là faites un clic droit dans l’explorateur d’assets Create > Shader > PBR Graph, pour créer votre premier shader avec ShaderGraph.

Création d'un graph pour un shader PBR
Création d’un graph pour un shader PBR

Puis double cliquez sur le Shader pour ouvrir ShaderGraph. Par défaut le graph sera peut être un peu petit, n’hésitez pas à utiliser la molette de la souris pour zoomer et pour vous déplacer. Vous devriez avoir quelque chose comme l’image ci-dessous.

Prise en main de ShaderGraph
Prise en main de ShaderGraph

Vous pouvez voir une liste de paramètre dans le rectangle du milieu. Ces paramètres vous les connaissez déjà.

  • Albedo est la texture principale (Albedo/Diffuse Texture)
  • Normal c’est la texture de normal
  • Emissive celle d’émission (pratique pour le bloom)
  • Smoothness permet de régler l’intensité de reflexion (Specular)
  • Workflow Metalic ou Specular, comme le « vieux » Shader Standard
  • Two Sidded indique qu’il faut dessiner ce matérial sur les deux faces d’un triangle
  • Etc….

Nous allons créer un shader tout simple avec une texture de diffuse (Albedo). Lorsque vous faites un clique droit sur le graph, vous pouvez créer un nouveau noeud (Create Node). Nous allons en créer deux. La premier sera un Texture 2D Asset, c’est le noeud qui permet de passer une texture en paramètre. Ensuite il faut créer un noeud Sample Texture 2D. Une fois que vous avez ces deux noeuds, il faut les relier ensemble comme sur l’image ci-dessous.

Votre premier shader simple avec ShaderGraph
Votre premier shader simple avec ShaderGraph

Vous remarquerez que vous pouvez choisir une texture par défaut sur le noeud Texture 2D Asset.

Utilisation d'une texture par défaut
Utilisation d’une texture par défaut

Si nous voulons un Shader réutilisable, il faut que l’on puisse changer la texture. Pour cela il faut en créer une propriété.

Conversion d'un noeud en paramètre
Conversion d’un noeud en paramètre

Pour cela rien de plus simple, faites un clic droit sur le noeud Texture 2D Asset, puis faites Convert To Property. La propriété apparait désormais sur le blackboard à votre gauche. Vous pouvez la renommer, choisir une valeur par défaut, etc…

On va ajouter un dernier paramètre, celui de Smoothness. Vous constatez sur le rectangle central a ce paramètre et qu’il a la valeur 0,5 par défaut. On va créer un nouveau noeud Vector 1 et le relier à la patte Smoothness. Pour ajouter une nouvelle propriété, on va faire un clic droit sur le noeud Vector 1 et choisir Convert To Property.

Création d'un nouveau paramètre
Création d’un nouveau paramètre

Vous remarquerez que l’on peut choisir le type d’affichage dans l’éditeur pour certaines propriétés. Pour Smoothness on peut utiliser un Slider 😛 On va revenir sur l’éditeur justement et assignez notre nouveau shader sur le material crée précédemment. Avant ça il ne faut pas oublier de cliquer sur Save Asset en haut à gauche pour que Unity compile le shader. Si votre shader ne fonctionne pas, c’est probablement car vous n’avez pas cliqué sur ce bouton.

Utilisation du shader crée avec ShaderGraph sur le material du cube
Utilisation du shader crée avec ShaderGraph sur le material du cube

Sachez que vous pouvez faire énormément de choses avec ShaderGraph. Il y a deux choses vraiment bien à garder en tête. Déjà vos graphes peuvent être utilisés sur les Lightweight et HD Render Pipeline. Donc si vous commencez un projet sur Lightweight, vous pourrez le migrez sur HD sans problème. Dans ce cas, il faudra ouvrir vos shader dans ShaderGraph et cliquer sur Save, pour qu’ils soient recompilés pour le Scriptable Render Pipeline Asset en cours dans Unity. Enfin cet éditeur de graph est puissant, il dispose d’un paquet de noeuds, par exemple il y a un noeud Create Normal, qui prend en paramètre une texture et donne en sortie une normal map ! Essayez donc de modifier le shader que nous venons de faire en ajoutant une normal map automatique 😉

Ajout de la création automatique d'une normal map
Ajout de la création automatique d’une normal map

Conclusion

Nous avons beaucoup de sujets à traiter pour parler d’Unity 2018, nous avons commencé avec le Lightweight Render Pipeline, mais nous traiterons prochainement du HD Render Pipeline, des C# Jobs, du nouveau système entité component qui va remplacer vos MonoBehaviours… Mais en attendant, vous avez déjà matière pour vous amuser et amener vos projets vers une nouvelle étape de qualité et de performances.

Evidemment nous sommes au début, donc beaucoup d’effets de l’asset store ne sont pas encore compatibles avec le Post Processing Stack V2. Mais ça va changer ! D’ailleurs le Post Processing intégré dans Unity est de très bonne qualité, alors n’ayez pas peur de l’utiliser 😉

N’hésitez pas à me poser vos questions ou vos attentes, l’objectif de cette série d’articles est de partager mes connaissances mais aussi de vous faire monter en compétence sur des sujets techniques avancés, afin que vous puissiez profiter du nouveau Unity, un moteur qui change, dans le bon sens.