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

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

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


person Jed Soane    schedule 08.12.2016    source источник


Ответы (1)


В 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:

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

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

person rickster    schedule 08.12.2016