现实套件 vs 场景套件 vs 金属 - 高质量渲染

75
我正在开发一款iOS应用程序,我打算在AR中显示逼真/高质量的渲染效果。在尝试这三个选项时,我仍然不确定应该选择哪一个来开发我的应用程序框架:SceneKit、RealityKit和Metal。
我已经了解到SceneKit是建立在Metal之上的,但我不确定是否值得花费时间/精力编写任何自定义着色器,而不是使用SceneKit默认提供的功能。关于RealityKit,我不需要它提供的任何动画或特效,只需要照片般逼真的渲染效果。
哪个选项是开发AR和高质量模型渲染最佳的?
1个回答

256

更新日期:2023年12月01日。

简而言之


这篇文章不仅涉及到RealityKit、SceneKit和Metal,还涉及到相关的框架。


RealityKit

enter image description here

RealityKit是苹果渲染技术家族中最年轻的软件开发工具包(SDK)。这个高级框架于2019年发布。它专为增强现实(AR)/ 虚拟现实(VR)项目而设计,具有简化的设置,可实现多用户体验,并可在iOS、visionOS、macOS和tvOS上使用。RealityKit执行多线程渲染、异步加载,并提供网络层以实现状态同步。基于RealityKit引擎,Vision Pro头戴设备支持基于焦点渲染的功能。
没有Objective-C的遗留问题,RealityKit支持Swift和Metal Shading Language,并且具有类似SwiftUI的声明性语法。RealityKit的主要优势在于其能够自定义Reality Composer Pro的场景,对于ARKit来说,它可以是一个强大的补充。在RealityKit中,主要内容是“实体”(ModelEntity、AnchorEntity、TriggerVolume、BodyTrackedEntity、PointLight、SpotLight、DirectionalLight和PerspectiveCamera),它们具有“组件”并且可以从ModelEntity等“资源”创建。在visionOS中,与iOS/macOS相比,有更多的组件。
该框架在CPU上运行实体组件系统(ECS)来管理诸如物理、动画、音频处理和网络同步等任务。但是RK也严重依赖于GPU硬件来执行多线程渲染。RealityKit拥有八种材质:MaterialX(由ILM推出的开放标准)、UnlitMaterial、SimpleMaterial、PortalMaterial、PhysicallyBasedMaterial(具有18个AOV用于控制表面外观)、OcclusionMaterial、VideoMaterial和当然还有CustomMaterial

enter image description here

特别注意iOS上的阴影 - 搭载A9...A11芯片组的设备会产生投影(也称为深度图)阴影,而搭载A12+和M1+芯片组的设备可以渲染光线追踪阴影。也许你的选择可以是虚假阴影。RealityKit中的许多现代渲染功能默认为开启:相机的景深、面部/人物遮挡、地面阴影、动态模糊、相机颗粒等。请注意,保持主CPU线程在16毫秒的时间范围内并不能保证60帧每秒的性能。

enter image description here

RealityKit支持读取.usdz、.rcproject和.reality文件格式。它支持变换和资源动画、刚体动力学、网格描述符、HDR图像基于照明、粒子系统(目前仅在visionOS和tvOS中支持粒子效果)、动画控制器播放、PBR材质、射线投射和空间音频。所有场景模型必须与锚点相连。框架会自动生成和使用一系列逐渐降低分辨率的对象纹理的mipmaps,以提高渲染远处对象时的渲染速度。RealityKit可以与通过Scene Reconstruction功能生成的多边形网格一起使用。我还想补充几句关于AR Quick Look的话 - 它是一个基于RealityKit引擎构建的零配置框架,旨在快速实现AR可视化。
visionOS应用程序的示例代码:
import SwiftUI
import RealityKit

struct ContentView: View {
    var body: some View {
        RealityView { content in
            let model = ModelEntity(mesh: .generateSphere(radius: 0.1))
            model.position.z = -1.0
           
            let anchor = AnchorEntity(.head)
            anchor.anchoring.trackingMode = .continuous
            anchor.addChild(model)
            
            content.add(anchor)
        }
    }
}

结论:RealityKit为您提供了高质量的渲染技术和最新的AR功能,开箱即用。支持LiDAR扫描仪。支持Photogrammetry工具。通过其Notification API播放Reality Composer的行为。RealityKit可以作为独立的框架使用,也可以与ARKit和MetalKit合作。通过Metal脚本和CustomMaterials,可以访问片段/像素着色器几何修改器。Reality系列软件具有CLI和GUI工具,用于快速和简便的USDZ转换。现在RealityKit的应用程序可以在Xcode的visionOS模拟器中运行。
RealityKit与UIKit的storyboards和SwiftUI界面兼容。它最大程度地减少了样板代码的使用。例如,RealityKit提供了非常简单的设置模型碰撞和手势(平移、旋转、缩放),包括2D手势的替代方案。支持跟踪射线投射。此外,它采用了组合优于继承的编程框架,因此在大多数情况下,代码中的紧耦合不再是一个问题。RealityKit与Combine响应式编程范式完美契合,有助于处理发布者、订阅者和异步事件。一个典型的例子是subscribe(to:on:_:)泛型实例方法,它返回一个表示对事件流订阅的对象,比如SceneEvents.Update.self,它在每帧间隔(60 fps)触发一次。
RealityKit的visionOS视图是RealityView和Model3D。
@available(visionOS 1.0, *)
@available(iOS, unavailable)
public struct RealityView<Content> : View where Content : View 

@available(xrOS 1.0, *)
@available(iOS, unavailable)
public struct Model3D<Content> : View where Content : View

RealityKit的iOS/macOS视图是ARView。
@available(OSX 10.15, iOS 13.0, *)
@objc open class ARView : ARViewBase

typealias ARViewBase = NSView            // AppKit view
typealias ARViewBase = UIView            // UIKit view


SceneKit

enter image description here

SceneKit是一个高级框架,也是苹果渲染技术家族中最古老的一个。它于2012年发布。SceneKit最初是为虚拟现实(VR)而设计的,可以在iOS、macOS、tvOS和watchOS上运行。对于增强现实(AR)项目,您只能与ARKit一起使用它。SceneKit支持Objective-C和Swift两种编程语言。在SceneKit中,主要的单位是一个节点(SCNNode类),它有自己的层次结构,并可以存储光源(SCNLight)、相机(SCNCamera)、几何体(SCNGeometry)、粒子系统(SCNParticleSystem)或音频播放器(SCNAudioPlayer)。SceneKit的主要优势在于其高度可定制性,可以在运行时更改几何体和材质,具有变形器(morphers)、蒙皮器(skinner)和约束器(constraints),可以以高达120帧每秒的速度渲染场景。它支持Blinn、Constant、Lambert、Phong、ShadowOnly和PBR着色器。

遮挡着色器在SceneKit中也是可用的,但以自定义形式存在(这里没有像在RealityKit中那样的开箱即用的遮挡材质)。如果您需要在SCNScene中使用视频材质,您应该将一个AVPlayer对象分配给SceneKit的diffuse.contents,或者使用带有SKVideoNode的SpriteKit场景。

enter image description here

SceneKit允许您渲染诸如美丽的深度景深效果、电影晕影效果、屏幕空间反射甚至带有动画参数的CoreImage滤镜等效果。此外,我们还可以使用SCNProgram对象执行自定义渲染-它是一个完整的Metal或OpenGL着色器程序,可以替代SceneKit对材质甚至几何体的渲染。SceneKit的可靠伴侣是一个Model I/O库,它使用共同的基础设施执行导入、导出和模型操作。SceneKit执行单线程渲染(当然是使用辅助线程,而不是主线程)。
iOS应用程序的示例代码:
import SwiftUI
import SceneKit

struct ContentView: View {
    @State private var scene = SCNScene()
    let options: SceneView.Options = [.autoenablesDefaultLighting]
    let sphere = SCNNode(geometry: SCNSphere(radius: 0.1))

    func createSphere() {
        sphere.geometry?.firstMaterial?.diffuse.contents = UIColor.purple
        scene.rootNode.addChildNode(sphere)
    }
    var body: some View {
        SceneView(scene: scene, options: options)
            .ignoresSafeArea()
            .onAppear {
                self.createSphere()
            }
    }
}

SceneKit支持读取多种文件格式,包括.usdz、.dae和.scn。它支持嵌套资源动画、动力学、粒子效果、PBR材质、HDR IBL和空间音频。对于任何节点的隐式和显式变换动画,您可以使用SCNAction、SCNTransaction和CAAnimation类。虽然在SceneKit中设置碰撞有点复杂。为了使用SceneKit创建一个模块化和可扩展的游戏架构,我们需要实现GameplayKit的实体-组件模式。
结论:SceneKit提供了高质量的渲染技术(但首先需要设置物理基于着色器),尽管对于AR项目,您只能与ARKit一起使用它。SceneKit具有高度可定制性,可以与Swift和Objective-C一起使用,并且它提供了一组有用的renderer(...)实例方法,这些方法来自ARSCNViewDelegate协议,允许您以60 fps更新AR模型和跟踪的锚点。它可以与UIKit和SwiftUI一起使用(尽管在Xcode中没有SceneKit+SwiftUI模板)。有明显的原因,苹果可能会在未来2年内将此框架弃用-自2017年以来,SceneKit没有进行更新,除了像clearCoat材质属性、SSR和SwiftUI的SceneView这样的小改动。请注意,在visionOS中,SceneKit内容不是3D的,而是放置在2D窗口中。
         SceneView(scene: SCNScene? = nil,
             pointOfView: SCNNode? = nil,
                 options: SceneView.Options = [],
preferredFramesPerSecond: Int = 60,
        antialiasingMode: SCNAntialiasingMode = .multisampling4X,
                delegate: SCNSceneRendererDelegate? = nil,
               technique: SCNTechnique? = nil)

虽然RealityKit变得越来越成熟,但SceneKit在某些方面仍然优于RealityKit。至少有一件事是Swift开发人员经常忽略的,那就是Objective-C的SceneKit应用程序可以确保更快的编译时间。
SceneKit的视图是SCNView和SceneView。
@available(iOS 8.0, tvOS 9.0, *)
open class SCNView : UIView, SCNSceneRenderer, SCNTechniqueSupport 
 
@available(OSX 10.8, *)
open class SCNView : NSView, SCNSceneRenderer, SCNTechniqueSupport

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
public struct SceneView : View


金属 | MetalKit

enter image description here

准确来说,Metal不是一种渲染技术,而是具有使用丰富着色语言(MSL)能力的GPU加速器。它于2014年发布。Metal是一个低级别的框架。Metal无处不在——RealityKit、SceneKit、ARKit、CoreML、Vision、AVFoundation等等。Metal将类似于已弃用的OpenGL ES和OpenCL的功能结合在一个API下。当然,Metal可以用作先进3D图形的渲染器。Metal不仅可以渲染反射,还可以渲染折射和次表面散射现象。
根据苹果文档:Metal是一种基于C++的编程语言,开发人员可以使用它来编写在GPU上执行的图形和通用数据并行计算的代码。由于Metal基于C++,开发人员会觉得它很熟悉和易于使用。使用Metal,可以使用单一的统一语言编写图形和计算程序,从而实现更紧密的集成。
除了Metal,您还可以使用MetalKit模块(于2015年发布),它可以帮助更快、更轻松地构建Metal应用程序,使用更少的代码。它可以在标准的Metal视图中渲染图形,从多个来源加载纹理,并与Model I/O框架提供的模型高效地工作。
引用: 当您渲染的多边形或3D粒子数量远远超过SceneKit或RealityKit的渲染能力时,Metal开始发挥作用。
当您知道Metal不仅可以在苹果生态系统中使用,还可以在Windows中使用时,您会感到惊讶。这是一个链接,您可以在其中下载Windows版Metal开发工具
示例代码:
import MetalKit
    
class RedCube: Primitive { ... }

class CubeScene: Scene {

    override init(device: MTLDevice) {           
        super.init(device: device)
            
        let redCube = RedCube(withDevice: device)
        objects.append(redCube)
        redCube.translate(direction: float3(0,0,-10))
        add(child: redCube)
    }
    override func render(commandEncoder: MTLRenderCommandEncoder, 
                              deltaTime: Float) {
        objects.forEach { 
            $0.rotate(angle: deltaTime, axis: float3(1, 1,-1)) 
        }
        super.render(commandEncoder: commandEncoder, deltaTime: deltaTime)
    }
}

结论:开发者通常使用Metal框架来生成高质量的GPU渲染,用于具有复杂3D环境的游戏,用于像Final Cut Pro和Nuke这样的视频处理应用程序,用于Maya这样的3D应用程序,或者用于必须进行科学研究的大数据科学应用程序。考虑到,使用Metal进行光线追踪比使用RealityKit更快。
MetalKit的原生视图是MTKView。
@available(iOS 9.0, tvOS 9.0, *)
open class MTKView : UIView, NSCoding, CALayerDelegate

@available(OSX 10.11, *)
open class MTKView : NSView, NSCoding, CALayerDelegate


ARKit

enter image description here

iOS ARKit | 2017
说到RealityKit,不得不提ARKit。iOS RealityKit和iOS ARKit一样,都是基于ARSession和ARConfiguration对象的。iOS ARKit是一个“总框架”,包括了SceneKit、SpriteKit、AVFoundation、Vision、UIKit和CoreMotion的依赖。iOS ARKit支持与SceneKit、RealityKit和Metal相同的4x4变换矩阵。iOS ARKit与NearbyInteraction框架的合作使用户能够使用ARKit的视觉能力获取附近设备的精确位置(可以获取距离、方向和ID),使用U1+芯片。iOS ARKit可以捕捉4K HDR视频。此外,iOS ARKit在地理空间跟踪方面表现出色。由于RealityKit没有ARGeoAnchor的等效物,因此只能与ARKit一起使用。

visionOS ARKit | 2023

visionOS的ARKit与iOS的ARKit基本上是不同的API。visionOS ARKit不再是以前iOS中RealityKit的低级步骤。现在这两个框架相互之间的依赖性较小,您不会经常使用ARKit。visionOS中的ARKit的基本原则仍然相同,但主要对象发生了重大变化 - 现在它们是ARKitSession、DataProvider和六种类型的锚点。不用说,全新的ARKit只能在SwiftUI上运行,并且变得异步和更加自动化。


iOS/visionOS ARKit内部没有渲染引擎。在这两种情况下,该模块只负责高质量的相机/物体跟踪场景理解功能(平面检测、射线投射、场景重建和光照估计)。但除此之外,iOS ARKit还能通过ARFaceGeometry类处理规范面部网格的数据,并通过ARMeshGeometry类管理重建几何体的顶点、法线、三角面和分类
以下是ARKit能够使用的五种视图类型 - ARSCNView、ARSKView、ARView、MTKView和RealityView。
@available(iOS 11.0, *)
open class ARSCNView : SCNView, ARSessionProviding

@available(iOS 11.0, *)
open class ARSKView : SKView, ARSessionProviding

@available(iOS 13.0, *)
@objc open class ARView : ARViewBase

@available(iOS 9.0, *)
open class MTKView : UIView, NSCoding, CALayerDelegate

@available(visionOS 1.0, *)
public struct RealityView<Content> where Content : View

如果您需要更多关于ARKit及其功能的信息,请阅读this post


美元 + 海德拉

enter image description here

Pixar的通用场景描述(Universal Scene Description,简称USD)不仅仅是另一种用于3D图形场景描述的文件格式,它更是一个开放且可扩展的生态系统,用于描述、组合、模拟和协作3D环境。USD文件以基元(或原始对象)的层次结构表示场景,包括场景布局、几何形状、材质、动画、灯光、相机、变换层次等。您可以通过用户界面(如Reality Composer Pro)或者通过Python编程的方式创建USD文件。USD的关键特性是能够组合层,实现非破坏性编辑。
目前,通用场景描述家族中有四个成员:
- USDA(ASCII格式) - USDC和USD(二进制格式) - USDZ(压缩存档格式)
USD的另一个重要特点是它带有Hydra,它是当前场景图和渲染器之间的中间层。换句话说,Hydra是一种针对处理非常大场景进行优化的现代渲染架构。多亏了Hydra,USD文件格式几乎支持任何光线追踪渲染器 - Storm、Metal、Renderman、Vulkan等。也就是说,Hydra实现了多个渲染器和场景图之间的通信。

enter image description here

这是Pixar官方文档关于Hydra的说明:
Hydra是作为USD分发的一部分提供的图像框架。它连接了消费场景数据的场景代理和将场景数据发送到特定渲染器的渲染代理,以使渲染和场景代理可以根据应用程序和消费者的需求进行混合和匹配。

enter image description here

Hydra的首个和主要渲染代理是光栅化的Storm渲染器,它最初是一个现代OpenGL渲染器,现在已经加入了一个“图形接口”抽象层,使Storm能够使用Vulkan、Metal和潜在的任何光栅化渲染API。Storm具有高度可扩展性、多通道渲染,并使用OpenSubdiv进行网格渲染。


SpriteKit

enter image description here

SpriteKit是苹果的基于节点的框架,用于创建和渲染2D游戏和2D图形。它于2013年发布。您可以将SpriteKit作为独立的API使用,也可以与SceneKit和ARKit一起使用。其主要特点是能够使用物理引擎绘制精灵、2D文本和形状、图像和视频,甚至可以对SceneKit场景进行光栅化。在SpriteKit中,您可以使用Objective-C或Swift编写代码。
一个渲染SpriteKit场景的SwiftUI视图对象如下所示:
        SpriteView(scene: SKScene,
              transition: SKTransition? = nil,
                isPaused: Bool = false,
preferredFramesPerSecond: Int = 60,
                 options: SpriteView.Options = [.shouldCullNonVisibleNodes],
            debugOptions: SpriteView.DebugOptions,
            shouldRender: @escaping (TimeInterval) -> Bool = { _ in true } )

官方文档:SpriteKit是一个通用的2D框架,利用Metal实现高性能渲染,同时提供简单的编程接口,使得创建游戏和其他图形密集型应用变得容易。通过丰富的动画和物理行为集合,您可以快速为视觉元素增添生命,并在屏幕之间优雅地过渡。
SpriteKit可以与两种视图类型(UIKit和AppKit)配合使用。同时也有SwiftUI版本。
@available(iOS 7.0, tvOS 9.0, *)
open class SKView : UIView

@available(OSX 10.9, *)
open class SKView : NSView

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
public struct SpriteView : View


房间计划

enter image description here

RoomPlan是建筑师、室内/游戏设计师、房地产经纪人和电子商务代表的魔法棒。由ARKit和RealityKit提供支持,RoomPlan是一个框架,利用iOS设备上的RGB摄像头和LiDAR扫描仪创建一个包括尺寸和物体类型等特征的房间的3D平面图。机器学习算法能够识别墙壁、窗户、门、楼梯、家电、家具和水暖设备。
框架的屏幕指导说明如何移动设备来捕捉室内环境。扫描完成后,视图会显示一个缩小版的扫描房间供用户确认。RoomPlan输出一个参数化的USDZ模型作为结果,这使得在3D软件中修改扫描房间的各个组件变得容易。
RoomPlan使用RealityKit的ARView,并具有自己的视图。
@available(OSX 10.15, iOS 13.0, *)
@objc open class ARView : ARViewBase

@available(iOS 16.0, *)
@objc class RoomCaptureView : UIView


AR快速查看

enter image description here

AR Quick Look是一个零配置的框架,它使用RealityKit的渲染引擎和ARKit的强大处理能力来锚定模型并显示增强现实体验。iOS和iPadOS内置的应用程序,如Safari、Mail或Notes,使用AR Quick Look来显示带有动画、空间音效、接触阴影和PBR材质的.reality和.usdz模型。如果您的设备配备了LiDAR扫描仪,AR QL应用程序将使用它来加速平面检测、射线投射和人体遮挡的ZDepth感知等重要功能。
与RealityKit不同,AR Quick Look会自动播放存在的动画。它还具有额外的"levitation"手势、完全集成的Apple Pay、拍照界面按钮、分享界面按钮、切换AR/VR模式按钮和关闭视图按钮。
您可以使用HTML 5的rel="ar"属性将AR Quick Look视图嵌入到您的移动网站版本中。
<html>
    <body>
        <div>
            <a href="/folder/character.usdz" rel="ar">
                <img src="/folder/char-image.jpg">
            </a>
        </div>
    </body>
</html>

要在您的iOS应用程序中使用它,您需要一个QLPreviewController的实例和QLPreviewItem
AR QuickLook的本地视图控制器。
@available(iOS 13.0, *)
class QLPreviewController : UIViewController

3
非常感谢你详细的回答,Andy。 - Acammm
2
@PeterPohlmann,看起来在SceneKit中可以使用一些LiDAR相关的东西。例如,您可以使用arSceneView.session.run(configuration),其中configuration是类型为ARWorldTrackingConfiguration的配置,该配置可以设置configuration.sceneReconstruction = .meshWithClassification - grantespo
3
您可以放弃使用SceneKit了。由于RealityKit提供了一个非增强现实(.nonAR)模式,因此它将成为其替代品。SceneKit是单线程的,而RealityKit是多线程的。我几天前才了解到.nonAR模式。 - Darkwonder
2
@AndyJazz 很精彩的摘要 -- 那你对 2023+ 的更新有什么看法? - mobibob
1
@mobibob,我认为它可能会叫做xrOS(现实操作系统)。 - Andy Jazz
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接