ShaderSimpler(8) : 初探Deferred shading

源碼下載:http://myshaders.googlecode.com/files/ShaderSimpler_05142007.rar

 對於一個基於Shader的渲染系統如何來計算多個動態光源的光照呢?這是一個困擾我很久的問題。基本上有這樣三種解決方案:
1. 在單個pass中計算物體的所有光照。這種方案的主要缺點就是shader管理非常複雜。常見的思路是基於一套shader模版,自動生成n個光照shader,n往往能達到上百個;另外一個主要的缺點就是很多fragment經過複雜的光照計算之後又被z測試剔除,造成計算的浪費(可以先進行一個z only pass來優化);
2. 爲每個燈光進行一個pass。這種方案也會有前者over draw的問題,另外還會造成draw call數量增加;
3. deferred shading,這種方案結構簡單,但是對顯卡要求較高,需要multi-render targets, float point render target;還有就是對於透明面,目前還沒有很好的解決方法。

下面就介紹一下Deferred Shading的思路。它的想法非常的簡單、直接,簡單的說就是我們可以把光照計算需要的一些參數先通過一個pass渲染到一些render target中(稱爲Attributes buffer或G-Buffer),然後可以爲每個燈光進行一個pass來計算光照。

源碼中演示了deferred shading的基本概念,實現了4個點光源的phong 光照渲染。爲了能在Geforce 5600上跑,沒有使用multi-render targets,而是用了多個pass來生成G-Buffer,這樣也可以更清楚的演示deferred shading的概念。
首先程序創建了position,normal,diffuse三個render target,在渲染時使用3個pass,把場景的“世界座標”,“法線(世界座標系)”,“顏色”,分別渲染到這三個render target中;爲了簡單起見,假設所有燈光都覆蓋整個屏幕――爲每個燈光進行一個pass,渲染一個全屏幕的quad,然後爲每個象素計算光照,並使用additive混合,把光照強度累加到屏幕緩衝中。


下面是G-buffer的抓圖,這些圖片在上傳的時候都進行了縮小。
position:

normal

diffuse

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章