في الأشهر القليلة الماضية ، غمر Facebook
صورًا ثلاثية الأبعاد . إذا لم تكن قادرًا على رؤيتها ، فسأوضح لك: الصور ثلاثية الأبعاد هي صور داخل المنشور تعمل على تغيير الزاوية بسلاسة عند تمرير الصفحة أو عند تحريك الماوس فوقها.
قبل ظهور هذه الميزة ببضعة أشهر ، اختبر Facebook ميزة مشابهة مع النماذج ثلاثية الأبعاد. على الرغم من أنه يمكنك بسهولة فهم كيف يمكن لـ Facebook تقديم نماذج ثلاثية الأبعاد وتدويرها وفقًا لموضع الماوس ، إلا أنه من خلال الصور ثلاثية الأبعاد ، قد لا يكون الموقف بديهيًا.
أحيانًا ما تسمى التقنية التي يستخدمها Facebook لإنشاء ثلاثي الأبعاد للصور ثنائية الأبعاد
بإزاحة خريطة الارتفاع . ويستخدم ظاهرة بصرية تسمى
المنظر .
مثال لصورة ثلاثية الأبعاد على Facebook (GIF) ما هو المنظر
إذا لعبت Super Mario ، فأنت تعرف بالضبط ما هو المنظر. على الرغم من أن ماريو يعمل بنفس السرعة ، يبدو أن الكائنات البعيدة في الخلفية تتحرك أبطأ (انظر أدناه).
يخلق هذا التأثير وهم أن بعض العناصر ، مثل الجبال والسحب ، تقع أبعد. إنه فعال لأن دماغنا يستخدم المنظر (إلى جانب الإشارات البصرية الأخرى) لتقدير المسافة إلى الأشياء البعيدة.
كيف يقيم الدماغ المسافة؟من المفترض أن يستخدم العقل البشري عدة آليات لتقدير المسافة. في المدىين القصير والمتوسط ، يتم حساب المسافات من خلال مقارنة الاختلافات في موضع الكائن المرئي بالعينين اليمنى واليسرى. وهذا ما يسمى
الرؤية المجسمة وعلى نطاق واسع في الطبيعة.
ومع ذلك ، بالنسبة للأجسام البعيدة بما فيه الكفاية ، فإن الرؤية المجسمة ليست كافية. الجبال والغيوم والنجوم تختلف قليلاً عن عيون مختلفة لتلاحظ وجود فرق كبير. لذلك ، يأتي المنظر النسبي في اللعب. الكائنات في الخلفية تتحرك أقل من الكائنات في المقدمة. إن حركتهم النسبية هي التي تتيح لك ضبط المسافة النسبية.
في تصور المسافة ، يتم استخدام العديد من الآليات الأخرى. وأشهرها هو الضباب الجوي ، الذي يعطي الأجسام البعيدة صبغة زرقاء. في عوالم أخرى ، لا توجد معظم هذه القرائن في الغلاف الجوي ، لذلك من الصعب للغاية تقييم حجم الأجسام الموجودة على كواكب أخرى والقمر. يفسر مستخدم YouTube Alex McCulgan هذا على قناة
Astrum الخاصة به ، ويوضح مدى صعوبة تحديد حجم الكائنات القمرية التي تظهر في الفيديو.
المنظر بمثابة تحول
إذا كنت معتادًا على الجبر الخطي ، فربما تعلم مدى تعقيد الرياضيات ثلاثية الأبعاد وغير التافهة. لذلك ، هناك طريقة أكثر بساطة لفهم المنظر ، الذي لا يتطلب سوى التحولات.
دعونا نتخيل أننا ننظر إلى مكعب (انظر أدناه). إذا كنا محاذاة بدقة مع مركزها ، فستبدو الوجوه الأمامية والخلفية مثل مربعين من أحجام مختلفة لأعيننا. هذا هو
الاحتمال .
ومع ذلك ، ماذا يحدث إذا قمنا بتحريك الكاميرا لأسفل ، أو رفع المكعب لأعلى؟ بتطبيق نفس المبادئ ، يمكننا أن نرى أن الوجهين الأمامي والخلفي قد تحولا بالنسبة إلى وضعهما السابق. الأكثر إثارة للاهتمام هو أنها انتقلت نسبة إلى بعضها البعض. الوجه الخلفي ، الذي هو أبعد عنا ، كما لو تحركت أقل.
إذا أردنا حساب المواضع الحقيقية لهذه القمم من المكعب في نطاقنا المتوقع ، فسوف يتعين علينا أن نأخذ بجدية علم المثلثات. ومع ذلك ، هذا ليس ضروريا حقا. إذا كانت حركة الكاميرا صغيرة بدرجة كافية ، فيمكننا تقريبًا إزاحة الرؤوس ، ونقلها بما يتناسب مع المسافة.
الشيء الوحيد الذي نحتاج إلى تحديده هو المقياس. إذا قمنا بنقل X متر إلى اليمين ، فيجب أن يبدو أن الكائن Y على بعد متر قد تحرك Z متر. إذا بقيت X صغيرة ، يصبح المنظر مهمة
الاستيفاء الخطي بدلاً من علم المثلثات. وهذا يعني في جوهره أنه يمكننا محاكاة التدوير ثلاثي الأبعاد الصغير عن طريق تحويل البكسل وفقًا لبعدها عن الكاميرا.
توليد خرائط العمق
من حيث المبدأ ، ما يفعله Facebook لا يختلف كثيرًا عما يحدث في Super Mario. بالنسبة لصورة معينة ، يتم تبديل بعض وحدات البكسل في اتجاه الحركة استنادًا إلى المسافة إلى الكاميرا. لإنشاء صورة ثلاثية الأبعاد على Facebook ، فأنت تحتاج فقط إلى الصورة نفسها وخريطة توضح مدى بُعد كل بكسل عن الكاميرا. هذه الخريطة لها الاسم المتوقع -
"خريطة العمق" . ويسمى أيضًا
خريطة الارتفاع ، اعتمادًا على السياق.
التقاط صورة بسيط للغاية ، ولكن إنشاء خريطة العمق الصحيح يعد مهمة أكثر صعوبة. الأجهزة الحديثة تستخدم تقنيات مختلفة. غالبا ما تستخدم كاميرتين. كل يأخذ صورة لنفس الموضوع ، ولكن مع وجهة نظر مختلفة قليلا. يتم استخدام نفس المبدأ في
الرؤية المجسمة ، والتي يستخدمها الناس لتقييم العمق في المسافات القصيرة والمتوسطة. توضح الصورة أدناه كيف يمكن لـ iPhone 7 إنشاء خرائط متعمقة من صورتين قريبتين للغاية.
تم وصف تفاصيل تنفيذ إعادة الإعمار هذه في مقالة
فورية للتصوير ثلاثي الأبعاد ، قدمها
بيتر هيدمان ويوهانس كوبف في SIGGRAPH2018.
بعد إنشاء خريطة عمق عالية الجودة ، تصبح محاكاة الأبعاد الثلاثة مهمة تافهة تقريبًا. يتمثل القيد الحقيقي لهذه التقنية في أنه حتى لو تمكنت من إعادة إنشاء نموذج ثلاثي الأبعاد تقريبي ، فإنها تفتقر إلى معلومات حول كيفية جعل الأجزاء غير المرئية في الصورة الأصلية. في الوقت الحالي ، لا يمكن حل هذه المشكلة ، وبالتالي ، فإن جميع الحركات المرئية في الصور ثلاثية الأبعاد غير مهمة إلى حد ما.
تعرفنا على مفهوم الصور ثلاثية الأبعاد وتحدثنا بإيجاز عن كيفية إنشاء الهواتف الذكية الحديثة. في الجزء الثاني ، سوف نتعلم كيف يمكن استخدام نفس التقنيات لتنفيذ الصور ثلاثية الأبعاد في الوحدة باستخدام التظليل.
الجزء 2. تظليل المنظر وخرائط العمق
قالب تظليل
إذا كنا نريد إعادة إنشاء صور ثلاثية الأبعاد لفيسبوك باستخدام تظليل ، فعلينا أولاً تحديد ما سنفعله بالضبط. نظرًا لأن هذا التأثير يعمل بشكل أفضل مع الصور ثنائية الأبعاد ، سيكون من المنطقي تطبيق حل متوافق مع رموز الوحدة. سنقوم بإنشاء تظليل يمكن استخدامه مع
Sprite Renderer .
على الرغم من أنه يمكن إنشاء مثل هذا التظليل من البداية ، إلا أنه من الأفضل في الغالب البدء بقالب جاهز. من الأفضل البدء في المضي قدمًا عن طريق نسخ تظليل العفاريت المنتشر الحالي ، والذي تستخدمه Unity افتراضيًا لجميع العفاريت. لسوء الحظ ، لا يأتي المحرك مع ملف
تظليل يمكنك تحريره بنفسك.
للحصول عليها ، تحتاج إلى الانتقال إلى
أرشيف تنزيل Unity وتنزيل حزمة
shaders المضمنة (انظر أدناه) للحصول على إصدار المحرك الذي تستخدمه.
بعد استخراج الحزمة ، يمكنك عرض التعليمات البرمجية المصدر لجميع التظليلات التي تأتي مع الوحدة. نحن مهتمون بملف
Sprites-Diffuse.shader ، والذي يستخدم افتراضيًا لجميع العفاريت التي تم إنشاؤها.
صورة
الجانب الثاني الذي يحتاج إلى إضفاء الطابع الرسمي عليه هو البيانات التي لدينا. تخيل أن لدينا كل من الصورة التي نريد تحريكها وخريطة عمقها. سيكون الأخير صورة بالأسود والأبيض ، حيث تشير وحدات البكسل بالأبيض والأسود إلى مدى قربها أو قربها من الكاميرا.
الصور المستخدمة في هذا البرنامج التعليمي مأخوذة من
مشروع Pickle cat من
Dennis Hotson ، وهذا بلا شك أفضل ما ستراه اليوم.
تعكس خريطة الارتفاع المرتبطة بهذه الصورة مسافة كمامة القط من الكاميرا.
من السهل أن نرى كيف يمكن تحقيق نتائج جيدة من خلال خريطة العمق البسيطة هذه. هذا يعني أنه من السهل إنشاء خرائط عمق خاصة بالصور الموجودة.
الخصائص
الآن بعد أن أصبح لدينا جميع الموارد ، يمكننا أن نبدأ في كتابة رمز تظليل المنظر. إذا قمنا باستيراد الصورة الرئيسية على شكل شبح ، فستقوم الوحدة تلقائيًا
_MainTex
إلى التظليل عبر خاصية
_MainTex
. ومع ذلك ، نحتاج إلى إتاحة خريطة العمق للتظليل. يمكن تطبيق ذلك باستخدام
خاصية تظليل جديدة تسمى
_HeightTex
. قررت عمداً ألا أسميها
_DepthTex
، حتى لا تخلط بينها وبين
نسيج العمق (هذا هو مفهوم الوحدة مماثل يستخدم لتقديم خريطة عمق المشهد).
لتغيير قوة التأثير ، سنضيف أيضًا خاصية
_Scale
.
Properties { ... _HeightTex ("Heightmap (R)", 2D) = "gray" {} _Scale ("Scale", Vector) = (0,0,0,0) }
يجب أن تتوافق هاتان
CGPROGRAM
ENDCG
أيضًا مع متغيرين لهما نفس الاسم الذي يجب إضافتهما إلى قسم
CGPROGRAM
/
ENDCG
:
sampler2D _HeightTex; fixed2 _Scale;
الآن أصبح كل شيء جاهزًا ، ويمكننا البدء في كتابة التعليمات البرمجية التي ستؤدي الإزاحة.
الخطوة الأولى هي أخذ عينات من خريطة العمق ، والتي يمكن القيام بها باستخدام وظيفة
tex2D
. نظرًا لأن
_HeightTex
هو نسيج أبيض وأسود ، يمكننا فقط أخذ قناتها الحمراء وتجاهل الباقي. تقيس القيمة الناتجة المسافة في بعض الوحدات التعسفية من البيكسل الحالي إلى الكاميرا.
قيمة العمق بين
إلى
لكننا ستمتد إلى الفاصل الزمني من
إلى
. يسمح لك هذا بتقديم كلا من المنظر الإيجابي (اللون الأبيض) والسالب (اللون الأسود).
نظرية
لمحاكاة تأثير المنظر في هذه المرحلة ، نحتاج إلى استخدام معلومات العمق لتغيير بكسلات الصورة. كلما اقتربت البكسل ، زادت الحاجة إلى إزاحته. يتم شرح هذه العملية في الرسم البياني أدناه. يجب أن ينقل البيكسل الأحمر من
الصورة الأصلية ، وفقًا للمعلومات الواردة من خريطة العمق ، بكسلين إلى اليسار. وبالمثل ، يجب أن يحول البيكسل الأزرق نقطتين إلى اليمين.
على الرغم من أن هذا من
الناحية النظرية يجب أن ينجح ، إلا أنه لا توجد طرق سهلة لتنفيذ ذلك في التظليل. الشيء هو أن تظليل من حيث المبدأ لا يمكن إلا أن تغيير لون بكسل
الحالي . عند تنفيذ رمز التظليل ، يجب أن يرسم بكسل محدد على الشاشة ؛ لا يمكننا فقط نقل هذا البكسل إلى مكان آخر أو تغيير لون الواحد المجاور. يوفر
تقييد الموقع هذا عملية موازية فعالة جدًا للتظليل ، ولكنه لا يسمح لنا بتنفيذ جميع أنواع التأثيرات التي ستكون تافهة شريطة أن يكون هناك
وصول عشوائي للتسجيل لكل بكسل في الصورة.
إذا كنا نريد أن نكون دقيقين ، فإننا نحتاج إلى أخذ عينات من خريطة العمق لكل البيكسلات المجاورة لمعرفة أي واحد ينبغي (إذا كان ينبغي) الانتقال إلى الموضع الحالي. إذا كان يجب أن تكون عدة وحدات بكسل في نفس المكان ، فيمكننا متوسط تأثيرها. على الرغم من أن هذا النظام يعمل ويوفر أفضل نتيجة ممكنة ، إلا أنه غير فعال للغاية وربما يكون أبطأ بمئات المرات من التظليل المنتشر الأصلي الذي بدأناه.
سيكون البديل الأفضل هو الحل التالي: نحصل على عمق البكسل الحالي من خريطة العمق ؛ ثم ، إذا كنا بحاجة إلى تحويله
إلى اليمين ، فاستبدل اللون الحالي بالبكسل
على اليسار (انظر الصورة أدناه). نفترض هنا أنه إذا كنت تريد نقل البيكسل إلى اليمين ، فمن المفترض أيضًا أن البيكسلات المجاورة على اليسار يجب أن تتحرك بنفس الطريقة.
من السهل أن نرى أن هذا مجرد تقريب منخفض التكلفة لما أردنا تحقيقه حقًا. ومع ذلك ، فهي فعالة للغاية لأن خرائط العمق عادة ما تكون سلسة.
قانون
باتباع الخوارزمية الموضحة في القسم السابق ، يمكننا تنفيذ تظليل المنظر مع
إزاحة بسيطة
لإحداثيات الأشعة فوق البنفسجية .
هذا يؤدي إلى الكود التالي:
void surf (Input IN, inout SurfaceOutput o) {
تعمل هذه التقنية بشكل جيد مع الكائنات المسطحة تقريبًا ، كما هو موضح في الرسوم المتحركة أدناه.
ولكنه يعمل بشكل جيد للغاية مع النماذج ثلاثية الأبعاد ، لأنه من السهل جدًا تقديم نسيج العمق لمشهد ثلاثي الأبعاد. يوجد أدناه صورة ثلاثية الأبعاد وخريطة عميقة.
النتائج النهائية مبينة هنا: