可编程着色器 (AGSL Shaders)
从 Android 13 (API 33) 开始,Android 图形管线支持 AGSL (Android Graphics Shading Language)。Compose 提供了极简的 API 来使用它。
兼容性
AGSL 仅在 Android 13+ 上原生支持。对于低版本,你可以使用第三方库(如 Rikka)或降级为普通的 Canvas 绘制。
1. 编写 AGSL 代码
AGSL 的语法与 GLSL (OpenGL ES 着色语言) 非常相似。
kotlin
// 定义一个简单的“色差偏移”着色器
const val SHADER_SRC = """
uniform shader composable; // 输入的图像内容
uniform float2 size; // 图像尺寸
uniform float time; // 时间变量
half4 main(float2 fragCoord) {
// 计算偏移量
float offset = sin(time + fragCoord.y * 0.05) * 10.0;
// 分别采样 R, G, B 通道,产生错位
half4 color = composable.eval(fragCoord);
color.r = composable.eval(fragCoord + float2(offset, 0.0)).r;
color.b = composable.eval(fragCoord - float2(offset, 0.0)).b;
return color;
}
"""2. 创建 RuntimeShader
kotlin
val runtimeShader = remember { RuntimeShader(SHADER_SRC) }3. 应用于 GraphicsLayer
使用 RenderEffect 将着色器应用到任何 Composable 上(包括图片、文字甚至复杂的布局)。
kotlin
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun GlitchEffectImage() {
val time by rememberInfiniteTransition().animateFloat(
initialValue = 0f,
targetValue = 6.28f, // 2*PI
animationSpec = infiniteRepeatable(tween(1000))
)
Image(
painter = painterResource(R.drawable.hero),
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
// 更新 Uniform 变量
runtimeShader.setFloatUniform("size", size.width, size.height)
runtimeShader.setFloatUniform("time", time)
// 应用 RenderEffect
renderEffect = RenderEffect
.createRuntimeShaderEffect(runtimeShader, "composable")
.asComposeRenderEffect()
}
)
}4. 常见用途
- 动态模糊 (Blur)
- 噪点与颗粒感 (Grain)
- 水波纹 (Ripple)
- 全息效果 (Holographic)