חישת קרניים 101

מבוא

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

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

תצוגת פיקסלים של מסך מקרוב. לכל פיקסל יש רכיבים בצבע אדום, ירוק וכחול
איור 1 – פיקסלים של מסך מקרוב. לכל פיקסל יש רכיבים בצבעי אדום, ירוק וכחול.

החלקת שינשון

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

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

איור 2 – עם קצוות קשיחים לעומת קצוות קשיחים
איור 2 – עם קצוות קשיחים לעומת קצוות קשיחים

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

רינדור טקסט

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

עם זאת, מתברר שגישה של גווני אפור לקיבוע היא רק דרך אחת לטפל בה. לעיתים קרובות אנחנו נוקטים גישה קצת יותר סלקטיבית לגבי האופן שבו אנחנו מפעילים את רכיבי ה-RGB של הפיקסלים. התהליך נקרא 'הוזלת תת-פיקסלים' (Subpixel antialiasing), ובמשך השנים התמקד צוות ClearType ב-Microsoft הרבה זמן ומאמצים כדי להתקדם בתהליך. כיום נעשה בו שימוש נרחב יותר, וכל הדפדפנים המובילים משתמשים בו במידה רבה או נמוכה יותר.

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

איור 3 - חיטוי באמצעות גווני אפור לעומת תת-פיקסלים
איור 3 – הריפוי באמצעות גווני אפור לעומת תת-פיקסלים

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

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

איור 4 – טקסט משופע של תת-פיקסלים. רכיבים בודדים של הפיקסלים מופעלים כדי ליצור את האפקט הכולל
איור 4 – טקסט עובר ושב של תת-פיקסל. הרכיבים הנפרדים של הפיקסלים מופעלים כדי ליצור את האפקט הכולל

קדימה למרדף

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

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

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

  1. השכבה כוללת צבע רקע אטום לחלוטין. חשוב במיוחד להשתמש בערך border-radius או בערך background-clip שאינו ברירת המחדל, גורמים לכך שהשכבה תטופל כלא-אטומה ורינדור הטקסט יחזור לצבע של גווני אפור.
  2. אפשר להחיל על השכבה רק תרגום טרנספורמציה או תרגום אינטגרלי. באינטגרל אנחנו מתכוונים לערכים מעוגלים. כך לדוגמה translate(20.2px, 30px) יגרום לקיבוע בגווני אפור כי רכיב ה-x, 20.2px, הוא לא בלתי נפרד. המשמעות של טרנספורמציה של זהות היא שלא נדרשים שינויים נוספים, תרגום או קנה מידה נוספים מעבר לברירת המחדל שלהם.
  3. רמת האטימות של השכבה היא 1.0. כל שינוי באטימות ישנה את החלקיק מצבע משנה לגווני אפור.
איור 5 - לפני ואחרי: גווני אפור לעומת תת-פיקסל. בודקים את
    שולי הצבע של הטקסט שמשמאל
איור 5 – לפני ואחרי: גווני אפור לעומת תת-פיקסל. בודקים את שולי הצבע של הטקסט שמשמאל

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

וזה הכול על Chrome. בכל מקום שבו משתמשים בדפדפנים אחרים, Opera, כשהיא עוברת ל-Chromium, צריכה להיות זהה להתנהגות של Chrome. נראה ש-Internet Explorer משתמש בפעולת חילוק בתת-פיקסלים כמעט עבור כל הטקסט (אם הפעלת את ClearType, כמובן!), למרות שנראה שהיא לא פועלת במצב Metro של Windows 8. דפדפן Safari, עקב הקרבה של WebKit ל-Blink, מתנהג באופן דומה מאוד ל-Chrome, אם כי ללא השיפורים החדשים האלה שמאפשרים חיטוי של תת-פיקסלים רבים יותר. ברוב המקרים, Firefox מתנהג באותו אופן כמו Internet Explorer, כל עוד הוא משתמש בפעולת אנטיג-פיקסלים משניים עבור כל הטקסט. כמובן שזו רשימה חלקית בלבד, וסביר להניח שיהיו מקרים בכל הדפדפנים שבהם נעשה שימוש בהסרה של גווני אפור במקום בתת-פיקסל. עם זאת, כדאי לדעת שבהרבה דפדפנים נעשה שימוש נרחב בניקוי רעלים בתת-פיקסלים.

סיכום

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

משאבים וחומרי עזר