كيفية عمل شيدر كرتوني في محرك Unity

unity

مع تطور الرسوميات في الألعاب وظهور العاب اكثر واقعيه عن سابقتها, والتي قاربت على أن تشبه العالم الحقيقي أكثر واكثر, واعني هنا اللعبة التي صدرت لها مؤخرا استعراضات مثيرة للدهشة وهي “Unrecord”.

سنذهب اليوم في الاتجاه المعاكس, واعني هنا الرسومات الكرتونية, وأحدث مثال لها لعبة نينتندو الاخيره “زيلدا : دموع المملكة  –  Zelda tears of the kingdom”, التي قامت بتقديم مشاهد مميزة كالعادة من الناحية الكرتونية تحديدا.

 وجزء من هذا يرجع لما يسمي الـ Cel Shader او Toon Shader, او بمعني آخر فهو الشيدر الكرتوني, وله أسماء أخرى تختلف باختلاف أغراضها, ولكن سنقتصر هذه المرة على هذين الاسمين, والتركيز سيكون على الفكرة الاساسية له.

فكرة العمل

قبل كل شيء، لكي تستطيع معرفة حالة كل بكسل على المجسم من حيث الإضاءة، فستحتاج قبل ذلك ان تحصل على تدرج للضوء الحقيقي.

الخطوة التالية تكون بتعيين قيمة معينة تمثل الفاصل بين منطقة الضوء والظل, ومن ثم عمل اختبار لكل بكسل علي المجسم.

 فإذا كانت قيمة هذا البكسل أكبر من قيمة الفاصل تكون المحصلة 1, وهو ما يكافيء اللون الابيض, اما اذا كانت قيمة البكسل أقل من قيمة الفاصل تكون المحصلة 0, أي ما يكافئ اللون الأسود.

 ويمكنك ملاحظة هذا هنا, فاذا اعتبرنا أن الفاصل هو الـ T  – مع الاخذ في الاعتبار أن تدرج الظل والضوء يتدرج من -1 إلى 1, فيمكنك ملاحظة كيفية عمل اختبار تحقق مناطق الضوء والظل.

من ناحية رياضية:

هذا الجزء يتطلب أن يكون عندك معرفة جيدة برياضيات المتجهات.

في العادة كيف يتم حساب الضوء؟!:

يكون هذا عن طريق عملية الضرب القياسي لمتجهين, هما متجه اشعة الضوء نفسها, و متجه ناظم السطح الخاص بالمجسم, وفي عملية الضرب القياسي إذا كان المتجهان متوازيان وفي نفس الاتجاه تكون محصلة الضرب يساوي الـ 1.

بينما اذا كان المتجهان متعامدان, تكون المحصله تساوي الـ 0 , وما بينهما سيكون تدرج بقيم من الـ 0 الى الـ 1 وتختلف هذه القيمة باختلاف الزاوية.

حيث انه كلما كانت الزاوية أكبر كلما قلت قيمة المحصلة,  حتى تصل المحصلة إلى 0 وهذا عندما تكون الزاوية بين المتجهين تساوي 90 درجة.

أما عندما تكون الزاوية بين المتجهين اكبر من 90, ففي هذه الحاله ستكون المحصله نفسها عندما كانت الزاوية أقل من 90, ولكن في هذه الحالة ستكون بقيم سالبة, حتى تصل لقيمة -1 في حالة كانت الزاوية بين المتجهين تساوي 180 درجة, وبهذه الطريقة يصبح لديك تدرج بقيم من الـ -1 الى الـ 1.

ويمكنك ملاحظة ذلك في المثال التالي, حيث عندما كان متجه ناظم السطح N موازي لمتجه اتجاه الضوء L فان ناتج الضرب القياسي يساوي الـ 1, وهو ما يتم تمثيله باللون الابيض.

أما في حالة وجود زاوية 50 درجة على سبيل المثال بين المتجهين, فان ناتج الضرب القياسي يساوي قيمة اصغر من الـ 1, وهو ما يظهر بلون رمادي, ويختلف باختلاف الزاوية.

وفي حالة تعامد المتجهين يكون الناتج يساوي الـ 0, وهو ما يظهر باللون الاسود في منتصف الشكل.

بعد ذلك عندما تبدأ الزاوية بالزيادة عن 90 يصبح ناتج الضرب القياسي للمتجهين يساوي قيمة سالبة, حتى تصل لاصغر قيمة ممكنة وهي -1 عندما تكون الزاوية تساوي 180, أي أن المتجهين متوازيين, ولكن في اتجاه مضاد.

ولكن في حالة القيم السالبة يكون اللون الظاهر هو الاسود ايضا, وسبب هذا أنه لا توجد قيمة لونية تعبر عن السالب, فيتم التعبير عنها ايضا بلون اسود.

تجهيز المشروع

ستبدأ اولا بتجهيز المشروع بتغيير نظام الرسومات فيه بعد انشاء المشروع في محرك يونِتي, لتصبح قادرا على استعمال محرر الشيدر.

من خلال قائمة Window >> Package Manager >> Universal RP ثم تقوم بتثبيته في مشروعك.

ستقوم بعدها بعمل URP Asset, وهو عبارة عن ملف للتحكم باعدادات نظام الرسومات الجديد, ويمكنك إيجاده من خلال Rendering>> URP Asset with Universal Renderer  والذي يمكنك ايجادها من خلال نافذة المشروع  , ثم تأكد من تفعيل الـ Depth Texture والـ Opaque Texture والـ HDR فيه.

بعد هذا ستقوم بتطبيق المعالجة النهائية – Post Process, عن طريق الذهاب الى نافذة الـ Hierarchy, واضافة Global Volume من خلال قائمة Volume, ومن نافذة المشروع ستقوم بعمل Volume Profile.

بعد هذا ستقوم بإضافة تاثير الوهج – Bloom, والـ Vignette, الى الـ Volume Profile.
ويمكنك اضافة اي تاثير اخر تريده.
ثم ستقوم بتفعيل الـ Post Process في الكاميرا.

تحضير ملف الشيدر

بداية ستحتاج لأن تقوم بعمل ملف الشيدر واختيار نوعه, وفي هذه الحالة ستحتاج ان تقوم بتحديد النوع الي Unlit, لكي لا يتاثر باي اضائة خارجية.

لماذا؟ لأنه في هذه الحالة أنت من سيقوم بإعداد حسابات الضوء والظل كما تم شرحه مسبقا في فكرة العمل, ولكي تنشيء الملف, يكون هذا من خلال واجهة Create، ثم المسار التالي :
Shader Graph >> URP >> Unlit Shader Graph.

حساب الضوء الواقعي

بعد ذلك عندما تفتح محرر الشيدر, ستحتاج لأن تقوم بعمل متغير من نوع Vector 3 ليعبر عن متجه الضوء, مع جعل القيم الافتراضية تساوي  (1,1,0).

من ثم ستحتاج لمتجه ناظم السطح الخاص بالمجسم, عن طريق اضافة عقدة الـ Normal Vector, وبعد ذلك تقوم بتوصيلة بعقدة Normalize.

ووظيفة عقدة Normalize هي تحويل اي قيمة داخله اليها الى الـ 1, وفي هذه الحالة ستجعل قيمة متجه ناظم السطح  تساوي الوحدة.

لماذا ؟ لأنه في هذه الحالة ما ستحتاج إليه هو اتجاه ناظم السطح فقط وليس قيمته, لان هذه القيمة ستؤثر في ناتج الضرب القياسي للمتجهين.

 وفي حالة لم تكن تعرف, فان متجه ناظم السطح هو متجه طوله يساوي مساحة السطح المنطلق منه, و اتجاهه عمودي على هذا السطح,  لذا فالاستفاده من عقدة الـ Normalize في هذه الحالة, هو الحصول على الاتجاه فقط.

الان ستقوم بعملية ضرب قياسي بين متجه ناظم السطح, ومتجه اتجاه الضوء الذي كنت قد أعددته مسبقا بعد نحويلة لمتجه وحدة.

 وعند توصيل الناتج في مخرج الـ Base Color, وحفظ الشيدر, ومن ثم تطبيقه على مجسم كرة على سبيل المثال, ستلاحظ ظهور تدرج من الاسود للابيض.

الحصول على اتجاه الضوء الحقيقي

توجد الان مشكله, وهي ان التظليل لا يتغير عندما تغير اتجاه مصدر الضوء, وسبب هذا أن المتغير الذي يعبر عن متجه الضوء ليس له علاقة بمصدر الضوء الخارجي, ويمكن تغييره فقط يدويا.

والحل في هذه الحالة هو عمل دالة مخصصة, تقوم بالحصول علي متجه الضوء طول الوقت, ولكن هذا سيتطلب اولا ملفا برمجيا مخصصا, وهو ما تمت كتابته مسبقا من مبرمجي شركة يونتي أنفسهم, ويمكنك إيجاده هنا.

بعد تحميله ستقوم بإضافة عقدة Custom Function وضبط اعداداتها كما هو موضح. بعد ذلك عندما تجرب تغيير اتجاه الضوء الخارجي سيتغير تظليل الكرة تبعا لذلك.

التحويل إلى المظهر الكرتوني

بعد أن حصلت على التدريج الذي يحاكي الإضاءة الواقعية, ستحتاج بعمل اختبار التحقق الذي تم ذكره في الأعلى, ويمكن هذا عن طريقة عقدة المقارنة – Comparison, ولكن هذا سيتسبب بفواصل حاده جدا, والتي لا تبدو جيدة في معظم الحالات.

عوضا عن هذا ستقوم بعمل الفاصل عن طريقة عقدة Smooth Step, والتي من خلالها تستطيع التحكم بحالة الفاصل, من حيث كونه حادا او ناعما, عن طريق تغيير قيم هذه العقدة, وفي حالتي ساختار القيمتين 0 و 0.01 علي الترتيب.

من خلال هذا ستلاحظ ظهور هذا الفاصل الحاد الذي يحاكي الاضائه الكرتونية التي نحاول الوصول لها.

اضافة الالوان

تبقي الان اضافة عنصر الألوان والنسيج, ويكون هذا عن طريق عمل متغير من نوع النسيج – Texture 2D, متغيرين من نوع اللون, أحدهما للمنطقة المضيئة – Light Color, وجعل قيمته الافتراضية باللون الأبيض, والآخر للمنطقه المظللة – Shadow Color.

بعد ذلك ستقوم بتوصيل متغير النسيج بعقدة Sample Texture 2D, ومن ثم ضربها مره بمتغير اللون الخاص بالمنطقة المضيئة, ومرة اخرى بمتغير اللون الخاص بالمنطقة المظللة.

وهكذا يصبح لديك النسيج بحالتي الضوء والظل, لكن كيف ستقوم بتحديد مكان ظهور كل منهما على المجسم؟

سيكون هذا عن طريق توصيل ناتج عقدة الفصل السلس – Smooth Step بعقدة الاستيفاء الخطي – Lerp في خانة T, ووظيفتها هي اخراج او انتاج قيمة من احد القيمتين في خانتي A و B, وهذا يعتمد علي قيمة الـ T.

وبما ان قيمة الـ T في هذه الحالة تعبر عن اماكن الضوء والظل, فسيكون ناتج عقدة الاستيفاء الخطي عبارة عن قيم الضوء والظل الخاصة بالنسيج نفسه.

يمكنك الآن حفظ الشيدر وتطبيقة على اي مجسم, لتشاهد أن التأثير الكرتوني ظهر بالفعل, وبهذا تكون قد انتهيت من الجزء الأول الخاص بتحديد اماكن الضوء والظل.

كانت هذه الفكرة الاساسية,  التي من خلالها يمكنك تمييز هذا النوع من الشيدر عن غيره, بمظهره المميز والذي يمكن استعمالها لتطبيقات كثيرة,  واضافة المزيد من الخصائص عليه,  كاللمعان,  أو أنماط التظليل المختلفة.

  والتي تختلف تبعا لاحتياجات اللعبة,  ويمكنك ملاحظة استعماله بعدة طرق,  في مختلف الفئات, بدءا من استعماله على الشخصيات نفسها, كما في حالة عناوين مثل: Zelda,Guilty Gear, DRAGON BALL FighterZ.
انتهاءً بالمؤثرات البصرية والطبيعية, والتي سيكون لها نصيبها الخاص في مقال آخر.

0 0 votes
Article Rating
Subscribe
نبّهني عن
guest

0 تعليقات
Inline Feedbacks
View all comments