스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
RoomPlan으로 매개변수적 3D 룸 스캔 만들기
RoomPlan을 사용하면 앱에서 간단한 매개변수적 3D 룸 스캔을 빠르게 만들 수 있습니다. 이 API를 사용하여 룸 스캐닝 경험을 손쉽게 추가하는 방법을 알아보세요. 이 API를 도입하는 방법을 보여드리고, 3D 매개변수적 출력에 대해 살펴보며, 앱에서 모든 스캔에 대해 우수한 결과를 얻을 수 있는 모범 사례를 공유합니다.
리소스
관련 비디오
Tech Talks
WWDC23
WWDC22
-
다운로드
♪ 부드러운 힙합 음악 ♪ ♪ 안녕하세요, 전 Pravin이에요 Apple의 프로토타이핑 팀에서 일하고 있죠 안녕하세요, 전 Kai예요 비디오 엔지니어링 팀에서 일하죠 지난 몇 년간 Apple은 세상을 앱으로 끌어들이는 강력한 새 방법들을 만들어 냈죠 작년엔 Object Capture를 소개했습니다 실제 물체의 사진을 찍고 RealityKit의 Photogrammetry API를 사용해 앱에서 사용할 수 있는 3D 모델로 변환하는 거죠 Object Capture 이전에는 Scene Reconstruction API를 공개했습니다 공간의 기하학적 구조를 대략적으로 이해하고 앱에서 혁신적인 증강 현실 사용 사례를 가능하게 했죠 올해도 이런 발표를 하게 돼서 기쁘네요 RoomPlan이라는 새 프레임워크를 발표합니다 RoomPlan은 여러분의 방을 스캔할 수 있습니다 LiDAR를 지원하는 iPhone이나 iPad를 사용하죠 방과 방을 정의하는 물체들의 매개 변수 3D 모델을 앱에서 사용할 수 있도록 생성합니다 RoomPlan의 스캔 경험을 한번 보여 드리죠 RoomPlan은 정교한 기계 학습 알고리즘을 사용합니다 ARKit에 의해 구동되어 벽, 창문, 개구부 문뿐만 아니라 방을 정의하는 물체들인 벽난로, 소파, 탁자 진열장까지 감지하죠 RoomCaptureView API는 RealityKit을 사용하여 스캐닝과 동시에 렌더링하죠 스캔 환경을 앱에 쉽게 통합할 수 있습니다 스캔이 완료되면 RoomCaptureView는 여러분이 사용할 수 있게 사용하기에 적합한 후처리 결과를 제공하죠 처음으로 기계 학습과 컴퓨터 비전 알고리즘을 복잡하게 구현하지 않고도 사람들은 완전히 새로운 방식으로 본인의 방과 상호 작용 할 수 있습니다 예를 들어 인테리어 디자인 앱은 벽의 색상 변화를 미리 보고 방을 다시 칠하는 데 필요한 페인트 양을 정확히 계산할 수 있죠 이제 건축 앱을 통해 자기 방의 구조를 실시간으로 미리 보고 편집할 수 있습니다 부동산 앱을 통해 중개인은 이제 매물의 평면도와 3D 모델을 완벽하게 포착할 수 있죠 전자 상거래 앱은 실제 공간에서 제품 시각화를 통해 고객을 끌어들일 수 있습니다 이건 RoomPlan이 가능하게 하는 몇 가지 앱의 예일 뿐이죠 RoomPlan을 앱에 통합하는 게 얼마나 간단한지 알면 놀라실 거예요 자세히 살펴볼까요? RoomPlan을 사용하는 방법은 크게 두 가지가 있습니다 첫 번째는 차원이 다른 스캔 경험입니다 RoomPlan을 순조롭게 앱과 통합하는 방법이죠 두 번째는 Data API입니다 스캔의 실시간 매개 변수 데이터를 앱이 사용할 수 있도록 지원하면서 실제 사용에 적합한 결과물을 만들어 줍니다 이 두 가지 API를 사용해 최상의 스캔 결과를 얻을 수 있는 몇 가지 모범 사례를 추천해 드리죠 이 영상의 마지막에서 설명해 드릴게요 먼저 새로운 RoomCaptureView API를 사용해 앱에 가져올 수 있는 스캔 환경에 대해 이야기해 보죠 RoomCaptureView는 UIView의 하위 클래스로 앱에 쉽게 배치할 수 있습니다 오늘 발표에서는 세계 공간 스캔 피드백과 실시간 방 모델 생성 사용자 안내 및 지도에 대해 말씀드리죠 RoomCaptureView 기반의 스캔 중에 표시되는 디자인 요소를 자세히 살펴보겠습니다 RoomCaptureView를 활성화한 세션 중에 애니메이션 선은 감지한 벽과 창, 개구부와 방을 정의하는 물체들을 실시간으로 표시합니다 RoomCaptureView 하단에 실시간으로 생성된 대화형 3D 모델을 통해 스캔 진행률에 대한 개요를 한눈에 볼 수 있죠 마지막으로 텍스트 코칭은 최고의 스캔 결과물을 낼 수 있도록 안내합니다 간단한 4단계로 RoomCaptureView를 어떻게 사용하는지 살펴볼게요 먼저 ViewController에 참조자 RoomCaptureView를 생성합니다 2단계로 RoomCaptureSession 구성 개체에 대한 참조자를 생성합니다 3단계, 스캔 세션을 시작해 우리의 구성을 캡처 세션의 실행 함수에 전달합니다 마지막으로 우리 앱은 캡처 세션에 스캔 중단을 지시하죠 선택적으로 앱은 RoomCapture ViewDelegate 프로토콜을 따를 수 있고 제시된 후처리 결과물을 내보낸다거나 제시된 후처리 스캔 결과를 따로 처리할 수 있습니다 예를 들어 제공된 CapturedRoom 데이터 구조체에서 가능한 내보내기 함수를 호출해 결과를 USDZ로 내보낼 수 있습니다 RoomPlan을 여러분의 앱에 통합하는 건 이렇게나 간단합니다 여러분이 이 API로 뭘 만들지 정말 기대되네요 이제 제 동료 Kai가 RoomCaptureSession과 RoomPlan의 데이터 API에 대해 이야기하겠습니다 고마워요, Praveen 이 섹션에서는 Data API에 대해 설명합니다 스캔 중 기본 데이터 구조에 접근을 제공하고 스캔 환경의 맞춤형 시각화를 처음부터 구축하는 걸 도와주죠 기본 워크플로는 3단계로 구성됩니다 스캔, 프로세스, 내보내기입니다 스캔의 경우 캡처 세션을 설정하고 시작하는 방법과 캡처 프로세스를 표시하고 모니터링하는 법을 설명합니다 그다음 스캔 데이터가 어떻게 처리되고 최종 모델이 어떻게 수신되는지 살펴보겠습니다 마지막으로 출력 USD 파일을 생성하고 내보낼 수 있는 방법에 대해 설명하겠습니다 이 파일은 USD 워크플로에서도 사용되죠 이제 스캔 단계를 자세히 알아볼게요 RoomCaptureSession API를 사용해 세션을 설정하고 스캔을 계속하며 진행률을 표시합니다 코드로 보여 드릴게요 간단한 RealityKit 앱입니다 시작하려면 RoomPlan을 Swift 프로젝트로 가져오면 됩니다 여러분 앱의 ViewController에서 사용자 정의 유형을 사용해 결과를 시각화하고 RoomCaptureSession 인스턴스를 시작할 수 있습니다 또 RoomCaptureSession은 기본 AR 세션에 대한 핸들을 제공해 앱이 증강 현실 화면에 평면과 물체 경계 상자를 그릴 수 있게 합니다 RoomCaptureSession은 대리자 패턴을 적용합니다 ViewController 클래스에서 ViewController 자체를 captureSession의 대리자로 할당할 수 있습니다 그러면 ViewController가 RoomCaptureSession에서 실시간 업데이트를 가져올 수 있죠 이 업데이트에는 캡처 중에 사람들을 안내하기 위한 3D 모델과 지침이 포함되어 있습니다 이 업데이트를 가져오려면 ViewController가 RoomCaptureSessionDelegate 프로토콜을 준수하고 두 가지 메서드를 구현해야 합니다 첫 번째는 captureSession(_ session: didUpdate room:) 메서드로 CapturedRoom 데이터 구조를 실시간으로 얻게 됩니다 비주얼라이저는 이걸 사용해서 과정에 실시간 피드백을 제공하는 3D 모델의 AR 화면을 업데이트할 수 있죠 영상의 후반부에 CapturedRoom 구조에 대해 자세히 알아보겠습니다 이 메서드는 스캔하는 방에 대해 업데이트를 감지할 때 호출됩니다 두 번째 메서드는 captureSession(_ session: didProvide instruction:)입니다 이 메서드는 실시간 피드백을 포함하는 지시 구조를 제공합니다 비주얼라이저는 이 지시를 사용해 스캔하는 동안 사용자를 안내할 수 있죠 이 API가 제공하는 지시를 한번 살펴보겠습니다 이 지시에는 물체까지의 거리와 스캔 속도, 방의 조명 조정에 관한 내용이 있고 텍스처가 많은 방의 특정 영역에 초점을 맞추는 것도 포함되죠 이 지시 사항은 실시간 피드백으로 사람들을 안내하기 위해 스캔 중에 제공됩니다 다음은 프로세스 부분으로 넘어가겠습니다 이 섹션에서는 RoomBuilder 클래스를 사용해 스캔한 데이터를 처리하고 최종 3D 모델을 생성합니다 캡처한 데이터를 처리하는 첫 단계는 ViewController 클래스의 RoomBuilder 인스턴스를 시작하는 겁니다 다음은 캡처 과정 후 센서 데이터를 수신하기 위해 앱에서 메서드를 구현해야 합니다 앱에서 stop() 함수를 호출하거나 오류 때문에 RoomCaptureSession이 중단되면 CaptureRoomData 개체와 선택적 오류를 반환하기 위해 이 함수가 호출됩니다 마지막으로 캡처한 데이터를 처리하기 위해 roomBuilder의 비동기 roomModel(from:) 메서드를 대기 키워드로 호출합니다 이 방법은 스캔한 데이터를 처리하고 최종 3D 모델을 구축하기 위해 비동기로 실행되죠 지난해 WWDC에서 소개한 Swift의 비동기/대기 함수를 활용합니다 몇 초 후에 앱에서 최종 프리젠테이션을 위해 모델을 사용할 수 있습니다 자, 이제 CapturedRoom 데이터 구조에 대한 세부 사항과 앱에서 사용할 수 있도록 내보내는 방법을 알아보죠 제일 높은 층에는 CapturedRoom이 있습니다 표면과 물체로 구성되어 있죠 표면에는 반경 같은 곡선과 시작 각도와 끝나는 각도 평면의 네 가지 다른 모서리와 벽, 개구부, 창문, 문 등 건축 범주를 나타내는 고유한 속성이 포함돼 있습니다 개체에는 탁자, 침대, 소파 같은 가구 범주가 포함됩니다 표면과 물체는 공통 속성을 몇 가지 공유하는데요 우선 치수가 있고 신뢰도가 있죠 스캔한 표면 또는 물체에 대한 세 단계의 신뢰도를 말합니다 3D 변형 매트릭스와 고유 식별자가 있습니다 코드로는 어떻게 표현되는지 보시죠 CapturedRoom 구조체는 방의 요소를 온전히 매개 변수로 표현한 겁니다 벽, 개구부, 문, 창, 물체까지 다섯 가지의 속성이 있죠 처음 네 개의 요소는 표면 구조를 대표하는데요 2D 평면 건축 구조를 나타냅니다 오른쪽에 앞서 설명한 표면의 다양한 속성을 볼 수 있습니다 마지막 속성은 방에 있는 3D 물체의 배열로 직육면체로 표현됩니다 오른쪽에서 물체들의 다양한 속성을 볼 수 있습니다 이건 RoomPlan에서 지원하는 물체 유형 목록입니다 일반적인 가구 유형이 포함됩니다 예를 들어 소파, 탁자, 의자 침대 등이 있죠 마지막으로 내보내기 함수를 통해 이 CapturedRoom을 기존 워크플로의 USD나 USDZ 데이터로 내보낼 수 있습니다 Cinema 4D에서 USD로 내보낸 파일을 직접 여는 방법을 보여 주는 예시입니다 방의 계층적 데이터 구조와 방의 요소 또는 물체의 치수 및 위치를 훑어보고 편집할 수 있죠 또 기존의 USD 및 USDZ의 워크플로를 활용하여 스캔한 방의 렌더링을 부동산, 전자 상거래, 시설 인테리어 디자인 등 다양한 관련 앱에 추가할 수 있습니다 지금까지 우리는 스캔 경험과 기본 RoomPlan API에 대해 다뤘습니다 이제 RoomPlan에서 좋은 결과를 얻을 수 있도록 몇 가지 모범 사례를 살펴볼게요 스캔을 잘할 수 있는 권장 조건과 방을 선택할 때 주의해야 할 방의 요소 그리고 스캔과 열에 관련해 염두해야 할 고려 사항을 설명해 보겠습니다 RoomPlan API는 일반적인 가정에서 가장 일반적인 구조와 물체를 지원합니다 스캔하는 방의 조건 중에서 최대 크기가 가로로 약 9m, 세로 약 9m인 주거용 방에 가장 적합합니다 밝기도 API에 중요합니다 깨끗한 영상 스트림을 얻고 AR 추적 성능이 향상되죠 API 사용에는 최소 50lux에 더 높은 밝기가 권장됩니다 밤에 일반 가정 거실의 조도가 보통 이 정도입니다 하드웨어를 보면 RoomPlan API는 LiDAR 지원 iPhone과 iPad Pro 모델은 전부 가능합니다 API 활용도가 저하될 수 있는 몇 가지 특별한 조건이 있습니다 예를 들어 전신 길이의 거울이나 유리는 LiDAR 센서가 예상한 출력을 생성하는 데 어려움을 줍니다 높은 천장도 LiDAR 센서의 스캔 범위 한계를 초과할 수 있죠 또 매우 어두운 표면은 장치가 스캔하기 어려울 수 있습니다 더 나은 스캔 결과를 얻기 위해 고려할 사항이 몇 가지 있습니다 첫째로 높은 정확도를 요구하는 앱의 경우 스캔 전에 방을 준비하면 스캔 품질을 높일 수 있습니다 예를 들어 커튼을 열면 자연광이 더 많이 들어오고 창문이 닫히는 걸 줄일 수 있죠 스캔은 낮에 하는 게 더 적합합니다 문을 닫으면 방 외부의 불필요한 영역을 스캔할 가능성이 줄어듭니다 API로 좋은 스캔 결과를 얻기 위해서는 좋은 스캔 동작을 따르는 것도 매우 중요합니다 그래서 사용자 지시 대리자 메서드를 제공하는 거죠 스캔하는 동안 사람들에게 질감, 거리, 속도나 조명 조건 등에 대한 피드백을 제공합니다 또 주의해야 할 점은 배터리와 장치의 열입니다 좋은 스캔 경험을 보장하기 위해 RoomPlan API에서는 많은 최적화를 수행했습니다 그래도 반복적인 스캔이나 5분이 넘어가는 스캔은 피하는 게 좋습니다 피로한 건 물론이고 배터리가 방전되고 열 문제가 발생해서 앱의 사용자 환경에 영향을 줄 수 있죠 오늘 다룬 내용이 참 많은데요 새 API RoomPlan을 소개했습니다 여러분의 방을 캡처할 수 있는 직관적인 스캔 경험이자 환경을 이해하는 강력한 기계 학습 모델이죠 또 완전히 매개 변수화된 USD 출력 형식을 제공해 여러분의 앱에 쉽게 통합할 수 있습니다 새로운 RoomPlan 경험을 더 잘 설계하고 구현하는 방법에 대한 안내는 아래 있는 관련 영상을 참고해 주세요 이제 여러분의 앱에서 RoomPlan을 시도할 차례예요 새 API로 여러분이 뭘 만들지 기대됩니다 봐 주셔서 감사합니다 ♪
-
-
4:36 - RoomCaptureView API - Scan & Process
// RoomCaptureView API - Scan & Process import UIKit import RoomPlan class RoomCaptureViewController: UIViewController { var roomCaptureView: RoomCaptureView var captureSessionConfig: RoomCaptureSession.Configuration private func startSession() { roomCaptureView?.captureSession.run(configuration: captureSessionConfig) } private func stopSession() { roomCaptureView?.captureSession.stop() } }
-
5:00 - RoomCaptureView API - Export
// RoomCaptureView API - Export import UIKit import RoomPlan class RoomCaptureViewController: UIViewController { … func captureView(shouldPresent roomDataForProcessing: CapturedRoomData, error: Error?) -> Bool { // Optionally opt out of post processed scan results. return false } func captureView(didPresent processedResult: CapturedRoom, error: Error?) { // Handle final, post processed results and optional error. // Export processedResults … try processedResult.export(to: destinationURL) … } }
-
6:50 - RoomCaptureSession - setup previewVisualizer
import UIKit import RealityKit import RoomPlan import ARKit class ViewController: UIViewController { @IBOutlet weak var arView: ARView! var previewVisualizer: Visualizer! lazy var captureSession: RoomCaptureSession = { let captureSession = RoomCaptureSession() arView.session = captureSession.arSession return captureSession }() override func viewDidLoad() { super.viewDidLoad() captureSession.delegate = self // set up previewVisualizer } }
-
7:40 - RoomCaptureSession - live results and user instructions
// Getting live results and user instructions extension ViewController: RoomCaptureSessionDelegate { func captureSession(_ session: RoomCaptureSession, didUpdate room: CapturedRoom) { previewVisualizer.update(model: room) } func captureSession(_ session: RoomCaptureSession, didProvide instruction: Instruction) { previewVisualizer.provide(instruction) } }
-
9:12 - Setup RoomBuilder
// RoomBuilder import UIKit import RealityKit import RoomPlan import ARKit class ViewController: UIViewController { @IBOutlet weak var arView: ARView! var previewVisualizer: Visualizer! // set up RoomBuilder var roomBuilder = RoomBuilder(options: [.beautifyObjects]) }
-
9:30 - RoomBuilder - generate final 3D CapturedRoom
// RoomBuilder with the latest CapturedRoomData to generate final 3D CapturedRoom extension ViewController: RoomCaptureSessionDelegate { func captureSession(_ session: RoomCaptureSession, didEndWith data: CapturedRoomData, error: Error?) { if let error = error { print("Error: \(error)") } Task { let finalRoom = try! await roomBuilder.capturedRoom(from: data) previewVisualizer.update(model: finalRoom) } } }
-
11:20 - CapturedRoom and export
// CapturedRoom and export public struct CapturedRoom: Codable, Sendable { public let walls: [Surface] public let doors: [Surface] public let windows: [Surface] public let openings: [Surface] public let objects: [Object] public func export(to url: URL) throws // Surface definitions ... // Object definitions ... }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.