SCNLevelOfDetails委托/通知 [英] SCNLevelOfDetails delegate/notification

查看:102
本文介绍了SCNLevelOfDetails委托/通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将SCNLevelOfDetails与SceneKit一起使用.

I'm using SCNLevelOfDetails with SceneKit.

我想知道是否有一种方法可以知道引擎何时更改特定节点的几何图形的levelOfDetails.

I was wondering if there's a way to know when the engine changes the levelOfDetails for a particular node's geometry.

非常感谢.

推荐答案

我正在回答自己的问题.为了提供更多的上下文,我们需要知道LOD何时会更改以停止空闲动画,我们会对模型进行了外观设置. 如果在LOD更改时不禁用此动画,会发生以下情况,即地理遍历整个地方,而且看起来不对.

I'm answering my own question. To give more context, we needed to know when the LOD would change in order to stop an idle animation, our model is skinned. What happens if you don't disable this animation when the LOD changes is that the geo goes all over the place and it looks wrong.

对我们来说,解决方案是克隆渲染的节点地理区域,使用此地理区域克隆创建一个节点,并为其提供不同的LOD(在距离较远时),然后将该节点添加到层次结构中.这样,节点不受关节和动画的影响.我们将此节点称为lowLODNode.

The solution for us was to clone the rendered node geo, create a node using this geo clone and give it our different LOD for when it's far, add this node to the hierarchy. This way the node is not affected by the joints and the animation. We call this node lowLODNode.

您渲染的节点的LOD为零时,它的LOD为零,所以消失了,lowLODNode踢了进来.请注意,当lowLODNode关闭时,其LOD为零.

Your rendered node will have LOD of nil when it's too far so it disappear and the lowLODNode kicks in. Note the the lowLODNode has a LOD of nil when it's close.

要禁用动画,我们使用渲染器循环来计算距POV的距离,并在达到LOD阈值时将其禁用.请注意,我们每0.25秒对1000个以上的节点进行迭代,这要归功于simd库,该计算平均仅需要0.0016秒.

To disable the animation we use the renderer loop to compute distance from POV and disable it if the LOD threshold is reached. Note that we are iterating through more than a 1000 nodes every 0.25 seconds, this calculation only takes 0.0016 second in average thanks to the simd library.

我要添加一个代码示例来展示该技术:

I'm adding a code example to show off the technique:

private func setupLOD() {
    // Keep animation and LOD working with a rigged node.
    // Scene graph
    // YourNodeSubclass
    //  - loadedDAENode
    //      - rigNode
    //      - geoGroupNode
    //          - geoNode -> this one has a SCNGeometry, empty geo when far LOD = [ geoNode.geo, nil ]
    //      - lowLODNode -> this one has the low poly versions and an empty geo when close LOD = [ nil, lowPoly1, lowPoly2, ... ]

    // LOD for the geometry affected by the rig. The geo disappear when far enough. Animations are working.
    let lowLevelMain = SCNLevelOfDetail(geometry: nil, worldSpaceDistance: 3.0)
    renderedNode.childNode(withName: "\(renderedNodeName)_geo", recursively: true)?.geometry?.levelsOfDetail = [lowLevelMain]

    // 1) Load low poly geo and eventual LOD geos from folder(s).
    // 2) Copy each LOD geo.
    // 3) Create a geo, make it transparent. This will be the high LOD geo the default one.
    // 4) Create a lowLODNode using this geo.
    // 5) Ceate your [LOD]
    // 6) Assign LOD to lowLODNode geometry
    // 7) Add the lowLODNode as a child to the rendered node

    // 1) 2)
    if let lowVersionScene = SCNScene(named: "art.scnassets/yourScene.dae"), let itemNode = lowVersionScene.rootNode.childNode(withName: "rootNodeName", recursively: false), let geo = itemNode.childNode(withName: "nodeWithGeo", recursively: true)?.geometry?.copy() as? SCNGeometry {
        // 3)
        let tranparentCube = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.0)
        tranparentCube.firstMaterial?.diffuse.contents = UIColor.clear
        // 4)
        let lowLODNode = SCNNode(geometry: tranparentCube)
        // 5)
        let lowLOD = SCNLevelOfDetail(geometry: geo, worldSpaceDistance: 3.0)
        // 6)
        lowLODNode?.levelsOfDetail = [lowLOD]
        // 7)
        renderedNode.addChildNode(lowLODNode)
    }
}

唯一的缺点是我们必须根据距离而不是像素大小来使用LOD,因为我们需要知道何时禁用动画并且不想以像素为单位来计算对象的大小.

The only downside to this is that we have to use LOD based on distance NOT pixel size because we need to know when to disable the animation and don't want to compute the size of the object in pixels.

使用这种技术,我们能够真正降低CPU和GPU的使用率.

We were able to really lower the CPU and GPU usage using this technique.

这篇关于SCNLevelOfDetails委托/通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆