시작
AR 주사위 던지는 앱을 만들기 앞서
이해를 돕기 위해 들어가기 앞서 간단한 Cube(정육면체)와 Shpere(구)를 만들어 봅시다.
처음 생성하기
iOS -> Augmented Reality App 선택
Content Technology : SceneKit
을 선택해 줍시다.
Art.scnassets
객체의 이미지 및 재질의 설정을 위한 공간입니다.
기본적으로 폴더에 ship.scn
과 texture.png
파일이 생성이 됩니다.
ship.scn
은 파일은 객체를 만들 때 사용이 되고 texture.png
는 재질 설정을 할 때 사용이 됩니다.
참고: 확장자 .dae와 .scn는 서로 변환이 가능하다
여기 설정 중 Node
와 Material
에 대하여 간단히 설명드리겠습니다.
Node 란
Node
는 기본적으로 3D 공간의 위치를 나타냅니다. 위치 및 크기를 지정하고 개체를 생성하죠.
AR로 디스플레이되는 물체들은 Node라고 칭합니다.
여기서 Node는 rootNode와 내부의 childNode로 구성됩니다.
rootNode와 childNode는 node계층(scene graph)으로 서로 묶여있지만,
그렇다고 해서 visual적인 부분들까지 계층을 이루는 것은 아닙니다.
(ex. rootnode를 이루는 색이 빨간색이라고 해서 childNode도 빨간색이 되진 않습니다.)
그리고 기본적으로 커스텀 Node는 아무것도 보이지 않습니다.
눈에 보이는 콘텐츠를 만들려면 조명, 카메라 또는 지오메트리(뼈대)와 같은 다른 구성 요소를 Node에 추가해야 합니다.
이 작업을 할 수 있는 곳이 바로 Material
입니다.
Material 이란
렌더링 시 나타나는 조명 및 카메라 또는 지오메트리(뼈대)를 설정할 수 있는 세트입니다.
Material Inspector
로 들어가 보면 Diffuse를 설정할 수 있습니다.
Diffuse는 재질의 질감 및 색을 변경할 수 있습니다.
Configuration Objects
프로젝트 생성 시 기본으로 생성된 코드 중 configuration
에 대하여 조금만 알고 들어갑시다.
(처음 viewWillAppear에 있는 let configuration = ARWorldTrackingConfiguration()
)
configuration
종류에 대하여 간단히 두 가지만 알아보고 가겠습니다.
1. ARWorldTrackingConfiguration
장치가 움직여도 가상객체는 현실세계 있는 것처럼 증강현실 착시를 만듭니다.
6개의 자유도(6DOF)로 만들어 집니다.
세 개의 회전 축(roll, pitch, yaw)과 3개의 변환 축(x, y, z 축의 움직임)으로 장치의 이동을 추적합니다.
자세한 설명은 공식문서 링크 참조
2. AROrientationTrackingConfiguration
장치와 함께 가상객체가 움직입니다.
세 가지 자유도(3DOF)로 만들어 집니다.
특히 세 가지 회전 축(roll, pitch, yaw)으로 장치의 이동을 추적합니다
디바이스 중에 A9 칩셋 이하이면 움직이는 그래픽 처리가 힘들기 때문에 오래된 디바이스나 ARWorldTrackingConfiguration
를 부득이하게 사용하지 못할 때 대체수단으로 잠시 사용하는 것을 권장합니다.
자세한 설명은 공식문서 링크 참조
기기 지원 확인 방법
// 나의 기기가 지원하는지 알수 있습니다.
// (요즘 대부분 iPhoneSE 이상을 사용하므로 딱히 분기처리를 하여 사용할 필요는 없을 듯 싶다)
print("Orientation Tracking is supported = \(ARConfiguration.isSupported)")
print("World Tracking is supported = \(ARWorldTrackingConfiguration.isSupported)")
Cube(정육면체)를 만들어보자
각각의 코드들을 주석으로 설명해 놨습니다.
순서와 중요한 포인트 몇 개만 정리하겠습니다.
1. 원하는 모양 생성하기
ARKit의 기본 크기의 단위는 미터(m)입니다.
(기본 모양들은 프레임워크 내에 이미 만들어져 있습니다.)
SCNText // 3차원 텍스트
SCNFloor // 바닥에 비친 반사 모양
SCNBox // 정육면체 모양
SCNCapsule // 캡슐 모양
SCNCone // 원뿔 모양
SCNCylinder // 원통 모양
SCNPlane // 평면 모양
SCNPyramid // 피라미드 모양
SCNSphere // 구 모양
SCNTorus // 튜브(도넛) 모양
SCNTube // 구명 뚫린 원통 모양
2. 재질을 설정해 줍니다.
diffuse로 색상 및 png 파일을 통해 외관을 설정할 수 있습니다.
3. node를 생성해 줍니다.
Node의 주요 속성인 position(위치), geometry(뼈대)을 설정 해줍니다.
4. addChildNode에 생성한 노드를 추가해 줍니다.
아래 코드를 viewDidLoad
에서 실행만 시켜주면 됩니다.
func makeCube() {
// 앞의 SCN은 Scene의 줄임말 (SceneKit 프레임워크)
// 정육면체를 만든다 (SCNBox 파라미터의 단위는 미터(m)이다, chamferRadius: 모서리를 라운드 크기)
let cube = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)
// 재료 설정을 위해 Scene의 material 생성
let material = SCNMaterial()
// 색상 설정
material.diffuse.contents = UIColor.red
// 위의 만든 큐브에 재질을 만든 재질로 변경 (배열로 감싼다)
cube.materials = [material]
// 큐브를 만들고 스타일까지 만들어 줬습니다.
// 다음으로 Node를 만들어줘야 합니다.
// SCNNode는 기본적으로 3D 공간의 위치를 나타낸다. 위치를 지정하고 개체를 생성해야한다.
// SCNNode안에는 기본적으로 아무것도 보이지 않습니다.
// 눈에 보이는 콘텐츠를 만들려면 조명, 카메라 또는 지오메트리(뼈 대)와 같은 다른 구성 요소를 노드에 추가해야 합니다.
let node = SCNNode()
// position의 타입은 SCNVector3입니다. 3차원 벡터(X, Y, Z)를 가르킨다.
// Q: 여기서 Z축만 왜 마이너스(-)를 사용하는가?
// A: 양수이면 Z축의 방향은 나에게 오는 방향이다.
// A: 나를 기준으로 멀리 떨어뜨리려고 마이너스를 사용함
node.position = SCNVector3(x: 0, y: 0.05, z: -0.5)
// geometry: node와 연결된 형상을 가르킨다 (뼈대)
node.geometry = cube
// rootNode: 기존에 있던 노드에서 addChildNode로 새로운 노드를 추가 시킨다.
sceneView.scene.rootNode.addChildNode(node)
// 위의 과정까지 마치면 뭔가 입체감이 없는 주사위가 만들어졌을 것이다.
// 그 이유는 빛과 그림자 설정을 안해줘서 그렇다.
// autoenablesDefaultLighting는 자동으로 조명값을 만들어 준다.
sceneView.autoenablesDefaultLighting = true
}
autoenablesDefaultLighting
(자동 조명 효과)
Shpere(구)를 통한 달(Moon) 만들기
정육면체를 만드는 과정과 동일합니다.
다만 diffuse.contents
부분에 색상을 넣는 대신 이번엔 달 모양의 PNG, JPEG 파일을 사용하면 됩니다.
행성의 textures를 다운을 받아 봅시다
홈페이지에서 Explore -> textures -> 원하는 texture 선택 후 (고해상도를 원하면 8K) 그림을 다운로드
다운로드한 PNG 혹은 JPEG을 art.scnassets
에 넣어 줍시다
func makeMoon() {
// 구 모양을 원하는 반지름의 크기로 생성한다.
let sphere = SCNSphere(radius: 0.2)
let material = SCNMaterial()
// 추가한 texture 파일을 UIImage로 불러오기만 하면된다.
// art.scnassets 폴더 안에 있으므로 (/)를 통해 경로를 추가하여 넣어준다.
material.diffuse.contents = UIImage(named: "art.scnassets/moon.jpeg")
sphere.materials = [material]
let node = SCNNode()
node.position = SCNVector3(x: 0, y: 0.05, z: -1)
node.geometry = sphere
// 배경을 추가하기
// sceneView 자체의 background에 접근하여 배경을 설정해줌
sceneView.scene.background.contents = UIImage(named: "art.scnassets/space.jpeg")
sceneView.scene.rootNode.addChildNode(node)
sceneView.autoenablesDefaultLighting = true
}
ScnenKit의 다른 예제를 보고 싶다면 아래 링크를 참고하세요
참고
'Xcode > Framework' 카테고리의 다른 글
[iOS/Swift] SceneKit의 사용법 (3) - 카메라 줄자, 거리 측정하기 (0) | 2023.01.10 |
---|---|
[iOS/Swift] SceneKit의 사용법 (2) - 주사위 만들기 (0) | 2023.01.08 |
[iOS/Swift] ARKit의 종류 (0) | 2023.01.07 |
[iOS/Swift] CoreML (2) - 훈련 된 Model 사용하기 (3) | 2023.01.04 |
[iOS/Swift] CoreML (1) - Create ML으로 Model 만들기 (0) | 2023.01.03 |