مرحبا يا هبر! أقدم لكم ترجمة مقال
"Pseudo Lens Flare" للمخرج جون تشابمان.
توهج العدسات (
توهج العدسات) هو قطعة أثرية فوتوغرافية تنبع من تشتت وانكسار الضوء في نظام العدسات. على الرغم من كونه قطعة أثرية ، إلا أن هناك العديد من الأسباب لاستخدام
عدسة مضيئة في رسومات الكمبيوتر:
- لأنه يزيد من السطوع المتصورة والمدى الديناميكي المرئي للصورة.
- غالبًا ما يتم العثور على إضاءة العدسات في الصور ، لذلك يمكن أن يكون غيابها ملفتًا للنظر
- يمكن أن تلعب دورًا مهمًا في الأسلوب أو الدراما ، أو يمكن أن تكون جزءًا من اللعب في الألعاب (تخيل وهج يعمى أحد اللاعبين)
تقليديا ، تم تنفيذ
عدسة مضيئة في الوقت الحقيقي باستخدام التقنيات القائمة على العفريت. على الرغم من أن العفاريت تعطي نتائج يمكن التحكم فيها بسهولة وواقعية للغاية ، إلا أنه يجب وضعها بشكل صريح وتتطلب عرض بيانات الإغلاق بشكل صحيح. سوف أصف هنا تأثير مساحة الشاشة بسيطًا ورخيصًا نسبيًا يعمل على إنشاء
عدسة زائفة
مضيئة من مخزن الألوان المؤقت. لا يعتمد على الفيزياء ، وبالتالي فإن النتيجة مختلفة قليلاً عن النتيجة الواقعية ، ولكن يمكن استخدامها مع (أو كبديل) للتأثيرات التقليدية القائمة على العفريت.
خوارزمية
يتكون من 4 مراحل:
- Downsample / العتبة.
- جيل من عناصر مضيئة عدسة .
- طمس
- الراقي / المزج مع الصورة الأصلية.
1. downsample / العتبة
الاختزال - التحسين لتقليل تكلفة الخطوات اللاحقة. بالإضافة إلى ذلك ، نريد تحديد مجموعة فرعية من ألمع بكسل في الصورة الأصلية. يوفر استخدام
scale / bias (scale / bias) طريقة مرنة لتحقيق ذلك:
uniform sampler2D uInputTex; uniform vec4 uScale; uniform vec4 uBias; noperspective in vec2 vTexcoord; out vec4 fResult; void main() { fResult = max(vec4(0.0), texture(uInputTex, vTexcoord) + uBias) * uScale; }

ضبط
النطاق / التحيز هو الطريقة الرئيسية لضبط التأثير ؛ ستعتمد أفضل الإعدادات على النطاق الديناميكي لمخزن الألوان المؤقت ، وكذلك على مدى رغبتك في رؤية النتيجة. نظرًا لحقيقة أن هذه التقنية تقريبية ، فمن المرجح أن تبدو الدقة بشكل أفضل.
2. جيل من عناصر مضيئة عدسة
تميل عناصر
إضاءة العدسة إلى الدوران حول مركز الصورة. من خلال محاكاة هذا التأثير ، يمكننا توسيع نتيجة المرحلة السابقة أفقياً / رأسياً. من السهل القيام بذلك في مرحلة إنشاء العناصر عن طريق توسيع إحداثيات النسيج:
vec2 texcoord = -vTexcoords + vec2(1.0);
هذا ليس ضروريا ؛ جيل عنصر يعمل بشكل جيد مع وبدون ذلك. ومع ذلك ، فإن نتيجة تغيير إحداثيات النسيج تساعد على فصل بصري تأثير
توهج العدسة عن الصورة الأصلية.
أشباح
تقوم "
الأشباح " (الأشباح) بتكرار الإبرازات التي تعكس المساحات المشرقة في المخزن المؤقت للألوان ، والتي تتكشف بالنسبة إلى مركز الصورة. تتمثل الطريقة التي اخترت إنشاءها في الحصول على متجه من البيكسل الحالي إلى مركز الشاشة ، ثم تحديد عدة اختيارات على طول هذا المتجه.

uniform sampler2D uInputTex; uniform int uGhosts;
لاحظ أنني أستخدم
الكسر () لضمان أن الإحداثيات تنسج حولها ؛
بالتساوي يمكنك استخدام وضع التفاف
GL_REPEAT للنسيج.
هذه هي النتيجة:

يمكنك تحسين النتيجة من خلال السماح فقط للمساحات الساطعة القريبة من مركز الصورة بإنشاء أشباح. يمكننا تحقيق ذلك عن طريق إضافة الأوزان التي ستنخفض من المركز للعينات:
vec4 result = vec4(0.0); for (int i = 0; i < uGhosts; ++i) { vec2 offset = fract(texcoord + ghostVec * float(i)); float weight = length(vec2(0.5) - offset) / length(vec2(0.5)); weight = pow(1.0 - weight, 10.0); result += texture(uInputTex, offset) * weight; }
وظيفة الوزن بسيطة قدر الإمكان - خطية. السبب في حساب الوزن داخل الحلقة هو أن المساحات المشرقة في وسط صورة الإدخال يمكن أن تلقي أشباحًا بالحدود ، لكن المساحات الساطعة على الحدود لا يمكنها إرسال أشباح إلى الوسط.

التحسين النهائي هو تغيير لون شعاعي من الشبح ، وفقا للنسيج 1D:

يتم تطبيقه بعد الدورة للتأثير على اللون النهائي للشبح:
result *= texture(uLensColor, length(vec2(0.5) - texcoord) / length(vec2(0.5)));
هالوس (هالات)
إذا أخذنا المتجه إلى مركز الصورة ، كما هو الحال في حساب
الشبح ، لكن مع إصلاح طول المتجه ، نحصل على تأثير مختلف: الصورة الأصلية مشوهة شعاعيًا:

يمكننا استخدام هذا لإنشاء "هالة" بضرب الوزن بعينة ، وبالتالي الحد من مساهمة الصورة المشوهة في حلقة يتحكم في نصف قطرها
uHaloWidth :

التشوه اللوني (تشويه اللون)
بعض مشاعل العدسات لها تشوه في اللون ناتج عن اختلافات في انكسار الضوء بأطوال موجية مختلفة. يمكننا محاكاة ذلك عن طريق إنشاء وظيفة تختار القنوات الحمراء والخضراء والزرقاء بشكل منفصل مع إزاحة مختلفة قليلاً على طول متجه العينة:
vec3 textureDistorted( in sampler2D tex, in vec2 texcoord, in vec2 direction,
يمكن استخدامه كبديل مباشر للاتصال
الملمس () في القائمة السابقة. أحسب
الاتجاه والتشويه على النحو التالي:
vec2 texelSize = 1.0 / vec2(textureSize(uInputTex, 0)); vec3 distortion = vec3(-texelSize.x * uDistortion, 0.0, texelSize.x * uDistortion); vec3 direction = normalize(ghostVec);
على الرغم من أن وظيفة الجلب بسيطة ، إلا أنها تكلف عينات x3 من النسيج ، على الرغم من أنها يجب أن تكون جميعها صديقة للذاكرة المخبأة ما لم
تقم بتعيين
التشوه على قيمة هائلة.
مع جيل من العناصر ، كل شيء. هذه هي النتيجة:

3. طمس
بدون تشويش ، تميل عناصر
إضاءة العدسة (خاصة الأشباح) إلى الحفاظ على مظهر الصورة. بإضافة الضبابية إلى عناصر
إضاءة العدسة ، نقوم بإضعاف الترددات العالية وبالتالي تقليل التباين مع صورة الإدخال ، مما يساعدنا على بيع التأثير.

لن أخبرك عن كيفية طمس ؛ يمكنك أن تقرأ عنها على موارد الإنترنت المختلفة (Gaussian blur).
4. الراقي / مزيج مع الصورة الأصلية
لذلك ، لدينا عناصر
مضيئة عدسة لدينا ، غير واضحة بشكل جيد. كيف يمكننا دمجها مع الصورة المصدر الأصلي؟ هناك العديد من الاعتبارات المهمة المتعلقة بخط أنابيب العرض بالكامل:
- يجب تطبيق أي تمويه حركة أو عمق مجال لاحق قبل الجمع مع توهج العدسة ، لذلك لن تشارك عناصر توهج العدسات في هذه التأثيرات.
- يجب أن يتم تطبيق إضاءة العدسات قبل إجراء أي تصوير . هذا أمر منطقي ، نظرًا لأن التصوير المقطعي يحاكي استجابة الفيلم / CMOS للضوء الوارد ، والذي يعد توهج العدسات جزءًا لا يتجزأ منه.
مع وضع ذلك في الاعتبار ، هناك بعض الأشياء التي يمكننا القيام بها في هذه المرحلة لتحسين النتيجة:
لينس ديرت
أولاً ، تحتاج إلى تعديل عناصر
إضاءة العدسة بنسيج قذر بدقة كاملة (يستخدم على نطاق واسع في Battlefield 3):

uniform sampler2D uInputTex;
المفتاح لهذا هو الملمس الأوساخ جدا على العدسات. إذا كان التباين منخفضًا ، تميل أشكال
إضاءة العدسة إلى السيطرة على النتيجة. مع زيادة التباين ، تكون عناصر
إضاءة العدسات مكتومة ، مما يعطي مظهرًا جماليًا مختلفًا ويخفي أيضًا بعض العيوب.
الانهيار STARBURST
كتحسين إضافي ، يمكننا استخدام نسيج
النجمي من خلال إضافته إلى
عدسة الأوساخ :
كملمس ،
النجمي لا تبدو جيدة جدا. ومع ذلك ، يمكننا تمرير مصفوفة التحويل إلى التظليل ، مما سيسمح لنا بتدوير / تشوه
انفجار النجمي في كل إطار والحصول على التأثير الديناميكي المطلوب:
uniform sampler2D uInputTex;
تعتمد مصفوفة تحويل
uLensStarMatrix على القيمة التي تم الحصول عليها من اتجاه الكاميرا على النحو التالي:
vec3 camx = cam.getViewMatrix().col(0);
هناك طرق أخرى للحصول على قيمة camrot ؛ الأهم من ذلك ، يجب أن تتغير باستمرار عند تشغيل الكاميرا. المصفوفة نفسها مبنية على النحو التالي:
mat3 scaleBias1 = ( 2.0f, 0.0f, -1.0f, 0.0f, 2.0f, -1.0f, 0.0f, 0.0f, 1.0f, ); mat3 rotation = ( cos(camrot), -sin(camrot), 0.0f, sin(camrot), cos(camrot), 0.0f, 0.0f, 0.0f, 1.0f ); mat3 scaleBias2 = ( 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, ); mat3 uLensStarMatrix = scaleBias2 * rotation * scaleBias1;
تحتاج مصفوفات
المقياس والتحيز إلى إزاحة أصل الملمس حتى نتمكن من تدوير
النجمي بالنسبة إلى مركز الصورة.
الخاتمة
حتى الآن كل شيء! توضح هذه الطريقة كيف تعطي عملية النشر المبسطة نسبيًا
عدسة مضيئة جيدة المظهر. إنه ليس واقعيًا تمامًا ، ولكن إذا تم استخدامه بشكل صحيح ، فإنه يمكن أن يؤدي إلى نتائج ممتازة.

محدثنشر المؤلف أيضًا
مقالة ذات تحسينات طفيفة.
شفرة المصدر يمكن رؤيتها
هنا وهنا .