Проблемы с CIImageAccumulator из текстуры MTKView

Я хочу захватить вывод MTKView через текстуру представления в CIImageAccumulator для достижения эффекта постепенного наращивания рисования. Проблема в том, что аккумулятор, кажется, не работает с цветовым / альфа / цветовым пространством оригинала, как показано ниже:

введите описание изображения здесь

На изображении выше я запечатлел более темный мазок кисти с помощью свойства 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())

Я пробовал использовать различные kCIFormats в определении CIImageAccumulator, но безрезультатно. Что делает CIImageAccumulator, чтобы испортить оригинал, и как это исправить? Обратите внимание, что я намерен использовать ciSubCurveAccumulator, чтобы постепенно создавать непрерывный мазок однородного цвета. Для простоты вопроса накапливающую часть не показываю. Эта проблема останавливает меня как вкопанный.

Любые предложения будут приняты во внимание


person Plutovman    schedule 23.03.2018    source источник
comment
Как вы настроили MTKView? В частности, каково значение его свойства framebufferOnly?   -  person Ken Thomases    schedule 24.03.2018
comment
Теперь для него установлено ложное значение по умолчанию. Я выбрал для него значение true, что означало изменение MTLTextureDescriptor.usage для чтения | записи и записи в пользовательскую текстуру (в отличие от currentDrawable). К сожалению, результат тот же. Вот почему я думаю, что сузил проблему до CIAccumulator. Добавление чего-либо в него, кажется, меняет цветовое поведение вывода.   -  person Plutovman    schedule 26.03.2018


Ответы (1)


Проблема свелась к двум вещам: во-первых, мне нужно было настроить MTLRenderPipelineDescriptor () для композитинга поверх и, во-вторых, мне нужно было установить CIFilter для промежуточного композитинга поверх накапливающегося CIImageAccumulator. Этот CIFilter также необходимо было настроить для CIOverCompositing. Ниже приведен фрагмент кода, который фиксирует все вышеперечисленное:

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 () позволяет постепенно накапливать рисование. Надеюсь, это кому-то поможет в какой-то момент.

person Plutovman    schedule 28.06.2018