【发布时间】:2019-05-06 05:59:34
【问题描述】:
我正在编写 CIFilter,但结果像素颜色与金属函数的返回值不同。
kernel.metal
#include <CoreImage/CoreImage.h>
extern "C" { namespace coreimage {
float4 foo(sample_t rgb){
return float4(0.3f, 0.5f, 0.7f, 1.0f);
}
}
MetalFilter.swift
import CoreImage
class MetalFilter: 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: "foo", 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])
}
}
当我得到 outputImage 时,我有这些值:
R = 0.58431372549019611
G = 0.73725490196078436
B = 0.85490196078431369
这是金属函数返回值后的某种后处理(如 pow(x, 1/2.373)。
【问题讨论】:
-
听起来支持输出图像的纹理是 sRGB 编码的。
-
明确地说,这是预期的行为:您从内核返回一个线性空间值,并对其进行 sRGB 编码以匹配输出图像的默认颜色空间。如果您希望图像中的值是您在上面指定的值,则需要在返回值之前使用
srgb_to_linear函数手动“去伽玛”它们。这将取消发生在输出上的线性到 srgb 转换。大多数时候,您都需要自动 sRGB 转换,而在现代 Apple GPU 上,它实际上是免费的。 -
既然您正在编写自定义过滤器,我想您已经找到了我所坚持的成功。我正在尝试将一个简单的晕影滤镜应用于使用金属的实时摄像机馈送。结果非常缓慢且滞后,如果您能告诉我缺少什么,请检查一下:stackoverflow.com/q/53898780/1364053
-
将 sRGB 实现为线性的类似问题:stackoverflow.com/questions/55384641/…
-
同样的问题,你解决了吗?