Ios 穿过物体前方时的Spritekit剪影效果

Ios 穿过物体前方时的Spritekit剪影效果,ios,sprite-kit,skspritenode,Ios,Sprite Kit,Skspritenode,我正在制作一个精灵套件游戏,我试图在物体经过特定物体(在本例中为红色太阳)前时创建一个特定的轮廓照明效果。我希望它前面的任何东西都显示为黑色,其他所有东西都显示为正常(因此,如果某个对象部分位于前面,则只有该部分应该为黑色)。 但我不知道如何有效地做到这一点。我尝试过使用不同的SKBlendModes,但到目前为止还没有太大的成功。主要的挑战似乎是在保持背后太阳颜色的同时实现这种效果 我不确定是否可以用现有的SKBlendModes实现这一点,或者是否需要其他东西 我附上了一张图表来说明我要做什

我正在制作一个精灵套件游戏,我试图在物体经过特定物体(在本例中为红色太阳)前时创建一个特定的轮廓照明效果。我希望它前面的任何东西都显示为黑色,其他所有东西都显示为正常(因此,如果某个对象部分位于前面,则只有该部分应该为黑色)。 但我不知道如何有效地做到这一点。我尝试过使用不同的SKBlendModes,但到目前为止还没有太大的成功。主要的挑战似乎是在保持背后太阳颜色的同时实现这种效果

我不确定是否可以用现有的SKBlendModes实现这一点,或者是否需要其他东西

我附上了一张图表来说明我要做什么,以及当前最适合的图片


我对这个问题很感兴趣,所以我想出了一个简单的解决办法。它既不完美,也不能很好地扩展,但我相信基础满足了你的需要,它可能会为其他人指明正确的方向

我不使用任何特殊的SKBlendMode。相反,我使用了一个复制对象来表示在太阳前面移动的对象。此重复对象使用SKCropNode进行裁剪,该SKCropNode将太阳的副本作为遮罩。因此,我的节点树如下所示:

  • 太阳(白日)
  • SKSpriteNode(
    object1
    )(旋转的紫色正方形,alpha为0.25)
  • SKCropNode
    • maskNode:SKSpriteNode(
      sunDuplicate=[sun copy]
    • SKSpriteNode(
      object1副本
      ,与
      object1
      大小相同,但带有
      [SKColor blackColor]
在更新方法中,将副本与原始副本对齐,以确保动画正确转发

- (void)update:(CFTimeInterval)currentTime {
  self.object1duplicate.position = self.object1.position;
  self.object1duplicate.zRotation = self.object1.zRotation;
}
正如我所说,这不能很好地缩放,因为您必须手动添加重复的对象,并为在太阳对象前面移动的每个对象跟踪它们。也许可以更优雅地使用


您可以使用
SKCropNode
、遮罩节点和背景节点创建轮廓效果。
SKCropNode
在其节点树中选择性地屏蔽精灵节点的像素。在这里,它将通过隐藏/显示黑色圆圈的部分来提供轮廓效果

首先,创建以下对象:

  • 形状节点(黄色圆圈),其
    zPosition
    设置为-1
  • 与黄色节点大小相同的精灵节点(黑色圆圈)
  • 裁剪节点(
    SKCropNode
    )和掩码节点(
    SKNode
  • 其次,

  • 在场景中心添加黄色圆圈
  • 将黑色精灵添加为裁剪节点的子节点
  • 将遮罩节点指定给裁剪节点的
    maskNode
    属性
  • 在场景中心添加裁剪节点
  • 由于遮罩节点当前没有子节点,因此黑色圆圈将完全隐藏,其下方的整个黄色圆圈将可见。当我们将精灵添加到遮罩节点时,与精灵相交的黑色圆圈的像素将被取消遮罩(以黑色显示),从而产生轮廓效果

    剩下的就是添加一个“演示”节点,当遮罩节点的精灵位于黑圈之外时,该节点将显示。演示节点将镜像遮罩节点的精灵的位置和旋转。这应该在
    didSimulatePhysics
    中完成,以确保在物理和动作更新后演示和遮罩节点精灵同步

    但是,等等……如果表示节点移动到黄色圆圈上,它不会遮住太阳吗?如果我们将其表示节点的
    zPosition
    设置为-2,则不会

    以下显示了上述功能的实现:


    您是用Swift还是Obj-C编码?我可能有办法解决这个问题。这会有所不同吗?非常感谢你的回答。我肯定不能对所有对象都这样做(我们已经在限制我们可以拥有多少精灵),但我们至少可以对某些关键对象这样做。我以前做过一些核心OpenGL,所以对片段着色器的工作原理有一个模糊的概念,我不确定的是如何访问那里像素的颜色(比如说它是在太阳前面复制的片段着色器,如果像素不是太阳颜色,则将其绘制为黑色,否则,将其绘制为太阳颜色)。基本上,我想要的信息与SKBlendMode使用的信息相同。遮罩节点不是正方形的副本吗?太阳的副本是裁剪节点的子节点吗?@0x141E当然可以,它会导致渲染相同的形状。但是如果你想对正方形进行纹理处理(如OP的屏幕截图),你必须裁剪
    object1duplicate
    ,而不是
    sundupplicate
    。我不确定最好的地方在哪里,但我研究了skshader,并使用了我自己的片段着色器。在缺少可编程混合模式或顶点着色器的情况下,似乎没有特别好的方法使用SKSHADER来实现这一点。非常感谢您的响应,我对你们付出的努力感到惊讶。我不确定SKCropNode在内部是如何工作的,这个可伸缩性好吗?(假设我们有700个精灵,几乎没有进展,所有精灵都需要有maskNode的子项的副本)当我在iPhone 6上添加250个节点对到场景中时,我看到了60 fps。我建议你1)尽可能重复使用纹理,2)只有当精灵靠近太阳时才将节点添加到遮罩中,3)当精灵离开屏幕时将其移除