Как вы составёте контент 3D SceneKit на видеокадрах на графическом процессоре на iOS?

Я работаю над AR-приложением. У меня есть сцена SceneKit, которая отображается в SCNView (используя OpenGL ES в качестве API визуализации). Под этим – еще один вид, показывающий предварительный просмотр камеры. Я хотел бы создать фильм, содержащий как видео, так и 3D-сцену.

Я использую код на основе примера кода Apple RosyWriter для обработки пиксельных буферов видеофрагмента с помощью шейдеров OpenGL. Я не думаю, что я достаточно хорошо понимаю концепции, потому что не уверен, как накладывать рендеринг SceneKit на видеокадры. Могу ли я получить буфер пикселей из SCNView / SCNSceneRenderer или мне нужно использовать SCNRenderer для повторной рендеринга сцены в текстуру в офшорном буфере, который использует конвейер захвата OpenGL для обработки видеокадров?

В iOS 11 теперь есть технология, позволяющая легко выполнять не только наложения SceneKit на видео, но и целый опыт дополненной реальности: ARKit . (Кроме того, если вы загружаете свой собственный бит технологии отслеживания AR, который требуется отображать с помощью SceneKit, в iOS 11 вы можете установить AVCaptureDevice в качестве содержимого любого свойства материала SceneKit, включая фон сцены).

Для более старых версий iOS приведенный ниже совет применяется …


Если у вас уже есть контент, который вы создаете с помощью OpenGL (или Metal, если на то пошло), и вы хотите добавить к нему контент SceneKit, используйте SCNRenderer . Настройте сцену на нем точно так же, как и с помощью SCNView , сделайте всю существующую рендеринг OpenGL так, как вы обычно это делаете, а затем вызовите renderAtTime:

Просто для доказательства концепции, вот очень быстрый взлом при добавлении рендеринга SceneKit поверх RosyWriter . Все приведенные ниже коды идут в RosyWriterOpenGLRenderer.m .

В объявлении переменных экземпляра:

 @interface RosyWriterOpenGLRenderer () { //... existing ivars, plus: SCNRenderer *_scnRenderer; } 

В init после настройки _oglContext :

 _scnRenderer = [SCNRenderer rendererWithContext:_oglContext options:nil]; SCNScene *scene = [SCNScene scene]; SCNNode *node = [SCNNode nodeWithGeometry:[SCNBox geometry]]; [node runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:1 y:1 z:1 duration:1]]]; [scene.rootNode addChildNode:node]; _scnRenderer.scene = scene; 

В copyRenderedPixelBuffer , между существующим вызовом glFlush() и меткой bail :

 glFlush(); [_scnRenderer renderAtTime:CFAbsoluteTimeGetCurrent()]; bail: 

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

нет, мой стол на самом деле не такой розовый.