AGSL תוכנן כך שיהיה תואם במידה רבה ל-GLSL ES 1.0. מידע נוסף זמין בפונקציה המקבילה במסמכי התיעוד של שפת ההצללה של OpenGL ES. כשהדבר אפשרי, אנחנו מנסים לציין במסמכים האלה את ההבדלים בין AGSL ל-GLSL.
סוגים
AGSL תומך בסוגי GLSL ES 1.0, וגם בדרך נוספת לייצוג סוגי וקטורים ומטריצות. ב-AGSL יש תמיכה בסוגי short
ו-half
נוספים שמייצגים דיוק בינוני.
סוגים בסיסיים
סוג | תיאור |
---|---|
void
|
אין ערך מוחזר בפונקציה או רשימת פרמטרים ריקה. בניגוד ל-GLSL, פונקציות ללא סוג החזרה מסוג void חייבות להחזיר ערך. |
bool, bvec2, bvec3, bvec4 (bool2, bool3, bool4) . |
וקטור/סקלר בוליאני |
int, ivec2, ivec3, ivec4 (int2, int3, int4) |
highp מספר שלם/וקטור עם סימן
|
float, vec2, vec3, vec4 (float2, float3, float4)
|
highp (single precision) floating point
scalar/vector |
short, short2, short3, short4
|
שווה ערך למערך/מספר שלם signed mediump int |
half, half2, half3, half4 |
שווה ערך לסקלר/לוקטור mediump float |
mat2, mat3, mat4 (float2x2, float3x3, float4x4) |
מטריצת float בגודל 2x2, 3x3 או 4x4
|
half2x2, half3x3, half4x4 |
שווה ערך לסוגים של מטריצות mediump float |
ערכי דיוק וטווח מינימלי
אלה רמת הדיוק והטווח המינימליים המובטחים שמשויכים לכל שינוי, על סמך מפרט OpenGL ES 2.0. מאחר שרוב המכשירים תומכים ב-ES 3.0, הם יהיו בטוחים יותר לגבי רמת הדיוק/הטווח של highp
ורמת הטווח של int mediump
. אפשר להחיל משתני דיוק על משתנים ופרמטרים של סקלר, וקטור ומטריצה. רק הערכים המינימליים שמפורטים בהמשך מובטחים. הערך lowp
לא בהכרח נמוך יותר מבחינת הדיוק מ-mediump
, ו-mediump
לא בהכרח נמוך יותר מבחינת הדיוק מ-highp
. נכון לעכשיו, AGSL ממיר את lowp
ל-mediump
בפלט הסופי.
מגביל | טווח 'float' | טווח עוצמה של 'float' | דיוק 'float' | טווח 'int' |
---|---|---|---|---|
highp | \(\left\{-2^{62},2^{62}\right\}\) | \(\left\{2^{-62},2^{62}\right\}\) | יחסי: \(2^{-16}\) | \(\left\{-2^{16},2^{16}\right\}\) |
mediump | \(\left\{-2^{14},2^{14}\right\}\) | \(\left\{2^{-14},2^{14}\right\}\) | יחסי: \(2^{-10}\) | \(\left\{-2^{10},2^{10}\right\}\) |
lowp | \(\left\{-2,2\right\}\) | \(\left\{2^{-8},2\right\}\) | מוחלט: \(2^{-8}\) | \(\left\{-2^{8},2^{8}\right\}\) |
בנוסף לתחביר של אינדקס מספרי של מערך, למשל: var[num], names of vector
components for vectors of length 2 - 4 are denoted by a single letter. Components
can be swizzled and replicated. ex:
vect.yx,
vect.yy`
vect.xyzw
– משתמשים ב-vect.xyzw
כשניגשים לווקטורים שמייצגים נקודות/נורמלים
vect.rgba
– משתמשים בקוד הזה כשניגשים לווקטורים שמייצגים צבעים
vect.LTRB
– משתמשים בו כאשר הווקטור מייצג מלבן (לא ב-GLSL)
ב-AGSL, אפשר להשתמש ב-0 וב-1 כדי ליצור ערך קבוע של 0 או 1 בערוץ הזה.
דוגמה: vect.rgb1 == vec4(vect.rgb,1)
מבנים ומערכים
ההצהרה על המבנים מתבצעת באותו תחביר כמו ב-GLSL, אבל AGSL תומך במבנים ברמת גלובלי בלבד.
struct type-name {
members
} struct-name; // optional variable declaration.
יש תמיכה רק במערכים חד-ממדיים עם גודל מערך מפורש, באמצעות תחביר בסגנון C או בסגנון GLSL:
שם המשתנה <base type>[<array size>] – לדוגמה: half[10] x;
שם משתנה מסוג <base type>[<array size>] – לדוגמה: half x[10];
אי אפשר להחזיר מערך מפונקציה, להעתיק אותו, להקצות אותו או להשוות בינו לבין מערך אחר. הגבלות על מערכים מופצות למבנים שמכילים מערכים. אפשר ליצור אינדקס למעריכים רק באמצעות קבוע או משתנה לולאה.
מוקדמות
סוג | תיאור |
---|---|
const
|
קבוע בזמן הידור או פרמטר של פונקציה לקריאה בלבד. |
uniform
|
הערך לא משתנה במהלך העיבוד של הפרימיטיב.
המדים מועברים מ-Android באמצעות שיטות של RuntimeShader עבור setColorUniform , setFloatUniform , setIntUniform , setInputBuffer ו-setInputShader . |
in
|
לפרמטרים של פונקציות שהועברו. זוהי ברירת המחדל. |
out
|
לפרמטרים של פונקציות שהועברו. צריך להשתמש באותה רמת דיוק כמו בהגדרת הפונקציה. |
inout
|
לפרמטרים שמועברים גם פנימה וגם החוצה מפונקציה. צריך להשתמש באותה רמת דיוק כמו זו של הגדרת הפונקציה. |
הצהרת משתנה
ההצהרות חייבות להיות בהיקף מפורש בסוגריים מסולסלים. אסור להצהיר על y
בדוגמה הבאה:
if (condition)
int y = 0;
עקרונות בסיסיים של מטריצות/מבנים/מערכי נתונים
דוגמאות למבנה של מטריצה
כאשר מטריצה נוצרת עם ערך יחיד, כל הערכים לאורך האלכסון מקבלים את הערך הזה, והשאר מקבלים אפס. לכן, float2x2(1.0)
תיצור מטריצת זהות בגודל 2x2.
כשיוצרים מטריצה עם כמה ערכים, העמודות מתמלאות קודם (בסדר עמודות ראשי).
חשוב לזכור שבניגוד ל-GLSL, לא ניתן להשתמש ב-Swift ב-constructors שמפחיתים את מספר הרכיבים של וקטורים שהועברו, אבל אפשר להשתמש ב-swizzling כדי להשיג את אותו אפקט. כדי ליצור vec3
מ-vec4
ב-AGSL עם אותה התנהגות כמו ב-GLSL, מציינים vec3 nv = quadVec.xyz
.
דוגמה למבנה של מגדיר
struct light { float intensity; float3 pos; };
// literal integer constants auto-converted to floating point
light lightVar = light(3, float3(1, 2, 3.0));
רכיבי מטריצה
גישה לרכיבים של מטריצה באמצעות תחביר של אינדקס מערך.
float4x4 m; // represents a matrix
m[1] = float4(2.0); // sets second column to all 2.0
m[0][0] = 1.0; // sets upper left element to 1.0
m[2][3] = 2.0; // sets 4th element of 3rd column to 2.0
שדות מבניים
בוחרים שדות מבנה באמצעות האופרטור הנקודה .
. דוגמאות לאופרטורים:
מפעיל | תיאור |
---|---|
. |
בורר שדות |
==, != |
שוויון |
= |
מטלה |
רכיבי מערך
כדי לגשת לרכיבי מערך, משתמשים באופרטור המשנה של המערך [ ]
. לדוגמה:
diffuseColor += lightIntensity[3] * NdotL;
מפעילים
המספרים מתייחסים לסדר העדיפות. האופרטורים של יחסי השוויון ויחסי הגודל > < <= >= == != מקבלים ערך בוליאני. כדי להשוות בין וקטורים לפי רכיבים, משתמשים בפונקציות כמו lessThan()
, equal()
וכו'.
מפעיל | תיאור | תכונה אסוסיטיבית | |
---|---|---|---|
1 | () |
קיבוץ בסוגריים | לא רלוונטי |
2 | [] () . ++ --
|
קריאה לפונקציה של אינדקס מערך, מבנה של שדה או בוחר שיטות של מגדיר, הוספה וירידה של סיומת פוסטפיקס | משמאל לימין |
3 | ++ -- + - !
|
הוספה וירידה של קידומת חד-ערך | מימין לשמאל |
4 | * / |
כפל וחילוק | משמאל לימין |
5 | + - |
חיבור וחיסור | משמאל לימין |
7 | < > <= >= |
יחסיים | משמאל לימין |
8 | == != |
שוויון/חוסר שוויון | משמאל לימין |
12 | && |
'וגם' בלוגיקה | משמאל לימין |
13 | ^^ |
XOR לוגי | משמאל לימין |
14 | || |
'או' בלוגיקה | משמאל לימין |
15 | ?\:
|
בחירה (אופרטור שלם אחד) | משמאל לימין |
16 | = += -= *= /=
|
הקצאה משימת אריתמטיקה משימת אריתמטיקה | משמאל לימין |
17 | , |
רצף | משמאל לימין |
פעולות על מטריצות ועל וקטורים
כשאופרטורים אריתמטיים חלים על ערכים סקלריים, התוצאה היא סקלר. באופרטורים שאינם מודולו, אם אחד המשתנים הוא סקלר והשני הוא וקטור או מטריצה, הפעולה מתבצעת לפי רכיבים והתוצאה היא אותו סוג של וקטור או מטריצה. אם שתי הפעולות הן וקטורים באותו גודל, הפעולה מתבצעת לפי רכיבים (ומחזירה את אותו סוג וקטור).
פעולה | תיאור |
---|---|
m = f * m |
הכפלת מטריצה לפי רכיבים בערך סקלר |
v = f * v |
הכפלה של וקטור לפי רכיבים בערך סקלרי |
v = v * v |
הכפלת וקטור לפי רכיבים בערך וקטור |
m = m + m |
חיבור של רכיבי מטריצה |
m = m - m |
חיסור לפי רכיבים של מטריצות |
m = m * m |
כפל אלגברי לינארי |
אם אחד מהאופרטורים הוא וקטור שתואם לגודל השורה או העמודה של המטריצה, אפשר להשתמש באופרטור המכפלה כדי לבצע כפל אלגברי של שורות ועמודות.
פעולה | תיאור |
---|---|
m = v * m |
וקטור שורה * כפל אלגברי לינארי במטריצה |
m = m * v |
הכפלה אלגברית לינארית של מטריצה * וקטור עמודה |
משתמשים בפונקציות המובנות למכפלה סקלרית, למכפלה וקטורית ולמכפלה לפי רכיבים:
פעולה | תיאור |
---|---|
f = dot(v, v) |
מכפלה סקלרית של וקטורים |
v = cross(v, v) |
מכפלה וקטורית (cross product) |
m = matrixCompMult(m, m) |
כפל לפי רכיבים |
בקרת תוכנית
קריאה לפונקציה | קריאה לפי החזרת ערך |
---|---|
איטרציה | for (<init>;<test>;<next>) { break, continue } |
בחירה | if ( ) { } if ( ) { } else { } switch () { break, case }
- default case last |
קפיצה | break, continue, return (לא ניתן להשליך) |
הערך | half4 main(float2 fragCoord) |
מגבלות על לולאות For
בדומה ל-GLSL ES 1.0, לולאות 'for' מוגבלות למדי. המהדר צריך להיות מסוגל לבטל את הלולאה. המשמעות היא שהמפעיל, תנאי הבדיקה והצהרת next
חייבים להשתמש בערכי קבועים כדי שאפשר יהיה לחשב את הכל בזמן הידור. ההצהרה next
מוגבלת גם לשימוש ב-++, --, +=, or -=
.
פונקציות מובנות
GT
(סוג כללי) הוא float
, float2
, float3
, float4
או half
, half2
, half3
, half4
.
רוב הפונקציות האלה פועלות לפי רכיבים (הפונקציה חלה על כל רכיב). אם זה לא המצב, יצוין זאת.
זוויות ופונקציות טריגונומטריות
פרמטרים של פונקציות שצוינו כזווית נחשבים ליחידות של רדיאנים. אף אחת מהפונקציות האלה לא תגרום לשגיאה של חילוק באפס. אם המכפיל של היחס הוא 0, התוצאות לא מוגדרות.
פעולה | תיאור |
---|---|
GT radians(GT degrees) |
המרה של מעלות לרדיאנים |
GT degrees(GT radians) |
המרה של רדיאנים למעלות |
GT sin(GT angle) |
סינוס רגיל |
GT cos(GT angle) |
קוסינוס רגיל |
GT tan(GT angle) |
נגזרת רגילה |
GT asin(GT x)
|
הפונקציה מחזירה זווית שהסינוס שלה הוא x בטווח של $ \left[-{\pi\over 2},{\pi\over 2}\right] $. |
GT acos(GT x)
|
הפונקציה מחזירה זווית שהקוסינוס שלה הוא x בטווח של $ \left[0,\pi\right] $ |
GT atan(GT y, GT x)
|
הפונקציה מחזירה זווית שהארקטנגנס הטריגונומטרי שלה הוא $ \left[{y\over x}\right] $ בטווח $ \left[-\pi,\pi\right] $ |
GT atan(GT y_over_x)
|
הפונקציה מחזירה זווית שהארקטנגנס הטריגונומטרי שלה הוא y_over_x בטווח של $ \left[-{\pi\over 2},{\pi\over 2}\right] $ |
פונקציות אקספוננציאליות
פעולה | תיאור |
---|---|
GT pow(GT x, GT y) |
הפונקציה מחזירה את הערך $ x^y $ |
GT exp(GT x) |
הפונקציה מחזירה את הערך $ e^x $ |
GT log(GT x) |
הפונקציה מחזירה את הערך $ ln(x) $ |
GT exp2(GT x) |
הפונקציה מחזירה את הערך 2^x |
GT log2(GT x) |
הפונקציה מחזירה את הערך $ log_2(x) $ |
GT sqrt(GT x) |
הפונקציה מחזירה את הערך $ \sqrt{x} $ |
GT inversesqrt(GT x) |
הפונקציה מחזירה את הערך $ 1\over{\sqrt{x}} $ |
פונקציות נפוצות
פעולה | תיאור |
---|---|
GT abs(GT x) |
ערך מוחלט |
GT sign(GT x) |
הפונקציה מחזירה את הערכים -1.0, 0.0 או 1.0 על סמך הסימן של x |
GT floor(GT x) |
המספר השלם הקרוב ביותר <= x |
GT ceil(GT x) |
המספר השלם הקרוב ביותר >= x |
GT fract(GT x) |
הפונקציה מחזירה את החלק השברוני של x |
GT mod(GT x, GT y) |
הפונקציה מחזירה את הערך של x modulo y |
GT mod(GT x, float y) |
הפונקציה מחזירה את הערך של x modulo y |
GT min(GT x, GT y) |
הפונקציה מחזירה את הערך המינימלי של x או y |
GT min(GT x, float y) |
הפונקציה מחזירה את הערך המינימלי של x או y |
GT max(GT x, GT y) |
הפונקציה מחזירה את הערך המקסימלי של x או y |
GT max(GT x, float y) |
הפונקציה מחזירה את הערך המקסימלי של x או y |
GT clamp(GT x, GT
minVal, GT maxVal) |
הפונקציה מחזירה את הערך x שנמצא בין minVal ל-maxVal. |
GT clamp(GT x, float
minVal, float maxVal) |
הפונקציה מחזירה את הערך x שנמצא בין minVal ל-maxVal |
GT saturate(GT x) |
הפונקציה מחזירה את הערך של x שנמצא בטווח שבין 0.0 ל-1.0 |
GT mix(GT x, GT y,
GT a) |
הפונקציה מחזירה שילוב לינארי של x ו-y |
GT mix(GT x, GT y,
float a) |
הפונקציה מחזירה שילוב לינארי של x ו-y |
GT step(GT edge, GT x) |
הפונקציה מחזירה את הערך 0.0 אם x < edge, אחרת היא מחזירה את הערך 1.0 |
GT step(float edge,
GT x) |
הפונקציה מחזירה את הערך 0.0 אם x < edge, אחרת היא מחזירה את הערך 1.0 |
GT smoothstep(GT edge0,
GT edge1, GT x) |
ביצוע אינטרפולציה של Hermite בין 0 ל-1 כאשר edge0 < x < edge1 |
GT smoothstep(float
edge0, float edge1,
GT x) |
ביצוע אינטרפולציה של Hermite בין 0 ל-1 כאשר edge0 < x < edge1 |
פונקציות גיאומטריות
הפונקציות האלה פועלות על וקטורים כווקטורים, ולא לפי רכיבים. GT הוא ווקטורים של float/half בגדלים 2-4.
פעולה | תיאור |
---|---|
float/half length
(GT x) |
מחזירה את האורך של וקטור |
float/half distance(GT
p0, GT p1) |
הפונקציה מחזירה את המרחק בין הנקודות |
float/half dot(GT x,
GT y) |
הפונקציה מחזירה את המכפלה הפנימית |
float3/half3
cross(float3/half3 x,
float3/half3 y) |
הפונקציה מחזירה מכפלה וקטורית (cross product) |
GT normalize(GT x) |
נורמליזציה של וקטור באורך 1 |
GT faceforward(GT N,
GT I, GT Nref) |
הפונקציה מחזירה את הערך N אם dot(Nref, I) < 0, אחרת היא מחזירה את הערך -N. |
GT reflect(GT I, GT N) |
כיוון ההשתקפות I - 2 * dot(N,I) * N. |
GT refract(GT I, GT N,
float/half eta) |
הפונקציה מחזירה את וקטור השבירה |
פונקציות מטריציוניות
הטיפוס mat יכול להיות כל טיפוס של מטריצה ריבועית.
פעולה | תיאור |
---|---|
mat matrixCompMult(mat
x, mat y) |
כפל של x ב-y לפי רכיבים |
mat inverse(mat m) |
הפונקציה מחזירה את ההופכי של m |
פונקציות יחסיות של וקטורים
להשוות בין הרכיבים x ו-y. הגדלים של וקטור הקלט ווקטור ההחזרה של קריאה מסוימת חייבים להיות זהים. T הוא האיחוד של סוגי וקטורים של מספרים שלמים ומספרים בנקודה צפה. BV הוא וקטור בוליאני שתואם לגודל של ווקטורי הקלט.
פעולה | תיאור |
---|---|
BV lessThan(T x, T y) |
x < y |
BV lessThanEqual(T x,
T y) |
x <= y |
BV greaterThan(T x,
T y) |
x > y |
BV greaterThanEqual(T
x, T y) |
x >= y |
BV equal(T x, T y) |
x == y |
BV equal(BV x, BV y) |
x == y |
BV notEqual(T x, T y) |
x != y |
BV notEqual(BV x,
BV y) |
x != y |
bool any(BV x) |
true אם אחד מהרכיבים של x הוא true |
bool all(BV x) |
true אם כל הרכיבים של x הם true . |
BV not(BV x) |
השלמה לוגית של x |
פונקציות צבע
פעולה | תיאור |
---|---|
vec4 unpremul(vec4
color) |
המרת ערך צבע לאלפא לא מוכפלת |
half3 toLinearSrgb(half3
color) |
טרנספורמציה של מרחב צבעים ל-SRGB לינארי |
half3 fromLinearSrgb(half3
color) |
טרנספורמציה של מרחב צבעים |
דגימת Shader (הערכה)
אין תמיכה בסוגים של Sampler, אבל אפשר להעריך שגיאות אחרות של שגיאות. אם אתם צריכים לדגום טקסטורה, תוכלו ליצור אובייקט BitmapShader ולהוסיף אותו כמאפיין אחיד. אפשר לעשות זאת לכל שידרוג (shader), כלומר אפשר להעריך ישירות כל שידרוג של Android בלי להפוך אותו קודם ל-Bitmap, כולל אובייקטים אחרים של RuntimeShader. כך אפשר לקבל גמישות רבה, אבל הערכה של שיבוטים מורכבים עשויה להיות יקרה, במיוחד בלולאה.
uniform shader image;
image.eval(coord).a // The alpha channel from the evaluated image shader
דגימה של מאגר נתונים גולמי
רוב התמונות מכילות צבעים שצריך לנהל, אבל חלק מהתמונות מכילות נתונים שאינם צבעים, כולל תמונות שמאוחסנים בהן נתוני נורמלים, מאפייני חומר (למשל, מחוספסות), מפות גובה או כל נתון מתמטי אחר שנשמר בתמונה. כשמשתמשים בסוגי התמונות האלה ב-AGSL, אפשר להשתמש ב-BitmapShader כמאגר נתונים גולמי גנרי באמצעות RuntimeShader#setInputBuffer. כך תוכלו להימנע מהמרות של מרחב צבעים וסינון.