SceneKit Cocoa添加贴花

时间:2016-12-01 14:53:11

标签: objective-c swift cocoa scenekit

是否有足够的方法将贴花(纹理)添加到SCNNode? 现在,我所能做的就是创建具有SCNNode几何体的新SCNPlane 为其分配纹理的漫反射内容并将其添加到场景中...... 这种方法非常低效。

我想添加一个不会成为场景一部分的贴花 - 以提高游戏性能。 因为我想在地板节点上有相对大量的贴花。

可能有点类似于粒子内部如何工作? 或者其他一些快速图像绘制方法。

我已经尝试过@ rickster的建议编号1

  

使用SKEffectNode作为SpriteKit场景中的缓冲区 - 抛出泼溅物   到一个效果节点,直到它到达一定数量的孩子,   然后打开它的shouldRasterize选项,这样它就不会重新渲染   它的孩子了(并开始使用新的效果节点更多   溅出)。

在完全相同的SceneKit showreel项目中 - 仅此一项已经取得了不错的效果,FPS并没有因为继续播放好的场景而花费5分钟。

期待实施建议#2 - 我相信它会缩短2D场景渲染时间(现在这是一个非常大的问题)。

在此屏幕截图中有5k贴花

5k

1 个答案:

答案 0 :(得分:2)

我建议使用SpriteKit场景作为“喷溅”几何体的材质。 Apple有sample code,它说明了你在这里要做的很多事情:

  1. 制作一个SpriteKit场景,它是SceneKit几何体的材质。
  2. 当3D世界中的某些东西需要制作一个飞溅时,使用命中测试来查找材质中的纹理坐标并将它们转换为SpriteKit场景坐标。
  3. 将精灵放在该位置的SpriteKit场景中以创建贴花。
  4. 根据你的other question判断,你似乎已经开始朝着这个方向前进了......如果你解决了更多的问题,也许你会得到更好的帮助?

    注意:该示例代码在iOS 9 / macOS 10.11及更高版本上有一个错误,它会干扰飞溅效果。你可以通过在AAPLGameViewController.m中找到这一行来解决这个问题:

        ball.physicsBody.collisionBitMask = ~(0x4);
    

    并在其后添加以下行:

        ball.physicsBody.contactTestBitMask = ~(0x4);
    

    你可能会在那个演示中注意到,在一段时间之后,你的帧速率开始下降 - SpriteKit场景中越来越多的精灵使2D渲染越来越多地占用渲染循环。

    enter image description here (也许这是提示您other question的问题?)

    但是,即使没有“截屏”纹理的能力,也有一些方法可以针对这种情况进行优化。一些想要调查的想法:

    1. 使用SKEffectNode作为SpriteKit场景中的缓冲区 - 将泼溅投射到效果节点,直到它到达一定数量的子节点,然后打开其shouldRasterize选项,这样它就不会不再重新渲染它的子节点(并开始使用新的效果节点进行更多的泼溅)。

    2. 很多2D时间都浪费了绘制SK精灵,因为它们被埋在其他精灵之下而不可见。 (或者大多数都是埋藏的,并且只有几个像素可见。)因为你的,嗯,“绘画”是完全相同的颜色,你可以使用一些简单的方法将你的SpriteKit场景分成几个区域并决定一个区域是什么时候完全覆盖 - 此时,您可以从该区域删除所有精灵,用一个“全覆盖”精灵替换它们,并停止在该区域添加新的精灵。 quadtree可能是一个很好用的工具。

    3. 如果您想通过着色器修改器而不是使用基于SpriteKit的材质进行自定义绘制,那么SceneKit对纹理坐标映射技巧的命中测试也可以正常工作,您可能能够找到更有效的方法那里的长期覆盖跟踪(可能是#3中的一些技巧)。

    4. 如果您的飞溅不常发生,您可以在CPU上渲染它们,只需在材质上设置一个新图像。

    5. 一个想法的远景,不知道它是否有效或高效:使用Core Image as an accumulation buffer绘制泼溅物,并将其渲染到材料内容为的MTLTexture内调成。 (使用SceneKit的willRenderScene回调每帧渲染一次。)