为什么SCNNode .flattenedClone()崩溃或使性能变差? [英] Why does SCNNode .flattenedClone() either crash or make performance worse?
问题描述
我正在尝试向场景中添加约4.5k个SCNNode
对象.它们的几何形状是两个SCNPlane
之一,其材质由CALayer
s渲染(但我认为这并不重要,每个CALayerDelegate
都只被调用一次,因此似乎不是问题.)性能太差了(<1fps.)
I'm attempting to add around 4.5k SCNNode
objects to a scene. Their geometries are one of two SCNPlane
s, whose materials are rendered by CALayer
s (but I don't think that matters, the CALayerDelegate
s are only called once each, so that doesn't seem to be an issue.) Performance is terrible (< 1fps.)
启用.showsStatistics
时,我看到我正在进行近3.5k绘图调用,根据
With .showsStatistics
enabled I see I'm doing almost 3.5k draw calls, which is my problem according to this WWDC video from 2017. So, as suggested, I add all my nodes to one parent node and call .flattenedClone()
on it before adding that to the scene's root node. That gets me graphical corruption and a repeating error on my console:
2019-08-28 14:50:39.122937+0200 Breadboard[867:53252] [SceneKit] Error: C3DProgramHashCodeStoreRegisterProgramForRendererElement - index out of capacity (8192 > 8192)
("x> 8192"中的x每行增加一个)
(The x in "x > 8192" goes up by one every line)
如果我将节点分成两组,然后在将结果添加到根节点之前调用它们的.flattenedClone()
,错误就会消失,但是我的绘制调用计数上升接近5k!
If I split the nodes into two groups and call .flattenedClone()
on them before adding the results to the root node the error goes away but my draw call count goes up to almost 5k!
这是怎么回事?为什么在具有约2.5k个节点的节点上调用.flattenedClone()
不能将其扁平化?
What's going on? Why does calling .flattenedClone()
on a node with around 2.5k nodes not... flatten it?
推荐答案
问题 did 原来是CALayer
,但这很微妙:如果我改为将CALayer
渲染为UIImage
(实际上我全部作为UIGraphicsBeginImageContextWithOptions(...)
来做,不需要显式的CALayer
),.flattenedClone()
确实可以完成我期望的操作,并且在任意数量的单元格下我都接近60fps .如果将CALayer
直接附加到材质,则节点不会展平.
The problem did turn out to be the CALayer
s, but it's subtle: if I instead render the CALayer
into a UIImage
(actually I do it all as a UIGraphicsBeginImageContextWithOptions(...)
, there's no need for an explicit CALayer
), .flattenedClone()
does indeed do what I expect it to do and I get close to 60fps with any number of cells. If I attach the CALayer
directly to the material, the nodes don't flatten.
也许与CALayer
是可动画的事实有关吗?无论如何,使用静态UIImage
都可以. 此问题通过提及一些自动展平的情况为我提供了提示,甚至在您调用它的情况下也根本不会发生.
Maybe it's something to do with the fact a CALayer
is animatable? In any case, with static UIImage
it works. This question gave me the hint by mentioning some cases where flattening is automatic, and some where it doesn't happen at all even if you invoke it.
这篇关于为什么SCNNode .flattenedClone()崩溃或使性能变差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!