CATextLayer无法在SCNNode

时间:2018-11-21 01:08:56

标签: ios core-animation scenekit catextlayer scnscene

我有一个CALayers层次结构,我将其设置为SCNNode材质的漫反射属性。我使用以下代码拍摄场景的当前状态(只有一个节点)的快照,并将其另存为PNG文件:

scene.rootNode.addChildNode(node)
node.geometry?.firstMaterial?.diffuse.contents = self.createLayer() // CALayer

// Set transform of node.

let renderTime = CACurrentMediaTime() + 1
let size = CGSize(width: 600, height: 600)

let renderer = SCNRenderer(
  device: MTLCreateSystemDefaultDevice(),
  options: nil) 
let image = self.renderer.snapshot(
  atTime: renderTime,
  with: size,
  antialiasingMode: .multisampling4X)

return image

这通常可以正常工作,按预期方式渲染节点,但是大约有25-50%的时间,我作为self.createLayer()中返回的图层的子层拥有的任何CATextLayer均不会渲染文本。其他所有层似乎每次都可以很好地渲染。

例如,一张看起来像这样的图像:

correct

最终缺少文本“ N”: incorrect

该图层本身正在呈现,我可以通过更改文本图层的背景色来确认:

enter image description here

这似乎只是在创建图层后立即发生的问题。如果我以异步方式调度渲染代码,即使没有增加任何延迟,所有内容也会按预期渲染:

scene.rootNode.addChildNode(node)
node.geometry?.firstMaterial?.diffuse.contents = self.createLayer() // CALayer
// Set transform of node.
let renderTime = CACurrentMediaTime() + 1

let size = CGSize(width: 600, height: 600)
DispatchQueue.main.async {
  let image = self.renderer.snapshot(
    atTime: renderTime,
    with: size,
    antialiasingMode: .multisampling4X)

  completion(image)
}

上述解决方法似乎很hacky,我不相信它是可靠的。另外,我不想强​​迫自己的呼叫站点以异步方式调用该方法。

SceneKit或CoreAnimation中是否缺少我可以用来确保在尝试将其渲染为图像之前完全渲染该图层的属性或方法?

2 个答案:

答案 0 :(得分:1)

我知道使用DispatchMain是不可靠的,因为您不确定节点的渲染效果是否良好。因此,有一个函数告诉您渲染是否完成。在该完成句柄中调用快照。

{{1}}

如果认为加载时间太长,可以将其他节点添加到阵列中。

答案 1 :(得分:0)

通过在调用sceneView.snapshot()之前调用SCNTransaction.flush(),我已经成功制作了PNG快照。