[iOS/SceneKit] SCNScene 알아보기
https://developer.apple.com/documentation/scenekit/
SceneKit | Apple Developer Documentation
Create 3D games and add 3D content to apps using high-level scene descriptions, and easily add animations, physics simulation, particle effects, and realistic physically based rendering.
developer.apple.com
3D 모델링 파일을 화면에 구현하는 작업을 맡았다.
ARKit, RealityKit, SceneKit 를 활용해 3D 모델을 출력할 수 있는데
이중 SceneKit가 실제 카메라 기능 없이 구현이 가능하고 SwiftUI에서도 적용이 가능해 선택했다.
SceneKit의 핵심부터 알아보자
1. SCNScene
3D 장면을 구성하는 노드 계층과 전역 속성을 담고 있는 컨테이너.
장면 그래프를 정의하고 SceneKot에서 렌더링할 수 있는 장면을 만든다.
사용 방법
장면을 표시하려면 런타임에 Scene을 로드한 다음, SCNView의 scene 속성으로 설정한다.
guard let myScene = SCNScene(named: "MyScene")
else { fatalError("Unable to load scene file.") }
scnView.scene = myScene // Your app's SCNView
구현하는 가장 간단한 방법은 아래와 같다고한다.
The simplest way to create a scene is through Xcode’s SceneKit Scene Editor. Start by importing one or more assets from a 3D editor, such as Blender. Then you adjust the positions and attributes of the assets, and set global scene properties, such as lighting environment, to compose your scene. The scene editor creates a .scn file, which you save to a .scnassets folder in the app bundle. When you build your project, Xcode optimizes the scene file for your target platform.
Scene 내장함수들
Creating a Scene from a File (파일에서 장면 생성하기)
- init?(named: String)
- 설명: 앱의 메인 번들에서 지정된 이름의 파일로부터 장면을 로드합니다.
- init?(named: String, inDirectory: String?, options: [SCNSceneSource.LoadingOption : Any]?)
- 설명: 앱의 메인 번들의 특정 하위 디렉토리에서 지정된 이름의 파일로부터 장면을 로드합니다.
- init(url: URL, options: [SCNSceneSource.LoadingOption : Any]?)
- 설명: 지정된 URL에서 장면을 로드합니다.
Managing Animated Effects in a Scene (장면에서 애니메이션 효과 관리하기)
- var isPaused: Bool
- 설명: 장면 그래프에서 액션, 애니메이션, 입자 시스템, 물리 시뮬레이션을 실행할지 여부를 결정하는 Boolean 값입니다.
Accessing Scene Contents (장면 내용 접근하기)
- var rootNode: SCNNode
- 설명: 장면 그래프의 루트 노드입니다.
- var background: SCNMaterialProperty
- 설명: 장면의 나머지 부분이 렌더링되기 전에 렌더링될 배경입니다.
- var lightingEnvironment: SCNMaterialProperty
- 설명: 장면의 콘텐츠를 둘러싼 환경을 묘사하는 큐브 맵 텍스처로, 고급 조명 효과에 사용됩니다.
Managing Scene Attributes (장면 속성 관리하기)
- func attribute(forKey: String) -> Any?
- 설명: 지정된 키에 대한 장면 속성을 반환합니다.
- func setAttribute(Any?, forKey: String)
- 설명: 지정된 키에 대해 장면 속성을 설정합니다.
- struct SCNScene.Attribute
- 설명: 장면 속성을 나타내는 구조체입니다.
Exporting a Scene File (장면 파일 내보내기)
- func write(to: URL, options: [String : Any]?, delegate: (any SCNSceneExportDelegate)?, progressHandler: SCNSceneExportProgressHandler?) -> Bool
- 설명: 장면과 그 콘텐츠를 지정된 URL의 파일로 내보냅니다.
- protocol SCNSceneExportDelegate
- 설명: 장면을 파일로 내보내는 과정에 참여하기 위해 구현할 수 있는 메서드를 제공합니다.
Adding Fog to a Scene (장면에 안개 추가하기)
- var fogStartDistance: CGFloat
- 설명: 관찰 지점에서 안개가 장면 콘텐츠를 가리기 시작하는 거리입니다. 애니메이션 가능합니다.
- var fogEndDistance: CGFloat
- 설명: 관찰 지점에서 안개가 장면 콘텐츠를 완전히 가리게 되는 거리입니다. 애니메이션 가능합니다.
- var fogDensityExponent: CGFloat
- 설명: 안개의 강도가 시작 거리와 끝 거리 사이에서 변하는 곡선입니다. 애니메이션 가능합니다.
- var fogColor: Any
- 설명: 장면에 렌더링될 안개 효과의 색상입니다. 애니메이션 가능합니다.
Working With Physics in the Scene (장면에서 물리와 작업하기)
- var physicsWorld: SCNPhysicsWorld
- 설명: 장면과 관련된 물리 시뮬레이션입니다.
Working with Particle Systems in the Scene (장면에서 입자 시스템과 작업하기)
- func addParticleSystem(SCNParticleSystem, transform: SCNMatrix4)
- 설명: 지정된 변환을 사용하여 장면에 입자 시스템을 첨부합니다.
- var particleSystems: [SCNParticleSystem]?
- 설명: 장면에 첨부된 입자 시스템 목록입니다.
- func removeParticleSystem(SCNParticleSystem)
- 설명: 장면에서 첨부된 입자 시스템을 제거합니다.
- func removeAllParticleSystems()
- 설명: 장면에 직접 첨부된 모든 입자 시스템을 제거합니다.
Constants (상수)
- Scene Attributes (장면 속성)
- 설명: attribute(forKey:) 및 setAttribute(_:forKey:) 메서드에 사용할 수 있는 속성 키입니다.
- Scene Export Options (장면 내보내기 옵션)
- 설명: write(to:options:delegate:progressHandler:) 메서드에 대한 옵션입니다.
- typealias SCNSceneExportProgressHandler
- 설명: SceneKit이 장면 내보내기 동안 호출하는 블록의 서명입니다.
Instance Properties (인스턴스 속성)
- var screenSpaceReflectionMaximumDistance: CGFloat
- 설명: 화면 공간 반사가 적용될 최대 거리입니다.
- var screenSpaceReflectionSampleCount: Int
- 설명: 화면 공간 반사를 샘플링할 때 사용할 샘플의 수입니다.
- var screenSpaceReflectionStride: CGFloat
- 설명: 화면 공간 반사의 샘플링 간격입니다.
- var wantsScreenSpaceReflection: Bool
- 설명: 장면이 화면 공간 반사를 원하는지 여부를 나타내는 Boolean 값입니다.
직접 만들어보자!
1. 프로젝트 생성
New -> Project -> App 선택을 해 빈 프로젝트를 만들어주자.
2. SceneKit Scene Editor로 Scene 만들기
obj 파일이 아닌 .scn 파일로 구현을 하면 더 간단하게 만들 수 있기 대문애 Scene Editor 를 만들어주자
1. File > New > File 선택
2. SceneKit Scene File 선택
3. obj 파일 scn 파일로 변환
기존에 가지고 있는 obj 파일을 import 해주어야하는데
따로 import 버튼이 없어 드래그 앤 드랍으로 가져오면 .scn 파일로 자동 변환이 된다.
4. .scn 파일 프로젝트에 추가하기
.scnassets 폴더에 .scn 파일이 추가되어 있을 것이다.
없다면 File > New > File > SceneKit Catalog 를 선택해서 원하는 이름으로 만들어준다.
5. 파일 불러오기
import SwiftUI
import SceneKit
struct ContentView: View {
var body: some View {
SceneView(scene: loadScene(), options: [
.autoenablesDefaultLighting,
.allowsCameraControl
])
.edgesIgnoringSafeArea(.all)
}
func loadScene() -> SCNScene {
// .scn 파일을 로드하여 장면을 반환합니다.
let scene = SCNScene(named: "Dols.scnassets/cupid.scn")
return scene ?? SCNScene()
}
}
이렇게 하면 간단하게 3D 모델을 출력해올 수 있다.