ios Metal Core图像采样器像素格式

cclgggtu  于 11个月前  发布在  iOS
关注(0)|答案(1)|浏览(107)

我有这个金属代码,我想翻译成金属核心图像内核。

fragment half4 fragmentShaderThreshold ( MappedVertex in [[ stage_in ]],
                                 texture2d<half, access::sample> inputTexture [[ texture(0) ]]
                                 )
  {
  constexpr sampler s(s_address::clamp_to_edge, t_address::clamp_to_edge, min_filter::linear, mag_filter::linear);

  half3 rgb = inputTexture.sample(s, in.textureCoordinate).rgb; 
  half3 weights = half3(0.2126, 0.7152, 0.0722);

  float intensity = dot(rgb, weights);

  if (intensity >= 0.95) {
     rgb = half3(1.0, 0.0, 0.0);
  } else if (intensity <= 0.05) {
     rgb = half3(0.0, 0.0, 1.0);
  }

    return half4(rgb, 1.h);
 }

字符串
要在Metal Core Image内核中做同样的事情,我认为这是可以使用内置滤镜来完成的。因为内置滤镜可以在各种颜色空间中工作,例如BT.2020。请评论如何使用内置滤镜来实现这一点。
如果无法使用内置滤镜,我想将图像转换为灰度,并在Metal Core Image内核中读取强度(灰度值)。看起来Metal Core Image采样器只支持基于RGB的像素格式(不像Metal,纹理可以有像素格式,如r8)。这是正确的吗?

rjee0c15

rjee0c151#

不幸的是,没有简单的内置过滤器将图像转换为灰度。CIPhotoEffectNoir可以做到这一点,但它在幕后使用了颜色立方体/查找表,并且没有记录它是如何定义的。
你可以使用CIColorMatrix来完成内核的第一部分:

let colorMatrixFilter = CIFilter.colorMatrix()
let lumaCoefficients = CIVector(x: 0.2126, y: 0.7152, z: 0.0722, w: 0.0)
colorMatrixFilter.rVector = lumaCoefficients
colorMatrixFilter.bVector = lumaCoefficients
colorMatrixFilter.gVector = lumaCoefficients

字符串
您可以进一步调整亮度系数以匹配您正在使用的颜色空间,尽管默认情况下Core Image将所有内容转换为扩展线性sRGB,因此这些应该是正确的。
对于强度阈值,你可能会使用CIColorThresholdCIBlendWithMask的巧妙组合,但老实说,我会为此编写一个简单的自定义颜色内核。它在运行时也应该更快。
是的,Core Image始终支持4通道纹理。在仅生成单通道输出的自定义内核中,您通常在所有3个颜色通道中写入相同的值。或者,您也可以在使用init(functionName: String, fromMetalLibraryData: Data, outputPixelFormat: CIFormat)初始化内核时指定单通道outputPixelFormat,例如.Rh,但CI会在将其作为输入传递给下一个过滤器之前将其重新混合为4通道图像(除非这是一个显式处理单通道输入的处理器,但这很少见)。

相关问题