微軟 HoloLens 技術解謎(下):SDK 會是這樣?
原文 http://www.36kr.com/p/219188.html
本文作者張靜是前微軟上海Xbox ATG軟件工程師,微信公眾號“黑客與畫家”(HackerAndPainter), 知乎專欄地址 。歡迎各位童鞋與他交流探討。
在前一篇文章《微軟HoloLens技術解謎(上):如何還原三維場景》中我介紹了自己對于 HoloLens 背后的建模技術的看法,雖然之前在微軟的 Xbox 部門工作過,但是和大家一樣也是上周才知道 HoloLens 這個好玩的設備。當前微軟官方對于 HoloLens 透露出來的信息非常有限,最核心的兩個組件深度傳感器以及全息屏幕的原理依然充滿著迷題。文章發表后,在 微軟HoloLens技術解謎(上):如何還原三維場景 的留言中讀者提出了一些問題。
讀者提問之“HoloLens 的深度傳感器有沒有可能是基于 TOF?”
先介紹下背景知識,市面上常見的有三種類型的深度傳感器:
- 結構光,這個技術的代表產品是 Kinect 一代,它的傳感器芯片用的是 PrimeSense 家的。說句題外話,PrimeSense 現在是蘋果旗下的公司,這個領域未來一定會很精彩。
- TOF,time-of-flight,代表產品是 Kinect 二代,由于微軟對于 One 這個單詞的熱愛,它的官方名字是 Kinect One,有點混亂是吧?
- 雙目攝像頭,代表產品是 Google Tango 以及 Leap Motion,前者配有四臺攝像頭,后者有兩個。
我認為 HoloLens 沒有使用 TOF 技術的原因是因為如果這四個攝像頭的位置放的是 TOF 傳感器,那么還缺少一個朝前的 RGB 攝像頭用于視頻聊天類 App。讀者提到的中間部分我認為是微型的投影儀,HoloLens 使用微投在“擋風玻璃”上顯示全息的畫面。參見 Wired 的這篇報道 http://www. wired.com/2015/01/micro soft-nadella/
至于這個問題的標準答案,還得等微軟發布新的信息。
讀者提問之“HoloLens 能不能當 VR 用?
這個問題很好,的確可以這么玩,NASA 與微軟的的火星合作計劃基本上是一個虛擬現實的應用,它無視了真實的環境。如果 HoloLens 可以提供調節“擋風玻璃”透光度的 API,那么調成完全不透光時就好比戴著 Oculus Rift 的頭盔,是另一種體驗 VR 的途徑。可是朋友們,這是在浪費 HoloLens 的機能啊!
那么,作為未來的應用開發者,應該怎樣充分榨干它的機能呢?這是本篇文章的重點。
正文部分
首先讓我腦洞開一會,為大家“介紹”下 Holo SDK。按照微軟的偏好,SDK 標配的語言肯定有 C++ 和 C#,因此要進行開發,這兩門語言你至少得會一門。
然后,這個 SDK 里有哪些功能呢?根據官方 demo 中的場景,我覺得基本功能至少有:
-
(a) 攝像頭看到的圖像,即當前場景的 color buffer。
-
(b) 當前場景的深度圖,depth map 或 z buffer。
-
(c) SLAM 合成后的三維場景,這個場景所在的空間下文我們暫且稱為 Holo Space,它可能是以樂高方塊的形式表示,也可能是用三角形來表示。
-
(d) HoloLens 設備在 Holo Space 中的坐標 (x, y, z)、朝向 (tx, ty, tz)。
-
(e) 手勢識別的結果,類似 HRESULT OnGestureDetected(DWORD dwHandId, DWORD dwEventId, LPVOID lpUserInfo) 的樣子。
-
(f) 語音識別的結果,類似 HRESULT OnVoiceRecognized(std::string& strSentence, FLOAT confidence) 的樣子。同樣的,根據官方 demo,我將 HoloLens 應用分為三種:
-
偽全息的傳統應用
-
針對 HoloLens 特別優化過的應用
-
沉浸式的真-全息游戲
這一篇只講“偽全息的傳統應用”
這種類型的應用對于傳統開發者而言最容易上手,幾乎不需要修改代碼,自然也不需要擁有 3D 圖形學的知識。大部分人會從這種應用入手開始 Holo 開發。
如果不需要 3D 知識就能實現 3D 的界面,那么 3D 的效果是哪來的呢?那就是 Windows 10 引入的全息窗口管理器 —— explorer3d.exe。我們平時啟動 Windows 看到的“桌面”是窗口管理器(explorer.exe)的一部分,把“桌面”想像成三維的就行了,很簡單是吧?
一點都不簡單!
以視頻播放器為例,播放器并不會直接將視頻畫面顯示到桌面上,而是畫到一個緩存區域,經過一系列我不知道的步驟后,explorer.exe 再將畫面以“2D 的方式拷貝”到能被我們看到的地方。而 explorer3d.exe 用的是“3D的方式”。
所謂“3D的方式”就是使用 Direct3D 做一些“會的人嫌我講得啰嗦,不會的人看了還是不會”的事……
也就是在初始化應用的時候:
-
創建一個 3D 的矩形來表示 3D 的窗口,保存在頂點緩存 vertex bufer(可以認為是放在顯卡上的數組)
-
創建一個貼圖 texture(可以認為是放在顯卡上的圖片)
-
創建表示窗口平移、旋轉、拉伸值的 local_matrix(這里的 matrix 是數學中的矩陣概念,不是電影名稱)
在應用運行時:
-
如果需要在 Holo Space 中移動窗口,那么修改 local_matrix 中的平移值,功能與 explorer.exe 中的移動窗口類似,只是除了上下(y 軸方向)左右(x 軸方向)移動外還可以前后(z 軸方向)移動。
-
如果需要在 Holo Space 中旋轉窗口,那么修改 local_matrix 中的旋轉值。explorer.exe 中沒有類似的功能。
-
如果需要在 Holo Space 中放縮,那么修改 local_matrix 中的放縮值,功能與 explorer.exe 中按住窗口邊緣拖拉改變大小一致。
-
如果視頻內容需要更新,那么更新 texture 為最新的內容,只有這么做我們才能看到會動的視頻。
在應用退出時:
- 釋放 Direct3D 的資源
不用擔心,這些都是 explorer3d.exe 會負責的。
細心的讀者會發現我們沒有用到一個很重要的功能:
(d) HoloLens 設備在 Holo Space 中的坐標 (x, y, z)、朝向 (tx, ty, tz)。
要解釋它我必須講解 world、view、projection 三個矩陣,還要講解矩陣的乘法以及 dot product 的公式等等,這些完全是圖形學的知識了,一時半會講不完,我會再專門為它們寫一個系列。我打算用一句話解釋下,explorer3d.exe 會維護一個全局的 global_matrix,它等于 world * view * projection,view 的值由功能 (d) 中的信息可以得到。global_matrix 的作用就好比第一人稱射擊游戲中的鼠標,寫到這里我發現把 explorer3d.exe 視作一個 3D 游戲會簡單很多,3D 游戲場景里的電視機也能播放視頻,其實是一樣的道理。
總結一下,這個類型的應用程序員幾乎不需要修改代碼,由 explorer3d.exe 負責調用 Direct3D 將傳統應用的內容轉換成 3D 的貼圖。
結束語
這篇先寫到這里,看看大家的反饋意見。雖然文章叫做《HoloLens 技術解謎(下)》,但是放心這個系列并沒有完結,隨著腦洞的逐漸展開,我發現要介紹的內容越來越多。