تفاوت‌های بین AGSL و GLSL

AGSL و GLSL ازنظر نحو بسیار شبیه هستند، که باعث می‌شود بسیاری از جلوه‌های سایه‌زن قطعه GLSL با حداقل تغییرات به Android منتقل شوند. AGSL مجموعه ویژگی‌های GLSL خود را روی GLSL ES 1.0 (زبان سایه‌زنی مورداستفاده OpenGL ES 2.0) ثابت می‌کند تا حداکثر دسترسی دستگاه را فراهم کند.

سایه‌زن قطعه GLSL کل رفتار GPU را بین شطرنجی‌ساز و سخت‌افزار ترکیب کنترل می‌کند. آن سایه‌زن تمام کار محاسبه رنگ را انجام می‌دهد و رنگی که تولید می‌کند دقیقاً همان چیزی است که به مرحله ترکیب خط لوله داده می‌شود. وقتی سایه‌زنی را در AGSL می‌نویسید، درحال برنامه‌نویسی مرحله‌ای از خط لوله گرافیک Android هستید. بسیاری از تفاوت‌های زبانی از این موضوع ناشی می‌شود.

اجرای سایه‌زن

درست مانند سایه‌زن GLSL، سایه‌زن AGSL اجرا را در یک تابع اصلی آغاز می‌کند. برخلاف GLSL، این تابع موقعیت سایه‌زن را در مختصات «محلی» به‌عنوان پارامتر می‌گیرد. این شبیه به gl_FragCoord است، اما به‌جای مختصات میانگیر قاب، این مختصات ممکن است قبل‌از فراخوانی سایه‌زن شما ترجمه شده باشد. سپس سایه‌زن شما رنگ پیکسل را به‌عنوان vec4 در دقت متوسط یا بالا (مشابه out vec4 color یا gl_FragColor در GLSL) برمی‌گرداند.

mediump vec4 main(in vec2 fragCoord)

فضای مختصات

فضاهای مختصات GLSL درمقابل AGSL

سایه‌زن ترسیم‌شده بااستفاده از 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> نام‌گذاری‌شده اعلام کرد. می‌توانید از float2 به‌جای vec2 و از bool4 به‌جای bvec4 استفاده کنید. انواع ماتریس را می‌توان به‌عنوان <base type><columns>x<rows> نام‌گذاری‌شده اعلام کرد، بنابراین float3x3 به‌جای mat3. AGSL همچنین به اظهارات سبک GLSL برای mat و vec اجازه می‌دهد و این نوع‌ها به معادل‌های اعشاری‌شان نگاشت می‌شوند.

پیش‌پردازنده

AGSL از دستورالعمل‌های پیش‌پردازنده سبک GLSL پشتیبانی نمی‌کند. عبارت‌های define #را به متغیرهای const تبدیل کنید. کامپایلر AGSL از تاشدگی ثابت و حذف شاخه برای متغیرهای ثابت پشتیبانی می‌کند، بنابراین این موارد کارآمد خواهند بود.

فضاهای رنگی

رنگ برنامه‌های Android مدیریت می‌شود. فضای رنگی Canvas فضای رنگی کاری را برای طراحی تعیین می‌کند. محتوای منبع (مانند سایه‌زن‌ها، ازجمله BitmapShader) نیز دارای فضاهای رنگی هستند.

برای برخی‌از جلوه‌ها، مثل نورپردازی دقیق فیزیکی، محاسبات ریاضی باید در فضای رنگی خطی انجام شود. برای کمک به این امر، AGSL این توابع ذاتی را ارائه می‌دهد:

half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)

این‌ها رنگ‌ها را بین فضای رنگ کاری و فضای رنگ LINEAR_EXTENDED_SRGB Android تبدیل می‌کنند. این فضا از اصول اولیه رنگ sRGB (طیف رنگ) و تابع انتقال خطی استفاده می‌کند. این فضا مقادیر خارج از طیف sRGB را بااستفاده از مقادیر محدوده گسترده (زیر ۰٫۰ و بالای ۱٫۰) نشان می‌دهد.

یونیفرم

ازآنجایی‌که AGSL نمی‌داند آیا یونیفرم‌ها حاوی رنگ هستند یا نه، به‌طور خودکار تبدیل رنگ را برای آن‌ها اعمال نمی‌کند. می‌توانید half4/float4/vec4 را با layout(color) برچسب‌گذاری کنید، که به Android اطلاع می‌دهد که از uniform به‌عنوان رنگ استفاده خواهد شد، و به Android اجازه می‌دهد مقدار uniform را به فضای رنگی فعال تبدیل کند.

در AGSL، متغیر یکنواخت را به‌صورت زیر اعلام کنید:

layout(color) uniform half4 iColor;  // Input color
uniform float2 iResolution;          // Viewport resolution (pixels)

سپس در کد Android می‌توانید یکنواخت را به‌این‌صورت تنظیم کنید:

shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())