SceneKit –在SCNNode上应用的CIFilter隐藏了SCNTorus

时间:2018-11-03 17:45:36

标签: swift rotation scenekit cifilter scnsphere

我在场景中设置了以下节点: 具有子节点的容器节点:地球,圆环和月亮。我将下面的自定义HighlightFilter与CIBloom和CISourceOverCompositing滤镜应用于了地球节点的滤镜属性,以实现发光效果:

CIFilter类(真棒博客中的代码: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将修改后的图像覆盖在原始图像上。但是为什么隐藏了圆环而没有月亮呢? 我将圆环材料添加到了卫星上。材料属性,以查看材料是否有问题。但是还是一样,月亮是可见的,圆环是隐藏的。月亮与作为容器节点的子节点的helperNode一起旋转。

Moon is in visible, but torus not Torus is not visible behind this omninius rectangle

Scenegraph enter image description here

2 个答案:

答案 0 :(得分:2)

可能由于两个潜在的问题而发生。

解决方案1 ​​

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

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

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

enter image description here

在合成经典OVER操作时,具有以下公式:

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

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

此公式的第二部分是带有孔的背景图像-RGB2 *倒_A1。您已经使用(1-A)反转了Alpha通道。背景图像本身只能包含三个分量– RGB(不带A)。

然后使用简单的加法操作将两个图像加在一起。如果您有多个OVER操作-这些操作的顺序至关重要。

enter image description here

解决方案2

可能是由于Depth Buffer引起的。禁用writesToDepthBuffer实例属性。它是一个布尔值,用于确定在渲染材质时SceneKit是否生成深度信息。

yourTorusNode.geometry?.materials.first?.writesToDepthBuffer = false

enter image description here

希望这会有所帮助。

答案 1 :(得分:1)

我不知道为什么会发生这种奇怪的行为,但是删除以下行会使它消失。

self.torus.firstMaterial?.writesToDepthBuffer = false

将圆环上材质上的writesToDepthBuffer属性设置为false。