iOS/iOS 개발
iOS - BlendShapes 활용하기
포도 동
2021. 5. 27. 17:36
blendShapes를 활용할 head.scn 에셋과 그 안에 leftEye라는 chileNode가 있다고 가정합니다.
* 일반적인 .dae 3D 에셋을 XCODE로 불러오면 .scn 파일로 변환할 수 있습니다.
@IBOutlet var sceneView: ARSCNView!
var headNode: SCNNode?
var leftEyeNode: SCNNode?
먼저, ARKit과 SceneKit을 import 해줍니다.
그리고 화면을 나타낼 sceneView, 에셋을 연결할 headNode와 leftEyeNode를 SCNNode로 선언합니다.
override func viewDidLoad() {
sceneView.delegate = self
}
ARSCNViewDelegate를 채택해줍니다.
그 후, ARSCNViewDelegate의 renderer 함수를 구현합니다.
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
guard let faceAnchor = anchor as? ARFaceAnchor else { return nil }
headNode = SCNReferenceNode(named: "head")
leftEyeNode = headNode?.childNode(withName: "leftEye", recursively: true)
return headNode
}
head.scn 파일과 childNode를 만들어줍니다.
활용 예로 왼쪽 눈의 깜빡임에 따라 leftEye 노드의 z 스케일을 변경시켜보겠습니다.
head.scn 파일을 열고 leftEye 노드의 Transforms를 확인합니다.
제가 활용한 에셋은 눈을 완전히 뜨고 있을 때 z 스케일이 1 이기때문에
blendShapes의 eyeBlinkLeft의 값을 반대로 활용하겠습니다.
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let faceAnchor = anchor as? ARFaceAnchor else { return }
let blendShapes = faceAnchor.blendShapes
if let eyeBlinkLeft = blendShapes[.eyeBlinkLeft] as? Float {
leftEyeNode?.scale.z = 1 - eyeBlinkLeft
}
}
renderer - didUpdate 함수를 위와 같은 방식으로 구현하면 인식한 얼굴의 왼쪽 눈 깜빡임에 따른 blendShapes 값을 활용해 에셋을 실시간으로 변형할 수 있습니다.
참고자료 : https://developer.apple.com/documentation/arkit/arscnviewdelegate/