简介
从 iOS 17/macOS 14 开始,SwiftUI 支持使用 Metal shader 来实现一些特效。主要提供三个 View Modifier:colorEffect
、 distortionEffect
和 layerEffect
。每个 modifier 的第一个参数是传入的 Shader
实例。
此外,View 实例还新增了一个 visualEffect
modifier,用于暴露修饰内容的布局信息。函数签名为 func visualEffect(_ effect: @escaping (EmptyVisualEffect, GeometryProxy) -> some VisualEffect) -> some View
,在这个闭包中给 EmptyVisualEffect 添加上面的三种 shader modifier,通过 GeometryProxy 参数来获取所修饰内容的 size 等信息,可以进一步传递给 shader function。
可惜的是,这些 modifier 只适用于 SwiftUI 的 View,不适用于 UIKit/AppKit 包的 View。
用法
Shader Function
Shader 构造函数为 init(function: ShaderFunction, arguments: [Shader.Argument]
,而 ShaderFunction 的构造函数为 init(library: ShaderLibrary, name: String)
。ShaderLibrary 有一个 static 成员 default
,表示 app 的 main bundle 中的 shader library。此外 ShaderLibrary 还提供了 static subscript(dynamicMember _: String) -> ShaderFunction
方法,返回 default shader library 中名字为 name 的 MSL function。
三个 View Modifier 分别操作不同的元素,实现不同的效果,也对 MSL 函数有着各自不同的要求,下面一一介绍。
colorEffect
签名如下:
func colorEffect(
_ shader: Shader,
isEnabled: Bool = true
) -> some View
该 modifier 用来操作每个单独的像素,要求提供的 MSL 函数的签名必须和下面的匹配:
[[ stitchable ]] half4 name(float2 position, half4 color, args...)
其中 position 和 color 参数在运行 shader 函数的时候会自动传入,position 表示像素在 user-space 坐标系下的坐标(相对的,Metal 的 clip-space 坐标系区域为 (-1.0, -1.0) 到 (1.0, 1.0)),color 是当前 position 对应像素的颜色。我们也可以通过 args… 可变参数传入自定义的数据。该 shader 函数返回处理后的像素颜色(Fragment shader)。
示例 Shader:
[[ stitchable ]] half4 colorCircle(float2 position, half4 currentColor, float2 size, float radius, half4 circleColor) {
float2 center = size / 2; // 计算 view 的中心点
if (length(position - center) < radius) {
return circleColor * currentColor.a;
} else {
return currentColor;
}
}
在上面的 shader 函数中,除了会默认提供的两个参数 position 和 currentColor 外,我们还额外提供了三个参数 size,radius,circleColor,这三个函数需要在SwiftUI 中进行指定,如下所示:
struct ContentView: View {
let start = Date()
var body: some View {
ZStack {
TimelineView(.animation) { _ in
Text("
标签:layer,Metal,Shader,shader,SwiftUI,position,size,float2,View
From: https://www.cnblogs.com/jerrywossion/p/18090457