Retour au Blog

Bug des Lumen Reflections d'Unreal Engine 5.8 : corriger le fallback Screen-Space silencieux

Publié le 23 juin 2026
Bug des Lumen Reflections d'Unreal Engine 5.8 : corriger le fallback Screen-Space silencieux

En bref

Un bug critique dans Unreal Engine 5.8 provoque un fallback silencieux des Lumen Reflections vers le Screen-Space (SSR) dès lors que Lumen GI est désactivé, affectant la fidélité visuelle des projets utilisant du baked lighting. Cet article explique les causes architecturales sous-jacentes liées à la désactivation du Surface Cache et quantifie l'impact sur le GPU frame budget, particulièrement sur console. Plusieurs solutions de contournement sont présentées, incluant un actor component C++, des overrides de variables de console via DefaultEngine.ini et un correctif direct du code source du moteur dans LumenScene.cpp. Enfin, nous abordons l'impact de ce bug sur les chutes de frame rate et les desyncs en multiplayer, tout en suggérant l'utilisation de configurations dynamiques avec horizOn pour automatiser ces ajustements.

Le fallback silencieux : pourquoi vos Reflections ne fonctionnent plus sous UE 5.8

Passer à Unreal Engine 5.8 aurait dû être une simple mise à jour de pipeline, mais les ingénieurs graphiques constatent que leurs matériaux métalliques brillants semblent plats et ternes. Des surfaces qui affichaient auparavant des détails précis en Ray Tracing repassent désormais à des Screen-Space Reflections (SSR) floues dès que l'objet réfléchi sort de l'écran. Cette dégradation silencieuse du rendu est causée par le bug des Lumen Reflections d'Unreal Engine 5.8, où le moteur ne parvient pas à générer de Reflections à moins que Lumen Global Illumination (GI) ne soit totalement actif. Pour les jeux qui s'appuient sur du baked lighting ou d'autres solutions de GI alternatives, cela impose de choisir entre un overhead GPU massif et une fidélité visuelle gâchée.

Le problème de fond provient de la manière dont Unreal Engine 5.8 initialise son rendering pipeline. Dans les versions précédentes, les développeurs pouvaient désactiver le Lumen Global Illumination pour économiser des ressources GPU tout en gardant Lumen Reflections actif pour maintenir des specular highlights de haute qualité sur le métal et le verre. Ce mode de Reflections standalone est un incontournable pour le matériel de milieu de gamme et les profils d'optimisation ciblés où la global indirect lighting est intégrée dans des lightmaps (baked). Dans UE 5.8, cependant, désactiver le Lumen GI désactive silencieusement toute la représentation de la Lumen Scene, ce qui entraîne un fallback instantané des Reflections vers des méthodes de Screen-Space, sans avertissement ni erreur dans les logs.

Cette régression est particulièrement préjudiciable pour les sorties multiplateformes. Un jeu optimisé pour tourner à 60 FPS constants sur consoles peut voir son budget graphique exploser si les développeurs sont contraints de réactiver Lumen GI uniquement pour conserver l'aspect correct de leurs matériaux brillants. Comprendre pourquoi ce fallback se produit et comment le corriger est essentiel pour quiconque publie ou met à jour un projet Unreal Engine en 2026.

Comprendre l'architecture : Lumen Reflections vs. Global Illumination

Pour comprendre l'origine de ce bug, il est nécessaire d'examiner comment Lumen génère les Reflections et l'indirect lighting sous le capot. Lumen ne trace pas les rayons directement sur les static meshes détaillés de votre niveau, car cela serait beaucoup trop lourd en calculs pour des applications en temps réel. À la place, il construit une représentation simplifiée de la scène appelée la Lumen Scene, qui se compose de structures voxel basse résolution et de cartes 2D (cards) contenant des attributs de surface comme la base color, la roughness et l'opacity. Cet ensemble de données est connu sous le nom de Surface Cache.

Dans un état de fonctionnement normal du moteur, le Surface Cache est mis à jour en continu à mesure que la caméra se déplace dans l'environnement. Lorsqu'une surface réfléchissante nécessite un ray-trace, le moteur projette des rayons dans cette Lumen Scene pour déterminer quels objets sont visibles et quelle lumière ils émettent. Cette architecture permet à la passe de Reflection d'évaluer des Reflections brillantes complexes pour une fraction du coût d'un path tracing complet. Élément crucial, la Lumen Scene et son Surface Cache peuvent être initialisés indépendamment du fait que le moteur utilise ou non Lumen pour calculer la global indirect lighting.

Lorsque vous exécutez un profil de performance standard sur une console moderne telle que la PlayStation 5, le détail des coûts de performance montre clairement pourquoi le découplage de ces fonctionnalités est essentiel :

  • Lumen GI + Lumen Reflections : Le calcul de l'indirect lighting sur l'ensemble de la scène, la mise à jour du Surface Cache et le tracé des Reflections brillantes prennent environ 6,5 ms de temps de frame GPU en résolution 1440p.
  • Standalone Lumen Reflections : Le tracé des Reflections sur le Surface Cache tout en utilisant des baked lightmaps pour la GI ne prend que 1,8 ms de temps de frame GPU.
  • Screen-Space Reflections (SSR) : Le tracé des Reflections en utilisant uniquement le buffer d'écran visible prend 0,5 ms de temps de frame GPU, mais souffre d'un clipping visuel sévère sur les bords du viewport.

En forçant un fallback vers les SSR, le moteur supprime l'effet de parallaxe et la capacité de Reflection hors écran qui rendent les scènes modernes réalistes. À l'inverse, obliger les développeurs à activer Lumen GI pour retrouver ces Reflections ajoute une taxe massive de 4,7 ms au budget de frame du GPU. Cette latence supplémentaire est inacceptable pour les titres compétitifs ou d'action rapides qui visent des taux de rafraîchissement élevés.

Diagnostiquer le bug des Lumen Reflections d'Unreal Engine 5.8

Détecter ce bug en cours de développement nécessite de regarder au-delà du comportement par défaut du viewport de l'Unreal Editor, qui peut parfois masquer le problème en raison de paths de rendu réservés à l'éditeur. Le bug se manifeste spécifiquement lorsque le Hardware Ray Tracing (HWRT) est activé mais que la méthode de dynamic global illumination est désactivée. Pour confirmer si votre projet est affecté, vous devez reproduire les paramètres de configuration exacts où le fallback se produit.

Commencez par vérifier la configuration de rendu de votre projet. Dans Project Settings > Engine > Rendering, accédez à la section Global Illumination et réglez le Dynamic Global Illumination Method sur None (ou sur une autre méthode non-Lumen comme Screen Space). Ensuite, allez dans la section Reflections et réglez la Reflection Method sur Lumen. Sous l'en-tête Hardware Ray Tracing, assurez-vous que Support Hardware Ray Tracing et Use Hardware Ray Tracing When Available soient tous deux définis sur true.

+-------------------------------------------------------------------+
| Project Settings -> Engine -> Rendering                           |
+-------------------------------------------------------------------+
| Dynamic Global Illumination Method:  [ None / Screen Space ]      |
| Reflection Method:                   [ Lumen ]                    |
| Support Hardware Ray Tracing:        [ True ]                     |
| Use Hardware Ray Tracing:            [ True ]                     |
+-------------------------------------------------------------------+

Une fois ces paramètres appliqués, lancez votre scène dans une instance de jeu standalone ou une fenêtre PIE active. Exécutez la commande console r.Lumen.Visualize.CardPlacement 1 pour inspecter la Lumen Scene. Dans Unreal Engine 5.8, vous verrez un écran complètement vide, confirmant que le Surface Cache est inactif. Cela indique que le moteur a arrêté le pipeline de mise à jour des cards, forçant les Reflections à basculer vers des Screen-Space Reflections.

Profilez la scène à l'aide de l'outil Unreal Insights ou de la commande console standard stat GPU. Vous verrez LumenReflections disparaître de la passe de profiling, entièrement remplacé par ScreenSpaceReflections qui prend environ ~0,4 ms à ~0,8 ms selon la couverture de l'écran.

Correctifs programmatiques : détecter et corriger le fallback en C++

En attendant un hotfix officiel, vous pouvez détecter cet état par programmation côté client et forcer les configurations requises du moteur. Cela évite que la dégradation silencieuse n'affecte vos joueurs sur les systèmes prenant en charge le Hardware Ray Tracing. Ci-dessous se trouve une implémentation d'un actor component en C++ qui interroge le console manager, vérifie la configuration de rendu actuelle et résout dynamiquement le conflit.

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "HAL/IConsoleManager.h"
#include "Engine/World.h"
#include "LumenReflectionsChecker.generated.h"

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class MYGAME_API ULumenReflectionsChecker : public UActorComponent

{
    GENERATED_BODY()

public:
    ULumenReflectionsChecker();

protected:
    virtual void BeginPlay() override;

private:
    void ValidateLumenConfiguration();
};

ULumenReflectionsChecker::ULumenReflectionsChecker()
{
    PrimaryComponentTick.bCanEverTick = false;
}

void ULumenReflectionsChecker::BeginPlay()
{
    Super::BeginPlay();
    ValidateLumenConfiguration();
}

void ULumenReflectionsChecker::ValidateLumenConfiguration()
{
    // Retrieve critical engine console variables for Lumen setup
    IConsoleVariable* GiMethodVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DynamicGlobalIlluminationMethod"));
    IConsoleVariable* ReflectionMethodVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ReflectionMethod"));
    IConsoleVariable* ForceLumenSceneVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Lumen.ForceLumenScene"));

    if (GiMethodVar && ReflectionMethodVar)
    { 
        int32 GiMethod = GiMethodVar->GetInt();
        int32 ReflectionMethod = ReflectionMethodVar->GetInt();

        // In UE 5.8, if GI is 0 (None) and Reflection is 1 (Lumen), reflections fall back to SSR.
        if (GiMethod == 0 && ReflectionMethod == 1)
        { 
            UE_LOG(LogTemp, Warning, TEXT("[LumenChecker] Warning: Lumen GI is disabled, but Lumen Reflections are active. UE 5.8 forces SSR fallback in this state."));

            if (ForceLumenSceneVar)
            {
                // Mitigate the fallback by forcing the Lumen Scene to update
                ForceLumenSceneVar->Set(1, ECVF_SetByCode);
                UE_LOG(LogTemp, Log, TEXT("[LumenChecker] Applied CVar workaround: r.Lumen.ForceLumenScene set to 1."));
            }
        }
    }
}

Cet actor component peut être attaché à votre game state principal ou à votre actor d'initialisation. Au lancement du jeu, le script vérifie si les paramètres du projet correspondent à la configuration buggée. Si c'est le cas, il définit par programmation r.Lumen.ForceLumenScene sur 1. Cela indique au renderer de conserver le Surface Cache même si le système de global illumination ne le demande pas, maintenant vos Reflections pleinement opérationnelles.

Workarounds manuels et correctifs du code source du moteur

Pour les développeurs qui ne souhaitent pas exécuter de scripts C++ au runtime pour modifier les variables de console, il existe deux méthodes principales pour résoudre le fallback : modifier directement les fichiers de configuration ou patcher le code source du moteur. Les deux approches sont valables selon que vous utilisez la version launcher d'Unreal Engine ou un source build personnalisé.

Workaround 1 : Overrides de configuration via variables de console

Si vous utilisez la version Epic Games Launcher d'Unreal Engine 5.8, vous ne pouvez pas modifier le code du moteur directement. À la place, vous devez forcer le moteur à maintenir la Lumen Scene active en utilisant des fichiers de configuration. Ouvrez le répertoire de votre projet et accédez à Config/DefaultEngine.ini.

Sous la catégorie [/Script/Engine.RendererSettings], ajoutez les lignes suivantes :

r.DynamicGlobalIlluminationMethod=0
r.ReflectionMethod=1
r.Lumen.ForceLumenScene=1.Lumen.Reflections.AllowWithoutGI=1

Définir r.Lumen.ForceLumenScene sur 1 surcharge (override) la passe d'optimisation du rendering pipeline qui marque la Lumen Scene comme inutilisée lorsque la GI est désactivée. Cela force le moteur à allouer la mémoire GPU nécessaire et les passes de calcul pour construire et mettre à jour les cards du Surface Cache. Bien que cela restaure les Reflections, gardez à l'esprit que cela augmentera légèrement le coût de votre GPU base pass par rapport à UE 5.7, car le moteur effectue désormais ces mises à jour sans le contexte d'optimisation dont il disposait dans les versions précédentes.

Workaround 2 : Modifier le code source du moteur

Si vous compilez Unreal Engine 5.8 à partir des sources (source build), vous pouvez patcher le bug à l'origine. La cause première de la régression se trouve dans FDeferredShadingSceneRenderer::InitLumenScene, situé dans les fichiers de rendu privés du moteur (Private/Lumen/LumenScene.cpp). Dans UE 5.8, les vérifications conditionnelles qui déterminent si la Lumen Scene est requise ont été optimisées, mais elles ont omis par mégarde de vérifier les paramètres de Reflection.

Pour corriger cela, ouvrez LumenScene.cpp et localisez l'endroit où bNeedLumenScene est défini. Le code défectueux et sa correction ressemblent à ceci :

- // Faulty check in UE 5.8 that ignores reflection settings
- const bool bNeedLumenScene = Scene->DynamicGIProjectSetting == EEDynamicGlobalIlluminationMethod::Lumen;
+ // Corrected check restoring reflections-only compatibility
+ const bool bNeedLumenScene = Scene->DynamicGIProjectSetting == EEDynamicGlobalIlluminationMethod::Lumen || Scene->ReflectionProjectSetting == EEReflectionMethod::Lumen;

Après avoir modifié cette ligne, recompilez votre moteur. Ce changement restaure exactement la logique de pipeline utilisée dans UE 5.7, permettant au renderer d'initialiser la Lumen Scene dès que les Lumen Reflections sont sélectionnées, quelle que soit la méthode de Global Illumination. C'est la manière la plus propre de résoudre le problème, car elle évite d'exécuter des overrides de CVars qui peuvent prêter à confusion pour les membres de l'équipe ou encombrer vos fichiers de configuration.

L'impact en aval : Frame Spikes du client et Multiplayer Desync

Bien que les bugs graphiques soient souvent traités comme des problèmes visuels isolés, leurs effets secondaires peuvent se propager à l'ensemble de l'architecture de votre jeu. Lorsque les développeurs rencontrent ce bug, leur réaction initiale est souvent de simplement réactiver Lumen GI pour restaurer les Reflections. Cependant, ajouter 4 ms à 6 ms de charge GPU sur un client peut provoquer de graves chutes de frame rate, ce qui peut introduire des problèmes de desync en multiplayer.

Dans les jeux multiplayer, la simulation physique et le traitement des inputs des joueurs sont étroitement liés au frame tick rate du client. Lorsqu'un client subit un rendering stall soudain — par exemple, une passe de Reflection qui surcharge le GPU lors d'un mouvement de caméra —, le temps de frame de simulation du client grimpe en flèche. Ce retard peut entraîner l'envoi tardif de paquets réseau ou leur traitement dans le mauvais ordre, ce qui se traduit par du lag visible et des corrections du serveur. Pour éviter que ces pics de performance n'altèrent la sensation multiplayer de votre jeu, consultez notre guide sur comment corriger la desync de position des joueurs dans UEFN et le multijoueur d'Unreal Engine.

De plus, ces problèmes de rendu soulignent l'importance de séparer les paramètres graphiques côté client de la logique du serveur. Les headless dedicated servers ne devraient jamais compiler ou charger de rendering pipelines, de matériaux ou de volumes de post-processing. Lors de la compilation de l'exécutable de votre serveur, ne pas éliminer ces assets (asset stripping) entraîne des memory footprints gonflés et des temps de démarrage lents, ce qui peut dégrader la réactivité du matchmaker. Pour un guide détaillé sur l'optimisation des builds de votre serveur, lisez notre article sur comment maîtriser le dedicated server asset stripping sous Unreal Engine.

Résoudre l'overhead de configuration avec horizOn

Corriger des bugs de rendu comme le bug des Lumen Reflections d'Unreal Engine 5.8 sur votre machine locale n'est que la moitié de la bataille. Une fois votre jeu en ligne, vous devez gérer les profils graphiques, les overrides de variables de console et les paramètres du moteur sur des milliers de configurations PC clientes différentes. Hardcoder des CVars dans vos configurations locales signifie que si une autre régression de rendu est découverte dans une mise à jour mineure du moteur, vous devez compiler, packager et distribuer un tout nouveau patch à vos joueurs.

C'est dans la gestion de cet overhead de configuration que horizOn devient un outil inestimable pour les développeurs de jeux. Plutôt que de vous forcer à livrer de lourdes mises à jour du client de jeu pour résoudre les problèmes de rendu, notre plateforme vous permet de gérer dynamiquement les paramètres de votre jeu depuis un backend centralisé. En utilisant le service de configuration à distance de horizOn, vous pouvez définir des profils cibles pour différentes configurations matérielles et les mettre à jour en temps réel.

Par exemple, lorsqu'un joueur lance votre jeu, le client peut interroger le backend en lui transmettant des détails sur le GPU détecté et la version du moteur. Le serveur évalue ces données par rapport à vos règles de configuration actuelles et renvoie la liste optimisée de CVars. Si le joueur exécute UE 5.8 sur une carte de milieu de gamme, le backend renvoie dynamiquement r.Lumen.ForceLumenScene=1. Cela permet aux Reflections de fonctionner parfaitement sans vous obliger à écrire et maintenir des profils complexes côté client ni à déployer des patchs d'urgence.

Best practices pour configurer Lumen en production

Lors de la sortie d'un jeu qui utilise les Lumen Reflections ou le Global Illumination, suivre un QA process structuré permet d'éviter que des régressions visuelles n'atteignent les joueurs. Voici quatre best practices à intégrer dans votre pipeline de développement :

  1. Automatiser les vérifications de GBuffer : Créez des tests automatisés dans votre CI/CD pipeline qui capturent des images du viewport à l'aide de flags de rendu spécifiques. Utilisez ces tests pour vérifier que le canal de Reflection contient des données valides tracées en Ray Tracing au lieu de faire un fallback vers un espace d'écran vide.
  2. Découpler la GI et les Reflections pendant l'optimisation : Testez votre jeu avec la GI désactivée et les Lumen Reflections activées. Cela vous permet d'évaluer les gains de performance des solutions de baked lighting sur les systèmes bas de gamme tout en préservant les specular highlights brillants.
  3. Exécuter des validations de CVars au démarrage : Implémentez des scripts de validation au runtime qui vérifient l'état des variables de console comme r.DynamicGlobalIlluminationMethod et r.ReflectionMethod pendant la phase de chargement initial du jeu, garantissant qu'elles ne déclenchent pas de fallbacks.
  4. Utiliser des profils clients dynamiques : Évitez de hardcoder les préréglages graphiques dans les binaires de votre projet. Utilisez des outils de configuration dynamique pour ajuster les variables de rendu à la volée, vous permettant de réagir immédiatement aux régressions du moteur sans lancer de mise à jour complète du client.

Prêt à simplifier la gestion de la configuration de votre jeu et à déployer des dedicated servers stables ? Inscrivez-vous sur horizOn dès aujourd'hui ou lisez notre documentation de développement pour apprendre à intégrer des mises à jour dynamiques des paramètres dans votre pipeline Unreal Engine.


Source : Publication d'UE 5.8 - Lumen Reflections ne fonctionne pas sans activer Lumen GI