大多数浏览器和
Developer App 均支持流媒体播放。
-
如何在 Xcode 环境下 构建基于 Metal 的 Core Image 内核
了解如何将运用 Metal Shading 语言编写的 Core Image 核心程序与你的app融合在一起并进行加载,同时发现如何借助这些图像滤镜创造独特效果。探索如何使用 Xcode 规则和命名约定来完成由 Metal Shading 语言编写的 Core Image 核心程序。我们将解析借助 Metal 技术和 Metal Shading 语言来高效使用 Core Image APIs 的最佳方式。
资源
相关视频
WWDC21
WWDC20
-
下载
(你好 WWDC 2020)
你好 欢迎参加全球开发者大会
大家好 我叫大卫·海沃德 是 Core Image 团队的一名工程师 我今天要做一篇简短的演讲 主要内容是为你讲解 如何在 Xcode 环境下 构建基于 Metal 的 Core Image 内核 首先 为什么要用 Metal 来 编写自定义 CIKernel? 除了 CIKernel 那些常见的特性 比如自动平铺和级联之类 用 Metal 编写内核 可以减少运行时编译次数 把此类工作转移到 app 构建完毕的时候进行
让你的内核得以使用一些高性能的特性 例如聚集读取、分组写值、半浮点数学等 并通过打字时语法标亮 和构建时语法检查这两项功能 来简化你的 app 开发工作
优点至此介绍完毕 下面就让我来一步步为你展示 如何将 Metal Core Image 内核 添加到你的 app 里 一共需要五个简单的步骤 首先 为你的项目添加自定义构建规则
然后把 .ci.metal 资源 添加到你的项目里 编写你的内核
初始化你的 CIKernel 对象 以及应用你的内核 来创建一个新的 CIImage 与传统的 Metal 计算和图形着色器不同 Core Image Metal代码需要经过编译 并与特殊的标志相联 我建议你在自己的项目目标里 添加两个自定义构建规则 实现这些标志的自动化使用
首先 我们打开项目目标的设置界面 然后针对以 .ci.metal 为后缀的文件 添加一个构建规则 对于使用这一扩展名的文件 我们要运行一个长度为一行的脚本 来调用带有 -fcikernel 旗标的 Metal 编译器 这条构建规则会产生一个 以 .ci.air 为后缀的输出二进制数
接下来 针对以 .ci.air. 为后缀的文件 我们要添加第二条规则
对于使用这一扩展名的文件 我们要运行另一个长度为一行的脚本 来调用带有 -cikernel 标志的 Metal 链接器
这条构建规则会在你的 app 资源目录下 产生一个以 .ci.metal 为后缀的输出
这两条自定义构建规则添加完毕后 我们只需要再将一个 .ci.metal 源 添加到你的项目里就可以了 要实现这一点 你只需要前往文件菜单 依次选择“新建”、“文件”
然后选择你想添加一个 Metal 文件
然后创建一个以 .ci 为后缀的文件名 这样你项目里的新文件 就会以 .ci.metal 为后缀了 在今天这场讲座里 被我选为讲解示例的内核 在另外一篇精彩演讲里 已经向大家展示过了 那篇演讲的题目是《使用 AVFoundation 编辑和回放 HDR 视频》
在那场讲座里 这个内核 会使用一种动画化的斑马线效果 将一段 HDR 视频里 属于色调延伸范围的明亮部分高亮显示
要编写一个能实现这种效果的 自定义 CIKernel 很简单 首先 你需要在资源顶端 插入一个 CoreImage.h 标头 这样就可以存取 Metal 所有的普通类 以及 Core Image 额外提供的那些类
接下来 你要声明这个内核的函数 必须是关键字“C”
我们这里所举的例子是 CIColorKernel 它的函数必须要返回一个 float4 像素 并使用一些实际参数
这里的第一个实际参数是 Core Image sample_t 代表的是某张输入图像里的一个像素 这个像素属于 线性预乘 RGBA float4 类型 无论对于 SDR 还是 HDR 图像都很合适
最后这个实际参数则是 一个 Core Image 终点位置 可提供待返回的像素的坐标
在实现这个内核的时候 我们要使用 dest.coord 的 x 值和 y 值 来判断我们处在哪一条对角线上 然后通过一些简单的数学计算 来判断我们是不是在斑马线上
如果我们是在斑马线上 当前这个像素示例的亮度 又高于白色值为 1 的 正常标准动态范围 那么我们就返回一个亮红色像素 否则就原封不动地返回输入示例
有关 Core Image 内核所使用的 Metal 着色器语言 如果需要较详尽的说明文档 我建议你们访问 developer.apple.com 下载这份 PDF 格式的参考文献
里面记载了 Metal Core Image 内核的各个类 还描述了一些更加高级的特性 比如聚集读取和分组写入等
我今天要讲的最后几个步骤 需要通过 Swift 代码加载你的内核 然后应用它 从而创建新图像
通常来讲 内核会由 CIFilter 子类使用 这些子类都有一些输入属性 比如 InputImage 和其他参数
我们建议你用筛选器 通过一个静态属性 来将它的 CIKernel 对象实例化 这样一来 经过编译的 metallib 资源 只需要在第一次需要用到它的时候 加载一次就可以了
最后 CIFilter 子类必须要覆盖输出图像属性 在这个 getter 函数里 你需要将内核从静态属性中拿出 然后利用它的应用方法 来创建一个新的图像
关于如何在 Xcode 环境下构建 Metal Core Image 内核 我的分步解说就到此为止 我今天所讲解的内容有 如何将自定义构建规则添加到你的项目里 如何编写一个内核 并添加到你的项目里 以及如何将你的内核对象初始化并应用 从而创建一个新的图像
希望这些知识能让你 app 里的 图像和视频拥有更加出色的视觉效果 感谢你的观看 请尽情享受 2020全球开发者大会余下的部分吧
-
-
3:08 - Put your kernels in .ci.metal sources
// MyKernels.ci.metal #include <CoreImage/CoreImage.h> // includes CIKernelMetalLib.h using namespace metal; extern "C" float4 HDRZebra (coreimage::sample_t s, float time, coreimage::destination dest) { float diagLine = dest.coord().x + dest.coord().y; float zebra = fract(diagLine/20.0 + time*2.0); if ((zebra > 0.5) && (s.r > 1 || s.g > 1 || s.b > 1)) return float4(2.0, 0.0, 0.0, 1.0); return s; }
-
4:58 - Loading your kernel and applying it to create a new image
class HDRZebraFilter: CIFilter { var inputImage: CIImage? var inputTime: Float = 0.0 static var kernel: CIColorKernel = { () -> CIColorKernel in let url = Bundle.main.url(forResource: "MyKernels", withExtension: "ci.metallib")! let data = try! Data(contentsOf: url) return try! CIColorKernel(functionName: "HDRzebra", fromMetalLibraryData: data) }() override var outputImage : CIImage? { get { guard let input = inputImage else {return nil} return HDRZebraFilter.kernel.apply(extent: input.extent, arguments: [input, inputTime]) } } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。