כדי לשפר את המראה והביצועים של טקסטורות במשחק שלכם ל-Android, כדאי לפעול לפי השיטות המומלצות הבאות.
טקסטורות הן רכיב מרכזי באומנות התלת-ממדית. משחקי תלת-ממד שפועלים בצורה טובה במספר הגדול ביותר של מכשירים מתחילים עם גרפיקה תלת-ממדית שנועדה לנצל בצורה הטובה ביותר את מעבדי הגרפיקה. במדריך הזה מפורטות שיטות מומלצות לאופטימיזציה של טקסטורות בנייד, כדי לשפר את הביצועים של המשחק ולצמצם את צריכת החשמל, תוך שמירה על איכות חזותית גבוהה.
חלקים מהמאמר הזה מבוססים על עבודה שנתרמה על ידי Arm Limited ומוגנת בזכויות יוצרים שלה.
יצירת אטלסים של טקסטורות
אטלס טקסטורה הוא טקסטורה שנועדה להכיל את נתוני התמונה של כמה אובייקטים גרפיים, כמו רשתות תלת-ממדיות או ספריטים דו-ממדיים. במקום שלכל אובייקט תהיה טקסטורה משלו, נעשה שימוש בטקסטורה של אטלס כדי לשלב את התמונות מכל אובייקט.

צמצום מספר הקריאות לציור של פריים במשחק הוא מרכיב חשוב בהשגת ביצועי רינדור אופטימליים. שימוש באותו מרקם לאובייקטים שונים הוא אחד מהגורמים לשילוב שלהם בקריאה אחת לציור. הפחתת קריאות הציור חשובה במיוחד למשחקים שמוגבלים על ידי המעבד, כי כל קריאת ציור גוררת תקורה של המעבד בזמן העיבוד שלה על ידי מנהל ההתקן של הגרפיקה. בנוסף, הם מצמצמים את מספר קובצי נכסי הטקסטורה בנתוני זמן הריצה של המשחק. אפשר לאחד מאות או אפילו אלפי טקסטורות למספר קטן בהרבה של קובצי טקסטורה.
כשיוצרים רשתות תלת-ממדיות, כדאי לתכנן את הפריסה של אטלס הטקסטורה. אם האטלס נוצר לפני נכס הרשת, צריך לבצע פריסה של נכס הרשת לפי אטלס הטקסטורה. אם האטלס נוצר אחרי הכתיבה, באמצעות מיזוג או כלי יצירת אטלס בתוכנת ציור, צריך לסדר מחדש את האי UV בהתאם לטקסטורה.
איגום של בקשות להזזת פריט גרפי (draw call) שספציפיות למנוע
למנוע המשחקים Unity יש תכונה של batching של קריאות ציור שיכולה לשלב אובייקטים באופן אוטומטי. כדי שאובייקטים יעמדו בדרישות לאיחוד אוטומטי של אובייקטים, הם צריכים להיות עשויים מאותו חומר, כולל טקסטורות, וצריך לסמן אותם כסטטיים.
ב-Unreal Engine 4 נדרשת הגדרה ידנית כדי להשתמש באפשרות batching. אפשר למזג אובייקטים בתוכנת תלת-ממד לפני שמייבאים אותם ל-Unreal. ב-Unreal יש גם את הכלי UE4 Actor Merging שמאפשר לשלב רשתות וליצור קובצי טקסטורה.
יצירת מפות MIP
Mipmaps הם גרסאות של טקסטורה ברזולוציה נמוכה יותר. אוסף של מפות MIP לטקסטורה נתונה נקרא שרשרת מפות MIP. כל רמה עוקבת של mipmap בשרשרת היא ברזולוציה נמוכה יותר מהרמה הקודמת. משתמשים ב-Mipmaps כדי להטמיע את רמת הפירוט של הטקסטורה במהלך הרינדור. כשמרקם עם מיפוי MIP נקשר לשלב של מרקם, חומרת הגרפיקה משתמשת במרחב המרקם שתופס פרגמנט כדי לבחור רמה משרשרת מיפוי ה-MIP. כשמעבדים סצנה בתלת-ממד, אובייקט שנמצא רחוק יותר מהמצלמה ישתמש במפת MIP ברזולוציה נמוכה יותר מאשר אותו אובייקט שנמצא קרוב יותר למצלמה.
טקסטורה עם מיפמפה תופסת יותר זיכרון בהשוואה לטקסטורה בלי מיפמפה. רמות ה-mipmap הנוספות מגדילות את תצרוכת הזיכרון של טקסטורה ב-33%. אם מציירים טקסטורה במרחק קבוע מהמצלמה, יצירת מפות MIP היא שימוש מיותר בזיכרון.

שימוש נכון במפות MIP משפר את הביצועים של ה-GPU. זמינות של רמות מיפמפ ברזולוציה נמוכה יותר מפחיתה את השימוש ברוחב פס של הזיכרון ומשפרת את השהייה במטמון של הטקסטורה.
מיפוי Mip יכול גם לשפר את האיכות החזותית על ידי הפחתת aliasing של טקסטורה. אפשר לראות את האפקט של Aliasing במרקם כהבהוב באזורים רחוקים יותר מהמצלמה.

פרטים ספציפיים של מיפמפה למנוע
כדי להשתמש ב-mipmapping ב-Unreal Engine 4, נדרשות מידות של טקסטורה שהן חזקות של שתיים (למשל, 512x1024, 128x128). שרשראות של מיפמפים לא ייווצרו אם אחד או שני ממדי הטקסטורה לא הם חזקה של 2.
מנוע Unity יגדיל באופן אוטומטי את הטקסטורות עם מידות שלא מתאימות לחזקה של 2 כדי ליצור מפות MIP. כדי להימנע מהשינוי הזה בגודל, צריך לוודא שקובצי הטקסטורה של המקור הם חזקה של שתיים.
בחירת מצבי סינון מתאימים של טקסטורות
סינון טקסטורה הוא תכונת עיבוד חומרה שמשפיעה על המראה החזותי של משולש מעובד. שימוש נכון בסינון טקסטורה יכול לשפר את האיכות החזותית של סצנה. יש כמה מצבי סינון של טקסטורות, ולכל אחד מהם יש איזון שונה בין שיפור העיבוד לבין העלות. העלות כוללת את זמן החישוב ואת רוחב הפס של הזיכרון. שלושה מצבי סינון טקסטורה נפוצים: nearest (הקרוב ביותר, או נקודתי), bilinear (דו-ליניארי) ו-trilinear (תלת-ליניארי). סינון אניסוטרופי הוא שיטת סינון טקסטורה נוספת שאפשר לשלב עם סינון בילינארי או טרילינארי.
הכי קרוב
הסינון הקרוב ביותר הוא מצב הסינון הפשוט והזול ביותר של טקסטורות. הפונקציה Nearest דוגמת טקסל יחיד באמצעות הקואורדינטות שצוינו בטקסטורת המקור. למשולשים שמעובדים עם הגדרת המרחק הקרוב ביותר יהיה מראה מגושם או מפוקסל, במיוחד כשהם מעובדים קרוב למצלמה.
בילינארי
סינון דו-ליניארי דוגם את ארבעת הטקסלים שמקיפים את הקואורדינטות שצוינו במרקם המקור. המערכת מחשבת את הממוצע של ארבעת הטקסלים האלה כדי לקבוע את צבע הטקסטורה של הפרגמנט. סינון דו-ליניארי יוצר מעבר חלק יותר בין פיקסלים, וכך נמנעת התופעה של מראה מגושם שמאפיינת סינון של הפיקסל הקרוב ביותר. משולשים שמוצגים קרוב למצלמה ייראו מטושטשים ולא מפוקסלים. העלות של bilinear גבוהה יותר מהעלות של nearest בגלל הדגימות הנוספות של טקסלים והחישוב הממוצע.

טרילינארי
כשמעבדים רשת שבה המרחק של הקודקודים מהמצלמה משתנה, יכול להיות שייבחרו כמה רמות של Mipmap במהלך העיבוד. השינויים בין שתי רמות של מיפמפה יכולים להוביל לשינוי חד ובולט בנקודת המעבר. סינון טרילינארי מרכך את המעברים האלה על ידי ביצוע סינון בילינארי בשתי רמות שונות של מיפמאפ ואינטרפולציה של התוצאות. השימוש בכמה רמות MIP ואינטרפולציה הופך את הסינון הטרילינארי ליקר יותר מבחינת חישובים בהשוואה לסינון הבילינארי.

אניזוטרופי
סינון אניסוטרופי משפר את האיכות החזותית של רשתות מרקם שמעובדות בזווית קיצונית ביחס למצלמה. מישור קרקע הוא דוגמה נפוצה לסוג כזה של רשת. כדי שהסינון האניסוטרופי יפעל, צריך טקסטורות עם מיפוי MIP. אפשר להגדיר את היחס או הרמה של הסינון האניזוטרופי שמוחל במהלך העיבוד. העלות של סינון אניסוטרופי עולה ככל שהרמה עולה.

אסטרטגיה לבחירת מצב
סינון דו-ליניארי בדרך כלל מספק את האיזון הטוב ביותר בין ביצועים לבין איכות חזותית. סינון טרילינארי דורש רוחב פס גדול משמעותית בזיכרון, ולכן צריך להשתמש בו באופן סלקטיבי. במקרים רבים, סינון דו-ליניארי בשילוב עם סינון אניסוטרופי x2 ייראה ויפעל טוב יותר מסינון תלת-ליניארי עם סינון אניסוטרופי x1. הגדלת הרמות האניסוטרופיות מעבר ל-2x היא יקרה מאוד, ולכן צריך לעשות זאת באופן סלקטיבי מאוד עבור נכסי משחק קריטיים.
סינון טקסטורות יכול להוות עד מחצית מצריכת האנרגיה הכוללת של ה-GPU. בחירה במסנני טקסטורה פשוטים יותר, כשזה אפשרי, היא דרך מצוינת להפחית את דרישות ההספק של המשחק.
אופטימיזציה של גדלי הטקסטורה
חשוב לוודא שהממדים של הטקסטורה קטנים ככל האפשר, ועדיין מאפשרים להשיג את איכות התמונה הרצויה. בודקים את נכסי הטקסטורה כדי לוודא שאין טקסטורות גדולות מדי. העיקרון הזה חל גם על טקסטורות נפרדות וגם על טקסטורות של אטלס. אם המשחק שלכם תומך במכשירים רבים עם מגוון רחב של רזולוציות ויכולות ביצועים, כדאי ליצור גרסאות ברזולוציה נמוכה וגבוהה של נכסי הטקסטורה שלכם עבור סוג המכשיר המתאים.
כשמבצעים רינדור של רשת שמשתמשת בכמה טקסטורות בחומר שלה, כדאי לצמצם באופן סלקטיבי את הרזולוציה של חלק מהטקסטורות. לדוגמה, כשמשתמשים במרקם דיפוזי בגודל 1024x1024, יכול להיות שאפשר להקטין את המרקם של מפת החספוס או המתכת ל-512x512 עם השפעה מינימלית בלבד על איכות התמונה. חשוב לבדוק את ההשפעה של כל הניסויים האלה לשינוי גודל כדי לוודא שהם לא פוגעים ברמת האיכות הרצויה.
שימוש במרחב הצבעים המתאים
חבילות תוכנה רבות שמשמשות ליצירת טקסטורות פועלות במרחב הצבעים sRGB ומייצאות איתו. מרחב הצבעים sRGB יכול לשמש מרקמים מפוזרים שעוברים עיבוד כצבע. מרקמים שלא עוברים עיבוד כצבע, כמו מתכתיות, חספוס או מפות נורמליות, לא צריכים להיות מיוצאים במרחב הצבעים sRGB.
הגדרות המרקם של מנוע המשחק כוללות פרמטר שקובע אם המרקם משתמש במרחב הצבעים sRGB.

מכיוון שנתוני הפיקסלים של טקסטורות כאלה לא משמשים כנתוני צבע, שימוש במרחב הצבעים sRGB יפיק תמונות שגויות.

שימוש בדחיסת טקסטורה
דחיסת טקסטורה היא אלגוריתם לדחיסת תמונות שמוחל על נתוני פיקסלים לא דחוסים, והתוצאה היא טקסטורה שאפשר לבצע לה דקומפרסיה במהירות באמצעות חומרה גרפית במהלך הרינדור. שימוש יעיל בדחיסת טקסטורות יכול להקטין את השימוש בזיכרון ולשפר את הביצועים, עם השפעה מינימלית על האיכות החזותית. שלושת האלגוריתמים הנפוצים ביותר לדחיסת טקסטורות ב-Android הם: ETC1, ETC2 ו-ASTC. במשחקים מודרניים, בדרך כלל ASTC היא האפשרות העיקרית הטובה ביותר, ו-ETC2 היא אפשרות חלופית אם המשחק מיועד למכשירים שלא תומכים ב-ASTC.
ETC1
כל מכשירי Android תומכים ב-ETC1. ETC1 תומך רק במצב של ארבעה ביטים לכל פיקסל של נתוני צבע RGB. ETC1 לא תומך בערוצי אלפא. מנועי משחקים רבים שתומכים ב-ETC1 מאפשרים להגדיר טקסטורה שנייה של ETC1 שתשמש לייצוג נתוני ערוץ אלפא.
ETC2
יותר מ-90% ממכשירי Android הפעילים תומכים ב-ETC2. במכשירים ישנים מאוד שלא תומכים ב-OpenGL ES 3.0 API, אי אפשר להשתמש ב-ETC2. בהשוואה ל-ETC1, ETC2 מוסיף:
- תמיכה בערוץ אלפא, גם ב-8 ביט וגם ב'פריצה' של ביט יחיד
- גרסאות sRGB של טקסטורות RGB ו-RGBA
- ערוץ אחד ושני ערוצים, R11 ו-RG11, טקסטורות
ASTC
יותר מ-75% ממכשירי Android הפעילים תומכים ב-ASTC. ל-ASTC יש גדלים של בלוקי דחיסה שניתנים להגדרה, כך שאתם יכולים לשלוט בדחיסה בצורה מדויקת כדי לאזן בין יחס הדחיסה לבין איכות התמונה של טקסטורה נתונה. בדרך כלל, ASTC יכול להשיג איכות מעולה באותו גודל זיכרון כמו ETC2, או כמות דומה בגודל זיכרון קטן יותר מ-ETC2.

מהירות דחיסת הטקסטורה
אם במשחק יש הרבה טקסטורות, דחיסת הטקסטורות יכולה לקחת הרבה זמן. גם ל-ETC וגם ל-ASTC יש הגדרות איכות דחיסה שאפשר לבחור. הגדרות איכות גבוהה יותר דורשות יותר זמן לדחיסה. במהלך הפיתוח, יכול להיות שתרצו להקטין את רמת האיכות כדי לקצר את זמן הדחיסה, ולהגדיל את רמת האיכות לפני יצירת גרסאות חשובות.
דחיסת טקסטורות במנועי משחקים
אם אתם משתמשים במנוע משחק, יכול להיות שתצטרכו לבחור את פורמט הדחיסה של הטקסטורה (ETC או ASTC) ברמת הפרויקט. כדי לתמוך בכמה פורמטים של דחיסה ולהשיג תאימות מקסימלית, יכול להיות שיהיה צורך בעבודה נוספת. התכונה 'טירגוט לפי פורמט דחיסת טקסטורה' של Google Play Asset Delivery יכולה לעזור לכם לכלול מספר פורמטים במשחק, ולספק רק את הפורמט האופטימלי ביותר למכשיר ספציפי בזמן ההתקנה.
פתיחת פריסת UV
חשוב לשמור על צורת האי במיפוי ה-UV ישרה ככל האפשר. כך תוכלו לשפר את המרקם:
- קל יותר לארוז איים של UV, ולכן יש פחות בזבוז של מקום.
- פריסות UV ישרות מפחיתות את 'אפקט המדרגות' בטקסטורות.
- אריזת UV טובה מבטיחה קבלת רזולוציה אופטימלית מהטקסטורה.
- שיפור באיכות המרקם, גם אם יש עיוותים קלים ב-UV כתוצאה מהיישור.

תפרים גלויים של מרקם במודל נראים רע. כדאי לנסות למקם את התפרים של מיפוי ה-UV במקומות שבהם הם פחות בולטים. כדי ליצור מפות נורמליות טובות יותר, צריך לפצל את האי UV במקומות שבהם הקצוות חדים ולהשאיר קצת רווח מסביב לאי.
הימנעות מפרטים שלא ניתן להבחין בהם
כשיוצרים יצירות אומנות, לא כדאי להוסיף פרטים שלא ייראו, במיוחד במשחקים שמיועדים למכשירים עם מסכים קטנים יותר. אין טעם ליצור מרקם מפורט בגודל 4096x4096 עבור מודל קטן של כיסא שכמעט לא רואים בפינת החדר. במקרים מסוימים, יכול להיות שתצטרכו להגזים בהדגשת הקצוות (להוסיף הדגשות נוספות) ולהשתמש בהצללה כדי לשפר את תפיסת הצורה.

פרטי השילוב
למכשירים ניידים יש מסכים קטנים יותר וחומרה גרפית חלשה יותר מאשר למחשבים אישיים או לקונסולות משחקים. במקום לחשב אפקטים כמו הצללה סביבתית או הדגשה ספקולרית בזמן הריצה, כדאי 'לאפות' אותם בטקסטורה המפוזרת כשזה אפשרי. כך משפרים את הביצועים ומוודאים שהפרטים שלכם יהיו גלויים.

שימוש בגוון צבע
אם יש לכם אפשרות ליצור הצללות בהתאמה אישית, ויש לכם רשתות עם ערכת צבעים דומה או אחידה, כדאי להשתמש בגוון צבע ברשתות הרלוונטיות. כשמשתמשים בהטיית צבע, נעשה שימוש בטקסטורה בגווני אפור, שדורשת פחות זיכרון טקסטורה מטקסטורה מסוג RGB. נתוני הצבע לכל קודקוד מוחלים על ידי ה-shader כדי לצבוע את הרשת. שיטה חלופית להוספת גוון היא שימוש במסכת RGB והחלת המרקם על סמך טווח הצבעים של המסכה.

אריזת ערוצי טקסטורה
כשמעבדים חומרים עם כמה טקסטורות, כדאי לחפש הזדמנויות לשלב טקסטורות שמשתמשות רק בערוץ צבע אחד לטקסטורה אחת שמשתמשת בכל שלושת ערוצי הצבע. כך מצטמצם השימוש בזיכרון ופוחת מספר הפעולות של דגימת הטקסטורה שמבוצעות על ידי shader הפרגמנט.

כשדוחסים נתונים, מקצים לערוץ הירוק את הנתונים עם הכי הרבה פרטים. מכיוון שהעין האנושית רגישה יותר לירוק, חומרת הגרפיקה בדרך כלל מקצה יותר ביטים לערוץ הירוק. לדוגמה, מפת חספוס/חלקות בדרך כלל תהיה מפורטת יותר ממפת מתכת, ולכן עדיף להקצות אותה לערוץ הירוק.
אם אתם משתמשים בחומרים עם ערוץ אלפא, ואתם משתמשים רק בשני ערוצים בטקסטורה הדחוסה, כדאי להכניס את נתוני ערוץ האלפא לטקסטורה הדחוסה במקום לטקסטורה המפוזרת. בהתאם לפורמט של טקסטורת הדיפוזיה, אפשר להשתמש באפשרות הזו כדי להקטין את הגודל שלה או לשפר את האיכות החזותית שלה על ידי השמטת נתוני ערוץ האלפא.

חשוב לוודא שהמרקמים הדחוסים מוגדרים למרחב צבעים ליניארי RGB ולא ל-sRGB.
יצירת מפות רגילות
מיפוי נורמלי הוא טכניקה שנותנת למודל תלת-ממדי מראה מפורט בלי להשתמש בגיאומטריה נוספת. אפשר לדמות תכונות כמו קמטים או ברגים, שנדרשים הרבה משולשים כדי ליצור מודל שלהם, באמצעות מפת נורמלים. מיפוי רגיל עשוי להתאים או לא להתאים, בהתאם לסגנון האומנותי ולכיוון של המשחק.

מפות רגילות כרוכות בעלות מסוימת על הביצועים, ולכן מומלץ להשתמש בהן במשורה במכשירים ברמה נמוכה. מפת הנורמלים דורשת טקסטורה נוספת, ולכן יש לבצע דגימה נוספת של הטקסטורה וחישובים נוספים של הצללת הפיקסלים.
שיטות מומלצות לעבודה עם מפה רגילה
ריכזנו כאן כמה שיטות מומלצות ליצירת מפות נורמליות:
שימוש בכלוב
כלוב הוא גרסה גדולה יותר של מודל הפוליגונים הנמוך, או גרסה שמוזזת החוצה. כדי שהאפייה של מפת הנורמלים תפעל בצורה טובה, היא צריכה לכלול את המודל עם הפוליגונים הרבים. הכלוב משמש להגבלת מרחק ההטלה במהלך אפיית מפה רגילה, ועוזר למנוע בעיות בתפרים של נורמלים מפוצלים במפה הרגילה.


התאמה של אפייה לפי שם הרשת
אם תוכנת האפייה שלכם תומכת בכך, אפשר לאפות התאמה לפי שם הרשת. התכונה הזו מפחיתה את הבעיה של הטלת מפה נורמלית שגויה. אם אובייקטים קרובים מדי זה לזה, יכול להיות שהם יקרינו את מפת הנורמלים שלהם על הפאה הלא נכונה. התאמה לפי שם הרשת מבטיחה שה-baking יתבצע רק על המשטח הנכון. מידע נוסף על התכונה הזו ב-Substance Painter זמין בדף הזה. מידע נוסף על התכונה הזו ב-Marmoset Toolbag זמין בדף הזה.
פיצוץ הרשת
אם אתם לא מצליחים להתאים לפי שם הרשת כשאתם מבצעים אפייה, כדאי לפרק את הרשת. פיצוץ הרשת מרחיק חלקים זה מזה כדי שמפת הנורמלים לא תוקרן על המשטח הלא נכון. אם אתם גם מבצעים אפייה של הצללה סביבתית, יכול להיות שתצטרכו לבצע את האפייה הזו בנפרד עם רשת לא מפוצצת.

מזעור התפרים
המשכיות של מיפוי UV בקצוות קשים תגרום לתפרים גלויים, ולכן מומלץ לפצל את מיפוי ה-UV בקצוות קשים כדי למזער את האפקט הזה. כשמגדירים קבוצות החלקה, ככלל אצבע, צריך להקפיד שהזווית תהיה קטנה מ-90 מעלות. לחיבורי ה-UV צריכה להיות קבוצת החלקה שונה במשולשים.