首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CATextLayer未在SCNNode上正确呈现

CATextLayer未在SCNNode上正确呈现
EN

Stack Overflow用户
提问于 2018-11-21 01:08:55
回答 2查看 237关注 0票数 0

我有一个CALayers的层次结构,我将其设置为SCNNode材料的扩散属性。我使用以下代码将场景的当前状态(只有一个节点)快照为PNG保存到文件中:

代码语言:javascript
复制
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%的时间,任何CATextLayer作为在self.createLayer()中返回的层的子层,都不会呈现文本。所有其他层似乎每一次都呈现得很好。

例如,应该是这样的图像:

最后忽略了文本"N":

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

这似乎只是在创建层之后立即发生的问题。如果我异步地分派呈现代码,即使没有添加任何延迟,所有呈现都会如预期的那样:

代码语言:javascript
复制
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)
}

上面的解决办法似乎很麻烦,我不相信它是可靠的。此外,我不希望强制我的调用站点以异步方式调用该方法。

在SceneKit或CoreAnimation中是否有我缺少的属性或方法,在尝试将其呈现到图像之前,可以使用该属性或方法确保该层被完全呈现?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-21 02:15:34

我可以理解,使用DispatchMain是不可靠的,因为您不能确定节点是否呈现得很好。所以有一个函数告诉你渲染是否已经完成。调用完成句柄内的快照。

代码语言:javascript
复制
 scene.rootNode.addChildNode(node)
    node.geometry?.firstMaterial?.diffuse.contents = self.createLayer() // CALayer

    let renderer = SCNRenderer(
        device: MTLCreateSystemDefaultDevice(),
        options: nil)

----renderer.prepare([node]) { (success) in  // this line is useful
        if (success){
            let renderTime = CACurrentMediaTime() + 1
            let size = CGSize(width: 600, height: 600)
            let  image = renderer.snapshot(
                atTime: renderTime,
                with: size,
                antialiasingMode: .multisampling4X)
            complete(image)
        }
    }

如果您认为加载时间太长,可以向数组中添加其他节点。

票数 1
EN

Stack Overflow用户

发布于 2018-12-05 22:36:40

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53403913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档