創作內容

5 GP

學習日: Mesh Shader

作者:巧克力喬斯達│2024-02-02 23:51:04│巴幣:58│人氣:70
一如往常使用公司學習日,這次輪到Mesh Shader了
Mesh Shader基本上讓彩現流程簡化為:
省去了Input Assembly, Vertex Shader, Geometry/Tessellation Shader等等階段
(或者應該說,Mesh Shader處理IA/VS的部分,而GS/TS則要使用Amplification Shader)
以類似於Compute Shader的方式來處理網格,對於GPU來說可能可以改善執行緒效率

而後續的光柵化/Pixel Shader部分不變,簡單想成從vertex-to-pixel變成mesh-to-pixel即可
然後從下Draw call變成下Dispatch call,這也表示用async compute來處理網格是有可能的
(但免不了架構大改)

硬限制為GPU必須至少支援Shader Model 6.5以上,同時也要支援Mesh shader tier 1

參考資料
Mesh Shader - 官網規格
Mesh Shader - Github範例


CPU端實作
PSO的初始化如下:
與一般PSO初始化無異,只是結構換成MS專用的

呼叫Shader的方式如下:
直接把網格資料綁到Shader即可 (包含頂點、submesh資訊、index等等)
完全不用再呼叫IASetVertexBuffers之類的指令
CPU端的實作挺單純的


GPU端實作
天底下沒有免費的午餐,既然CPU端節省了很多寫法,那自然就是轉嫁到GPU端了
來看一下範例的Mesh shader:
看似只有短短幾行,但不了解其性質的話也無法運用自如 完整檔案連結

先從寫死的數字說起
  • 與Compute shader一樣,需要指定numthreads()屬性,上限為x*y*z = 128,寫死128,1,1是基於這個原因,上限比起compute shader小得多。
  • 輸出的vertices以及indices上限為256,所以說正常情況,把一個模型的網格切成好幾份來處理是必須的了。這邊微軟範例分別寫死126跟 在中國不存在的數字 。
SetMeshOutputCounts()則是MS的內建函式之一,告訴GPU我們要輸出的數量
  • 每個MS一定要呼叫一次,如果有用if else造成不同的執行路徑,那每一條路徑都要呼叫
  • 必定只能在輸出之前呼叫,以上圖為例,如果把SetMeshOutputCounts放在最後一行,那Validation Layer就會出來哭
SV_GroupID跟SV_GroupThreadID與一般的CS毫無差別
  • 這個範例在CPU端下的指令是DispatchMesh(2263,1,1),整個模型分成2263個子集合來處理,所以gid的範圍是[0, 2262],而gtid自然是[0, 127]了
  • 所以以這範例而言,這個模型有2263個Thread group在處理,而128個Threads負責不同位置的網格
其他部分就是自製化的部分了,微軟這邊在Meshlet這個自製結構存放了頂點數量+位移、三角形數量+位移等等,並且做後續的處理。

在GetVertexAttributes()裡可以看到vertex to pixel基本上是一樣的運算,只不過這次要自己indexing正確的頂點資訊,彈性相當高。

範例還順便秀了一波把indices從一個32-bit數字展開為三個10-bit的操作,這意味著網格壓縮/解壓縮更好處理了,過往開發者就是非得讓輸入為16-bit/32-bit index不可(於CPU端解壓),現在可以壓得更低且即時在GPU展開了。

D3D12MeshletRender範例的結果:


關於Mesh Culling
另一個範例D3D12MeshletCull展示了在GPU上做culling的方式
同時用上了Amplification shader跟Mesh shader
IsVisible裡面是一般的frustum culling,這裡根據visible的結果再呼叫一次DispatchMesh()。
而CPU端的呼叫現在是為了Amplification shader。
完全把culling移到GPU上不是問題,但會變好還是變壞還是要看設計。

另外這裡總算是看到了Wave operation的有效應用範例,傳統作法是利用InterlockedAdd之類的指令來計算那個visibleCount,但就是需要去做group的共享記憶體存取跟同步,有了wave操作更加靈活高效。

關於Mesh Instancing
當然是沒有DispatchMeshInstanced()這種東西,一樣要自己輸入資料並在MS實作。
帶入Instance的資料方式不外乎就是再餵一個structuredbuffer,設計上真的很自由

動態LOD的應用也有範例就不贅述

============================================================

又學了一招啊~越來越多工作能夠完全放在GPU了
未來的大作,GPU使用率衝滿但是CPU悠哉的情況會越來越多吧xd
不過這東西要完全普及,引擎架構勢必要有變動,要完全普及大概還要幾年吧
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5876139
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 1 篇留言

Toyakoyo
看到MS就想到UE等不及硬體MS自己先拿CS搞了一套Meshlet[e8]

02-11 16:25

巧克力喬斯達
哈~光追也同理,硬體光追出來前也不少用CS跑的02-11 20:24
我要留言提醒:您尚未登入,請先登入再留言

5喜歡★ltes50414 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:DirectML - S... 後一篇:Unheard Engi...

追蹤私訊切換新版閱覽

作品資料夾

leo25127更新至1225回
穿越奇幻日常系小說『公爵家的獨生子』更新囉,來看看我們無厘頭的ㄎ一ㄤ少爺怎麼在異世界作威作福吧!看更多我要大聲說5小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】