AMD在7900系列顯卡發布的時候同時推出了Leo demo, 並說明它不是用近年流行的Deferred框架渲染完成,而是用到了一種叫Forward+的框架。這個框架不需要Deferred的大帶寬要求,卻仍能 實時渲染上千光源。EG2012上有篇新paper叫做Forward+: Bringing Deferred Lighting to the Next Level,講述的就是這個方法。但目前作者還沒有放出該論文的全文,這里我只能通過只言片語和AMD的文檔來解析這個神奇的Forward+。
Tiled-based Deferred Shading
在進入正題之前,我們先回顧一下Intel在SIGGRAPH Courses 2010里提到的Tiled-based Deferred Shading。它的算法框架是:
- 生成G-Buffer,這一步和傳統deferred shading一樣。
- 把G-Buffer划分成許多16×16的tile,每個tile根據depth得到bounding box。
- 對於每個tile,把它的bounding box和light求交,得到對這個tile有貢獻的light序列。
- 對於G-Buffer的每個pixel,用它所在tile的light序列累加計算shading。
在原先的deferred框架下,每個light需要畫一個light volume,以決定它會影響到哪些pixel(也就是light culling)。而用tiled based的方法,只需要一個pass就可以對所有的光源進行求交。如果用了AMD在Mecha demo中用到的OIT方法,還可以做一個per-tile linked list,直接把light序列存在鏈表里。
Forward+ Rendering
有了Tiled-based Deferred Shading的基礎,理解Forward+就變得簡單多了。Forward+ Rendering和Tiled-based Deferred Shading的關系就好比原先的Forward Shading和Deferred Shading,所以我們可以照貓畫虎一次:
- Z-prepass,很多forward shading都會用這個作為優化,而在forward+中,這個變成了必然步驟。
- 把Z-Buffer划分成許多16×16的tile,每個tile根據depth得到bounding box。
- 對於每個tile,把它的bounding box和light求交,得到對這個tile有貢獻的light序列。
- 對於每個物體,在PS中用該pixel所在tile的light序列累加計算shading。
從這里可以看出,前兩步與Tiled-based deferred shading大同小異,但只需要Z-Buffer,而不需要很消耗帶寬的G-Buffer(G-Buffer最小也要32bit color + 32bit depth)。第三步是完全一樣的。第四部由於用了forward,可以有forward的各種好處:
- 復雜材質
- 支持硬件AA(雖然我一直認為硬件AA多算了很多東西,是一種巨大的浪費)
- 帶寬利用率高
- 支持透明物體
由於light已經在步驟3中cache了,所以也可以不像傳統的forward那樣,把材質和光源攪在一起。加上shader中動態分支的能力, 不難實現類似deferred那樣的巨量光源支持。由於帶寬省了很多,Forward+的速度能比Deferred快。在原paper里的性能比較足以說 明這個問題。
另一個有趣的地方是透明物體的渲染。雖然我在KlayGE中用Deep G-Buffer的方法解決了純Deferred下透明物體的渲染。 正如很多讀者指出的,這么做所帶來的帶寬翻倍在很大程度上拖慢了整個系統。在Forward+中,第一步生成Z-prepass的時候,可以采用雙Z- Buffer的辦法,一個放不透明物體的Z,另一個放透明物體的Z。在第二步計算tile bounding box的時候,不管透不透明都放在一起計算一個總的bounding box。后面步驟不變,就能原生支持透明物體。
由於有了Z-Buffer,其他原先對Deferred有利的效果,比如GI、SSR,都可以直接應用。SSAO、SSVO之類的方法,如果需要考慮pixel normal,就需要適當的修改才能應用上。
在AMD的demo中,步驟2和3是用compute shader實現的。而在Tiled-based Forward Rendering這篇blog中,他完全用PS實現了per-tile linked list,但仍然需要D3D11的UAV特性。所以Forward+還沒法再D3D11之前的硬件上實現。
總結
所謂三十年河東三十年河西,作為Forward框架的新發展,Forward+給我們提供了一個新思路。這樣的競爭性發展總比所有資源都投到一方、忽視另一方要好。
從貢獻程度來看,最有突破性的其實不是Forward部分,其實是Tiled-based。Forward+只能算作Tiled-based Deferred Shading的“Forward化”。順便說一下,很多移動平台的GPU在硬件上支持Tiled-based Rendering(TBR),也是利用它來最大化計算相關性和帶寬利用率。不支持TBR的Tegra就吃虧許多了。