前言
關於AR和Unity的基礎知識,請自行前往各自的文檔中心進行科普。
本文以國產的HiAR SDK為例,日后將嘗試高通的vuforia SDK
我的環境
基於Hi AR1.2.0 ( hiar_sdk_unity_20160809_v1.2.0_3c0e908.zip ( 47.4 MB ) )
Unity3D 5.3.5f1 x64
Windows 7 x64
羅技攝像頭(硬件),攝像頭支架
制作識別圖集
1. 在SDK的管理后台創建一個新應用,獲取應用的Appkey和Secret,在Unity中會用到。
2. 在SDK的管理后台中創建圖集,並添加圖片,完成之后發布圖集
3. 把圖集和應用進行關聯
4. 在SDK的管理后台中下載本地識別包文件,一般是以圖集為命名的unitypackage文件。
導入識別圖集到Unity
我創建的圖集名稱:xxdata
圖集中有以下兩張圖片:
-
battleboard.png
-
card.png
下載的本地識別包文件(xxdata.unitypackage),在導入到Unity中的文件如下:
Editor
HiAR
ImageTargetTextures
xxdata
battleboard.png
card.png
StreamingAssets
HiAR
xxdata.xml (里面是圖集中的圖片信息,一行是一張圖片的數據,Key值是一個32位字符串)
xxdata
792c5ed97942d50f185be13ed9822b3c.db(32位的key和xxdata中對應)
22b72d7e5b182ed15e9ede20268d8a6b.db
總結一下就是:
1. 在Editor\ImageTargetTextures\下有以圖集命名的文件夾,文件夾中有圖集中的圖片文件
2. 在StreamingAssets\HiAR\目錄下有以圖集命名的xml文件和圖集命名的文件夾,文件夾下有圖片Id命名的db文件
xxdata.xml文件內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<HiAR>
<KeyItemList>
<KeyItem name="card" targetID="22b72d7e5b182ed15e9ede20268d8a6b" width="535" height="528" extName=".png" version="1.2.0"></KeyItem>
<KeyItem name="battleboard" targetID="792c5ed97942d50f185be13ed9822b3c" width="1024" height="1024" extName=".jpg" version="1.2.0"></KeyItem>
</KeyItemList>
</HiAR>
32位key值文件名的db文件
某種格式的文件,從里面可以看到HiScene AR Key,猜測db中存儲了圖片的識別點數據
圖集中每個圖片有對應的一個db文件,可知此db文件必然和圖片有關聯關系。
示例分析
簡單識別
場景層次(Hierarchy)結構:
HiAR Camera (SDK的核心,綁定了兩個腳本:HiAREngineBehaviour,TargetManagerBehaviour)
camera (3D相機,渲染3D GameObject,綁定的腳本:HiARCameraBehaviour)
Imager Target (識別點,可以有多個,綁定的腳本:ImageTargetBehaviour,實現這幾個接口ITrackableEventHandler, ILoadBundleEventHandler, IRelativeMoveTarget)
識別成功:識別圖移動時或者有遮擋時,Transform的屬性會發生改變,並且ImageTarget下的Child會顯示
識別失敗:Transform屬性無變化,並且ImageTarget下的Child會隱藏
camera source (一個MeshRenderer,硬件攝像頭攝像到的圖像實時渲染在此(類似於render texture?))
camera background (2D相機,渲染camera source的圖形)
重點解釋:
camera (3D相機 Clear Flags為Depth,拍攝場景中的3D GameObject)
camera background (2D相機,Clear Flags為Solid Clear,渲染物體攝像頭拍攝的畫面)
攝像頭拍攝的圖像顯示在camera source(mesh renderer)上
攝像頭拍攝的真實畫面和引擎生成的三維物體進行疊加。
AR識別成功的應用
當識別圖識別成功之后,執行一些操作,可以理解為Callback。
HiAR的例子是:識別成功之后,播放視頻。
當然你可以在識別成功之后,生成一些模型和場景出來,這樣就和開發其它游戲一樣,可以對Scene中的GameObject進行控制,比如播放動畫,打斗,特效之類的。
塗塗樂
把識別圖上的圖像實時渲染在模型上(Material),類型塗鴉。
-
添加一個待塗包的模型,添加組件:HiARPaint,Shader:HiARPaint
-
硬件攝像頭拍攝識別圖(實時拍攝)
-
根據識別到的圖,提取圖像生成Material,動態地渲染。
-
期間會生成幾個識別點
過程中如果有拍攝到其它物體,新生成的材質會實時更新
多圖識別
多圖識別,就是在簡單識別的基礎上添加多個ImageTarget
步驟:
- 在HiAR Camera(HiAREngine組件) 的屬性面板勾選 MuiltTarget
- 在場景中添加多個ImageTarget,並為每一個ImageTarget選擇識別圖
動態加載
動態加載識別目標進行識別跟蹤的功能,繼承自TartgetDynamic
void OnGUI()
{
if (GUI.Button(new Rect(30, 30, 200, 80), "Add Key"))
{
AddImageTarget(System.IO.Path.Combine(Application.streamingAssetsPath, Pic1Path), Pic1Key, 1024, 1024);
}
}
//識別回調
public override void OnDynamicReco(RecoResult recoResult)
{
Debug.Log("識別成功。。。。。");
GameObject gameObject = null;
gameObject = new GameObject();
if (recoResult.keyType == KeyType.IMAGE)
{
gameObject.AddComponent<ImageTargetBehaviour>();
}
Debug.LogFormat("recoResult.keyType:{0}", recoResult.keyType);
Target target = gameObject.GetComponent<Target>();
if (target == null)
{
Debug.LogError("Get Target Null !");
return;
}
target.PixelWidth = recoResult.Width * 0.01f;
target.PixelHeight = recoResult.Height * 0.01f;
gameObject.transform.parent = transform.parent;
gameObject.SetActive(true);
if (recoResult.KeyId.Equals(Pic1Key))
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.parent = gameObject.transform;
cube.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
}
else
{
Debug.LogErrorFormat("recoResult.KeyId:{0} not equals :{1}", recoResult.KeyId, Pic1Key);
}
bindingGameObject(gameObject, recoResult.KeyId);
}
設置中心點
勾選 ImageTarget (ImageTargetBehaviour組件)的CenterPoint之后,帶有物理引擎效果的物體運動就有了中心點。