Проблемы с MTKView при повторном использовании currentDrawable.texture в цикле draw()

Я работаю над приложением для рисования на металлической основе, в котором я делю рисование обводки на два шага: первый шаг рисует передний край обводки на экране и захватывает все в текстуру MTL посредством:

metalTextureComposite = self.currentDrawable!.texture

второй шаг рисует обновленный передний край продвигающегося штриха, и композиты поверх многоугольника, текстурированного с последним сохраненным metalTextureComposite.

Этот метод позволяет мне рисовать бесконечно длинные штрихи без ущерба для производительности, так как эти два шага повторяются для каждого кадра цикла рисования.

Проблема, с которой я столкнулся, заключается в том, что при использовании желаемого композитного режима "источник поверх" (см. Код ниже) я вижу только передний край обводки, выводимой на экран. Это говорит мне о том, что либо я недостаточно адекватно извлекаю metalTextureComposite из currentDrawable, либо делаю неправильные предположения относительно используемого режима наложения, который, кстати, выглядит следующим образом:

renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha       
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha                 
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

Если я использую разные режимы смешивания, я вижу всю прорисовку обводки, но не обязательно, что мне нужно. Ниже приведена часть кода, который я включаю в метод draw () MTKView.

func metalRenderStampArray() {

    // first encode uber-stamp with previous loop's  metalTextureComposite in a background polygon
    // note metalTexture= metalTextureComposite contains previous loop's drawable contents
    metalCommandEncode(renderCommandEncoder: renderCommandEncoder, stampLayer: stampLayerMode.stampLayerBG, vertexArrayStamps: vertexArrayStampsBG, metalTexture: metalTextureComposite) // background uber-stamp

    // empty out uber-stamp in preparation for the next cycle
    initializeStampArrays(stampLayer: stampLayerMode.stampLayerBG) 

    // next, encode current subCurve chunk polygons in foreground
    // note metalTexture=brushTexture.texture is a round brush texture with alpha
    metalCommandEncode(renderCommandEncoder: renderCommandEncoder, stampLayer: stampLayerMode.stampLayerFG, vertexArrayStamps: vertexArrayStampsFG, metalTexture: brushTexture.texture) // foreground sub-curve chunk

    renderCommandEncoder?.endEncoding() // finalize renderEncoder set up

    // now present bg + fg composite which is where I see the problem
    commandBuffer?.present(self.currentDrawable!)

    // 7b. Render to pipeline
    commandBuffer?.commit() // commit and send task to gpu

    metalTextureComposite = nil // empty out before re-populating
    metalTextureComposite = self.currentDrawable!.texture // set up bg texture for next iteration 

    metalStampComputeComposite() // compute coordinates for the background composite stamp for the next iteration

 } // end of func metalRenderStampArray()

Должен ли я обрабатывать metalTextureComposite по-другому (поскольку он записывается со скоростью 1/fps) и, если да, как мне его обрабатывать? Цель состоит в том, чтобы использовать один режим наложения для фонового полигона и ведущих полигонов обводки. Любая помощь будет оценена.

1 ответ

Похоже, вы храните ссылку на текстуру для рисования и затем используете ее в следующем кадре.

Я вижу две возможные проблемы с этим: - на следующем цикле отрисовки кадра текстура предыдущего кадра еще не может быть прорисована графическим процессором - текстура отрисовки может использоваться системой и кодом приложения одновременно

Я бы посоветовал скопировать текстуру drawable для вашего использования в commandBuffer?.addCompletedHandler { }

Другие вопросы по тегам