如何在iOS上的GPU上将3D SceneKit内容合成到视频帧上?

Jed*_*ane 1 opengl-es core-video ios scenekit

我正在开发AR应用程序.我有一个SceneKit场景被渲染到SCNView(使用OpenGL ES作为渲染API).在此下方是另一个显示相机实时预览的视图.我想创建一个包含视频和3D场景的电影.

我正在使用基于Apple的RosyWriter示例代码的代码来处理带有OpenGL着色器的视频帧像素缓冲区.我认为我不太了解这些概念,因为我不确定如何在视频帧上叠加SceneKit渲染.我可以从SCNView/SCNSceneRenderer获取像素缓冲区,还是需要使用SCNRenderer将场景重新渲染到OpenGL捕获管道用于处理视频帧的屏幕外缓冲区中的纹理?

ric*_*ter 6

在iOS 11中,现在有一项技术可以轻松完成视频中的SceneKit叠加,但是整个增强现实体验:ARKit.(另外,如果您要使用SceneKit滚动自己的AR跟踪技术位,在iOS 11中,您可以设置AVCaptureDevice任何SceneKit材质属性的内容,包括场景的背景.)

对于较旧的iOS版本,以下建议仍然适用...


如果您已经拥有使用OpenGL(或Metal)进行渲染的内容,并且想要将SceneKit内容添加到其中,请使用SCNRenderer.像你一样在它上面设置一个场景,SCNView按照你通常的方式完成所有现有的OpenGL渲染,然后调用renderAtTime:.

只是一个概念证明,这里是一个非常快的黑客在对顶部添加SceneKit渲染RosyWriter.下面的所有代码都会进入RosyWriterOpenGLRenderer.m.

在实例变量的声明中:

@interface RosyWriterOpenGLRenderer ()
{
    //... existing ivars, plus:
    SCNRenderer *_scnRenderer;
}
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

在copyRenderedPixelBuffer现有的呼叫glFlush()和bail标签之间:

glFlush();

[_scnRenderer renderAtTime:CFAbsoluteTimeGetCurrent()];

bail:
Run Code Online (Sandbox Code Playgroud)

这足以在实时视频视图和录制的电影输出中获得一个大的旋转白色立方体.(由于默认的材料和灯光设置,它只是没有阴影.对于真实的用例,设置灯光,材料,相机,你想要的几何形状等)

不,我的桌子不是那么粉红色.