我有一个分配了着色器的SceneKit平面:
let scnNode = SCNNode()
let geom_plane = SCNPlane(width: 10.0, height: 10.0)
scnNode.geometry = geom_plane
已为该几何图形指定了基于着色器的材质。
我创建一个CIFilter并应用它:
let bloomFilter = CIFilter(name:"CIBloom")!
bloomFilter.setValue(10.0, forKey: "inputIntensity")
bloomFilter.setValue(4.0, forKey: "inputRadius")
scnNode.filters = [bloomFilter]
这将导致几何体上基于着色器的材质如期绽放。请注意,从未指定inputImage,而且滤镜似乎自动知道要使用着色器的内容。
现在,我想用自己的Metal Kernel Custom着色器替换此滤镜。到目前为止,我发现的唯一“自定义金属内核”过滤器帮助描述了如何制作这样的过滤器:
import CoreImage
class ScreenBloomFilter: CIFilter {
private let kernel: CIColorKernel
var inputImage: CIImage?
override init() {
let url = Bundle.main.url(forResource: "default", withExtension: "metallib")!
let data = try! Data(contentsOf: url)
kernel = try! CIColorKernel(functionName: "myColor", fromMetalLibraryData: data)
super.init()
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func outputImage() -> CIImage? {
guard let inputImage = inputImage else { return nil }
return kernel.apply(extent: inputImage.extent, arguments: [inputImage])
}
}
我使用此过滤器代替旧的Bloom过滤器:
scnNode.filters = [ScreenBloomFilter()]
但这会导致基于shder的材质为空白。这显然是由于没有指定inputImage且过滤器返回nil的事实。我的问题是;
>如何使我的新金属内核滤镜像原始滤镜那样工作,因为它不需要指定显式的inputImage并自动知道可以在材质的着色器上工作?