Hướng dẫn này cho bạn biết cách sử dụng SDK của Cardboard dành cho iOS để tạo trải nghiệm Thực tế ảo (VR) của riêng bạn.
Bạn có thể sử dụng SDK của Cardboard để biến điện thoại thông minh thành nền tảng thực tế ảo. Điện thoại thông minh có thể hiển thị cảnh 3D ở chế độ kết xuất lập thể, theo dõi và phản ứng với chuyển động của đầu, cũng như tương tác với ứng dụng bằng cách phát hiện khi người dùng nhấn nút trình xem.
Để bắt đầu, bạn sẽ sử dụng HelloCardboard, một trò chơi minh hoạ minh hoạ các tính năng cốt lõi của SDK Cardboard. Trong trò chơi, người dùng sẽ nhìn xung quanh một thế giới ảo để tìm và thu thập các vật thể. Hướng dẫn này sẽ hướng dẫn bạn cách:
- Thiết lập môi trường phát triển
- Tải và tạo ứng dụng minh hoạ
- Quét mã QR của thiết bị xem Cardboard để lưu các thông số của thiết bị
- Theo dõi cử động đầu của người dùng
- Kết xuất hình ảnh nổi bằng cách đặt độ méo chính xác cho mỗi mắt
Thiết lập môi trường phát triển
Yêu cầu về phần cứng:
- iPhone chạy iOS 12.0 trở lên
- Thiết bị xem Cardboard
Yêu cầu về phần mềm:
- Xcode 12.5 trở lên
- CocoaPods 1.9 trở lên
Tải và tạo ứng dụng minh hoạ
SDK của Cardboard được xây dựng bằng các tệp nguồn C++ có Vùng đệm giao thức được biên dịch trước. Bạn có thể xem các bước để tạo tệp nguồn từ đầu tại đây.
Sao chép SDK Cardboard và ứng dụng minh hoạ Hello Cardboard từ GitHub bằng cách chạy lệnh sau:
git clone https://github.com/googlevr/cardboard.git
Cài đặt phần phụ thuộc Protocol Buffers (Vùng đệm giao thức) vào dự án Xcode bằng cách chạy lệnh này tại gốc kho lưu trữ:
pod install
Mở không gian làm việc của Cardboard (
Cardboard.xcworkspace
) trong Xcode.Hãy thay đổi mã nhận dạng gói của ứng dụng để có thể ký ứng dụng với nhóm của mình.
Chuyển đến SDK > Xây dựng giai đoạn > Liên kết tệp nhị phân với thư viện
- Xoá
libPods-sdk.a
khỏi danh sách bằng cách chọn mục đó rồi nhấp vào nút "+". - Thêm
libProtobuf-C++.a
vào danh sách bằng cách nhấp vào nút dấu "+" rồi chọn. Trong trường hợp bật lên thông báo gợi ý sử dụng XCFramework, hãy nhấp vào "Vẫn thêm".
- Xoá
Nhấp vào Chạy.
Quét mã QR
Để lưu thông số thiết bị, hãy quét mã QR trên thiết bị xem Cardboard:
Dùng thử bản trình diễn
Trong HelloCardboard, bạn sẽ tìm kiếm và thu thập các quả cầu trắc địa trong không gian 3D.
Để tìm và thu thập hình cầu:
Di chuyển đầu theo hướng bất kỳ cho đến khi bạn nhìn thấy một quả cầu trôi nổi.
Nhìn thẳng vào quả cầu. Thao tác này sẽ làm thay đổi màu sắc.
Nhấn nút thiết bị xem Cardboard để "thu thập" hình cầu.
Định cấu hình thiết bị
Khi người dùng nhấn vào biểu tượng bánh răng để chuyển đổi thiết bị xem Cardboard, phương thức didTapSwitchButton
sẽ được gọi trong HelloCardboardOverlayView
.
- (void)didTapSwitchButton:(id)sender {
if ([self.delegate respondsToSelector:@selector(didTapBackButton)]) {
[self.delegate didChangeViewerProfile];
}
self.settingsBackgroundView.hidden = YES;
}
Thao tác này sẽ gọi CardboardQrCode_scanQrCodeAndSaveDeviceParams
để mở cửa sổ để quét mã QR của người xem. Khi người dùng quét mã QR, các tham số méo hình của thiết bị sẽ được cập nhật.
- (void)switchViewer {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
- (void)didChangeViewerProfile {
[self pauseCardboard];
[self switchViewer];
[self resumeCardboard];
}
Theo dõi chuyển động của đầu
Tạo thiết bị theo dõi chuyển động của đầu
Trình theo dõi chuyển động được tạo một lần trong phương thức viewDidLoad
của HelloCardboardViewController
:
_cardboardHeadTracker = CardboardHeadTracker_create();
Tạm dừng và tiếp tục thiết bị theo dõi chuyển động của đầu
Phương thức pauseCardboard
và resumeCardboard
trong lớp HelloCardboardViewController
sẽ tạm dừng và tiếp tục trình theo dõi chuyển động tương ứng. resumeCardboard
cũng đặt cờ _updateParams
, điều này khiến các tham số thiết bị được cập nhật trong lệnh gọi vẽ tiếp theo.
- (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;
}
Biến dạng ống kính
Mỗi khi Cardboard quét một mã QR mới, mã sau đây sẽ đọc các thông số đã lưu và sử dụng các thông số đó để tạo đối tượng méo ống kính, từ đó áp dụng độ méo ống kính thích hợp cho nội dung đã kết xuất:
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));
Kết xuất
Quá trình kết xuất nội dung trong Cardboard bao gồm những yếu tố sau:
- Tạo hoạ tiết
- Lấy ma trận nhìn và chiếu cho mắt trái và mắt phải
- Tạo trình kết xuất đồ hoạ và thiết lập lưới biến dạng
- Kết xuất từng khung
Tạo hoạ tiết
Nội dung được vẽ trên một hoạ tiết, được chia thành các phần cho mắt trái và mắt phải.
Các phần này lần lượt được khởi tạo trong _leftEyeTexture
và _rightEyeTexture
.
Ứng dụng mẫu sử dụng một hoạ tiết duy nhất cho cả hai mắt, nhưng bạn cũng có thể tạo một hoạ tiết riêng cho mỗi mắt.
// 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");
Các hoạ tiết này được truyền dưới dạng tham số cho CardboardDistortionRenderer_renderEyeToDisplay
.
Lấy ma trận nhìn và chiếu cho mắt trái và mắt phải
Trước tiên, hãy truy xuất ma trận mắt cho mắt trái và mắt phải:
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]);
Tiếp theo, hãy lấy lưới biến dạng cho mỗi mắt rồi truyền đến trình kết xuất biến dạng:
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kLeft, &leftMesh);
CardboardLensDistortion_getDistortionMesh(_lensDistortion, kRight, &rightMesh);
Tạo trình kết xuất đồ hoạ và thiết lập đúng lưới méo
Trình kết xuất chỉ cần được khởi chạy một lần. Sau khi tạo trình kết xuất, hãy thiết lập lưới méo mới cho mắt trái và mắt phải theo các giá trị lưới được hàm CardboardLensDistortion_getDistortionMesh
trả về.
_distortionRenderer = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(_distortionRenderer, &leftMesh, kLeft);
CardboardDistortionRenderer_setMesh(_distortionRenderer, &rightMesh, kRight);
Hiển thị nội dung
Truy xuất hướng đầu hiện tại từ CardboardHeadTracker_getPose
:
CardboardHeadTracker_getPose(_headTracker, targetTime, position, orientation);
_headView =
GLKMatrix4Multiply(GLKMatrix4MakeTranslation(position[0], position[1], position[2]),
GLKMatrix4MakeWithQuaternion(GLKQuaternionMakeWithArray(orientation)));
Sử dụng hướng đầu hiện tại với ma trận khung nhìn và ma trận chiếu để tạo ma trận phép chiếu khung hiển thị và sử dụng các ma trận này để kết xuất nội dung thế giới cho mỗi mắt:
// 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]));
Sử dụng CardboardDistortionRenderer_renderEyeToDisplay
để áp dụng tính năng chỉnh sửa độ méo cho nội dung và hiển thị nội dung đó trên màn hình.
CardboardDistortionRenderer_renderEyeToDisplay(_distortionRenderer, renderTarget, /*x=*/0,
/*y=*/0, _width, _height, &_leftEyeTexture,
&_rightEyeTexture);