案例研究 - 在混合實境中建立 Galaxy

在Microsoft HoloLens出貨之前,我們詢問開發人員社群想要查看新裝置的有經驗的內部小組組建。 分享超過 5000 個想法,並在 24 小時的 Twitter 投票之後,勝出者是稱為 Galaxy Explorer的概念。

Andy Zibits 是專案上的藝術負責人,而 Karim Luccin 是小組的圖形工程師,會討論藝術與工程之間的共同作業工作,導致在 Galaxy Explorer 中建立正確且互動式的 Galaxyy Way Galaxy 標記法。

技術

我們的小組 是由兩位設計工具、三位開發人員、四位作者、一位製作者和一位測試人員所組成,有六周的時間可讓人員瞭解並探索我們 Galaxyy Way Galaxy 的廣度和優點。

我們想要充分利用 HoloLens 直接在您的生活空間中轉譯 3D 物件的能力,因此我們決定要建立一個真實外觀的 Galaxy,讓人們能夠縮小並查看個別星形,每個都在其自己的軌道上。

在第一周的開發中,我們建立了一些代表 GalaxyY Way Galaxy 的目標:需要有深度、移動和感覺音量,這可協助建立星形的形狀。

建立具有數十億顆星的動畫星形問題在於需要更新的單一元素數目對於 HoloLens 使用 CPU 產生動畫效果的每個畫面太大。 我們的解決方案牽涉到複雜的藝術和科學混合。

在幕後

為了允許人們探索個別星號,我們的第一個步驟是找出我們可以一次呈現多少個物件。

轉譯物件

目前的 CPU 非常適合處理序列工作,而且最多一次處理一些平行工作 (取決於它們) 多少核心,但 GPU 在平行處理數千個作業時更有效率。 不過,因為它們通常不會與 CPU 共用相同的記憶體,因此在 CPU <> GPU 之間交換資料可能會快速成為瓶頸。 我們的解決方案是在 GPU 上建立星號,而且必須完全存在於 GPU 上。

我們開始在各種模式中使用數千個點物件進行壓力測試。 這可讓我們在 HoloLens 上取得 Galaxy,以查看作用和未運作的內容。

建立星形的位置

我們的其中一個小組成員已經撰寫 C# 程式碼,以在初始位置產生星號。 星形位於橢圓形上,而且其位置可由 (curveOffset橢圓形Size高度) 其中curveOffset是沿著橢圓形star的角度、橢圓形Size是沿著 X 和 Z 橢圓形的橢圓形維度,以及提高star在 galaxy 內的適當高度。 因此,我們可以建立緩衝區 (Unity 的 ComputeBuffer) ,以每個 star 屬性初始化,並將它傳送到 GPU 上供其餘體驗使用。 為了繪製此緩衝區,我們使用 Unity 的 DrawProcedural ,允許在任意點的 GPU) 上執行著色器 (程式碼,而不需有代表 galaxy 的實際網格:

Cpu:

GraphicsDrawProcedural(MeshTopology.Points, starCount, 1);

Gpu:

v2g vert (uint index : SV_VertexID)
{

 // _Stars is the buffer we created that contains the initial state of the system
 StarDescriptor star = _Stars[index];
 …

}

我們開始使用具有數千個物件的原始迴圈模式。 這提供我們所需的證明,我們可以管理許多物件,並以高效能的速度執行它,但我們對星形的整體形狀不滿意。 為了改善圖形,我們嘗試使用旋轉的各種模式和物件系統。 這些一開始是可行的,因為物件數目和效能保持一致,但圖形在中央附近中斷,而星形正向外發出,這並不實際。 我們需要一個可讓我們操作時間的發射,並讓物件實際移動,迴圈更接近 galaxy 的中心。

我們嘗試旋轉的各種模式和物件系統,如下所示。

我們嘗試旋轉的各種模式和物件系統,如下所示。

我們的小組對星形函數的方式進行一些研究,而我們特別為 Galaxy 製作了自訂的物件系統,以便我們可以根據「密度波理論」來移動橢圓形上的粒子,其會將星形的雙手定義為密度較高的區域,但常數的流量,例如交通干擾。 它看起來很穩定且穩固,但星形實際上在沿著其各自的橢圓形移動時移入和移出雙手。 在我們的系統中,物件永遠不會存在於 CPU 上,我們會產生卡片,並在 GPU 上全部導向它們,因此整個系統只是初始狀態 + 時間。 其進度如下:

具有 GPU 轉譯的物件系統進展

具有 GPU 轉譯的物件系統進展

一旦新增足夠的橢圓形並設定為旋轉,就會開始形成星形移動的「雙手」。 沿著每個橢圓形路徑的星距會獲得一些隨機性,而且每個star都加入一些位置隨機性。 這會建立更自然的star移動和手部形狀分佈。 最後,我們新增了根據中心距離驅動色彩的能力。

建立星形的動作

為了讓一般star動作產生動畫效果,我們需要為每個畫面新增一個固定角度,並讓星形以固定星形速度沿著橢圓形移動。 這是使用 curveOffset的主要原因。 這在技術上並不正確,因為星形會沿著橢圓形的長邊更快速移動,但一般動作感覺良好。

星形在長弧形上更快速移動,邊緣速度較慢。

星形在長弧形上更快速移動,邊緣速度較慢。

如此一來,每個star都會由 (curveOffset橢圓形高度年齡) 完整描述,其中Age是自從載入場景以來所經過的總時間累積。

float3 ComputeStarPosition(StarDescriptor star)
{

  float curveOffset = star.curveOffset + Age;
  
  // this will be coded as a “sincos” on the hardware which will compute both sides
  float x = cos(curveOffset) * star.xRadii;
  float z = sin(curveOffset) * star.zRadii;
   
  return float3(x, star.elevation, z);
  
}

這可讓我們在應用程式開始時產生數十萬顆星,然後我們會沿著已建立的曲線產生一組單一星形。 由於所有專案都在 GPU 上,因此系統可以平行顯示所有星形,完全不需要 CPU。

以下是繪製白色四邊形時的外觀。

以下是繪製白色四邊形時的外觀。

為了讓相機成為每個四邊形,我們使用幾何著色器將每個star位置轉換成畫面上將包含star紋理的 2D 矩形。

菱形,而不是四邊形。

菱形,而不是四邊形。

因為我們想要限制圖元的過度繪製 (次數,所以盡可能) 處理圖元,所以我們旋轉了四邊形,使其重迭較少。

新增雲端

有許多方式可讓磁片區感覺有一些物件,從光線在磁片區內部進行,以繪製盡可能多的物件來模擬雲端。 即時光線漫遊的成本太高且難以撰寫,因此我們先嘗試使用在遊戲中轉譯樹系的方法來建置模擬系統,而有許多面向相機的樹狀結構 2D 影像。 當我們在遊戲中執行此動作時,我們可以讓從旋轉的相機轉譯樹狀結構紋理、儲存所有這些影像,並在執行時間為每個帳單牌卡片選取符合檢視方向的影像。 當影像是全像投影時,這也不適用。 左眼與右眼之間的差異讓其需要更高的解析度,否則它看起來很平平、別名或重複。

第二次嘗試時,我們嘗試盡可能擁有許多物件。 當我們加法繪製物件,並在將物件新增至場景之前,將其模糊化時,就會達到最佳視覺效果。 該方法的一般問題與我們可以在單次繪製多少個物件以及它們所涵蓋的螢幕區域有關,同時仍維持 60fps。 將產生的影像模糊化,讓此雲端感覺通常是非常昂貴的作業。

如果沒有紋理,這就是雲端看起來與 2% 不透明度相同的內容。

如果沒有紋理,這就是雲端看起來與 2% 不透明度相同的內容。

加法並擁有許多兩者,表示我們在彼此之間會有數個四邊形,重複地陰影相同的圖元。 在 Galaxy 的中心,相同的圖元彼此有數百個四邊形,而且在完成全螢幕時會有龐大的成本。

執行全螢幕雲端並嘗試模糊它們是一個錯誤的主意,因此我們決定讓我們的硬體執行工作。

先有一些內容

在遊戲中使用紋理時,紋理大小很少符合我們想要使用的區域,但可以使用不同類型的紋理篩選,以從紋理的圖元插補我們所需的色彩, (紋理篩選) 。 我們感興趣的篩選是 雙向篩選 ,其會使用 4 個近鄰來計算任何圖元的值。

篩選前的原始

篩選之後的結果

使用這個屬性時,我們會看到每次嘗試將紋理繪製到一個區域兩倍時,都會模糊結果。

我們不需要轉譯成全螢幕,而是遺失可能花費在其他專案上的那些毫秒,而是轉譯成螢幕的小型版本。 然後,藉由複製此紋理並將它延展 2 倍,我們會回到全螢幕,同時將程式中的內容模糊化。

x3 向上調整回完整解析度。

x3 向上調整回完整解析度。

這可讓我們取得只有一小部分原始成本的雲端元件。 我們不會在完整解析度上新增雲端,而是只繪製 1/64 的圖元,並只將紋理延展回完整解析度。

左邊,從 1/8 到完整解析度的向上調整;和 右邊,使用 2 的 3 個上階。

左邊,從 1/8 到完整解析度的向上調整;和 右邊,使用 2 的 3 個上階。

請注意,嘗試從大小 1/64 到一次的完整大小看起來會完全不同,因為圖形卡在設定中仍會使用 4 圖元來著色較大的區域,而成品會開始出現。

然後,如果我們新增具有較小卡片的完整解析度星形,我們會取得完整的星形:

使用完整解析度星形轉譯的接近最終結果

當我們使用圖形位於正確的曲目之後,我們新增了一層雲端、將暫存點交換為在 Photoshop 中繪製的點,並新增一些額外的色彩。 結果是我們的藝術和工程小組都覺得很好,而且符合深度、音量和動作的目標,全都不需要對 CPU 造成稅務。

我們在 3D 中最終的 Galaxyy Way Galaxy。

我們在 3D 中最終的 Galaxyy Way Galaxy。

深入探索

我們已開放原始碼的 Galaxy Explorer 應用程式程式碼,並讓 開發人員可在 GitHub 上建置程式碼。

有興趣深入瞭解 Galaxy Explorer 的開發程式嗎? 查看 Microsoft HoloLens YouTube 頻道上過去的所有專案更新。

關於作者

他桌上的 Karim Luccin 圖片 Karim Luccin 是軟體工程師和美觀的視覺效果愛好者。 他是 Galaxy Explorer 的圖形工程師。
藝術潛在客戶 Andy Zibits 的相片 Andy Zibits 是一位藝術負責人和空間愛好者,負責管理適用于 Galaxy Explorer 的 3D 模型小組,並針對更多物件進行同步處理。

另請參閱