探索用于通过 compositor services 打造沉浸式 app 的 metal 渲染的最新改进。了解如何通过添加悬停效果来突出展示 app 的交互式元素,以及如何通过动态渲染质量实现更高保真度的渲染。了解新的 progressive 沉浸样式。探索如何通过将 mac 中的 metal 内容直接渲染至 vision pro,来为 macos app 提供沉浸式体验。
要充分利用好本次讲座,请先观看 wwdc23 讲座“探索 metal 技术打造沉浸式 app”。
此文章由AI生成,可能存在错误,如有问题,请联系djs66256@163.com
用于打造沉浸式 App 的 Metal 渲染新功能
苹果在 WWDC 上展示了通过 Compositor Services 打造沉浸式应用的 Metal 渲染最新改进。这些新功能包括悬停效果、动态渲染质量和渐进式沉浸风格,为开发者提供了更丰富的工具来提升应用交互性和视觉效果。
新渲染循环 API
Metal 沉浸式应用的渲染流程始于新的渲染循环 API。开发者需要创建包含合成器层的沉浸空间,该层提供用于渲染循环的层渲染器对象。今年的 Compositor Services 新增了返回数组的 queryDrawables 函数,根据系统上下文,该数组将包含 1 或 2 个 drawables。
// 场景渲染循环
extension Renderer {
func renderFrame(with scene: MyScene) {
guard let frame = layerRenderer.queryNextFrame() else { return }
frame.startUpdate()
scene.performFrameIndependentUpdates()
frame.endUpdate()
let drawables = frame.queryDrawables()
guard !drawables.isEmpty else { return }
guard let timing = frame.predictTiming() else { return }
LayerRenderer.Clock().wait(until: timing.optimalInputTime)
frame.startSubmission()
scene.render(to: drawable)
frame.endSubmission()
}
}
悬停效果
新的悬停效果功能让用户能直观看到哪些对象可交互。系统会动态高亮用户注视对象,为应用和游戏添加更丰富的交互细节。
开发者需要在层配置中设置追踪区域格式:
// 层配置
struct MyConfiguration: CompositorLayerConfiguration {
func makeConfiguration(capabilities: LayerRenderer.Capabilities,
configuration: inout LayerRenderer.Configuration) {
let trackingAreasFormat: MTLPixelFormat = .r8Uint
if capabilities.supportedTrackingAreasFormats.contains(trackingAreasFormat) {
configuration.trackingAreasFormat = trackingAreasFormat
}
}
}
对象渲染时需要处理悬停效果:
// 对象渲染函数
extension MyObject {
func render(drawable: Drawable, renderEncoder: MTLRenderCommandEncoder) {
var renderValue: LayerRenderer.Drawable.TrackingArea.RenderValue? = nil
if self.isInteractive {
let trackingArea = drawable.addTrackingArea(identifier: self.identifier)
if self.usesHoverEffect {
trackingArea.addHoverEffect(.automatic)
}
renderValue = trackingArea.renderValue
}
self.draw(with: commandEncoder, trackingAreaRenderValue: renderValue)
}
}
Metal 片段着色器需要同时输出颜色和追踪区域值:
// Metal 片段着色器
struct FragmentOut
{
float4 color [[color(0)]];
uint16_t trackingAreaRenderValue [[color(1)]];
};
fragment FragmentOut fragmentShader( /* ... */ )
{
return FragmentOut {
float4(outColor, 1.0),
uniforms.trackingAreaRenderValue
};
}
动态渲染质量
动态渲染质量功能允许应用根据场景复杂度调整内容分辨率。开发者可以指定适合应用的最大渲染质量,并根据显示内容类型在运行时调整质量。
// 质量常量
extension MyScene {
struct Constants {
static let menuRenderQuality: LayerRenderer.RenderQuality = .init(0.8)
static let worldRenderQuality: LayerRenderer.RenderQuality = .init(0.6)
static var maxRenderQuality: LayerRenderer.RenderQuality { menuRenderQuality }
}
}
层配置中需要设置最大渲染质量:
// 层配置
struct MyConfiguration: CompositorLayerConfiguration {
func makeConfiguration(capabilities: LayerRenderer.Capabilities,
configuration: inout LayerRenderer.Configuration) {
if configuration.isFoveationEnabled {
configuration.maxRenderQuality = MyScene.Constants.maxRenderQuality
}
}
}
运行时可以根据场景类型调整渲染质量:
// 设置运行时渲染质量
extension MyScene {
var renderQuality: LayerRenderer.RenderQuality {
switch type {
case .world: Constants.worldRenderQuality
case .menu: Constants.menuRenderQuality
}
}
}
extension Renderer {
func adjustRenderQuality(for scene: MyScene) {
guard layerRenderer.configuration.isFoveationEnabled else { return }
layerRenderer.renderQuality = scene.renderQuality
}
}
渐进式沉浸
渐进式沉浸风格允许用户通过旋转 Digital Crown 控制沉浸程度。系统仅渲染当前沉浸级别内的内容,通过门户模板屏蔽外部内容,节省计算资源。
相关资源
开发者可以通过以下资源深入了解这些新功能:
相关视频:
文档:
