如何渲染屏幕外SCNScene到UI
Image?
我知道SCNView提供了一个-snapshot方法,但不幸的是,这对于屏幕外视图不起作用.之前已经问过一个similar question,其中一个答案建议使用glreadPixels从OpenGL读取位图数据,但这种方法对我的离屏场景不起作用.
我尝试使用SCNRenderer渲染到GLKView的上下文中但没有成功.
解决方法
Swift 4与SCNRenderer:
您可以使用SCNRenderer的快照方法将屏幕外的SCNScene很容易地渲染为UIImage.
这里有一些警告,这使用金属.我不知道设备/ iOS版本的截止位置,但你需要一个更新的设备.您也将无法在模拟器上运行它.
第1步 – 像往常一样设置场景:
// Set up your scene which won't be displayed let hiddenScene = SCNScene() [insert code to set up your nodes,cameras,and lights here]
第2步 – 设置SCNRenderer – 渲染器将在模拟器上为零:
// Set up the renderer -- this returns nil on simulator let renderer = SCNRenderer(device: MTLCreateSystemDefaultDevice(),options: nil) renderer!.scene = hiddenScene
第3步 – 渲染场景到UIImage:
// You can use zero for renderTime unless you are using animations,// in which case,renderTime should be the current scene time. let renderTime = TimeInterval(0) // Output size let size = CGSize(width:300,height: 150) // Render the image let image = renderer!.snapshot(atTime: renderTime,with: size,antialiasingMode: SCNAntialiasingMode.multisampling4X)
如果您正在运行动画,则需要增加renderTime或将其设置为要渲染的时间索引.例如,如果要将帧渲染到场景中4秒,则将其设置为4.这仅影响动画 – 它不会回溯到时间并显示场景的历史视图.
例如,如果您运行的是使用SCNNode.runAction运行动画,您可能希望每隔60秒(0.16667秒)继续递增renderTime,这样无论何时您决定渲染,您都有一个更新的renderTime:
var timer : Timer var renderTime = TimeInterval(0) timer = Timer.scheduledTimer(withTimeInterval: 0.016667,repeats: true,block: { (t) in self?.renderTime += 0.016667 } })
这是一个非常快速和肮脏的implementation example.