【问题标题】:Problems with CIImageAccumulator from MTKView texture来自 MTKView 纹理的 CIImageAccumulator 问题
【发布时间】:2018-03-23 22:39:57
【问题描述】:

我想通过视图的纹理将 MTKView 的输出捕获到 CIImageAccumulator 中,以实现渐变的绘画效果。问题是累加器好像在弄乱原图的color/alpha/colorspace,如下图:

从上图中,我捕获看起来较暗的笔触的方式是通过视图的 currentDrawable.texture 属性:

lastSubStrokeCIImage = CIImage(mtlTexture: self.currentDrawable!.texture, options: nil)!.oriented(CGImagePropertyOrientation.downMirrored)
subStrokeUIView.image = UIImage(ciImage: lastSubStrokeCIImage)

现在,一旦我将相同的图像通过管道传输到 CIIAcumulator 中以供以后处理(每个绘图段只执行一次),结果就是附件上部显示的看起来更亮的结果:

lazy var ciSubCurveAccumulator: CIImageAccumulator =
    {
      [unowned self] in
      return CIImageAccumulator(extent: CGRect(x: 0, y: 0, width: self.frame.width * self.contentScaleFactor, height: self.frame.height * self.window!.screen.scale ) , format: kCIFormatBGRA8)
      }()!
ciSubCurveAccumulator.setImage(lastSubStrokeCIImage)
strokeUIView.image = UIImage(ciImage: ciSubCurveAccumulator.image())

我曾尝试在 CIImageAccumulator 定义中使用各种 kCIFormat,但均无济于事。 CIImageAccumulator 做了什么来弄乱原始文件,我该如何解决?请注意,我打算使用 ciSubCurveAccumulator 逐渐建立一致颜色的连续笔触。为简单起见,我没有展示累积部分。这个问题让我步履蹒跚。

任何建议都将不胜感激

【问题讨论】:

  • 你是如何配置MTKView的?特别是,它的framebufferOnly 属性值是多少?
  • 现在设置为默认的 false 值。我确实将其设置为 true,这意味着修改 MTLTextureDescriptor.usage 以读取|写入并写入用户定义的纹理(而不是 currentDrawable)。可悲的是,结果是一样的。这就是为什么我认为我已将问题范围缩小到 CIAccumulator。将任何东西插入其中似乎会改变输出的颜色行为。

标签: swift3 metal render-to-texture ciimage


【解决方案1】:

问题归结为两件事:第一,我需要设置 MTLRenderPipelineDescriptor() 来进行compositeOver 合成,第二,我需要设置一个CIFilter 来在累积的CIImageAccumulator 上保存中间合成。这个 CIFilter 也需要设置为 CIOverCompositing。以下是捕获上述所有内容的 sn-p 代码:

lazy var ciSubCurveAccumulator: CIImageAccumulator =
{
  [unowned self] in
  return CIImageAccumulator(extent: CGRect(x: 0, y: 0, width: self.frame.width * self.contentScaleFactor, height: self.frame.height * self.window!.screen.scale ) , format: kCIFormatBGRA8)
  }()! // set up CIImageAccumulator

let lastSubStrokeCIImage = CIImage(mtlTexture: self.currentDrawable!.texture, options: nil)!.oriented(CGImagePropertyOrientation.downMirrored)
let compositeFilter : CIFilter = CIFilter(name: "CISourceOverCompositing")!

compositeFilter.setValue(lastSubStrokeCIImage, forKey: kCIInputImageKey) // foreground image
compositeFilter.setValue(ciSubCurveAccumulator.image(), forKey: kCIInputBackgroundImageKey) // background image

let bboxChunkSubCurvesScaledAndYFlipped = CGRect(...) // capture the part of the texture that was drawn to
ciSubCurveAccumulator.setImage(compositeFilter.value(forKey: kCIOutputImageKey) as! CIImage, dirtyRect: bboxChunkSubCurvesScaledAndYFlipped) // comp bbox with latest updates

将上述代码封装在 draw() 中可以很好地累积渐变绘制。希望这在某些时候可以帮助某人。

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 2011-02-23
    • 2018-12-07
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 2012-11-24
    • 2020-03-26
    相关资源
    最近更新 更多