יום שישי, 15 באפריל 2011

Pixel Bender Starting Guide



למי שלא מכיר Pixel Bender זה Framework שעוצב ע"י Adobe במטרה לכתוב Filters ו Effects עבור המוצרים שלה, הסביבה הזאת תומכת בהרבה מוצרים של Adobe כמו: Photoshop, After Effects ,Flex. זאת שפה עצמאית המתלבשת על שפת C, ומאפשרת לנו להריץ את הקוד שלנו ע"ג ה Gpu ולקבל ביצועים טובים יותר, קיימים עשרות דוגמאות כיצד לממש בעזרתו אפקטים ופילטרים רבים על תמונות ואפילו סרטים בעזרת After Effect, השפה יחסית נוחה לכתיבה והביצועים שלה באמת מרשימים.

שלב ראשון: נעים להכיר Pixel Bender

ניתן להוריד את ה Toolkit של Pixel Bender , באופן חופשי והוא מאוד מזכיר את ה Extended Script של Indesign , אותו ממשק משעמם וממש לא מובן אבל כנראה זה מה יש..., השפה עצמה לא כל כך מסובכת מה שבאמת מסובך הוא להבין כיצד לעבד את התמונה והחישובים שצריכים לעשות על הפיקסל בשביל לקבל את התוצאה שאנחנו מחפשים.

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

קצת על הקוד:

כל קוד נפתח עם הכותרת הבאה:

< languageversion 1.0; >
  kernel NewFilter
   <
      namespace : "Your Namespace";
       vendor : "Your Vendor";
       version : 1;
       description : "your description";
    >

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

{


   input image4 src;
   output pixel4 dst;

   void evaluatePixel()
  {
       dst = sampleNearest(src,outCoord());
   }
}

כל פילטר חייב לעבוד עם 2 פרמטרים גלובלים מסוג Input ו Output , ה Input מייצג את התמונה המקורית , Image4 חייב להיות מוגדר על מנת שהפונקציה Evaluate pixel תעבוד,4 Pixel מייצג אובייקט של פיקסל החוזר לתמונה, המורכב מ 4 הערוצים של RGBA- Red,Green,Blue,Alpha.
אז כמו שאמרתי בהתחלה הפונקציה evaluatePixel היא פונקצית ה Main שלנו, היא חייבת להחזיר פיקסל בודד בחזרה, במקרה שלנו קיימת הפונקציה sampleNearest דוגמת לנו את הפיקסל שהגיע מהתמונה המקורית , הפונקציה הפנימית outCoord מחזירה את הקורדינטות של הפיקסל המקורי ומשווים אותו ל dst שהוא הפיקסל החוזר ובעצם לא השתנה כלום בתמונה.
שימוש בפרמטרים חיצוניים:

Pixel Bender מאפשר לנו להעביר אליו פרמטרים מבחוץ לדוגמה מ Photoshop,Flash ו After Effects.
 parameter int size
<
   minValue:1;
   maxValue:50;
   defaultValue:1;
>

פונקציות:
  • Mathematical functions - פונקציות מתמטיקאיות על פיקסלים ובין פיקסלים.
  • Geometric functions - פונקציות גיאומטריות לחישוב מרחקים ורדיוסים בין פיקסלים.
  • Region functions - פונקציות על איזורים בתמונה.
  • Sampling functions - פונקציות דגימה של פיקסלים.
  • Intrinsic functions - פונקציות כלליות.
משתנים:
  • Scalar - משתני בסיס כמו Bool,Int,Float,Pixel
  • Vector - משתנים ויקטורים שמכילים בתוכם בין 2 ל 4 משתני Scalar לדוגמה Pixel 2 מכיל בתוכו 2 משתנים מסוג Pixel.
  • Matrix - משתנים למטריצות מכילים משתנים מסוג Vector \ Scalar לדוגמה Float4x4 מכיל בתוכו מטריצה מסוג של Float בגודל 4 שורות ועמודות.
ניתן לממש ביטויים רבים כמו If,For,While,Do אבל חייבים לשים לב אם זה נתמך באפליקציה שהולכת להריץ את הסקריפט לדוגמה לולאות לא נתמכות ב Flash לכן חשוב מאוד לדעת את התמיכה באפליקציות כי זה חלק חשוב בתכנון הפילטר.

דוגמה 1:
משחק בסיסי


חישובי צבעים , ושליטה על ערוץ צבע ספציפי.
דוגמה 2:
משחקי בהירות


שינוי בהירות התמונה ע"י פרמטר חיצוני.

דוגמה 3:
שליטה על ערוצי צבע


שליטה על ערוצי הצבע בעזרת פרמטרים חיצוניים.

דוגמה 4
משחק בין ערוצי הצבע


שינוי ערוצי הצבע במימוש פרמטר חיצוני בעזרת ביטוי IF, אפשרות השוואה ליותר מ 2 פרמטרים.

דוגמה 5:
טשטוש תמונה


נאספו 4 פיקסלים שמסביב הפיקסל המקורי , נבחרו ע"פ המרחק שעבר לנו בפרמטר החיצוני ואח"כ חולקו ב 5 על מנת לקבל פיקסל ממוצע של כל הפיקסלים כולל המקורי.

Graph Language

Pixel Bender מאפשר לנו אפשרות יחודית , אנחנו יכולים לשרשר פילטרים ביחד, כלומר פיקסל אחד יכול לרוץ על כמה Kernel שכל אחד מהם מייצג פילטר, ריבוי של הפונקציה evalutePixel מאפשר לנו שילוב של כמה פילטרים על פיקסל בודד.


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


  <graph name="IdentityGraph" xmlns:pbg="http://ns.adobe.com/PixelBenderGraph/1.0">
  <metadata name="namespace" value="Your Namespace">
  <metadata name="vendor" value="Your Vendor">
  <metadata name="version" type="int" value="1">

  <!-- Image inputs and outputs of the graph -->
  <inputimage name="global_src" type="image4">
  <outputimage name="global_dst" type="image4">
 
   <kernel>
                          Kernel Code Here!
   </kernel>
   <!-- Instances of the nodes -->
  <node id = "identity1" name ="Identity1" namespace = "Your Namespace" vendor = "Your Vendor" version ="1" >
</node>
   <kernel>
                          Kernel Code Here!
   </kernel>
   <!-- Instances of the nodes -->
   <node id = "identity2" name ="Identity2" namespace = "Your Namespace" vendor = "Your Vendor" version ="1" >
   </node>
 <kernel>
                         Kernel Code Here!
   </kernel>
    <!-- Instances of the nodes -->
    <node id = "identity3" name ="Identity3" namespace = "Your Namespace" vendor = "Your Vendor" version ="1" >
    </node>
   

לאחר שהגדרנו 3 בלוקים של Kernel והגדרנו להם Node על מנת שה Graph יכיר בהם נשאר להגדיר את הסדר שלהם, איזה פילטר יהיה ראשון ומה יבוא אחריו.
<!-- Connections -->
<connect fromImage="global_src" toNode="identity1" toInput="src"/>
<connect fromNode="identity1" fromOutput="dst" toNode="identity2" toInput="src"/>
<connect fromNode="identity2" fromOutput="dst" toNode="identity3" toInput="src" toImage="global_dst"/>
</graph>

גם בעבודה עם Graph Language צריך לשים לב לתמיכה, היא לא נתמכת ע"י Flash.

להורדה חינם מאתר Adobe , ניתן למצוא עשרות דוגמאות חינמיות באתר ה Exchange של Adobe.
בהצלחה...

אין תגובות:

הוסף רשומת תגובה