الوحدة صورة الخلفية طمس



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

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

تخيل الآن أننا نريد أن نفعل الشيء نفسه أو ما شابه في تطبيقنا المفضل. كما أننا لسنا بدون ميزانية ولدينا خبرة قليلة مع الوحدة.

الجزء الأول - شادر


الفكرة الأولى التي نشأت هي أن كل شيء يجب أن يتحقق بالفعل. بالتأكيد باستخدام تظليل. وبالتأكيد يجب أن يكون في مربع الوحدة. أظهرت محاولة بحث وتثبيت سريعة وجود مثل هذا التظليل في Unity ، ولكن كما اتضح ، فهو جزء من Standard Assets ، وهو غير متوفر للحصول على ترخيص مجاني.

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

بالنسبة للتنفيذ الأول ، تم أخذ هذا التظليل . لاختباره ، ما عليك سوى إضافة تظليل كملف مصدر إلى المشروع ، وربطه بالمادة ، وربط المادة بالصورة.

الجزء الثاني - واجهة المستخدم


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

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

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

الجزء الثالث - الإنتاجية


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

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

أظهر التحليل أن التظليل المختار أعلاه له تعقيد مقارب O (r 2 ) اعتمادًا على نصف القطر المحدد. بمعنى آخر ، يصبح عدد الحسابات لكل نقطة أكبر بمقدار 625 مرة إذا قمت بزيادة نصف قطر التمويه من 1 إلى 25. في هذه الحالة ، تحدث الحسابات على كل إطار.

كانت الخطوة الأولى في الحل هي فكرة أنه ليست كل التظليل مفيدة بنفس القدر ، ويمكن تنفيذ تأثير التمويه بطرق مختلفة. للقيام بذلك ، يمكنك الحصول على تمويه منفصل ، جوهره هو التمويه أولاً الخطوط فقط أفقيًا ، ثم الخطوط فقط عموديًا. ونتيجة لذلك ، نحصل على O (r) ، وبقية السوائل ، ينخفض ​​التعقيد بأمر من الحجم. هناك طريقة إضافية تتمثل في أخذ خريطة أصغر ، والتي تستوعب بالفعل بعضًا من العمل الضبابي.

تم أخذ هذا التظليل كأساس. ومع ذلك ، تبين أن تأثيره الضبابي غير كافٍ ، ومع التباين العالي للرسم أصبحت الصورة "مقطعة". للحصول على تأثيرات أفضل ، تم تغيير التوزيع (عناصر GRABPIXEL). إذا كان في التظليل ، من 0.18 إلى 0.05 ، نصف القطر 4 ، في نسختنا ، من 0.14 إلى 0.03 ، نصف القطر 6 (ess ، ولكن يجب أن يكون مجموع الكل 1).

وبالتالي ، تم تقليل تعقيد المعالجة بمقدار 1-2 مرات من الحجم. لكن هذا ليس من الضروري التوقف.

الجزء الرابع - خلفية ثابتة


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

بعد ذلك ، دعنا نجرب مع مقتطفات الشفرة. قد يبدو تحضير نسيج الوجهة للشاشة بأكملها كما يلي:

_width = Screen.width / 2;
_height = Screen.height / 2;
_texture = new Texture2D(_width, _height);

var fillColor = Color.white;
var fillColorArray = _texture.GetPixels();
for (var i = 0; i < fillColorArray.Length; ++i)
{
	fillColorArray[i] = fillColor;
}
_texture.SetPixels(fillColorArray);
_texture.Apply();

_from.GetComponent<Image>().sprite = Sprite.Create(_texture, new Rect(0, 0, _texture.width, _texture.height), new Vector2(0.5f, 0.5f));

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

RenderTexture temp = RenderTexture.GetTemporary(_width, _height);
Graphics.Blit(_from_image.mainTexture, temp, _material);
RenderTexture.active = temp;

_texture.ReadPixels(new Rect(0, 0, temp.width, temp.height), 0, 0, false);
_texture.Apply();

_to_image.sprite = Sprite.Create(_texture, new Rect(0, 0, _texture.width, _texture.height), new Vector2(0.5f, 0.5f));
RenderTexture.ReleaseTemporary(temp);

لالتقاط صورة باستخدام mainTexture باستخدام رسومات تظليل (على _material) Graphics.Blit يتم استخدامه. بعد ذلك ، نحفظ النتيجة في الملمس الجاهز ونضعها في الصورة المستهدفة.

سيكون كل شيء على ما يرام ؛ في الممارسة العملية ، واجه تأثيرًا كبيرًا ، اعتمادًا على الجهاز ، تنقلب صورة الخلفية رأسًا على عقب. يصبح السبب بعد بعض دراسة المشكلة وتصحيح الأخطاء واضحًا - الفرق في أنظمة الإحداثياتDirect3D و OpenGL ، وهو ما لا يمكن للوحدة إخفاؤه. في الوقت نفسه ، يكتشف جهاز تظليلنا الأشعة فوق البنفسجية ويعالجها بشكل صحيح ، ويحدث الانقلاب بالفعل في بيئة الوحدة (ReadPixels). هناك الكثير من النصائح على الشبكة ، مثل "إذا كنت قد قلبت رأسًا على عقب ، اقلبها على نفسك" ، أو "تغيير علامة الأشعة فوق البنفسجية". لم يساعد استخدام الماكرو UNITY_UV_STARTS_AT_TOP في الحصول على تعميم جيد لجميع الأجهزة قيد الاختبار. بالإضافة إلى ذلك ، على سبيل المثال ، واجهنا مثل هذه الحالة التي إذا قمت بإعداد التجميع لمضاهاة في Xcode على iPhone ، ولم تستخدم Unity Metal ، ولكن فقط OpenGLES ، فأنت بحاجة إلى اعتراض مثل هذه الحالات مثل مضاهاة جهاز يعمل على برامج أخرى.

بعد تجربة عدد من الخيارات ، استقرت على قرصين. الأول هو إجبار تقديم الكاميرا(تعيين forceIntoRenderTexture في وقت التقاط الصورة). والثاني هو تحديد نوع النظام الرسومي على الطاير من خلال SystemInfo.graphicsDeviceType ، مما يجعل من الممكن تعريف OpenGL-like أو Direct3D-like (المجموعة الأولى هي OpenGLES2 و OpenGLES3 و OpenGLCore و Vulkan). علاوة على ذلك ، في تنفيذنا لـ Direct3D-like ، نحتاج إلى التقليب ، والذي يتم إجراؤه (على سبيل المثال ، مثل هذا ).

استنتاج


آمل أن تكون هذه المقالة مفيدة لشخص ما في التغلب على أشعل النار غير معروف ، وتحسين حياة المستخدمين وفهم الوحدة. اذا نظرتم الى تأثير في استخدام القتال، ثم في الوحدة يبدو هذا . في التطبيق ، تكون الأحاسيس مختلفة إلى حد ما ، لكن هذه الرسوم المتحركة يمكن أن تعطي فكرة كافية.

All Articles