【问题标题】:CIFilter can't be applied to SCNMaterial [duplicate]CIFilter 不能应用于 SCNMaterial [重复]
【发布时间】:2020-12-13 18:10:56
【问题描述】:

任何CIFilter 在应用于 UIImageView 时都能正常工作。

import UIKit
import CoreImage

@IBOutlet var imageView: UIImageView!
let ciBlurFilter = CIFilter(name: "CIGaussianBlur")!


func gaussianBlur() -> UIImage? {        
    let uiImage = UIImage(named: "texture.png")!
    let ciImage = CIImage(image: uiImage)
    ciBlurFilter.setValue(ciImage, forKey: "inputImage")
    let resultedImage = ciBlurFilter.value(forKey: "outputImage") as! CIImage
    let blurredImage = UIImage(ciImage: resultedImage)
    return blurredImage
}

override func viewDidLoad() {
    super.viewDidLoad()        
    imageView.image = self.gaussianBlur()
}

但是如果应用到SceneKit的材质上就不行了:

import SceneKit

@IBOutlet var sceneView: SCNView!
let ciBlurFilter = CIFilter(name: "CIGaussianBlur")!


func gaussianBlur() -> UIImage? {        
    let uiImage = UIImage(named: "texture.png")!
    let ciImage = CIImage(image: uiImage)
    ciBlurFilter.setValue(ciImage, forKey: "inputImage")
    let resultedImage = ciBlurFilter.value(forKey: "outputImage") as! CIImage
    let blurredImage = UIImage(ciImage: resultedImage)
    return blurredImage
}

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.scene = SCNScene()       
    let sphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
    sphereNode.geometry?.firstMaterial?.diffuse.contents = self.gaussianBlur()
    sceneView.scene?.rootNode.addChildNode(sphereNode)
}

为什么带有 CIFilter 的 SCNMaterial 是不可见的(尽管它支持 UIImages)?

怎么了?

【问题讨论】:

    标签: swift uikit scenekit core-image cifilter


    【解决方案1】:

    您使用该构造函数创建的UIImage 在那一刻实际上并未呈现。图片的接收者需要知道图片在使用前需要渲染,这个貌似不是SceneKit处理的。

    详情请看我的回答here

    这是在 Swift 中渲染 CIImage 的方法:

    // ideally you create this once and re-use it;
    // you should not create a new context for every draw call
    let ciContext = CIContext()
    
    let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
    let uiImage = cgImage.flatMap({ UIImage.init(cgImage: $0) })
    

    您可以将CGImage 传递给材料或将其包装成UIImage,两者都应该工作。

    【讨论】:

    • 嗨@Frank,谢谢你的回答。对于我的情况,你能在这里写下如何使用 Swift 使用 CIContext 吗?
    • 非常感谢@FrankSchlegel!它按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 2018-02-17
    • 2014-07-14
    相关资源
    最近更新 更多