2017-11-13 3 views
2

프로젝트에서 - 나는 GPUImageView를 사용하여 투명도가있는 비디오 (그린 스크린에 기록됨)를 표시했습니다. GPUImageChromaKeyBlendFilter 사용하기 등등. 우수하며 작동합니다.GPUImageView SKNode 재질로 SKKene 내부 - ARKit 투명 비디오 재생

ARKIT을 기반으로하는 다른 프로젝트 -B-는 공간에서 나를 평범한 비디오로 보여 주며 SKVideoNode 및 AVPlayer를 사용하여 잘 작동합니다.

이제는 모든 것을 하나로 결합하는 것입니다. 공간에서 비디오를 표시하고 싶지만 투명도가 있습니다 ... 불행히도 SpriteKit 요소에서 GPUImageView를 렌더링 할 수없고 SKScene에 추가 할 수 없습니다 , SCNPlane에 대한 애니메이션 텍스처입니다, 그것은 전혀 가능합니까? 아니면 ARKit으로 투명 필름으로 비디오를 렌더링하는 다른 방법이있을 수 있습니다. 어떤 제안

+0

아직이 문제에 대한 진전 사항이 있습니까? – Felix

답변

0

에 대한

들으 나는 같은 작업을했다! 내 솔루션 here을 참조하십시오.

나는 기본적으로 ChromaKeyMaterialLësha Turkowski에서 구현했으며 비디오를 배치하고 재생하기 위해이 코드를 작성했습니다.

import UIKit 
import ARKit 

class ARTransVC: UIViewController{ 

@IBOutlet weak var arSceneView: ARSCNView! 
let configuration = ARWorldTrackingConfiguration() 

private var player: AVPlayer = { 
    guard let url = Bundle.main.url(forResource: "FY3A4278", withExtension: "mp4") else { fatalError() } 
    return AVPlayer(url: url) 
}() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.arSceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints] 
    self.arSceneView.session.run(configuration) 

    //a delay for ARKit to capture the surroundings 
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) { 

     // A SpriteKit scene to contain the SpriteKit video node 
     let spriteKitScene = SKScene(size: CGSize(width: self.arSceneView.frame.width, height: self.arSceneView.frame.height)) 
     spriteKitScene.scaleMode = .aspectFit 
     spriteKitScene.backgroundColor = .clear 
     spriteKitScene.scaleMode = .aspectFit 

     //Create the SpriteKit video node, containing the video player 
     let videoSpriteKitNode = SKVideoNode(avPlayer: self.player) 
     videoSpriteKitNode.position = CGPoint(x: spriteKitScene.size.width/2.0, y: spriteKitScene.size.height/2.0) 
     videoSpriteKitNode.size = spriteKitScene.size 
     videoSpriteKitNode.yScale = -1.0 
     videoSpriteKitNode.play() 
     spriteKitScene.addChild(videoSpriteKitNode) 

     // To make the video loop 
     self.player.actionAtItemEnd = .none 
     NotificationCenter.default.addObserver(
      self, 
      selector: #selector(ARTransVC.playerItemDidReachEnd), 
      name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, 
      object: self.player.currentItem) 

     // Create the SceneKit scene 
     let scene = SCNScene() 
     self.arSceneView.scene = scene 

     //Create a SceneKit plane and add the SpriteKit scene as its material 
     let background = SCNPlane(width: CGFloat(1), height: CGFloat(1)) 
     background.firstMaterial?.diffuse.contents = spriteKitScene 
     let chromaKeyMaterial = ChromaKeyMaterial() 
     chromaKeyMaterial.diffuse.contents = self.player 

     let backgroundNode = SCNNode(geometry: background) 
     backgroundNode.geometry?.firstMaterial?.isDoubleSided = true 
     backgroundNode.geometry!.materials = [chromaKeyMaterial] 

     backgroundNode.position = SCNVector3(0,0,-2.0) 
     scene.rootNode.addChildNode(backgroundNode) 

     //video does not start without delaying the player 
     //playing the video before just results in [SceneKit] Error: Cannot get pixel buffer (CVPixelBufferRef) 
     DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
      self.player.seek(to:CMTimeMakeWithSeconds(1, 1000)) 
      self.player.play() 
     } 
    } 
} 

@objc func playerItemDidReachEnd(notification: NSNotification) { 
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem { 
     playerItem.seek(to: kCMTimeZero, completionHandler: nil) 
    } 
}