iOS용 Google Cardboard 빠른 시작

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

이 가이드에서는 iOS용 Cardboard SDK를 사용하여 자체 가상 현실 (VR) 환경을 만드는 방법을 보여줍니다.

Cardboard SDK를 사용하여 스마트폰을 VR 플랫폼으로 변환할 수 있습니다. 스마트폰은 입체 렌더링으로 3D 장면을 표시하고, 머리 움직임을 추적 및 반응하며, 사용자가 뷰어 버튼을 누르는 시점을 감지하여 앱과 상호작용할 수 있습니다.

시작하려면 Cardboard SDK의 핵심 기능을 보여주는 데모 게임인 HelloCardboard를 사용합니다. 게임에서 사용자는 가상 세계를 둘러보며 객체를 찾고 수집합니다. 다음 방법을 안내합니다.

  • 개발 환경 설정
  • 데모 앱 다운로드 및 빌드
  • Cardboard 뷰어의 QR 코드를 스캔하여 매개변수를 저장하세요.
  • 사용자의 머리 움직임 추적
  • 각 눈의 올바른 왜곡을 설정하여 입체 이미지를 렌더링합니다.

개발 환경 설정

하드웨어 요구사항:

소프트웨어 요구사항:

데모 앱 다운로드 및 빌드

Cardboard SDK는 사전 컴파일된 프로토콜 버퍼 C++ 소스 파일을 사용하여 빌드됩니다. 소스 파일을 처음부터 빌드하는 단계는 여기에서 확인할 수 있습니다.

  1. 다음 명령어를 실행하여 GitHub에서 Cardboard SDK 및 Hello Cardboard 데모 앱을 클론합니다.

    git clone https://github.com/googlevr/cardboard.git
  2. 저장소 루트에서 다음 명령어를 실행하여 프로토콜 버퍼 종속 항목을 Xcode 프로젝트에 설치합니다.

    pod install
  3. Xcode에서 Cardboard 작업공간 (Cardboard.xcworkspace)을 엽니다.

  4. 팀과 함께 앱에 서명할 수 있도록 앱의 번들 ID를 변경합니다.

  5. SDK > Build Phases > Link Binary With Libraries로 이동합니다.

    1. libPods-sdk.a를 선택하고 '-' 버튼을 클릭하여 목록에서 삭제합니다.
    2. '+' 버튼을 클릭하고 선택하여 libProtobuf-C++.a를 목록에 추가합니다. XCFramework 사용을 제안하는 메시지가 표시되면 "Add Anyway;를 클릭합니다.
  6. 실행을 클릭합니다.

QR 코드 스캔

기기 매개변수를 저장하려면 Cardboard 뷰어에서 QR 코드를 스캔하세요.

데모 사용해 보기

HelloCardboard에서 3D 공간에서 측지 구를 찾고 수집합니다.

구를 찾고 수집하려면 다음 단계를 따르세요.

  1. 플로팅 구가 표시될 때까지 머리를 원하는 방향으로 움직입니다.

  2. 구체를 직접 보세요. 이로 인해 색상이 변경됩니다.

  3. Cardboard 뷰어 버튼을 눌러 구를 수집하세요.

기기 구성

사용자가 톱니바퀴 아이콘을 탭하여 Cardboard 뷰어를 전환하면 didTapSwitchButton 메서드가 HelloCardboardOverlayView에서 호출됩니다.

- (void)didTapSwitchButton:(id)sender {
  if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
    [self.delegate didChangeViewerProfile];
  }
  self.settingsBackgroundView.hidden = YES;
}

그러면 CardboardQrCode_scanQrCodeAndSaveDeviceParams가 호출되어 뷰어의 QR 코드를 스캔하는 창이 열립니다. 사용자가 QR 코드를 스캔하면 기기 왜곡 매개변수가 업데이트됩니다.

- (void)switchViewer {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

- (void)didChangeViewerProfile {
  [self pauseCardboard];
  [self switchViewer];
  [self resumeCardboard];
}

머리 추적

헤드 추적기 만들기

헤드 추적기는 HelloCardboardViewControllerviewDidLoad 메서드에서 한 번 생성됩니다.

_cardboardHeadTracker = CardboardHeadTracker_create();

헤드 추적기 일시중지 및 재개

HelloCardboardViewController 클래스의 pauseCardboardresumeCardboard 메서드는 각각 헤드 추적기를 일시중지하고 다시 시작합니다. 또한 resumeCardboard는 다음 그리기 호출에서 기기 매개변수가 업데이트되도록 하는 _updateParams 플래그를 설정합니다.

- (void)pauseCardboard {
  self.paused = true;
  CardboardHeadTracker_pause(_cardboardHeadTracker);
}

- (void)resumeCardboard {
  // Parameters may have changed.
  _updateParams = YES;

  // Check for device parameters existence in app storage. If they're missing,
  // we must scan a Cardboard QR code and save the obtained parameters.
  uint8_t *buffer;
  int size;
  CardboardQrCode_getSavedDeviceParams(&buffer, &size);
  if (size == 0) {
    [self switchViewer];
  }
  CardboardQrCode_destroy(buffer);

  CardboardHeadTracker_resume(_cardboardHeadTracker);
  self.paused = false;
}

렌즈 왜곡

Cardboard가 새 QR 코드를 스캔할 때마다 다음 코드가 저장된 매개변수를 읽고 이를 사용하여 렌즈 왜곡 객체를 만듭니다. 이 객체는 렌더링된 콘텐츠에 적절한 렌즈 왜곡을 적용합니다.

CardboardQrCode_getSavedDeviceParams(&encodedDeviceParams, &size);

// Create CardboardLensDistortion.
CardboardLensDistortion_destroy(_cardboardLensDistortion);
_cardboardLensDistortion =
    CardboardLensDistortion_create(encodedDeviceParams, size, width, height);

// Initialize HelloCardboardRenderer.
_renderer.reset(new cardboard::hello_cardboard::HelloCardboardRenderer(
      _cardboardLensDistortion, _cardboardHeadTracker, width, height));

렌더링

Cardboard에서 콘텐츠를 렌더링하려면 다음이 필요합니다.

  • 텍스처 만들기
  • 왼쪽 및 오른쪽 눈의 뷰 및 투영 매트릭스 가져오기
  • 렌더기 만들기 및 왜곡 메시 설정
  • 각 프레임 렌더링

텍스처 만들기

콘텐츠는 텍스처에 그려지고 왼쪽과 오른쪽 눈의 섹션으로 분할됩니다. 이러한 섹션은 각각 _leftEyeTexture_rightEyeTexture에서 초기화됩니다. 샘플 앱은 양쪽 눈에 단일 텍스처를 사용하지만 각 눈마다 별도의 텍스처를 만들 수도 있습니다.

// Generate texture to render left and right eyes.
glGenTextures(1, &_eyeTexture);
glBindTexture(GL_TEXTURE_2D, _eyeTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

_leftEyeTexture.texture = _eyeTexture;
_leftEyeTexture.left_u = 0;
_leftEyeTexture.right_u = 0.5;
_leftEyeTexture.top_v = 1;
_leftEyeTexture.bottom_v = 0;

_rightEyeTexture.texture = _eyeTexture;
_rightEyeTexture.left_u = 0.5;
_rightEyeTexture.right_u = 1;
_rightEyeTexture.top_v = 1;
_rightEyeTexture.bottom_v = 0;
CheckGLError("Create Eye textures");

이러한 텍스처는 CardboardDistortionRenderer_renderEyeToDisplay에 매개변수로 전달됩니다.

왼쪽 및 오른쪽 눈의 뷰 및 투영 매트릭스 가져오기

먼저 왼쪽 및 오른쪽 눈의 눈 행렬을 검색합니다.

CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kLeft, _eyeMatrices[kLeft]);
CardboardLensDistortion_getEyeFromHeadMatrix(_lensDistortion, kRight, _eyeMatrices[kRight]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kLeft, kZNear, kZFar,
                                            _projMatrices[kLeft]);
CardboardLensDistortion_getProjectionMatrix(_lensDistortion, kRight, kZNear, kZFar,
                                            _projMatrices[kRight]);

그런 다음 각 눈의 왜곡 메시를 가져와 왜곡 렌더기에 전달합니다.

CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);

렌더기 만들기 및 올바른 왜곡 메시 설정

렌더러는 한 번만 초기화하면 됩니다. 렌더기가 생성되면 CardboardLensDistortion_getDistortionMesh 함수에서 반환된 메시 값에 따라 왼쪽 및 오른쪽 눈에 대한 새 왜곡 메시를 설정합니다.

_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);

콘텐츠 렌더링

CardboardHeadTracker_getPose에서 현재 헤드 방향을 검색합니다.

CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
    GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
                       GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));

뷰 및 투영 매트릭스와 함께 현재 헤드 방향을 사용하여 뷰 투영 매트릭스를 구성하고 이를 사용하여 각 눈의 세계 콘텐츠를 렌더링합니다.

// Draw left eye.
glViewport(0, 0, _width / 2.0, _height);
glScissor(0, 0, _width / 2.0, _height);
DrawWorld(_leftEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kLeft]));

// Draw right eye.
glViewport(_width / 2.0, 0, _width / 2.0, _height);
glScissor(_width / 2.0, 0, _width / 2.0, _height);
DrawWorld(_rightEyeViewPose, GLKMatrix4MakeWithArray(_projMatrices[kRight]));

CardboardDistortionRenderer_renderEyeToDisplay을 사용하여 왜곡 수정을 콘텐츠에 적용하고 화면에 콘텐츠를 렌더링합니다.

CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
                                               /*y=*/0, _width, _height, &_leftEyeTexture,
                                               &_rightEyeTexture);