2015-08-15 69 views
2

我正在使用WebGL做硬件蒙皮,但是更新我的模型節點層次結構會對性能造成巨大沖擊。每個節點都需要查詢其當前的位置/旋轉/縮放關鍵幀,用它們構造一個局部矩陣,如果它有一個父節點,則將它與其父節點的世界矩陣相乘。Javascript - 優化3D動畫的節點層次結構更新

矩陣數學本身就像獲得的一樣得到了優化(基於gl矩陣的矩陣構造的特殊變體)。但是,如果我更新許多模型,每個模型都有數十個節點(有些甚至有數百個,可悲),這使得瀏覽器的所有執行時間都耗盡了。

我曾嘗試使用骯髒的狀態,當節點實際上並不需要更新,但只是檢查如果他們的本地數據更改(主要是檢查位置或旋轉更改)實際上導致相同數量的處理,只是計算矩陣。

WebCL將是理想的,但似乎無處可去,因爲2014年

我開始覺得在着色器運行的這一切,但我不能完全換我如何設計它的頭(例如,存儲關鍵幀,這是幀 - >數據的映射,或者如何寫回數據)。

另一種方法是將所有動畫轉換緩存到紋理中,但這並不能很好地擴展。對於具有足夠低關鍵幀數量的模型,這是可以的,但對於長動畫的模型,這會變成非常快的數百兆字節。 這主要是因爲我想不出任何方式來存儲稀疏數據。如果可能的話,那麼我可以存儲與關鍵幀相同數量的轉換,這些轉換不會佔用大量內存(現在,我將存儲每一幀的轉換)。當然,這需要做矩陣插值,而我不確定這是多麼可靠。

有沒有人有任何想法?

回答

0

我不認爲它的實際將卸載整個節點層次結構計算到GPU。您可以做的最好的事情是將2個絕對世界轉換關鍵幀上傳到GPU,並讓GPU進行插值。但我不確定插值的世界變換是否與通過節點層次結構實際計算一樣。如果可能的話,那將是一個可行的解決方案。請注意,您不能在矩陣之間插值。您需要將其轉換爲支持插值的形式,例如四元數+其他數據。

我實際上遇到了這個問題,以及我的項目。我發現更新轉換計算是最耗時的操作,儘管還有完整的碰撞系統+響應。

我通過減少此更新轉換需要調用的次數來解決此問題。例如,如果您可以斷定整個模型不在您的視野範圍內,那麼您根本不需要計算轉換。這可能會將您需要執行的計算量減少到〜1/6至〜1/4之間。其次,對於遠處的物體,你不需要每幀更新它們的變換。只需每隔幾幀更新一次轉換即可。請記住,只有30FPS的遊戲才能發貨,因此對於遠處的物體可能不會引人注意。

最後,這可能不適用於JavaScript,所以我沒有做(尚),你應該存儲和訪問緩存一致的方式的數據。見these slides。可能會有10倍的性能提升。但是,再次,可能無法用於Javascript,因爲很好,JavaScript陣列不保證按順序打包數據。

+0

我的模擬已經在30FPS下工作。你鏈接的幻燈片是不錯的,但我真的不知道他們對JS有多相關。我的節點實際上已經在一個共享的類型數組中(儘管所有的成員都按順序存儲,即[local_matrix1,world_matrix1,local_location1,...,local_matrix2,...]',不知道這是否會影響),我不認爲我曾經注意到這會加快速度 - 我其實是做了這個改變,只是爲了能夠圍繞web工作者移動這個數組。 剔除和LOD可能會起作用,但我寧願儘可能快地將最大的N個可見對象放在第一位。 – user2503048