AGSL 与 GLSL 之间的区别
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
AGSL 和 GLSL 在语法上非常相似,允许使用多种 GLSL fragment 着色器
只需极少的更改即可引入 Android 平台。AGSL 修复其 GLSL
GLSL ES 1.0(OpenGL ES 2.0 使用的着色语言)
最大限度地扩大设备覆盖面
GLSL fragment 着色器控制 GPU 的
光栅化处理程序和混合硬件该着色器会完成
它生成的颜色就是供给混合阶段的颜色
流水线。使用 AGSL 编写着色器时,
Android 图形管道许多语言的差异都源于此。
着色器执行
就像在 GLSL 着色器中一样,AGSL 着色器开始在 main 函数中执行。
与 GLSL 不同,该函数使用“local”中的着色器位置坐标为
参数。它与 gl_FragCoord
类似,但不是帧缓冲区
坐标,在调用您的
着色器。然后,着色器会以 vec4
(中等色)或
高精度(类似于 GLSL 中的 out vec4 color
或 gl_FragColor
)。
mediump vec4 main(in vec2 fragCoord)
坐标空间

使用 GLSL 绘制的着色器与使用 AGSL 绘制的几乎相同的着色器
默认情况下,AGSL 和 GLSL 使用不同的坐标空间。在 GLSL 中,fragment 为
坐标 (fragCoord) 相对于左下角进行定义。AGSL 匹配屏幕
Canvas 的坐标系,
也就是说,Y 轴从左上角开始。如果需要,您可以
可以通过将分辨率作为 uniform 传递,在这两个空间之间进行转换
并使用 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 语句转换为常量变量。AGSL 的编译器
支持针对常量变量进行常量折叠和分支消除,
效率。
颜色空间
Android 应用支持颜色管理。画布的颜色空间决定了
用于绘制的工作颜色空间源内容(例如着色器,包括
BitmapShader)
还有颜色空间
对于某些效果(例如精确的光照效果),应该先进行数学计算
线性颜色空间中的颜色。为此,AGSL 提供了这些固有的
函数:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
这些颜色可在工作颜色空间与 Android 颜色空间之间转换颜色
LINEAR_EXTENDED_SRGB
颜色空间。该空间使用 sRGB 原色(色域),以及线性
传输函数。它使用扩展符号来表示 sRGB 色域以外的值,
范围值(低于 0.0 和高于 1.0)。
由于 AGSL 不知道 uniform 是否包含颜色,因此不会自动应用
转换为这些颜色。您可以使用如下标签为 half4
/float4
/vec4
添加标签:
layout(color)
,以便 Android 知道 uniform 将用作
颜色,使 Android 能够将统一的值转换为工作颜色
空间。
在 AGSL 中,按如下方式声明 uniform:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
然后,您可以在 Android 代码中按如下方式设置 uniform:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Differences between AGSL and GLSL\n\nAGSL and GLSL are very similar in syntax, allowing many GLSL fragment shader\neffects to be brought over to Android with minimal changes. AGSL fixes its GLSL\nfeature set at GLSL ES 1.0 (the shading language used by OpenGL ES 2.0) to\nprovide for maximum device reach.\n\nA GLSL fragment shader controls the entire behavior of the GPU between the\nrasterizer and the blending hardware. That shader does all the work to compute a\ncolor, and the color it generates is exactly what is fed to the blending stage\nof the pipeline. When you write a shader in AGSL, you are programming a stage of\nthe Android graphics pipeline. Many of the language differences stem from this.\n\nShader execution\n----------------\n\nJust like in a GLSL shader, an AGSL shader begins execution in a main function.\nUnlike GLSL, the function takes the shader position in \"local\" coordinates as a\nparameter. This is similar to `gl_FragCoord`, but rather than framebuffer\ncoordinates, these coordinates may have been translated prior to calling your\nshader. Your shader then returns the pixel color as a `vec4` in medium or\nhigh precision (similar to `out vec4 color` or `gl_FragColor` in GLSL). \n\n mediump vec4 main(in vec2 fragCoord)\n\nCoordinate space\n----------------\n\n*Shader drawn using GLSL vs [Near identical shader drawn using AGSL](https://shaders.skia.org/?id=9dc5c7170e82d49c47a3ee20d679ad5bef45b5ca7e23c4327dd93b8d3101256f)*\n\nAGSL and GLSL use different coordinate spaces by default. In GLSL, the fragment\ncoordinate (fragCoord) is relative to the lower left. AGSL matches the screen\ncoordinate system of [Canvas](/reference/android/graphics/Canvas),\nwhich means that the Y axis begins from the upper left corner. If needed, you\ncan convert between these two spaces by passing in the resolution as a uniform\nand using `resolution.y - fragCoord.y` for the Y axis value. Alternatively, you\ncan apply a local transformation matrix to your shader. \n\n // AGSL to GLSL coordinate space transformation matrix\n val localMatrix = Matrix()\n localMatrix.postScale(1.0f, -1.0f)\n localMatrix.postTranslate(0.0f, viewHeight)\n gridShader.setLocalMatrix(localMatrix)\n\nPrecision and types\n-------------------\n\nGLSL compatible precision modifiers are supported, but AGSL introduces\n`half` and `short` types which also represent medium precision.\n\nVector types can be declared as named \\\u003cbase type\\\u003e\\\u003ccolumns\\\u003e. You can use\n`float2` instead of `vec2` and `bool4` instead of `bvec4`.\nMatrix types can be declared as named \\\u003cbase type\\\u003e\\\u003ccolumns\\\u003ex\\\u003crows\\\u003e, so\n`float3x3` instead of `mat3`. AGSL also allows GLSL-style declarations\nfor `mat` and `vec` and these types are mapped to their float\nequivalents.\n\nPreprocessor\n------------\n\nAGSL doesn't support GLSL style\n[preprocessor](https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives)\ndirectives. Convert #define statements to const variables. AGSL's compiler\nsupports constant folding and branch elimination for const variables, so these\nwill be efficient.\n\nColor spaces\n------------\n\nAndroid Applications are color managed. The color space of a Canvas determines\nthe working color space for drawing. Source content (like shaders, including\n[BitmapShader](/reference/android/graphics/BitmapShader))\nalso have color spaces.\n\nFor certain effects, such as physically accurate lighting, math should be done\nin a linear color space. To help with this, AGSL provides these intrinsic\nfunctions: \n\n half3 toLinearSrgb(half3 color)\n half3 fromLinearSrgb(half3 color)\n\nThese convert colors between the working color space and Android's\n[`LINEAR_EXTENDED_SRGB`](/reference/android/graphics/ColorSpace.Named#LINEAR_EXTENDED_SRGB)\ncolor space. That space uses the sRGB color primaries (gamut), and a linear\ntransfer function. It represents values outside of the sRGB gamut using extended\nrange values (below 0.0 and above 1.0).\n\n### Uniforms\n\nSince AGSL doesn't know if uniforms contain colors, it won't automatically apply\na color conversion to them. You can label `half4`/`float4`/`vec4` with\n`layout(color)`, which lets Android know that the uniform will be used as a\ncolor, allowing Android to transform the uniform value to the working color\nspace.\n\nIn AGSL, declare the uniform like this: \n\n layout(color) uniform half4 iColor; // Input color\n uniform float2 iResolution; // Viewport resolution (pixels)\n\nIn Android code, you can then set the uniform like this: \n\n shader.setColorUniform(\"iColor\", Color.GREEN)\n shader.setFloatUniform(\"iResolution\", canvas.width.toFloat(), canvas.height.toFloat())"]]