SceneKit - 在 SCNNode 上应用 CIFilter 隐藏 SCNTorus

SceneKit – Applied CIFilter on SCNNode hides SCNTorus

我的场景中有以下节点设置: 具有子节点的容器节点:earth、torus 和 moon。我向地球节点的过滤器 属性 应用了以下带有 CIBloom 和 CISourceOverCompositing 过滤器的自定义 HighlightFilter 以获得发光效果:

CIFilter Class(来自很棒的博客的代码:Highlighting SCNNode with Glow

class HighlightFilter: CIFilter {

static let filterName = "highlightFilter"

@objc dynamic var inputImage: CIImage?
@objc dynamic var inputIntensity: NSNumber?
@objc dynamic var inputRadius: NSNumber?

override var outputImage: CIImage? {
    guard let inputImage = inputImage else {
        return nil
    }

    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(inputImage, forKey: kCIInputImageKey)
    bloomFilter.setValue(inputIntensity, forKey: "inputIntensity")
    bloomFilter.setValue(inputRadius, forKey: "inputRadius")

    let sourceOverCompositing = CIFilter(name:"CISourceOverCompositing")!
    sourceOverCompositing.setValue(inputImage, forKey: "inputImage")
    sourceOverCompositing.setValue(bloomFilter.outputImage, forKey: "inputBackgroundImage")

    return sourceOverCompositing.outputImage
}}

我不明白这个看不见的矩形。我认为这是因为 CIFilter SourceOverCompositing 将修改后的图像覆盖在原始图像上。但为什么环面是隐藏的而月亮不是? 我将圆环 material 添加到卫星中。 material属性,看看是不是material有问题。但还是一样,月亮是可见的,环面是隐藏的。月亮以 helperNode 作为 containerNode 的子节点旋转。

这可能是由于两个潜在的问题。

解决方案 1.

当您使用 CISourceOverCompositing 时,您需要一个预乘 RGBA 图像 (RGB * A) 作为前景,其中一个 alpha 通道具有 与地球相同的形状 (左图)。但是你有一个覆盖所有图像的 alpha 通道(右图)。

如果您想知道地球图像中 Alpha 通道的形状 – 使用以下合成应用程序之一:Foundry Nuke、Adobe After Effect、Apple Motion、Blackmagic Fusion 等。

此外,如果您想分别合成月球和地球,则必须将它们作为两个不同的图像。

在合成经典OVER运算中有如下公式:

(RGB_image1 * A_image1) + (RGB_image2 * (1 – A_image1))

这个公式的第一部分是预乘前景图像(地球)- RGB1 * A1。

这个公式的第二部分是一个有洞的背景图片 – RGB2 * inverted_A1。您已经使用 (1-A) 反转了 alpha 通道。背景图像本身只能有三个分量——RGB(没有 A)。

然后使用简单的加法运算将两个图像相加。如果您有多个 OVER 操作 – 这些操作的顺序至关重要。

解决方案 2.

这可能是由于 Depth Buffer。禁用 writesToDepthBuffer 个实例 属性。是一个布尔值,决定SceneKit在渲染material.

时是否产生深度信息
yourTorusNode.geometry?.materials.first?.writesToDepthBuffer = false

希望这对您有所帮助。

我不知道为什么会出现这种奇怪的行为,但删除以下行使其消失。

self.torus.firstMaterial?.writesToDepthBuffer = false

圆环 material 上的 writesToDepthBuffer 属性 设置为 false。