微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – 将屏幕外SCNScene呈现为UIImage

如何渲染屏幕外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
    }   
})

然而,使用CAdisplayLink可能是更好的解决方案.

这是一个非常快速和肮脏的implementation example.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐