上篇提到的tbdr是軟體Deferred Render技術之一,但其提到的「常用於手機」並非"遊戲軟體使用tbdr渲染",而是手機硬體使用tbdr技術去處理"渲染"的過程。
軟體使用deferred render能避免forward Render的問題——光的數量造成高複雜度[2]。但實際上電腦硬體是執行immediate-render(一個frame渲染完後直接整張輸出螢幕);手機硬體則多採用tbdr技術[1]。
Deferred render會產生許多紋理資訊(如深度圖、法線圖......),PC的GPU Ram夠大所以可以裝下那麼多的framebuffer資訊。 而手機較快的GPU快取SRam大小不夠一次塞下那麼多資訊,存放在較遠的DRam又會造成頻寬功耗增加且速度較慢。因此手機硬體採用tbdr技術,將光柵化後的像素拆成一小塊一小塊的,分批送往SRam訪問framebuffer與執行運算,最後將整個畫面的輸出結果送往DRam儲存[1]。
(問題: 在[1]中寫《為什麼pc不使用tbr,這是因為實際上直接對DRAM上進行讀寫的速度是最快的》,為甚麼不是在更快的SRam讀寫?)
FrameData:想像在frame與frame之間來了2個command:
- vertex1移動(1,0,0)
- vertex1移動(-1,0,0)
在frame結束時結果是一樣的,但若一個command就要刷新一次畫面,則為了同樣的結果就刷新了2次tiles太浪費了。 所以對策是每個command過來時只會執行vs並儲存,直到非得要刷新畫面時才處理fs[1]。
Alpha Test / Alpha Blend [1][4]
對於透明的shader在之前的文章也有探討過一點。簡單說,不通過ZTest的fs會被捨棄,通過的則會透過Z-write在剛像素寫下自己的Z值,供下一個被render的物件ZTest去比較該像素深度。
[1]指出在硬體tbdr技術下使用alpha test會造成GPU負擔,而alpha blend的消耗則是微乎其微。這不禁讓人懷疑兩者的差別。
Alpha Test:
- 不需要關閉Zwrite
- 不是0就是1。 (例如圖片cut off效果)
- 不能預先寫入深度
Alpha blend:
- 要關閉Zwrite (否則會看不到後面的物體)
- Depth buffer唯讀 (因為ZTest還是開著)
- RenderQueue須註明"Transparent" (最後被Render)
- 不會修改深度
在Unity,如果shader選擇cut off,會看到鋸齒不圓滑的透明剔除效果,簡單的原因是該像素alpha值沒通過alpha test所以被剃除。它為甚麼會造成tbdr的效能問題呢? 因為他在alpha test之前無法寫入深度,而現在的GPU有種優化機制叫Early-Z,會在fs之前做一次depth test粗略刪除不可能被渲染的像素。(圖)
因為在alpha test之前還不能確定深度,alpha test才會寫入深度,理應被alpha test剔除的像素不就白白執行了前面的fs了嗎?而alpha blend如上述所提,對depth buffer是唯讀(Z write off),所以並不影響early-z的執行。還有blending運算本身較單純。
渲染順序:
因為alpha blend關閉Zwrite,所以無從得知透明物件的前後關係。
Unity的作法是[4]
- 除了Geometry render之外都是用距離來sort[4] (使用網格中心點位置)。
- 從最遠的render到最近的。(從遠而近)
將向量圖示轉成光柵圖示(像素圖)的過程。意思是把資料轉印在螢幕pixel上的工作[3]。
參考文獻
[3]Rasterisation (光柵化)