Sur cette page

Lightmaps et illumination globale

Introduction

Note : A partir de Qt 6.4, le lightmap baking est dans un état d'avant-première technologique. Des changements au niveau des fonctionnalités, de la qualité et de l'API sont susceptibles d'intervenir dans les prochaines versions.

Les lightmaps cuites permettent de pré-générer l'éclairage direct à partir de lumières telles que DirectionalLight, PointLight, et SpotLight, y compris les ombres projetées par les lumières. Au moment de l'exécution, au lieu d'effectuer les calculs appropriés dans le nuanceur de fragment et, dans le cas des ombres, de générer les cartes d'ombres potentiellement coûteuses en temps réel, la carte d'image pré-générée est échantillonnée à la place.

Une carte lumineuse est générée par Model. Même si un site Model possède plusieurs sous-mailles et est donc associé à plusieurs matériaux, une seule image de carte lumineuse sera générée pour l'ensemble du modèle.

Les lightmaps sont générées à l'aide du raytracing qui, par nature, fournit une occlusion correcte ("la lumière ne traverse pas les murs") et des ombres probablement plus réalistes que les techniques d'éclairage et de shadow mapping en temps réel.

Plus important encore, les lightmaps permettent également de faire de l'éclairage indirect, en fournissant une solution pour l'illumination globale. Cette solution prend en compte les rayons lumineux réfléchis par d'autres surfaces de la scène.

Voici un exemple simple. La scène contient quatre modèles Rectangle et un modèle Sphere, avec un DirectionalLight pointant vers le bas et un PointLight. Les modèles Rectangle sont tournés de 0 et 90 degrés, ce qui exagère les limites des calculs d'éclairage en temps réel car ils sont tous parallèles ou perpendiculaires à la direction du DirectionalLight.

Sur la deuxième image, la scène est rendue avec le lightmapping activé, après avoir cuit les lightmaps pour les cinq modèles. Les deux lumières sont réglées sur "fully baked", ce qui signifie que l'éclairage direct et indirect est cuit. L'éclairage indirect utilise 256 samples et un maximum de 3 bounces. Les lightmaps résultantes ont ensuite été débruitées. Cela donne une image nettement plus réaliste.

Éclairage en temps réel

Scène simple avec une sphère, des rectangles et deux lumières

Éclairage entièrement cuit

La même scène avec les deux éclairages réglés sur une cuisson complète

L'extrait ci-dessous montre comment les résultats des lightmaps ont été obtenus. La différence réside dans les propriétés usedInBakedLighting, bakeMode et bakedLightmap. Pour cet exemple, la taille du lightmap a été réduite à l'aide de la propriété texelsPerUnit, afin d'économiser de l'espace disque et de réduire le temps de chargement de l'application.

DirectionalLight {
    bakeMode: Light.BakeModeAll

    eulerRotation.x: -90
    brightness: 0.5
    castsShadow: true
    shadowFactor: 75
}
PointLight {
    bakeMode: Light.BakeModeAll

    y: 200
    z: 100
    color: "#d9c62b"
    castsShadow: true
    shadowFactor: 75
}
Model {
    usedInBakedLighting: true
    bakedLightmap: BakedLightmap {
        enabled: true
        key: "sphere1"
    }

    source: "#Sphere"
    materials: PrincipledMaterial { }
    y: 100
}
Model {
    usedInBakedLighting: true
    bakedLightmap: BakedLightmap {
        enabled: true
        key: "rect1"
    }

    source: "#Rectangle"
    materials: PrincipledMaterial { }
    eulerRotation.x: -90
    scale: Qt.vector3d(10, 10, 10)
}

// ... three additional Rectangle models, with rotations 0, 90, and -90

L'exemple ci-dessus utilise des lumières entièrement cuites. Une lumière peut également être configurée pour n'utiliser que l'éclairage cuit pour l'éclairage indirect, tout en effectuant l'éclairage direct et le mappage des ombres en temps réel. Dans la scène ci-dessous, il y a 5 lumières ponctuelles, toutes réglées sur BakeModeIndirect pour la deuxième capture d'écran. Bien que l'éclairage direct et les ombres soient identiques, la deuxième image est nettement meilleure en raison de l'ajout d'un certain degré d'illumination globale.

Éclairage en temps réel

Scène avec les modèles Sponza et Suzanne et les lumières à 5 points

Avec l'ajout d'un éclairage indirect cuit

Même scène avec un éclairage indirect cuit mais un éclairage direct en temps réel

Considérations importantes à prendre en compte lorsque l'on travaille avec des lightmaps

Les lumières contribuant à l'éclairage cuit ont leur propriété bakeMode définie sur Light.BakeModeIndirect ou Light.BakeModeAll. Cette dernière indique que la contribution directe et indirecte pour cette lumière particulière provient de la carte lumineuse. La contribution directe inclut toujours les ombres. En revanche, si l'objectif de la carte lumineuse est uniquement d'ajouter un éclairage indirect à la scène pour une lumière particulière, tout en continuant à calculer l'éclairage direct (et à effectuer le mappage des ombres) en temps réel, la lumière devrait plutôt utiliser Light.BakeModeIndirect.

Remarque : les Lightmaps sont, de manière générale, adaptées aux modèles statiques en ce qui concerne les transformations, la géométrie et les matériaux. Il en va de même pour les lumières participant à l'éclairage cuit.

Par exemple, une scène qui fait pivoter une Model en animant la propriété eulerRotation donnera des résultats visuellement incorrects si l'on applique un lightmap à cette Model. Les résultats du rendu pour cette Model particulière seront incorrects, car l'image lumineuse pré-générée ne capture qu'un seul état de rotation pour l'objet. Il en va de même, pour prendre un autre exemple, si le matériau de l'une des sous-mailles du modèle modifie dynamiquement sa propriété baseColor en fonction du temps (animation) ou d'une interaction de l'utilisateur. La carte de lumière ne peut capturer qu'un seul matériau donné baseColor. Il en va de même pour les lumières. Par exemple, un DirectionalLight qui tourne, change de luminosité, de couleur, etc. au fil du temps n'est pas adapté à l'éclairage cuit.

Note : D'un autre côté, c'est toujours au concepteur de choisir quand utiliser le lightmapping. En particulier avec les lumières BakeModeIndirect, il est probable qu'il y aura des scènes où les résultats seront toujours visuellement satisfaisants, même si certains des objets de la scène lightmappée ont un comportement dynamique.

Le lightmapping est un moteur et un outil complexes. Il remplace et réimplémente plusieurs éléments du pipeline de rendu du moteur. Elle fonctionne avec un modèle de rendu fondamentalement différent lors de la création de lightmaps, tout en consommant et en interagissant avec la même structure de scène, les mêmes données d'actifs et les mêmes structures de données du moteur. Les résultats basés sur le raytracing seront souvent supérieurs aux alternatives en temps réel, parfois de manière significative, ce qui se fait aux dépens de limitations, telles que le caractère statique obligatoire des modèles et des lumières impliqués, et, parfois, des problèmes de qualité et d'artefacts de rendu qui sont spécifiques au lightmapping.

Dans la pratique, le choix du type d'éclairage à utiliser et du moment où il sera utilisé relèvera d'un choix artistique de la part des concepteurs. Les trois paramètres de bakeMode ont chacun leur utilité, et les scènes complexes et plus vastes peuvent très bien utiliser les trois pour des éclairages différents, en fonction de ce qui est jugé approprié pour une section donnée de la scène, et du type de modèles, de matériaux et de comportements dynamiques présents. Le lightmapping n'est pas un simple interrupteur marche/arrêt que l'on peut activer pour n'importe quelle scène ou application, mais une fonction puissante qui suppose une évaluation minutieuse des besoins en éclairage d'une scène donnée, et qui exige souvent que le contenu et le comportement de la scène soient conçus en conséquence, en combinaison avec une boucle de test et d'ajustement où différents paramètres de cuisson et de qualité du lightmap sont explorés et testés avant de décider de l'approche finale et des paramètres associés.

Remarque : les lightmaps ne prennent pas en charge les surfaces à deux faces. Avec l'éclairage en temps réel, un matériau avec une adresse cull mode de Material.NoCulling inverse automatiquement la normale en fonction de l'orientation du fragment. Ce n'est pas une option pour les lightmaps puisque la cuisson des lightmaps ne fonctionne pas dans l'espace de visualisation. Par conséquent, évitez l'éclairage cuit pour les modèles qui en ont besoin.

Cuisson de lightmaps

Propriétés et types pertinents pour la cuisson des lightmaps, c'est-à-dire le processus hors ligne de génération des cartes d'images qui capturent l'éclairage direct et indirect et peuvent être utilisées par le moteur de rendu lors des exécutions ultérieures de l'application :

Depuis Qt 6.4, le processus de cuisson des cartes lumineuses doit être déclenché manuellement. Chaque fois que l'argument de ligne de commande --bake-lightmaps est présent, ou que la variable d'environnement QT_QUICK3D_BAKE_LIGHTMAPS est fixée à 1 (ou à une autre valeur non nulle), le moteur fonctionnera en mode cuisson et quittera l'application une fois la cuisson terminée. Les étapes du processus de cuisson peuvent être suivies en vérifiant les messages imprimés sur la sortie de débogage. Le résultat est un fichier binaire (lightmaps.bin par défaut) écrit dans le répertoire de travail courant contenant toutes les lightmaps cuites de la scène. Il y aura également un fichier .raw créé qui contient l'ensemble de la carte lumineuse et quelques données supplémentaires qui sont nécessaires pour le débruitage. Chaque carte lumineuse est identifiée de manière unique dans le fichier par la clé unique de BakedLightmap::key.

La préparation d'une scène avec lightmap se fait selon les étapes suivantes :

  • Identifier les modèles qui doivent utiliser une carte lumineuse et ceux qui doivent contribuer à la carte lumineuse. Les modèles qui font partie de la scène lightmap doivent définir Model::usedInBakedLighting sur true. Les modèles qui font l'objet d'un lightmap (c'est-à-dire qu'un lightmap doit être créé pour eux) doivent en outre attribuer la valeur Model::bakedLightmap à un objet BakedLightmap activé, qui fournit une clé unique permettant d'identifier de manière persistante l'instance particulière de l'objet Model (en effet, Qt a besoin d'une clé pour identifier les données du modèle dans le stockage sur disque persistant). Seuls les modèles dont la géométrie, la transformation et les matériaux sont statiques sont garantis d'avoir des résultats corrects lorsqu'ils sont mappés à la lumière au moment de l'exécution. Le plus souvent, tout ce qui entraîne une transformation non statique du monde dans le temps, comme une position, une rotation ou une échelle modifiée ou animée dynamiquement, disqualifie le modèle. Les besoins artistiques peuvent cependant l'emporter, en particulier pour les modèles qui ne contribuent qu'à l'éclairage indirect cuit, mais qui ne sont pas eux-mêmes des lightmaps. Pour ces modèles, il peut souvent être visuellement acceptable d'avoir des transformations dynamiques, mais cela dépend toujours du modèle et de la scène en question.
  • Identifiez les lumières qui doivent contribuer, et dans quelle mesure. Light::bakeMode propose trois options :
    • Light.BakeModeDisabled, la valeur par défaut, qui fait que la lumière est ignorée pour tous les besoins du lightmapping.
    • Light.BakeModeIndirect est souvent le choix le plus sûr, si le seul objectif est d'avoir un niveau d'illumination globale (éclairage indirect) dans la scène, tout en n'affectant pas les résultats du rendu pour la lumière d'une autre manière. Dans ce mode, le moteur de rendu continuera à effectuer tous les éclairages, y compris les éclairages diffus, spéculaire, les contributions du ciel/de l'environnement et le mappage des ombres pour cette lumière en utilisant les techniques standard en temps réel. Cependant, la lumière contribuera à l'éclairage indirect à l'aide des données précuites, ce qui permettra éventuellement d'éclairer des surfaces qui n'auraient pas été touchées par les calculs d'éclairage standard en temps réel.
    • Light.BakeModeAll est une option qui sera probablement utilisée pour certaines lumières seulement, sur la base de l'évaluation des concepteurs pour ce qui est jugé approprié pour une scène donnée. Dans ce mode, toutes les contributions de la lumière sont cuites, y compris les ombres. Depuis Qt 6.4, l'éclairage spéculaire n'est pas pris en charge dans le cadre de l'éclairage cuit, de sorte que ces lumières n'auront pas de contributions spéculaires. En revanche, elles génèrent des ombres cuites, tracées dans les rayons, et ont une occlusion correcte pour la lumière (elles ne "passent pas à travers les murs", par exemple), puisque toutes les contributions directes à l'éclairage résultant de la lumière sont tracées dans les rayons au moment de la cuisson de la carte lumineuse, au lieu d'être calculées au moment de l'exécution. En outre, l'éclairage indirect est cuit, comme avec BakeModeIndirect.
  • L'exécution de la scène (application) en mode cuisson, en s'assurant que les lightmaps sont générées avec succès. À partir de la version 6.4 de Qt, les applications sont censées être structurées de manière à ce que la scène de lumière soit la première vue affichée, ou que la scène en question puisse être chargée avec un visualiseur QML tel que l'outil qml. Une fois la cuisson terminée, dont la progression peut être suivie sur la console/la sortie de débogage, l'application se termine.
  • Lancer la scène (l'application) normalement, pour voir à quoi elle ressemble avec les lightmaps chargées. Le réglage peut alors commencer :
    • Pour certains modèles, il sera judicieux de réduire texelsPerUnit de la valeur par défaut à quelque chose de plus petit. Ceci s'applique particulièrement aux primitives intégrées et à tout ce qui a une géométrie assez simple. Cela permet d'obtenir des lightmaps plus petites et des temps de cuisson plus rapides. Lors de la première cuisson, la valeur par défaut devrait suffire, la valeur peut être ajustée par la suite.
    • L'objet Lightmapper expose de nombreux paramètres qui ont des valeurs par défaut raisonnables, mais il n'est pas improbable que certains d'entre eux doivent être ajustés pour correspondre aux attentes des concepteurs. Par exemple, samples et bounces peuvent être modifiés pour affecter la qualité de l'éclairage indirect, tandis que indirectLightFactor permet d'accentuer la contribution indirecte. Si des artefacts apparaissent, en particulier autour des ombres, bias peut être réglé avec précision.
    • Le débruitage des cartes lumineuses générées est essentiel. L'éclairage indirect est calculé à l'aide du traçage de chemin, qui produit des images bruitées en fonction du nombre de samples utilisés. L'augmentation du nombre d'échantillons réduit le bruit, mais augmente le temps nécessaire à la génération de la carte lumineuse. Quel que soit le nombre d'échantillons, il sera presque toujours utile d'utiliser un débruiteur sur les cartes lumineuses générées, qui sont des images RGBA 32 bits à virgule flottante stockées dans un fichier binaire.

Depuis Qt XML 6.5, une solution d'exécution est fournie de manière interactive par l'intermédiaire de DebugView. Sous Tools, il y a maintenant un bouton qui, lorsqu'il est pressé, déclenche le processus de cuisson. Une fenêtre s'ouvre pour montrer le processus en cours. Il est possible d'annuler le processus en appuyant sur le bouton d'annulation ou en fermant la fenêtre. Une fois terminé, le processus écrira le binaire de la carte lumineuse dans le répertoire courant.

Débruitage

Voici un exemple d'une scène de boîte de Cornell, rendue d'abord en utilisant la lightmap cuite avec 256 samples et un maximum de 3 bounces. Dans le deuxième exemple, le fichier image généré a été débruité, et les résultats sont nettement meilleurs, le bruit ayant pratiquement disparu.

Original

Scène de boîte de maïs avec une lumière ponctuelle, lightmap entièrement cuite

Débruitée

Scène de la boîte de maïs avec les lightmaps débruitées

Le débruitage est effectué automatiquement sur chaque lightmap cuite. Il est possible de ne faire que du débruitage, si un fichier lightmap .raw cuit existe dans le répertoire de travail, en cliquant sur le bouton Denoise dans DebugView. Il est également possible de débruiter en appelant l'application avec l'argument --denoise-lightmaps. Pour ajuster la force du débruitage, la propriété denoiseSigma peut être utilisée.

UV de la carte lumineuse

Les coordonnées UV de la carte lumineuse n'utilisent pas les mêmes données UV que les textures ordinaires. Lors du rendu avec des lightmaps, ni les données UV0 ni UV1 ne sont utilisées par le moteur de rendu lors de l'échantillonnage de la lightmap. Au lieu de cela, il y a un canal UV supplémentaire dédié dans le maillage, contenant des cartes UV disposées d'une manière adaptée aux objectifs de la cartographie lumineuse. Cela implique d'éviter les chevauchements et d'avoir un rembourrage le cas échéant. Pour les données UV ordinaires, il n'y a pas de telles exigences, et on peut très bien vouloir utiliser les mêmes coordonnées U et V pour plus d'un sommet.

Le processus de génération d'un ensemble d'UV approprié est appelé "lightmap UV unwrapping". Qt effectue cette opération lors de la création de lightmaps et stocke le maillage résultant dans le fichier lightmaps afin qu'un maillage compatible soit toujours chargé et utilisé pour le lightmap généré. Cela signifie que, si un modèle utilise toujours un éclairage cuit, le fichier de maillage source n'a pas besoin d'être livré avec l'application.

Taille de la texture de la carte lumineuse

Pour chaque modèle, y compris toutes ses sous-mailles, le processus de cuisson de la couche de lumière déterminera une taille de texture de couche de lumière appropriée au cours de la phase de génération des UV de la couche de lumière. Cette taille a un impact sur la qualité, les performances et l'utilisation des ressources (à la fois sur le disque et dans la mémoire).

La valeur par défaut est souvent appropriée et ne nécessite aucun ajustement, en particulier pour les modèles de complexité moyenne à élevée.

Pour les modèles très simples, il peut être souhaitable de réduire manuellement la taille, car une taille de lightmap plus petite peut encore donner des résultats visuellement satisfaisants, tandis que la réduction de la taille de l'actif (image de lightmap) permet d'économiser de l'espace disque et de la mémoire. Pour ce faire, réglez la valeur texelsPerUnit sur un nombre suffisamment petit. En fonction de la taille et de la géométrie du modèle, la largeur et la hauteur réelles de la carte lumineuse tenteront alors d'approcher la densité du texel de manière à ce qu'elle corresponde à texelsPerUnit.

Lorsque l'on modifie la valeur, il faut toujours recréer les lightmaps et inspecter visuellement les résultats afin d'évaluer les effets de la modification de la taille de la lightmap.

Utilisation des cartes lumineuses au moment de l'exécution

Propriétés et types pertinents lors de l'utilisation des lightmaps précuites au moment de l'exécution :

Une fois la cuisson terminée, l'exécution normale de l'application (sans l'argument de ligne de commande ou la variable d'environnement définie) récupérera les images de la carte lumineuse générée et effectuera un rendu correct, ce qui n'est pas possible tant que les cartes lumineuses n'ont pas été cuites au préalable. Si vous le souhaitez, l'application peut les placer à un autre endroit, ou les intégrer à l'exécutable via le système de ressources Qt. Cela est possible grâce à la propriété source.

En reprenant l'exemple de code avec la sphère et les quatre rectangles ci-dessus, le processus de cuisson génère un fichier lightmaps.bin contenant tous les maillages et les lightmaps cuits. L'application doit envoyer ce fichier pour qu'il puisse être trouvé par le moteur, à l'emplacement spécifié par source.

Voir également Qt Quick 3D - Baked Lightmap Example et Qt Quick 3D - SSGI Lightmap Example.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.