العودة إلى المدونة

Unreal Engine 5.8 Lumen Reflections Bug: إصلاح الـ Screen-Space Fallback الصامت

نُشر في 23 يونيو 2026
Unreal Engine 5.8 Lumen Reflections Bug: إصلاح الـ Screen-Space Fallback الصامت

باختصار

يتناول هذا المقال خللًا برمجياً في Unreal Engine 5.8 يؤدي إلى تراجع صامت لانعكاسات Lumen إلى Screen-Space Reflections عند تعطيل Global Illumination. يشرح المقال الأسباب البنيوية وراء هذه المشكلة وتأثيرها على ميزانية أداء الـ GPU وإطارات الألعاب التنافسية. كما يقدم المقال حلولاً برمجية باستخدام C++ وتعديلات على ملفات التكوين والـ CVars، بالإضافة إلى الكود المصدري للمحرك لتجاوز هذا الخلل. وأخيراً، يستعرض كيفية استخدام منصة [horizOn](https://horizon.pm) لإدارة هذه التكوينات ديناميكياً عن بعد.

التراجع الصامت: لماذا تعطلت الانعكاسات (Reflections) لديك في UE 5.8

ترقية المشروع إلى Unreal Engine 5.8 كان ينبغي أن تكون تحديثًا اعتياديًا لـ pipeline التطوير، ولكن مهندسي الرسوميات (graphics engineers) يجدون أن خاماتهم المعدنية اللامعة (glossy metallic materials) تبدو مسطحة وباهتة. فالأسطح التي كانت تعرض سابقًا تفاصيل دقيقة بتقنية ray-traced تتراجع الآن إلى انعكاسات ضبابية بتقنية screen-space reflections (SSR) بمجرد خروج الكائن العاكس خارج الشاشة (off-screen). هذا التدهور الصامت في عملية الـ rendering يرجع إلى unreal engine 5.8 lumen reflections bug، حيث يفشل المحرك في توليد الانعكاسات ما لم تكن تقنية Lumen Global Illumination (GI) نشطة بالكامل. وبالنسبة للألعاب التي تعتمد على baked lighting أو حلول GI بديلة، فإن هذا يفرض الاختيار بين استهلاك هائل لموارد الـ GPU أو التضحية بالدقة البصرية (visual fidelity).

ينبع لب المشكلة من كيفية تهيئة Unreal Engine 5.8 لـ rendering pipeline الخاص به. في الإصدارات السابقة، كان بإمكان المطورين تعطيل Lumen Global Illumination لتوفير موارد الـ GPU مع إبقاء Lumen Reflections نشطًا للحفاظ على specular highlights عالية الجودة على المعادن والزجاج. وضع الانعكاسات المستقل (standalone reflections mode) هذا يعد ركيزة أساسية للأجهزة متوسطة الأداء وملفات تحسين الأداء (optimization profiles) المستهدفة حيث يتم خبز الإضاءة غير المباشرة (global indirect lighting) داخل lightmaps. ولكن في UE 5.8، يؤدي تعطيل Lumen GI بشكل صامت إلى تعطيل تمثيل Lumen Scene بالكامل، مما يفرض تراجع الانعكاسات فورًا إلى طرق screen-space دون أي تحذير أو أخطاء في السجلات (logs).

هذا التراجع (regression) يسبب ضررًا كبيرًا للألعاب متعددة المنصات (multi-platform releases). فاللعبة التي تم تحسينها لتعمل بمعدل إطارات ثابت 60 FPS على منصات الألعاب (consoles) قد تواجه تجاوزًا كبيرًا لـ graphics budget المتاح إذا أُجبر المطورون على إعادة تفعيل Lumen GI فقط للحفاظ على المظهر الصحيح للمواد اللامعة (glossy materials). إن فهم سبب حدوث هذا الـ fallback وكيفية ترقيعه (patch) أمر بالغ الأهمية لأي مطور يقوم بشحن أو ترقية مشروع Unreal Engine في عام 2026.

فهم البنية البرمجية: Lumen Reflections مقابل Global Illumination

لفهم سبب حدوث هذا الـ bug، من الضروري فحص كيفية توليد Lumen للانعكاسات والإضاءة غير المباشرة خلف الكواليس. لا يقوم Lumen بتتبع الأشعة (trace rays) مباشرة ضد الـ static meshes كاملة التفاصيل في مستواك، لأن القيام بذلك سيكون مكلفًا للغاية من الناحية الحسابية لتطبيقات الوقت الفعلي (real-time applications). بدلاً من ذلك، يقوم ببناء تمثيل مبسط للمشهد يسمى Lumen Scene، والذي يتكون من هياكل voxel منخفضة الدقة وبطاقات ثنائية الأبعاد (2D cards) تحتوي على سمات السطح (surface attributes) مثل base color و roughness و opacity. يُعرف تجمع البيانات هذا باسم Surface Cache.

في حالة المحرك السليمة، يتم تحديث Surface Cache باستمرار أثناء تحرك الكاميرا عبر البيئة. عندما يتطلب سطح عاكس عملية ray-trace، يقوم المحرك بإطلاق أشعة داخل Lumen Scene لتحديد الكائنات المرئية والضوء الذي تبعثه. تتيح هذه البنية لـ reflection pass تقييم الانعكاسات اللامعة المعقدة بجزء بسيط من تكلفة الـ path tracing الكامل. والأهم من ذلك، أنه يمكن تهيئة Lumen Scene والـ Surface Cache الخاص به بشكل مستقل عن استخدام المحرك لـ Lumen لحساب الإضاءة غير المباشرة (global indirect lighting).

عند تشغيل ملف تعريف أداء قياسي (performance profile) على منصة حديثة مثل PlayStation 5، يظهر تحليل تكاليف الأداء بوضوح سبب أهمية فصل هذه الميزات عن بعضها:

  • Lumen GI + Lumen Reflections: حساب الإضاءة غير المباشرة عبر المشهد بأكمله، وتحديث Surface Cache، وتتبع الانعكاسات اللامعة يستغرق حوالي 6.5ms من زمن إطار الـ GPU بدقة 1440p.
  • Standalone Lumen Reflections: تتبع الانعكاسات مقابل Surface Cache مع استخدام baked lightmaps لنظام GI يستغرق 1.8ms فقط من زمن إطار الـ GPU.
  • Screen-Space Reflections (SSR): تتبع الانعكاسات باستخدام عازل الشاشة المرئي (visible screen buffer) فقط يستغرق 0.5ms من زمن إطار الـ GPU ولكنه يعاني من قص بصري حاد (severe visual clipping) عند حواف viewport.

من خلال فرض التراجع إلى SSR، يجرد المحرك المشهد من تأثير اختلاف المنظر (parallax effect) وقدرة الانعكاس خارج الشاشة (off-screen reflection) التي تجعل المشاهد الحديثة تبدو واقعية. على العكس من ذلك، فإن إجبار المطورين على تفعيل Lumen GI لاستعادة تلك الانعكاسات يضيف عبئًا هائلاً يبلغ 4.7ms إلى GPU frame budget. هذا التأخير الإضافي (latency) غير مقبول للألعاب التنافسية السريعة أو ألعاب الحركة (action titles) التي تستهدف معدلات إطارات عالية.

تشخيص خلل Unreal Engine 5.8 Lumen Reflections Bug

يتطلب الكشف عن هذا الـ bug أثناء التطوير النظر إلى ما وراء السلوك الافتراضي لـ viewport في Unreal Editor، والذي قد يخفي المشكلة أحيانًا بسبب مسارات الـ rendering المخصصة للمحرر فقط. يظهر الـ bug تحديدًا عند تفعيل Hardware Ray Tracing (HWRT) وتعطيل طريقة الإضاءة غير المباشرة الديناميكية (dynamic global illumination method). لتأكيد ما إذا كان مشروعك متأثرًا، يجب عليك محاكاة إعدادات التكوين الدقيقة التي يحدث عندها هذا الـ fallback.

ابدأ بفحص إعدادات الـ rendering لمشروعك. ضمن Project Settings > Engine > Rendering، انتقل إلى قسم Global Illumination واضبط Dynamic Global Illumination Method على None (أو أي طريقة أخرى بخلاف Lumen مثل Screen Space). بعد ذلك، انتقل إلى قسم Reflections واضبط Reflection Method على Lumen. تحت عنوان Hardware Ray Tracing، تأكد من ضبط كل من Support Hardware Ray Tracing و Use Hardware Ray Tracing When Available على 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 ]                     |
+-------------------------------------------------------------------+

بمجرد تطبيق هذه الإعدادات، قم بتشغيل المشهد في نسخة لعبة مستقلة (standalone game instance) أو نافذة PIE نشطة. قم بتشغيل أمر الكونسول r.Lumen.Visualize.CardPlacement 1 لفحص الـ Lumen Scene. في Unreal Engine 5.8، سترى شاشة فارغة تمامًا، مما يؤكد أن Surface Cache غير نشط. يشير هذا إلى أن المحرك قد أوقف الـ card update pipeline، مما يفرض تراجع الانعكاسات إلى screen-space reflections.

قم بتحليل أداء المشهد (Profile) باستخدام أداة Unreal Insights أو أمر الكونسول القياسي stat GPU. سترى اختفاء LumenReflections من مرحلة الـ profile pass، ليحل محله بالكامل ScreenSpaceReflections الذي يستغرق حوالي ~0.4ms إلى ~0.8ms اعتمادًا على تغطية الشاشة.

الإصلاحات البرمجية: الاستعلام عن التراجع وإصلاحه في C++

أثناء انتظار إصدار hotfix رسمي، يمكنك اكتشاف هذه الحالة برمجيًا لدى العميل (client) وفرض إعدادات المحرك اللازمة. يمنع هذا التدهور الصامت من التأثير على اللاعبين الذين يمتلكون أنظمة تدعم الـ hardware ray tracing. فيما يلي تطبيق لمكون Actor Component بلغة C++ يستعلم عن مدير الكونسول (console manager)، ويفحص إعدادات الـ rendering الحالية، ويحل التعارض بشكل ديناميكي.

#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."));
            }
        }
    }
}

يمكن إرفاق هذا المكون بـ game state الرئيسي أو actor التهيئة (initialization actor). عند تشغيل اللعبة، يفحص السكريبت ما إذا كانت إعدادات المشروع تطابق التكوين الذي يحتوي على الخلل. إذا كانت كذلك، فإنه يضبط برمجيًا r.Lumen.ForceLumenScene على 1. يوجه هذا نظام الـ renderer للحفاظ على الـ Surface Cache بالرغم من أن نظام الإضاءة غير المباشرة (global illumination) لا يطلبه، مما يجعل الانعكاسات تعمل بكامل كفاءتها.

الحلول البديلة اليدوية وإصلاحات الكود المصدري للمحرك

بالنسبة للمطورين الذين لا يرغبون في تشغيل سكريبتات C++ في وقت التشغيل (runtime) لتغيير متغيرات الكونسول، هناك طريقتان رئيسيتان لحل هذا التراجع: تعديل ملفات التكوين (configuration files) مباشرة أو ترقيع (patching) الكود المصدري للمحرك. كلا الحلين صالحان اعتمادًا على ما إذا كنت تستخدم نسخة launcher من Unreal Engine أو بناءً مخصصًا من الكود المصدري (custom source build).

الحل البديل 1: تجاوز التكوين عبر متغيرات الكونسول (Console Variables)

إذا كنت تستخدم نسخة Epic Games Launcher من Unreal Engine 5.8، فلا يمكنك تعديل كود المحرك مباشرة. بدلاً من ذلك، يجب عليك إجبار المحرك على إبقاء Lumen Scene نشطًا باستخدام ملفات التكوين. افتح دليل مشروعك وانتقل إلى Config/DefaultEngine.ini.

تحت فئة [/Script/Engine.RendererSettings]، أضف السطور التالية:

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

ضبط r.Lumen.ForceLumenScene على 1 يتجاوز مرحلة التحسين (optimization pass) في الـ rendering pipeline التي تحدد Lumen Scene كغير مستخدم عند تعطيل GI. يفرض هذا على المحرك تخصيص ذاكرة الـ GPU وخطوات الحوسبة (compute passes) اللازمة لبناء وتحديث بطاقات Surface Cache. على الرغم من أن هذا يستعيد الانعكاسات، ضع في اعتبارك أنه سيزيد من تكلفة الـ GPU base pass قليلاً مقارنة بـ UE 5.7، حيث يقوم المحرك الآن بإجراء هذه التحديثات بدون سياق التحسين (optimization context) الذي كان متوفرًا في الإصدارات السابقة.

الحل البديل 2: تعديل الكود المصدري للمحرك

إذا كنت تقوم بتجميع Unreal Engine 5.8 من الكود المصدري (source)، فيمكنك ترقيع هذا الخلل من مصدره. السبب الجذري لـ regression يكمن داخل FDeferredShadingSceneRenderer::InitLumenScene الموجود في ملفات الـ rendering الخاصة بالمحرك (Private/Lumen/LumenScene.cpp). في UE 5.8، تم تحسين الفحوصات الشرطية (conditional checks) التي تحدد ما إذا كان Lumen Scene مطلوبًا أم لا، ولكنها أغفلت عن غير قصد فحص إعدادات الانعكاس.

لإصلاح ذلك، افتح LumenScene.cpp وحدد مكان تعريف bNeedLumenScene. يبدو الكود الخاطئ ونظيره المصحح كما يلي:

- // 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;

بعد تعديل هذا السطر، قم بإعادة بناء (rebuild) المحرك الخاص بك. يستعيد هذا التغيير نفس منطق الـ pipeline المستخدم في UE 5.7، مما يسمح للـ renderer بتهيئة Lumen Scene عندما يتم اختيار انعكاسات Lumen، بغض النظر عن طريقة الـ Global Illumination. هذه هي الطريقة الأنظف لحل المشكلة، لأنها تتجنب تنفيذ تجاوزات CVar التي قد تسبب حيرة لأعضاء الفريق أو تملأ ملفات التكوين بالبيانات غير الضرورية.

التأثيرات التبعية: ارتفاعات زمن الإطار لدى العميل و Multiplayer Desync

بينما تُعامل أخطاء الرسوميات (graphics bugs) غالبًا كمسائل بصرية معزولة، فإن تأثيراتها الثانوية يمكن أن تنعكس على بنية اللعبة (game architecture) بالكامل. عندما يواجه المطورون هذا الـ bug، غالبًا ما تكون استجابتهم الأولى هي إعادة تشغيل Lumen GI ببساطة لاستعادة الانعكاسات. ومع ذلك، فإن إضافة 4ms إلى 6ms من عبء العمل على الـ GPU لدى العميل (client) يمكن أن يتسبب في انخفاض حاد في معدل الإطارات (frame rate)، مما قد يؤدي إلى مشكلات multiplayer desync.

في ألعاب الـ multiplayer، ترتبط محاكاة الفيزياء (physics simulation) ومعالجة إدخالات اللاعبين بشكل وثيق بـ frame tick rate للعميل. عندما يواجه العميل توقفًا مفاجئًا في الـ rendering — مثل تحميل زائد على الـ GPU بسبب reflection pass أثناء دوران الكاميرا — يرتفع زمن إطار المحاكاة لدى العميل بشكل حاد. هذا التأخير يمكن أن يؤدي إلى إرسال حزم الشبكة (network packets) متأخرة أو معالجتها خارج الترتيب، مما ينتج عنه lag مرئي وتصحيحات من السيرفر. لمنع ارتفاعات الأداء هذه من إفساد شعور الـ multiplayer في لعبتك، تفقد دليلنا حول كيفية إصلاح عدم تزامن موقع اللاعب في UEFN و Unreal Engine multiplayer.

علاوة على ذلك، تسلط مشكلات الـ rendering هذه الضوء على أهمية فصل إعدادات الرسوميات من جانب العميل (client-side) عن منطق السيرفر (server logic). لا ينبغي أبدًا للسيرفرات المخصصة عديمة الواجهة (headless dedicated servers) أن تقوم بتجميع (compile) أو تحميل rendering pipelines، أو الخامات (materials)، أو مؤثرات post-processing volumes. عند تجميع ملف السيرفر التنفيذي (server executable)، يؤدي الفشل في إزالة (strip out) هذه الأصول (assets) إلى تضخم استهلاك الذاكرة وبطء أوقات التشغيل، مما قد يقلل من معدلات استجابة الـ matchmaker. للحصول على دليل مفصل حول تحسين بناء السيرفرات الخاصة بك، اقرأ مقالنا حول كيفية احتراف تجريد أصول dedicated server في Unreal Engine خطوة بخطوة.

حل أعباء إدارة التكوين مع horizOn

إن إصلاح مشكلات الـ rendering مثل الـ unreal engine 5.8 lumen reflections bug على جهازك المحلي هو نصف المعركة فقط. فبمجرد إطلاق لعبتك، يجب عليك إدارة ملفات تعريف الرسوميات (graphics profiles)، وتجاوزات متغيرات الكونسول (console variable overrides)، وإعدادات المحرك عبر الآلاف من تكوينات أجهزة الكمبيوتر المختلفة لدى اللاعبين (clients). وتثبيت قيم CVars بشكل جامد (hardcoding) في إعداداتك المحلية يعني أنه في حال اكتشاف تراجع (rendering regression) آخر في تحديث فرعي للمحرك، سيتعين عليك تجميع وحزم وتوزيع تحديث (patch) جديد تمامًا لقاعدة لاعبيك.

هذا العبء المرتبط بإدارة التكوين (configuration management) هو المكان الذي تصبح فيه منصة horizOn أداة لا تقدر بثمن لمطوري الألعاب. بدلاً من إجبارك على شحن تحديثات ضخمة لملف اللعبة لدى العميل (client) لحل مشكلات الـ rendering، تتيح لك منصتنا إدارة إعدادات لعبتك ديناميكيًا من backend مركزي. باستخدام خدمة التكوين عن بعد (remote configuration) من horizOn، يمكنك تحديد ملفات تعريف مستهدفة لمختلف تكوينات الأجهزة وتحديثها في الوقت الفعلي (real-time).

على سبيل المثال، عندما يقوم لاعب بتشغيل لعبتك، يمكن للعميل (client) الاستعلام من الـ backend، وإرسال تفاصيل حول بطاقة الرسوميات (GPU) المكتشفة وإصدار المحرك. يقوم السيرفر بتقييم هذه البيانات بموجب قواعد التكوين الحالية ويعيد قائمة CVars المحسنة. إذا كان اللاعب يقوم بتشغيل UE 5.8 على بطاقة رسوميات متوسطة الأداء، فإن الـ backend يرسل متغير r.Lumen.ForceLumenScene=1 بشكل ديناميكي. يحافظ هذا على عمل الانعكاسات بشكل مثالي دون إجبارك على كتابة وصيانة ملفات تعريف معقدة من جانب العميل (client-side) أو إرسال تحديثات طارئة.

أفضل الممارسات لتكوين Lumen في مرحلة الإنتاج (Production)

عند شحن لعبة تستخدم انعكاسات Lumen أو الإضاءة غير المباشرة (global illumination)، فإن اتباع عملية QA منظمة يمنع وصول التراجعات البصرية (visual regressions) إلى اللاعبين. فيما يلي أربعة من أفضل الممارسات التي يمكنك دمجها في pipeline التطوير الخاص بك:

  1. أتمتة فحوصات GBuffer: قم ببناء اختبارات مؤتمتة في pipeline الخاص بالـ CI/CD لالتقاط صور viewport باستخدام flags مخصصة للـ rendering. استخدم هذه الاختبارات للتحقق من أن قناة الانعكاس (reflection channel) تحتوي على بيانات ray-traced صالحة بدلاً من التراجع إلى مساحة شاشة فارغة.
  2. فصل GI عن Reflections أثناء التحسين (Optimization): اختبر لعبتك مع تعطيل GI وتفعيل Lumen reflections. يتيح لك هذا تقييم مكاسب الأداء لحلول baked lighting على الأنظمة الأقل كفاءة مع الحفاظ على specular highlights اللامعة.
  3. تنفيذ عمليات التحقق من CVars عند بدء التشغيل: قم بتطبيق سكريبتات تحقق تعمل في وقت التشغيل (runtime validation) لفحص حالة متغيرات الكونسول مثل r.DynamicGlobalIlluminationMethod و r.ReflectionMethod خلال مرحلة التحميل الأولية للعبة، لضمان عدم تسببها في حدوث حالات fallback.
  4. استخدام ملفات تعريف ديناميكية للعملاء (Dynamic Client Profiles): تجنب تثبيت إعدادات الرسوميات الجاهزة (graphics presets) بشكل جامد في ملفات مشروعك الثنائية (binaries). استخدم أدوات التكوين الديناميكية لضبط متغيرات الرسوميات (render variables) بشكل فوري، مما يتيح لك التفاعل بسرعة مع تراجعات المحرك دون الحاجة لإطلاق تحديث كامل للعميل.

هل أنت مستعد لتبسيط إدارة تكوينات لعبتك ونشر dedicated servers مستقرة؟ سجل في horizOn اليوم أو اقرأ وثائق المطورين لمعرفة كيفية دمج تحديثات الإعدادات الديناميكية في pipeline التطوير الخاص بك في Unreal Engine.


Source: UE 5.8 Release - Lumen Reflections not working unless Lumen GI enabled