
عند الكتابة إلى Framebuffer ، يتم تقليل قيم سطوع الألوان إلى الفاصل الزمني من 0.0 إلى 1.0. وبسبب هذا ، للوهلة الأولى ، ميزة غير ضارة ، يتعين علينا دائمًا اختيار هذه القيم للإضاءة والألوان التي تناسبها في هذا التقييد. يعمل هذا النهج ويعطي نتائج لائقة ، ولكن ماذا يحدث إذا التقينا بمنطقة مشرقة بشكل خاص مع الكثير من مصادر الضوء الساطع ، وتجاوز السطوع الكلي 1.0؟ ونتيجة لذلك ، سيتم تحويل جميع القيم الأكبر من 1.0 إلى 1.0 ، والتي لا تبدو لطيفة جدًا:

نظرًا لأن قيم الألوان يتم تخفيضها إلى 1.0 لعدد كبير من الأجزاء ، يتم ملء المساحات الكبيرة من الصورة بنفس اللون الأبيض ، ويتم فقد عدد كبير من تفاصيل الصورة ، وتبدأ الصورة نفسها في الظهور بشكل غير طبيعي.
قد يكون الحل لهذه المشكلة هو تقليل سطوع مصادر الضوء بحيث لا توجد شظايا أكثر سطوعًا من 1.0 على المسرح: هذا ليس الحل الأفضل ، مما يفرض استخدام قيم الإضاءة غير الواقعية. أفضل طريقة هي السماح لقيم السطوع بتجاوز سطوع 1.0 مؤقتًا وفي الخطوة الأخيرة قم بتغيير الألوان بحيث يعود السطوع إلى النطاق من 0.0 إلى 1.0 ، ولكن دون فقدان تفاصيل الصورة.
شاشة الكمبيوتر قادرة على إظهار الألوان مع سطوع يتراوح من 0.0 إلى 1.0 ، ولكن ليس لدينا مثل هذا القيد عند حساب الإضاءة. من خلال السماح بألوان الجزء لتكون أكثر سطوعًا من الوحدة ، نحصل على نطاق سطوع أعلى للعمل - HDR (نطاق ديناميكي مرتفع) . مع HDR ، تبدو الأشياء الساطعة مشرقة ، والأشياء المظلمة يمكن أن تكون مظلمة حقًا ، وبذلك سنرى التفاصيل.
في البداية ، تم استخدام نطاق ديناميكي مرتفع في التصوير الفوتوغرافي: التقط المصور عدة صور متطابقة للمشهد مع تعرضات مختلفة ، والتقاط ألوان من أي سطوع تقريبًا. تشكل مجموعة هذه الصور صورة HDR حيث تصبح معظم التفاصيل مرئية بسبب مجموعة الصور مع خسائر التعرض المختلفة. على سبيل المثال ، أدناه على الصورة اليسرى ، تظهر الأجزاء المضيئة للغاية من الصورة بوضوح (انظر إلى النافذة) ، ولكن هذه التفاصيل تختفي عند استخدام التعرض العالي. ومع ذلك ، فإن التعرض العالي يجعل التفاصيل على المناطق المظلمة من الصورة التي لم تكن مرئية من قبل.

هذا مشابه لكيفية عمل العين البشرية. مع نقص الضوء ، تتكيف العين ، بحيث تصبح التفاصيل الداكنة مرئية بوضوح ، وبالمثل للمناطق المضيئة. يمكن القول أن العين البشرية لديها تحكم تلقائي في التعرض ، اعتمادًا على سطوع المشهد.
يعمل عرض HDR بنفس الطريقة تقريبًا. عندما نقدم ، نسمح باستخدام مجموعة كبيرة من قيم السطوع لجمع معلومات حول التفاصيل الساطعة والداكنة للمشهد ، وفي النهاية سنحول القيم من نطاق HDR إلى LDR (النطاق الديناميكي المنخفض ، النطاق من 0 إلى 1). يُسمى هذا التحويل تعيين النغمة ، وهناك عدد كبير من الخوارزميات التي تهدف إلى الحفاظ على معظم تفاصيل الصورة عند التحويل إلى LDR. غالبًا ما تحتوي هذه الخوارزميات على إعداد تعريض يسمح لها بعرض المناطق المضيئة أو الداكنة من الصورة بشكل أفضل.
يتيح لنا استخدام النطاق الديناميكي العالي (HDR) عند العرض عدم تجاوز نطاق LDR من 0 إلى 1 وحفظ المزيد من تفاصيل الصورة فحسب ، بل يجعل من الممكن أيضًا الإشارة إلى السطوع الحقيقي لمصادر الضوء. على سبيل المثال ، تحتوي الشمس على سطوع ضوء أكبر بكثير من شيء مثل مصباح يدوي ، فلماذا لا تضبط الشمس على هذا (على سبيل المثال ، أعطها سطوعًا 10.0)؟ سيسمح لنا ذلك بتعديل إضاءة المشهد بشكل أفضل باستخدام معلمات سطوع أكثر واقعية ، وهو أمر مستحيل مع عرض LDR ونطاق سطوع من 0 إلى 1.
نظرًا لأن الشاشة تعرض سطوعًا من 0 إلى 1 فقط ، فإننا مضطرون لتحويل نطاق قيم HDR المستخدمة إلى نطاق الشاشة. لن يكون قياس النطاق ببساطة حلًا جيدًا ، حيث ستبدأ المناطق الساطعة في السيطرة على الصورة. ومع ذلك ، يمكننا استخدام معادلات أو منحنيات مختلفة لتحويل قيم HDR إلى LDR ، مما يمنحنا تحكمًا كاملاً في سطوع المشهد. يُطلق على هذا التحول تعيين النغمة وهو الخطوة الأخيرة في عرض HDR.
العائمة Framebuffers
لتنفيذ عرض HDR ، نحتاج إلى طريقة لمنع إحضار القيم إلى نطاق من 0 إلى 1 من جهاز تظليل الأجزاء. إذا كان Framebuffer يستخدم تنسيق النقطة الثابتة المعياري (GL_RGB) لمخازن الألوان المؤقتة ، فإن OpenGL يحد تلقائيًا من القيم قبل الحفظ في Framebuffer. ينطبق هذا التقييد على معظم تنسيقات Framebuffer باستثناء تنسيقات الفاصلة العائمة.
لتخزين القيم التي تقع خارج النطاق [0.0..1.0] ، يمكننا استخدام مخزن الألوان المؤقت بالتنسيقات التالية: GL_RGB16F, GL_RGBA16F, GL_RGB32F or GL_RGBA32F
. هذا رائع لتقديم تقرير التنمية البشرية. سيطلق على هذا المخزن المؤقت إطار فاصلة عائمة.
يختلف إنشاء مخزن مؤقت للفاصلة العائمة عن مخزن مؤقت عادي فقط من حيث أنه يستخدم تنسيق داخلي مختلف:
glBindTexture(GL_TEXTURE_2D, colorBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
يستخدم برنامج OpenGL Framebuffer بشكل افتراضي 8 بت فقط لتخزين كل لون. في أداة GL_RGB32F
GL_RGBA32F
بتنسيقات GL_RGBA32F
أو GL_RGBA32F
، يتم استخدام 32 بت لتخزين كل لون - 4 مرات أكثر. إذا لم تكن الدقة العالية مطلوبة ، GL_RGBA16F
تنسيق GL_RGBA16F
كافيًا تمامًا.
إذا تم إرفاق مخزن مؤقت للفاصلة العائمة مع الإطار Framebuffer للون ، فيمكننا عرض المشهد فيه مع مراعاة أن قيم الألوان لن تقتصر على النطاق من 0 إلى 1. في التعليمات البرمجية لهذه المقالة ، نقوم أولاً بتقديم المشهد إلى Framebuffer العائم ثم نقوم بعرض المحتويات الألوان المخزنة على مستطيل نصف الشاشة. يبدو شيء مثل هذا:
glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // [...] hdr glBindFramebuffer(GL_FRAMEBUFFER, 0); // hdr 2 hdrShader.use(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, hdrColorBufferTexture); RenderQuad();
هنا قد تكون قيم الألوان الموجودة في المخزن المؤقت للألوان أكبر من 1. بالنسبة لهذه المقالة ، تم إنشاء مشهد بمكعب كبير ممدود يشبه نفقًا به أربعة مصادر للضوء ، يقع أحدها في نهاية النفق وله سطوع كبير.
std::vector<glm::vec3> lightColors; lightColors.push_back(glm::vec3(200.0f, 200.0f, 200.0f)); lightColors.push_back(glm::vec3(0.1f, 0.0f, 0.0f)); lightColors.push_back(glm::vec3(0.0f, 0.0f, 0.2f)); lightColors.push_back(glm::vec3(0.0f, 0.1f, 0.0f));
إن التقديم إلى المخزن المؤقت للفاصلة العائمة هو نفسه تمامًا كما لو كنا نعرض المشهد إلى Framebuffer عادي. الشيء الجديد الوحيد هو تظليل hdr المجزأ ، والذي يتعامل مع تظليل بسيط لمستطيل ملء الشاشة بقيم من نسيج ، وهو مخزن مؤقت للون عائم. للبدء ، دعنا نكتب تظليلًا بسيطًا ينقل بيانات الإدخال دون تغيير:
#version 330 core out vec4 FragColor; in vec2 TexCoords; uniform sampler2D hdrBuffer; void main() { vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb; FragColor = vec4(hdrColor, 1.0); }
نأخذ الإدخال من النقطة العائمة في المخزن المؤقت للألوان ونستخدمه كقيمة إخراج للتظليل. ومع ذلك ، نظرًا لأن المستطيل ثنائي الأبعاد يتم تقديمه في أداة Framebuffer بشكل افتراضي ، فإن قيم الإخراج للتظليل ستقتصر على فاصل زمني من 0 إلى 1 ، على الرغم من حقيقة أن القيم في بعض الأماكن أكبر من 1.

يصبح من الواضح أن قيم الألوان الكبيرة جدًا في نهاية النفق تقتصر على الوحدة ، لأن جزءًا كبيرًا من الصورة أبيض بالكامل ، ونفقد تفاصيل الصورة الأكثر سطوعًا من الوحدة. نظرًا لأننا نستخدم قيم HDR مباشرة كـ LDR ، فإن هذا يعادل عدم وجود HDR. لإصلاح ذلك ، يجب علينا عرض قيم الألوان المختلفة مرة أخرى في النطاق من 0 إلى 1 دون فقدان أي تفاصيل في الصورة. للقيام بذلك ، قم بتطبيق ضغط الدرجة اللونية.
ضغط النغمة
ضغط النغمة هو تحويل قيم الألوان لتلائمها في النطاق من 0 إلى 1 دون فقدان تفاصيل الصورة ، غالبًا بالاشتراك مع إعطاء الصورة توازن اللون الأبيض المطلوب.
تُعرف أبسط خوارزمية تعيين النغمة باسم خوارزمية تخطيط نغمة Reinhard . يعرض أي قيم HDR في نطاق LDR. أضف هذه الخوارزمية إلى تظليل الجزء السابق ، وقم أيضًا بتطبيق تصحيح جاما (واستخدام مواد SRGB).
void main() { const float gamma = 2.2; vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb; // vec3 mapped = hdrColor / (hdrColor + vec3(1.0)); // - mapped = pow(mapped, vec3(1.0 / gamma)); FragColor = vec4(mapped, 1.0); }
ملاحظة عبر. - بالنسبة للقيم الصغيرة لـ x ، تتصرف الدالة x / (1 + x) مثل x تقريبًا ، لأن x الكبيرة تميل إلى الوحدة. الرسم البياني للدالة:

مع ضغط نغمة Reinhardt ، لم نعد نفقد التفاصيل في المناطق المضيئة من الصورة. تفضل الخوارزمية المناطق المضيئة ، مما يجعل المناطق المظلمة أقل تميزًا.

هنا يمكنك رؤية التفاصيل مرة أخرى في نهاية الصورة ، مثل نسيج الخشب. باستخدام هذه الخوارزمية البسيطة نسبيًا ، يمكننا أن نرى بوضوح أي ألوان من نطاق HDR ويمكننا التحكم في إضاءة المشهد دون فقدان تفاصيل الصورة.
من الجدير بالذكر أنه يمكننا استخدام ضغط الدرجة اللونية مباشرة في نهاية آلة التظليل لحساب الإضاءة ، وبعد ذلك لا نحتاج إلى أداة تأطير الفاصلة العائمة على الإطلاق. ومع ذلك ، في المشاهد الأكثر تعقيدًا ، ستواجه غالبًا الحاجة إلى تخزين قيم HDR الوسيطة في المخازن المؤقتة للفاصلة العائمة ، لذلك سيكون هذا مفيدًا.
ميزة أخرى مثيرة للاهتمام لضغط النغمة هي استخدام معلمة التعرض. قد تتذكر أنه في الصور في بداية المقال ، كانت التفاصيل المختلفة مرئية بقيم التعرض المختلفة. إذا كان لدينا مشهد يتغير فيه النهار والليل ، فمن المنطقي استخدام التعرض المنخفض خلال النهار وعالية في الليل ، وهو ما يشبه تكيف العين البشرية. باستخدام معلمة التعرض هذه ، يمكننا تكوين معلمات الإضاءة التي ستعمل ليلًا ونهارًا في ظروف الإضاءة المختلفة.
تبدو خوارزمية ضغط الدرجة اللونية البسيطة نسبيًا مع التعرض كما يلي:
uniform float exposure; void main() { const float gamma = 2.2; vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb; // vec3 mapped = vec3(1.0) - exp(-hdrColor * exposure); // - mapped = pow(mapped, vec3(1.0 / gamma)); FragColor = vec4(mapped, 1.0); }
ملاحظة per: أضف رسمًا بيانيًا لهذه الوظيفة مع التعرض 1 و 2:

حددنا هنا متغيرًا للضوء ، وهو 1 افتراضيًا ويسمح لنا باختيار التوازن بين جودة عرض المناطق المظلمة والمشرقة للصورة بشكل أكثر دقة. على سبيل المثال ، مع تعرض كبير ، نرى المزيد من التفاصيل في المناطق المظلمة من الصورة. على العكس من ذلك ، فإن التعرض المنخفض يجعل المناطق المظلمة لا يمكن تمييزها ، لكنه يسمح لك برؤية المناطق المضيئة من الصورة بشكل أفضل. فيما يلي صور نفق بمستويات تعرض مختلفة.

تظهر هذه الصور بوضوح فوائد عرض تقرير التنمية البشرية. مع تغير مستوى التعرض ، نرى المزيد من التفاصيل حول المشهد الذي سيتم فقده في العرض العادي. خذ نهاية النفق كمثال - مع التعرض الطبيعي ، بالكاد يكون نسيج الشجرة مرئيًا ، ولكن مع التعرض المنخفض ، يكون النسيج مرئيًا تمامًا. وبالمثل ، عند التعرض العالي ، تكون التفاصيل في المناطق المظلمة واضحة للغاية.
كود المصدر للعرض هنا.
المزيد HDR
هذه الخوارزميات الانضغاطية اللتين تم عرضهما ليست سوى جزء صغير من بين عدد كبير من الخوارزميات الأكثر تقدمًا ، لكل منها نقاط القوة والضعف الخاصة به. تركز بعض الخوارزميات بشكل أفضل على ألوان / سطوع معينة ، وتظهر بعض الخوارزميات مناطق داكنة ومشرقة في نفس الوقت ، مما يعطي صورًا أكثر تفصيلاً وتفصيلاً. هناك أيضًا العديد من الطرق المعروفة بتعديل التعرض التلقائي أو التكيف مع العين . إنها تحدد سطوع المشهد في الإطار السابق وتغير (ببطء) معلمة التعرض ، بحيث يصبح المشهد المظلم أكثر سطوعًا ببطء ، والسطوع - الداكن: مشابهًا للاعتياد على العين البشرية.
من الأفضل رؤية الفوائد الحقيقية لـ HDR في المشاهد الكبيرة والمعقدة باستخدام خوارزميات الإضاءة الخطيرة. لأغراض التدريب ، استخدمت هذه المقالة أبسط مشهد ممكن ، حيث قد يكون إنشاء مشهد كبير أمرًا صعبًا. على الرغم من بساطة المشهد ، إلا أن بعض مزايا عرض HDR مرئية عليه: في المناطق المظلمة والمشرقة من الصورة ، لا تضيع التفاصيل ، حيث يتم حفظها باستخدام ضغط النغمة ، ولا تؤدي إضافة مصادر ضوئية متعددة إلى ظهور مساحات بيضاء ، ولا يجب أن تتناسب القيم مع LDR النطاق.
علاوة على ذلك ، يجعل عرض HDR أيضًا بعض التأثيرات المثيرة للاهتمام أكثر تصديقًا وواقعية. أحد هذه الآثار هو الإزهار ، والذي سنناقشه في مقال لاحق.
موارد إضافية:
ملاحظة : لدينا برقية أسيوط لتنسيق التحويلات. إذا كانت لديك رغبة جادة في المساعدة في الترجمة ، فأنت مرحب بك!