Praneat Blog

sai
20 Apr 2020

ARCore in Unity

ARCore คืออะไร

ARCore เป็น ชุดพัฒนาซอฟต์แวร์เกียวกับ Augmented Reality ใน มือถือ Android
ก่อนหน้านี้ Google เคยเปิดตัวเทคโนโลยี Augmented Reality มาก่อนคือโปรเจ็ค Tango
ซึ่งโปรเจ็ค Tango มีข้อเสียคือต้องใช้ฮาร์ดแวร์เฉพาะทาง มือถือทั่วไปไม่สามารถใช้งานได้
Google จึงได้พัฒนาต่อมาเป็น ARCore ที่สามารถใช้งานในมือถือ Android ธรรมดาทั่วไปก็ได้

ARCore ยังอยู่ในช่วงการทดลอง ตอนนี้มีเครื่องที่รองรับแค่ไม่กี่เครื่องคือ Google Pixel และ Samsung Galaxy S8 เท่านั้น แต่ก็จะมีเพิ่มขึ้นอีกในอนาคต

ในความจริง หลายเครื่องที่ Google ยังไม่รองรับ ARCore แต่จริงๆสามารถทำงานได้
หากใครสนใจให้เครื่องทำงานได้เข้าไปดูในลิงค์นี้ https://github.com/tomthecarrot/arcore-for-all

ความสามารถของ ARCore

ARCore มีความสามารถหลักๆ อยู่ 3 อย่างคือ

1.Motion tracking

ARCore ได้ใช้กระบวนการ COM เพื่อสามารถรับรู้ตำแหน่งของมือถือในพื้นรอบๆได้
โดย ARCore จะตรวจจับภาพ จับตำแหน่งของมือถือในขณะเคลื่อนไหวและสร้างโลกจำลองของตัวมันเองขึ้นมา
รูปลักษณที่แตกต่างและชัดเจนจากภาพ ออกมาเป็น Feature Point เป็นจุดต่างๆ

2.Environmental understanding

สามารถรับรู้สภาพแวดล้อม โดยจะตรวจจับจากจุด Feature Point ต่างๆมาคำนวณหาออกมาเป็นพื้นผิวแนวนอน เป็น Planes ใน App
แต่เพราะใช้การตรวจจับจากจุด Feature Point พื้นผิวที่ไม่มี Texture เช่น โต๊ะสีขาว อาจไม่สามารถตรวจจับได้

3.Light estimation

ARCore สามารรับรู้แสงของสภาพแวดล้อมและนำข้อมูลที่ได้ไปจำลองแสงเงาของวัตถุใน App

Start with Unity

คำศัพท์ที่ควรรู้สำหรับ ARCore

Session เก็บข้อมูลสถานะทั้งหมดของ ARCore จัดการเรื่องการ Anchor และ Planes
และทำการจำลองยิง Raycast ใส่วัตถุ

Frame เก็บข้อมูลสถานะ ของ ARcore รวมทั้ง สถานะของการตรวจจับวัตถุ Pose ของกล้อง
ค่าของแสง และข้อมูลของ Object ที่ ARCore พบเจอ

Plane คือ แผ่นพื้นผิวในโลกจริงที่ ARCore ตรวจจับได้

Anchor คือ จุดยึด มีข้อมูล Position Rotation เกี่ยวกับ Object ไปใน Global Coordinate System
ซึ่งจะเอาใช้กับ GameObject ในการจดจำแก้ไขตำแหน่งเวลามีการเครื่องไหวของกล้อง
ถ้า ARCore ไม่สามารถตรวจจับ anchor ได้ GameObject ที่เชื่อมต่ออยู่ด้วยจะถูก Inactive ไป

Pose คือ การตำแหน่งพิกัดของ Object ใน World Coordinate Frame

Light Estimate เป็น การประเมินแสงของสภาพแวดล้อมของ ARCore จะออกมาเป็นความเข้มของ pixel มึค่า 0.0 (สีดำ)ถึง 1.0(สีขาว)

1. การเตรียมโปรแกรม

  1. ลง Android SDK version 7.0 ขึ้นไป
  2. ลง Unity 2017.2 Beta 11 และลง Android Build Support
  3. โหลด SDK Preview for Unity สำหรับ Unity

สำหรับ Device ที่ใช้ทดลอง

  1. เปิดทำงาน developer options และ USB debugging
  2. ดาวโหลด ARCore Service
  3. ลง ARCore Service ผ่าน adb command

2. เริ่มสร้าง Project

  1. สร้าง Project ใหม่ขึ้นมา
  2. ทำการ import ARCore SDK
  3. Build Setting ทำการ Switch Platform เป็น Android
  4. Player Setting ทำการตั้งค่าดังนี้
    • Other Settings > Multithreaded Rendering: Off
    • Other Settings > Package Name: ตั้งชื่อ unique app ID
    • Other Settings > Minimum API Level: Android 7.0 or higher
    • Other Settings > Target API Level: Android 7.0 or 7.1
    • XR Settings > ARCore Supported: On

ใน SDK จะมีตัวอย่างโค้ดให้ดูอยู่ ชื่อ HelloARExample เป็นโดยเป็นแอพที่เมื่อเราคลิกที่พื้นจะสร้างหุ่นกระป่องแอนดรอยขึ้นมา

2 Object หลักๆที่ต้องมีใน Scene คือ ARCore Device กับ Environmental Light

ARCore Device จะมีทั้งกล้องใน Scene, Setting ของ Driver และ Setting ของ Session สำหรับทำงาน AR Session

โดยปกติ Update Type เป็น Before Render เพื่อมั่นใจว่าให้กล้องใน Scene Sync ตรงกับกล้องในโลกจริง

Environmental Light จะเป็น Component ที่จะส่งค่าแสงของโลกจริงไปให้ ARCore shaders ให้แสดงผลแสงเงาของ Object


Shader แนะนำใช้ของที่ ARCore ให้มา หรือจะเขียนขึ้นมาเองก็ได้ไม่ยาก ตัวของ ARCore นั้นรองรับ ambient light ได้

3. Placing Object

Anchors

สร้าง Anchor ขึ้นมา และเอา Object มาติดกับ Anchor
ควรเอา Digital object ติดกับ Physical object เพื่อให้ตำแหน่งถูกต้องมากขึ้น และหลีกเลี่ยงการใช้ Global Coordinate System

ตัวอย่าง Code ในการสร้าง Anchor และ สร้าง Object มาติดกับ Anchor

var anchor = Session.CreateAnchor(hit.Point, Quaternion.identity);

var andyObject = Instantiate(m_andyAndroidPrefab, hit.Point, Quaternion.identity,anchor.transform);         

Planes

มีให้เลือกระหว่าง แผ่นเดียว หรือจะ มีหลายแผ่นได้
ตัวPlanes ใช้เวลาและอาจจะต้องมีการขยับรอบๆ ในการตรวจจับได้
สามารถเข้าถึงPlanesได้โดยใช้ Frane.GetAllPlanes() และสามารถเช็คทิศทาศการชนโดยใช้ Session.Raycast

ตัวอย่าง Code การหา Plane เพื่อเปิดปิด UI

bool showSearchingUI = true;
Frame.GetAllPlanes(ref m_allPlanes);
for (int i = 0; i < m_allPlanes.Count; i++)
{
   if (m_allPlanes[i].IsValid)
   {
     showSearchingUI = false;
     break;
   }
}
m_searchingForPlaneUI.SetActive(showSearchingUI);

ตัวอย่าง Code เช็คการโดนของ Raycast กับ Plane

TrackableHit hit;
TrackableHitFlag raycastFilter = 
TrackableHitFlag.PlaneWithinBounds | TrackableHitFlag.PlaneWithinPolygon;

    if(Session.Raycast(m_firstPersonCamera.ScreenPointToRay(touch.position), raycastFilter, out hit))
    {
            //Do something on hit 
    }

ตัวอย่างหน้าตาของเกมจะออกมาเป็นแบบนี้

หากสนใจสามารถศึกษาต่อเพิ่มเติมได้ในลิงค์นี้ https://developers.google.com/ar/develop/unity/getting-started