คู่มือนี้จะแสดงวิธีใช้ Cardboard SDK สำหรับ iOS เพื่อสร้างประสบการณ์ Virtual Reality (VR) ของคุณเอง
คุณใช้ Cardboard SDK เพื่อเปลี่ยนสมาร์ทโฟนเป็นแพลตฟอร์ม VR ได้ สมาร์ทโฟนสามารถแสดงฉาก 3 มิติพร้อมการแสดงภาพสามมิติ ติดตามและตอบสนองต่อการเคลื่อนไหวของศีรษะ และโต้ตอบกับแอปด้วยการตรวจจับเมื่อผู้ใช้กดปุ่มบนแว่น
ในการเริ่มต้นใช้งาน คุณจะใช้ HelloCardboard ซึ่งเป็นเกมสาธิตที่สาธิตฟีเจอร์หลักๆ ของ Cardboard SDK ในเกม ผู้ใช้สำรวจโลกเสมือนเพื่อค้นหาและเก็บวัตถุ ซึ่งจะแสดงวิธีการต่อไปนี้
- ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์
- ดาวน์โหลดและสร้างแอปเดโม
- สแกนคิวอาร์โค้ดของแว่น Cardboard เพื่อบันทึกพารามิเตอร์
- ติดตามการเคลื่อนไหวศีรษะของผู้ใช้
- แสดงภาพสามมิติโดยการตั้งค่าความผิดเพี้ยนที่ถูกต้องสำหรับตาแต่ละข้าง
ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์
ข้อกำหนดเกี่ยวกับฮาร์ดแวร์
- iPhone ที่ใช้ iOS 12.0 ขึ้นไป
- แว่น Cardboard
ข้อกำหนดของซอฟต์แวร์
- Xcode 12.5 ขึ้นไป
- CocoaPods 1.9 ขึ้นไป
ดาวน์โหลดและสร้างแอปเดโม
Cardboard SDK สร้างขึ้นโดยใช้ไฟล์ซอร์ส Protocol Buffers ที่คอมไพล์ไว้ล่วงหน้า ดูขั้นตอนการสร้างไฟล์ต้นฉบับตั้งแต่ต้นได้ที่นี่
โคลน SDK ของ Cardboard และแอปสาธิต Hello Cardboard จาก GitHub โดยเรียกใช้คำสั่งนี้
git clone https://github.com/googlevr/cardboard.git
ติดตั้งการพึ่งพา Protocol Buffers ในโปรเจ็กต์ Xcode โดยเรียกใช้คำสั่งนี้ที่รูทของที่เก็บ:
pod install
เปิดพื้นที่ทำงานของ Cardboard (
Cardboard.xcworkspace
) ใน Xcodeเปลี่ยนรหัสชุดของแอปเพื่อให้คุณลงนามแอปกับทีมได้
ไปที่ SDK > สร้างระยะ > ลิงก์ไบนารีกับไลบรารี
- นำ
libPods-sdk.a
ออกจากรายการด้วยการเลือกดังกล่าวแล้วคลิกปุ่ม "-" - เพิ่ม
libProtobuf-C++.a
ในรายการโดยคลิกที่ปุ่ม "+" แล้วเลือก ในกรณีที่มีข้อความแนะนำให้ใช้ XCFramework ปรากฏขึ้น ให้คลิก "เพิ่มทันที"
- นำ
คลิกเรียกใช้
สแกนคิวอาร์โค้ด
หากต้องการบันทึกพารามิเตอร์ของอุปกรณ์ ให้สแกนคิวอาร์โค้ดบนแว่น Cardboard ดังนี้
ลองใช้เดโม
ใน HelloCardboard คุณจะค้นหาและรวบรวมทรงกลมลูกโลกในพื้นที่ 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 ของผู้ชม เมื่อผู้ใช้สแกนคิวอาร์โค้ด ระบบจะอัปเดตพารามิเตอร์การบิดเบี้ยวของอุปกรณ์
- (void)switchViewer {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
- (void)didChangeViewerProfile {
[self pauseCardboard];
[self switchViewer];
[self resumeCardboard];
}
การติดตามการเคลื่อนไหวของศีรษะ
สร้างเครื่องมือติดตามศีรษะ
ระบบจะสร้างอุปกรณ์ติดตามศีรษะขึ้น 1 ครั้งในเมธอด viewDidLoad
ของ HelloCardboardViewController
ดังนี้
_cardboardHeadTracker = CardboardHeadTracker_create();
หยุดติดตามศีรษะชั่วคราวและกลับมาใช้งานอีกครั้ง
เมธอด pauseCardboard
และ resumeCardboard
ในคลาส HelloCardboardViewController
จะหยุดชั่วคราวและกลับมาใช้เครื่องติดตามศีรษะต่อตามลำดับ 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 สแกนคิวอาร์โค้ดใหม่ โค้ดต่อไปนี้จะอ่านพารามิเตอร์ที่บันทึกไว้ และนำไปใช้ในการสร้างวัตถุที่บิดเบี้ยวของเลนส์ ซึ่งทำให้มีการบิดเบี้ยวของเลนส์อย่างเหมาะสม กับเนื้อหาที่แสดงผล
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
ตามลำดับ
แอปตัวอย่างใช้พื้นผิวเดียวสำหรับตาทั้ง 2 ข้าง แต่ก็สามารถสร้างพื้นผิวแยกกันสำหรับดวงตาแต่ละข้างได้
// 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);
สร้างโหมดแสดงภาพและตั้งค่าตาข่ายการบิดเบี้ยวที่ถูกต้อง
โหมดแสดงภาพต้องเริ่มต้นเพียงครั้งเดียว เมื่อสร้างตัวแสดงผลแล้ว ให้ตั้งค่าตาข่ายการบิดเบี้ยวใหม่สำหรับตาซ้ายและขวาตามค่า Mesh ที่แสดงผลจากฟังก์ชัน 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);