線性蒙皮分解演算法及其在遊戲中的應用

遊資網發表於2020-03-04
線性蒙皮分解演算法及其在遊戲中的應用

2K20開發終於又進入了尾聲,我也就又來更新文章了!

今天給大家介紹一種線性蒙皮分解演算法,簡稱SSDR(Smooth Skinning Decomposition With Rigid Bones)。SSDR模型可以從一系列動作中分解出線性蒙皮資料,從而通過一定數量的骨骼和頂點權重圖來近似擬合出模型的形變。

為什麼要分解和使用線性蒙皮?線性蒙皮(Linear blend skinning)這個概念對於做遊戲或者動畫專業的同學必然不會陌生。因為其簡單,高效相比去對偶四元數蒙皮(Dual Quaternion Skinning)更加廣泛的被工業界使用。這個概念在Maya裡被稱作Smooth Skinning, 在3D studio Max裡叫做Bones Skinning, 以及在Blender裡叫Blend Skinning。在遊戲開發中,blendshape或者simulation cache這些頂點動畫對於無論GPU還是記憶體都是極其昂貴的。

舉個例子:如果這樣一組83個表情進入遊戲,每個表情需要記錄5000個頂點位置,那麼總共我們需要記錄 83 * 5000個位置。但是如果我們可以將這麼多表情分解成X個骨骼驅動的蒙皮動畫,我們就只需要儲存一張頂點權重圖和83 * X個位置了。


線性蒙皮分解演算法及其在遊戲中的應用
blendshape表情

結合動畫壓縮技術以及硬體加速渲染的技術,如果可以通過SSDR模型將這一系列形變分解出蒙皮動畫,這可以大大幫助遊戲的效能優化的。

先上結果:

線性蒙皮分解演算法及其在遊戲中的應用
200個骨骼的線性蒙皮結果

線性蒙皮分解演算法及其在遊戲中的應用

除了應用在人物表情上,SSDR模型還可以將各種simulation的結果轉化成骨骼驅動的蒙皮,比如衣料模擬,肌肉模擬,水面模擬等等。

線性蒙皮分解演算法及其在遊戲中的應用
衣料模擬:右邊是simulation結果,左邊是SSDR模型解算出的蒙皮結果

線性蒙皮的實現方法:在介紹SSDR的實現方法之前我先簡單描述下線性蒙皮的原理。 線性蒙皮是由一系列骨骼驅動的。每個頂點會根據頂點權重圖和相應的骨骼關聯。根據骨骼在當前位置相對於靜止位置的變換矩陣以及此頂點相對於該骨骼

的權重,我們可以計算出該頂點在該骨骼影響下的位置。假設Wij是第j個骨骼對於第i個頂點的權重,Pi是第i個頂點在靜止位置的座標,|B|是骨骼的數量, Rjt和Tjt分別是第j個骨骼在第t個位置下的旋轉矩陣和位移矩陣。綜上Vit, 在第t個姿勢下第i個頂點的位置可以表述為:

線性蒙皮分解演算法及其在遊戲中的應用
公式1

同時注意線上性蒙皮中, 權重Wij是大於等於零,並且所有骨骼對於頂點i的權重相加的和是1。

程式碼如下:

線性蒙皮分解演算法及其在遊戲中的應用

線性蒙皮分解演算法:SSDR模型是通過一系列已知的形變資料,反向解算出線性蒙皮資料的演算法。假設有一個有t個目標姿勢,|V|個頂點的模型,在第t個目標姿勢中第i個頂點,我們記做Vit. 那麼SSDR模型將所有頂點的位置, {Vit: t=1...|t|, i=1...|V|}當做輸入資料,將其分解為骨骼變換矩陣和頂點權重圖

輸入資料Vit可以考慮成一個|V| x |t|的矩陣,其中每個元素是個3 X 1的向量代表每個頂點在目標姿勢下的空間座標。同樣,在靜止位置下P是|V|個頂點的空間座標。演算法的輸出結果是骨骼-頂點權重W={wij}以及骨骼的變換矩陣B ={Rjt, Tjt}。其中權重W是一個|V| x |B|矩陣,其元素均為非負數且每一行元素的和為1。

線性蒙皮分解演算法及其在遊戲中的應用
計算輸入輸出資料

這裡將SSDR模型可以理解為一個線性迴歸模型,我們選擇使用帶約束的最小二乘法對引數進行估計。

線性蒙皮分解演算法及其在遊戲中的應用

服從於 Wij >=0

線性蒙皮分解演算法及其在遊戲中的應用

所有骨骼對於一個頂點的權重之和應當為1

線性蒙皮分解演算法及其在遊戲中的應用
確保Rjt為旋轉矩陣

這裡就不贅述如何求解這個非負數的最小二乘法解法了。我這裡使用了scipy庫的nnls(non-negative least squares)幫助求解。通過nnls得到初始值後,使用minimize函式增加約束,使得求解係數(權重)的和為1。

線性蒙皮分解演算法及其在遊戲中的應用
使用minimize函式實現稀疏約束

在解算出理想權重後,我們可以考慮時候根據當前權重重新計算骨骼的形變矩陣。這裡我就不進一步解釋如何計算骨骼形變矩陣了,大概方法是需要理解一些 cloud point mapping的知識:通過Singular Value Decomposition (SVD)來尋找最優旋轉值。

總結此演算法的最終流程:

輸入:

線性蒙皮分解演算法及其在遊戲中的應用

在第t個姿勢下第i個頂點的空間座標,靜止姿勢下頂點的空間座標
輸出:

線性蒙皮分解演算法及其在遊戲中的應用

  • 頂點骨骼權重圖,骨骼變換矩陣
  • 初始化骨骼變換矩陣
  • 重複一下步驟
  • 更新頂點骨骼權重圖
  • 更新骨骼變換矩陣
  • 直到收斂或者達到預定的迭代次數
  • 更新靜止位置


最後SSDR還可以用於快速生成蒙皮資訊,這無非對於Rigger是很好的訊息。在Maya裡面通過將delta mesh變形器的結果分解生成權重圖:

線性蒙皮分解演算法及其在遊戲中的應用
外國大神通過SSDR實現的快速蒙皮框架

總結,我認為在未來的遊戲開發流程中,隨著對更加精細的動畫技術,和離線模擬技術的依賴SSDR模型會越來越多的被使用。烘焙成簡單高效的蒙皮動畫可以提高遊戲效能,同時也可以將寶貴的效能留給更需要的地方。

SSDR相關論文(感謝評論):http://graphics.cs.uh.edu/ble/papers/2012sa-ssdr/


作者:王滕昊
專欄地址:https://zhuanlan.zhihu.com/p/78377681

相關文章