AGSL và GLSL có cú pháp rất giống nhau, cho phép nhiều chương trình đổ bóng mảnh GLSL chuyển sang Android bằng những thay đổi tối thiểu. AGSL sửa GLSL bộ tính năng tại GLSL ES 1.0 (ngôn ngữ tô bóng được sử dụng bởi OpenGL ES 2.0) để cung cấp phạm vi tiếp cận tối đa của thiết bị.
Chương trình đổ bóng mảnh GLSL kiểm soát toàn bộ hành vi của GPU giữa công cụ tạo điểm ảnh và phần cứng trộn. Chương trình đổ bóng đó thực hiện tất cả công việc để tính toán và màu mà hệ thống tạo ra chính xác là màu được đưa vào giai đoạn pha trộn của quy trình. Khi viết chương trình đổ bóng trong AGSL, bạn đang lập trình một giai đoạn quy trình đồ hoạ Android. Nhiều điểm khác biệt về ngôn ngữ là do điều này.
Thực thi chương trình đổ bóng
Tương tự như trong chương trình đổ bóng GLSL, chương trình đổ bóng AGSL bắt đầu thực thi trong hàm chính.
Không giống như GLSL, hàm này nhận vị trí chương trình đổ bóng trong "local" toạ độ dưới dạng
. Hàm này tương tự như gl_FragCoord
, nhưng không phải là vùng đệm khung
Những toạ độ này có thể đã được dịch trước khi gọi
chương trình đổ bóng. Sau đó, chương trình đổ bóng sẽ trả về màu pixel dưới dạng vec4
theo giá trị trung bình hoặc
có độ chính xác cao (tương tự như out vec4 color
hoặc gl_FragColor
trong GLSL).
mediump vec4 main(in vec2 fragCoord)
Không gian toạ độ
Chương trình đổ bóng được vẽ bằng GLSL so với chương trình đổ bóng gần giống hệt được vẽ bằng AGSL
Theo mặc định, AGSL và GLSL sử dụng các không gian toạ độ khác nhau. Trong GLSL, mảnh
toạ độ (fragCoord) so với góc dưới bên trái. AGSL khớp với màn hình
hệ toạ độ của Canvas,
có nghĩa là trục Y bắt đầu từ góc trên bên trái. Nếu cần, bạn
có thể chuyển đổi giữa hai khoảng trắng này
bằng cách truyền độ phân giải dưới dạng
và sử dụng resolution.y - fragCoord.y
cho giá trị trục Y. Ngoài ra, bạn
có thể áp dụng ma trận biến đổi cục bộ cho chương trình đổ bóng.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
Độ chính xác và loại
Hỗ trợ đối tượng sửa đổi độ chính xác tương thích với GLSL, nhưng AGSL ra mắt
Các loại half
và short
cũng thể hiện độ chính xác trung bình.
Các loại vectơ có thể được khai báo dưới dạng <loại cơ sở><cột>. Bạn có thể sử dụng
float2
thay vì vec2
và bool4
thay vì bvec4
.
Các loại ma trận có thể được khai báo dưới dạng <loại cơ sở><cột>x<hàng>, do đó
float3x3
thay vì mat3
. AGSL cũng cho phép khai báo kiểu GLSL
cho mat
và vec
, đồng thời các loại này được liên kết với số thực của chúng
quy tắc tương đương.
Bộ tiền xử lý
AGSL không hỗ trợ kiểu GLSL bộ tiền xử lý . Chuyển đổi các câu lệnh #define thành biến const. Trình biên dịch của AGSL hỗ trợ gấp liên tục và loại bỏ nhánh cho các biến const, vì vậy sẽ hiệu quả.
Hệ màu
Ứng dụng Android được quản lý màu. Hệ màu của Canvas xác định hệ màu dùng để vẽ. Nội dung nguồn (như chương trình đổ bóng, bao gồm BitmapShader) cũng có hệ màu.
Đối với một số hiệu ứng nhất định, chẳng hạn như ánh sáng chính xác về mặt vật lý, bạn nên tính toán trong hệ màu tuyến tính. Để giải quyết vấn đề này, AGSL cung cấp các hàm nội tại này hàm:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Các chế độ xem này chuyển đổi màu giữa hệ màu hoạt động và hệ thống màu của Android
LINEAR_EXTENDED_SRGB
hệ màu. Không gian đó sử dụng dải màu sơ cấp sRGB (gam màu) và dải màu tuyến tính
hàm truyền tải. Thuộc tính này biểu thị các giá trị nằm ngoài gam màu sRGB bằng cách sử dụng
phạm vi giá trị (dưới 0,0 và trên 1,0).
Đồng phục
Vì AGSL không biết đồng nhất có chứa màu sắc hay không nên AGSL sẽ không tự động áp dụng
chuyển đổi màu cho chúng. Bạn có thể gắn nhãn half4
/float4
/vec4
bằng
layout(color)
cho Android biết rằng đồng phục sẽ được dùng làm
màu, cho phép Android chuyển đổi giá trị đồng nhất thành màu làm việc
.
Trong AGSL, hãy khai báo đồng nhất như sau:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
Trong mã Android, bạn có thể đặt kiểu đồng nhất như sau:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())