AGSL و GLSL از نظر نحو بسیار شبیه به یکدیگر هستند و به بسیاری از افکتهای سایهزن قطعه GLSL اجازه میدهند تا با حداقل تغییرات به اندروید منتقل شوند. AGSL تنظیم ویژگی GLSL خود را در GLSL ES 1.0 (زبان سایه استفاده شده توسط OpenGL ES 2.0) برای ارائه حداکثر دسترسی به دستگاه اصلاح می کند.
یک شیدر قطعه GLSL کل رفتار GPU را بین شطرنجساز و سختافزار ترکیبی کنترل میکند. آن سایه زن تمام کارها را برای محاسبه یک رنگ انجام می دهد و رنگی که تولید می کند دقیقاً همان چیزی است که به مرحله ترکیب خط لوله داده می شود. هنگامی که یک سایه زن در AGSL می نویسید، در حال برنامه ریزی مرحله ای از خط لوله گرافیکی اندروید هستید. بسیاری از تفاوت های زبانی از این موضوع ناشی می شود.
اجرای سایه بان
درست مانند یک سایه زن GLSL، یک سایه زن AGSL اجرا را در یک تابع اصلی آغاز می کند. برخلاف GLSL، تابع موقعیت سایه زن را در مختصات "محلی" به عنوان پارامتر می گیرد. این شبیه به gl_FragCoord
است، اما به جای مختصات فریم بافر، ممکن است این مختصات قبل از فراخوانی شیدر شما ترجمه شده باشند. سپس سایهزن شما رنگ پیکسل را به صورت vec4
با دقت متوسط یا بالا برمیگرداند (شبیه به out vec4 color
یا gl_FragColor
در GLSL).
mediump vec4 main(in vec2 fragCoord)
فضای مختصات
سایه زن با استفاده از GLSL در مقابل سایه زن تقریباً یکسان که با استفاده از AGSL کشیده شده است
AGSL و GLSL به طور پیش فرض از فضاهای مختصات متفاوتی استفاده می کنند. در GLSL، مختصات قطعه (fragCoord) نسبت به پایین سمت چپ است. AGSL با سیستم مختصات صفحه نمایش Canvas مطابقت دارد، به این معنی که محور Y از گوشه سمت چپ بالا شروع می شود. در صورت نیاز، می توانید بین این دو فاصله را با عبور رزولوشن به صورت یکنواخت و با استفاده از resolution.y - fragCoord.y
برای مقدار محور Y تبدیل کنید. از طرف دیگر، می توانید یک ماتریس تبدیل محلی را به سایه زن خود اعمال کنید.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
دقت و انواع
اصلاحکنندههای دقیق سازگار با GLSL پشتیبانی میشوند، اما AGSL انواع half
و short
را معرفی میکند که نشاندهنده دقت متوسط نیز هستند.
انواع بردار را می توان با نام <base type><columns> اعلان کرد. می توانید به جای vec2
از float2
و به جای bvec4
از bool4
استفاده کنید. انواع ماتریس را می توان با نام <base type><columns>x<rows> اعلان کرد، بنابراین به جای mat3
float3x3
. AGSL همچنین اعلانهای سبک GLSL را برای mat
و vec
اجازه میدهد و این انواع به معادلهای شناور خود نگاشت میشوند.
پیش پردازنده
AGSL از دستورالعمل های پیش پردازنده سبک GLSL پشتیبانی نمی کند. دستورات #define را به متغیرهای const تبدیل کنید. کامپایلر AGSL از تاشو و حذف شاخه ثابت برای متغیرهای const پشتیبانی می کند، بنابراین این موارد کارآمد خواهند بود.
فضاهای رنگی
برنامه های Android مدیریت رنگ هستند. فضای رنگی یک بوم، فضای رنگی کار برای طراحی را تعیین می کند. محتوای منبع (مانند سایهزنها، از جمله BitmapShader ) نیز دارای فضای رنگی هستند.
برای جلوه های خاص، مانند نورپردازی دقیق فیزیکی، ریاضیات باید در فضای رنگی خطی انجام شود. برای کمک به این امر، AGSL این توابع ذاتی را ارائه می دهد:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
اینها رنگ ها را بین فضای رنگی کار و فضای رنگی LINEAR_EXTENDED_SRGB
Android تبدیل می کند. آن فضا از رنگ های اولیه sRGB (gamut) و یک تابع انتقال خطی استفاده می کند. این مقادیر خارج از محدوده sRGB را با استفاده از مقادیر دامنه گسترده (زیر 0.0 و بالاتر از 1.0) نشان می دهد.
لباس فرم
از آنجایی که AGSL نمی داند که آیا یونیفرم ها دارای رنگ هستند یا خیر، به طور خودکار تبدیل رنگ به آنها اعمال نمی کند. شما می توانید half4
/ float4
/ vec4
را با layout(color)
برچسب بزنید، که به اندروید اجازه می دهد بداند که لباس به عنوان یک رنگ استفاده می شود، و به اندروید اجازه می دهد مقدار یکنواخت را به فضای رنگ کاری تبدیل کند.
در AGSL، یونیفرم را به صورت زیر اعلام کنید:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
در کد اندروید، میتوانید لباس را به شکل زیر تنظیم کنید:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())