I want to make an app that shows the AR in the screen and records it at the same time. The simplest idea is just record it from iOS11's new screen recording feature, but you cannot take control over the recording behavior so that's not for me. Using ReplayKit is a good idea and I tried it actually, but I haven't been able to make it work for unknown error. I'm researching this issue as well in a different path, so let me exclude that topic here.
The approach I'm taking as one of my options is, using an ARSCNView for viewing and on top that having a separated SCNRenderer dedicated for recording.
This approach is going seemingly good, as it shows the model on the screen and records to the file as well.
But the rendering result is weird, the one with SCNRenderer is rendered differently, kinda seems like hidden plane removal is not working.
(See the image below. The image on the corner is the rendering result form SCNRenderer, which is exactly same as what is recorded to the file.)
I cannot show here but the animation is also going wrong.
I, of course, intended to set everything in the same way for both, but are there any more setting parameters or something to consider? Or the way of giving the model is wrong?
The code for the scene/renderer setup is like below. The synchronization between two renderers is done in the ARKit's delegate method, which is not shown here.
// sceneView is instance variable, which is an ARSCNView
sceneView.delegate = self
//
// Create a empty scenes and wrapper nodes
//
sceneView.scene = SCNScene(named: "art.scnassets/scene.dae")!
secondaryScene = SCNScene(named: "art.scnassets/scene.dae")!
charNode = SCNNode();
sceneView.scene.rootNode.addChildNode(charNode)
charNode2 = SCNNode();
secondaryScene.rootNode.addChildNode(charNode2);
//
// Load the model
//
let url = Bundle.main.url(forResource: "art.scnassets/idle",withExtension: "dae");
let scene = try! SCNScene(url: url!, options: nil);
for child in idleScene.rootNode.childNodes {
charNode.addChildNode(child)
}
// Create exactly the same scene as a new instance.
// (Sharing same instance makes app crash)
let scene2 = try! SCNScene(url: url!, options: nil);
for child in idleScene2.rootNode.childNodes {
charNode2.addChildNode(child)
}
//
// Run the AR session
//
let configuration = ARWorldTrackingSessionConfiguration()
self.sceneView.session.run(configuration)
self.sceneView.session.delegate = self;
//
// Prepare OpenGL
//
let group = GPUImageContext.sharedImageProcessing().context.sharegroup
self.eaglContext = EAGLContext(api: .openGLES2, sharegroup: group! )
let options = ["preferredRenderingAPI": SCNRenderingAPI.openGLES2]
// Secondary renderer for rendering to an OpenGL framebuffer
self.secondaryRenderer = SCNRenderer(context: self.eaglContext, options: options)
self.secondaryRenderer?.scene = secondaryScene
Any idea is helpful. Thanks!
