Shadow Volume!
打從Doom3資料被公布的第一天起,人們就開始關注這個詞匯了。這個Shadow Volume究竟是什么?注意了,這就是和Doom3那幾可亂真的陰影技術相關的重要名詞——“陰影錐”!比較酷一點的說法叫做“陰影容積”,不過反而更難以理解了^^

09-ShadowVolume
如圖9這種解釋陰影錐的圖片已經太多太多了。很多人認為這是一種跨時代的技術,其實早在Quake3時代,這種陰影技術就已經開始使用了。在Quake3中有3種陰影:
第一種是人物腳下一個黑斑,這個其實不能算實時陰影。
第二種是平面陰影(Planar Shadow),它把物體映射在一個平面上,然后很據光線數據把這個陰影“貼”在它應該在的表面上。這種方法在環境簡單時非常不錯,比如球場上的球員陰影。但其缺點在于,被映射的物體形狀越復雜,計算效率越低,且不能把陰影映射在曲面上。
第三種就是Doom3所采用的體積陰影技術,當時因為計算能力限制,只能簡單運用在人物身上,外加場景復雜度不夠,所以并未產生驚人效果。
隨著硬件和游戲引擎的飛速發展,體積陰影技術終于在Doom3引擎上大規模應用,我們就來看看體積陰影技術究竟有什么秘密:
名詞解釋:體積陰影,測定投影空間式陰影,Volumetric Shadow。該算法最早于1977年提出,其基本原理是根據光源和遮蔽物的位置關系計算出場景中會產生陰影的區域,即陰影錐。然后對所有物體進行檢測,以確定其會不會受陰影的影響。這個方法的要點在于,它不是利用“把物體投影到環境表面”的方式來產生陰影,而是去找出場景中有哪些像素是在陰影中。

如圖10,我們可以做個實驗:拿一個小球,正對光源(比如一盞臺燈)。光線是向四面八方直線傳播的,既然小球不透光,那么小球必然會在擋住朝小球方向的光線,在小球的逆光面形成一個錐形的無光線區域,也就是陰影錐。很明顯的,只要任何物體或物體的部分位于這個區域以內,就會處在陰影之中。
現在我們深入一些,假設有一個已經繪制完成的3D場景,因為使用Z軸緩沖(Z buffer,用以表現場景的深度)的關系,對每一個像素而言都有一個Z值,即表示該像素和觀察者的距離的值。假設現在有一個三角形物體,把陰影投射到這個場景中,并畫出這個物體的陰影錐。因為物體是一個三角形,所以它的陰影錐也是一個三角錐。那么,要如何知道場景中有哪些像素會受這個陰影錐的影響,從而處在陰影內呢?
其實方法很簡單:想象許多射線,由觀察者射向每個像素。如果射線和陰影錐完全沒有交集,它所對應的像素當然就不會受陰影錐影響,就不會處于陰影中。不過,即使是射線和陰影錐有交集,并不一定表示該射線對應的像素就一定受陰影錐影響,因為射線可能會穿越陰影錐。所以,只有在射線射入陰影錐之后,在離開陰影錐之前就遇到其對應的像素時,才表示這個像素和受陰影錐影響,處于陰影之中。
我們以圖11來講解這幾種不同的情形:

11-陰影錐分析
圖中的(1)和(2)都是面對觀察者的面,它們所涵蓋的像素,是“射線會射入陰影錐”的像素。而(3)是背對觀察者的面,它所涵蓋的像素是“射線會離開陰影錐”的像素。所以,會受陰影錐影響,處于陰影中的像素,就是(1)+(2)-(3)的那些像素,也就是陰影所在的位置。
要怎么在3D繪圖中,得到(1)+(2)- (3)的結果呢?這就需要OpenGL的模板緩沖區(Stencil Buffer)。OpenGL的模板緩沖區可以讓顯卡進行“加1”和“減1”的計算。所以,只要把模板緩沖區設定成在繪制(1)和(2)的面時,讓模板緩沖區加1;而在繪制(3)的面時,讓模板緩沖區減1。這樣一來,在繪制完(1)至(3)時,那些模板值不為0的像素就是陰影了。最后,把所有模板不為0的像素亮度降低,就可以達到繪制陰影的效果。
體積陰影最主要的缺點是在于它過于復雜。要做出有效率的“陰影錐”,需要對物體做相當麻煩的處理,基本上就是要找出物體在某個方向的 “外緣”(Silhouette)。這需要花費相當的顯卡核心處理時間。另外,為所有的物體繪制出陰影錐,需要耗費相當大的填充率、顯存帶寬甚至是CPU 占用率——這顯然不適合需要一定幀數率的Doom3。
那么,我們就要看看Doom3是怎樣加速陰影生成的:
沒錯,又是Vertex Shader)!頂點引擎的可編程特性可以讓生成Shadow Volume的工作由顯卡核心完成,這樣可以大幅度減輕CPU的運算負擔。與此同時,借助頂點引擎的寄存器組,連數據的來回傳輸都省略了,這樣就可以帶來驚人的速度提升。
此外還有Ultra Shadow技術。它是NVIDIA在NV35以后的GPU中增加的功能,關于此技術對提升Doom3運行效能的作用在本雜志今年第6期GeForce 6顯卡介紹文章中有詳細介紹,這里就不復述了。不過,Doom3默認并未開啟Ultra Shadow技術,我們可以在Doom3安裝目錄下的Doomconfig文件中加入“set r_usedepthboundstest 1”語句來開啟Doom3對Ultra Shadow技術的支持。不過,使用NV35以下GPU的用戶就不要做無意義的嘗試了。
值得一提的是,Ultra Shadow技術是開放的,所以有可能會有其它廠商采用。當然,這其中很多優化特性依靠軟件也可以執行,僅僅速度的提升不如GPU直接參于那么明顯罷了。

12-沒有體積陰影的架子

13-打開體積陰影的架子