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。
我的场景中有以下节点设置: 具有子节点的容器节点: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。