實時渲染
專業術語
實時渲染的本質就是圖形數據的實時計算和輸出。最典型的圖形數據源是頂點。頂點包括了位置、法向、顏色、紋理坐標、頂點的權重等。在第一代渲染技術中(1987年以前)。內容:頂點屬性只包含位置和顏色,實質是圖形數據的實時計算和輸出。
在2002年,顯卡的性能得到了極大的發展,首先是AGP8X在顯卡介面上的引入,使得顯卡和處理器在數據傳輸的帶寬上得到了成倍的增加,達到了2.1Gb/s,此外,一些3D性能極其強大的GPU也隨著顯卡巨頭ATI和nVIDIA的競爭不斷被發布,如ATI的Radeon9700 pro以及NVIDA的Geforce FX,都支持微軟最新一代DirectX 9.0。其中,NVIDIA的Geforce FX更是由於CineFX架構的採用,號稱可以支持實時渲染,那麼實時渲染對於我們的應用會產生什麼影響呢?實時渲染的時代真的要來了嗎?
渲染效果
頂點屬性只包含位置和顏色,頂點運算只包括對頂點位置的簡單變換、頂點的裁剪和投影,光柵化處理中對頂點顏色也只進行了簡單的內插,像素運算則很簡單——覆蓋。渲染技術發展到第二代(1987~1992年)
頂點屬性中增加了法向,用來進行光照計算。第二代渲染技術中引進了一個很重要的概念——深度,典型的應用就是深度緩衝。在光柵化處理中還增加了深度內插。像素運算中增加了顏色混合技術。第二代渲染技術豐富了畫面的色彩感和層次感,但整個畫面看起來還是很單調。第三代渲染技術解決了這一問題(1992~2000年)——紋理貼圖,頂點屬性中又增加了紋理坐標,頂點運算中也相應地增加了紋理坐標的變換和內插。光柵化處理中增加了紋理坐標內插。像素運算中增加了紋理定址和混合以及反鋸齒等技術。第三代渲染技術讓畫面更加絢麗多彩。隨著圖形處理技術的飛速發展,早期的固定函數渲染管線已經不能滿足圖形開發人員的要求,他們需要圖形處理過程中更大的自由度。第四代渲染技術產生了(2000年後)——可編程渲染。在第四代渲染技術中,圖形開發人員可以對渲染管線中的頂點運算和像素運算分別進行編程處理了,而無須象以前那樣套用一些固定函數。比如,對於頂點渲染,你不僅僅能簡單套用SetTransform方法實現頂點位置的變換,更為靈活的是,你可以通過編寫程序(彙編程序或高級語言程序),實現頂點位置的更為複雜的變換;在光照計算中,你可以從最基本的光照模型出發,編寫程序分別計算漫射、高光、折射、散射等,更重要的是,你還可以將計算結果作為像素渲染程序的輸入,以實現各種豐富的效果。在像素渲染中,除了煩瑣調用大量固定函數來實現外,你還可以編寫程序,從外部或者上游獲取參數和紋理資源,進行像素渲染運算。像素渲染需要的運算量遠遠大於頂點渲染,但輸出畫面的質量卻很高。許多高質量的畫面都是用像素渲染代替頂點渲染獲得的。
談到可編程渲染,那就必然要談到編程語言。早期對圖形處理器的編程採用Vertex Shader和Pixel Shader——它們一種類似彙編語言的程序語言,編寫工作量大。隨著圖形硬體的發展,圖形處理器所能處理的指令數快速增長,採用類似彙編的方式進行編程的工作量達到了讓人不能接受的地步,於是用於圖形處理器編程的高級語言誕生了。Cg語言就是其中的一個。Cg語言是nVIDIA公司與微軟合作進行HLSL語言的研發過程中,nVIDIA公司開發的一個副產品。兩者從本質上是一樣的。為使得自己的產品更有通用性,nVIDIA的Cg語言是跨平台和跨API的。關於HLSL的介紹很多,這裡就以Cg語言為例介紹一下可編程渲染。
Cg即C for Graphic,意即用於圖形處理的C語言。其語法結構類似於C語言,但所有指令卻是由GPU來執行的。C語言的指令都是由CPU來執行的。以C語言為基礎,Cg針對GPU的特點進行了改進和優化。配合Cg語言的發布,nVIDIA提供了一套完整的工具包,其中主要包括:Cg用戶手冊、Cg語言編譯器、Cg標準庫、Cg運行時庫、Cg瀏覽器等。用戶手冊向開發人員提供了有關Cg語言使用的詳細說明;編譯器允許你先將程序編譯輸出為彙編代碼,直接供應用程序調用;Cg標準庫非常類似於C語言的標準庫,大大簡化了編程,Cg標準庫包括數學函數、幾何函數、紋理映射函數以及一些導出函數等;Cg運行時庫允許應用程序在運行時編譯和連接Cg程序,運行時庫包括核心運行庫和API相關運行庫兩種;Cg瀏覽器方便開發者瀏覽nVIDIA公司提供的渲染實例效果。nVIDIA公司同樣支持微軟的.fx文件。FX文件中封裝了渲染指令和渲染狀態。針對FX文件同樣有運行時庫支持。nVIDIA為DCC們提供了一個插件,該插件調用FX文件,使得模型離線渲染的效果與運行時渲染的結果保持一致。
nVIDIA在Cg語言中提出了一個Profile的概念,不同的Profile決定了Cg程序在編譯時其中的某些語法、控制指令、標準庫函數、數據精度等是否被支持。從這一點上來講,Profile似乎翻譯成“版本”比較合適。如果這個“版本”被硬體所支持,Cg程序才可能得以正常執行。Cg支持所有當前硬體支持的Profile。這一點與HLSL不同,微軟允許軟體模擬——即由CPU去模擬本應由GPU完成的渲染任務。所以HLSL中允許軟體渲染的Vertex Shader和Pixel Shader版本超過硬體所支持的版本。另一方面,由於Cg支持跨API,所以Cg還支持OpenGL 各個版本的Vertex Program Profile和Fragment Program Profile, HLSL則只支持DirectX Vertex Shader和Pixel Shader。
在討論可編程GPU時,為什麼要將Vertex Program和Fragment Program分開呢。與CPU只是一個處理器不同,GPU內部包含兩個處理器——頂點處理器和像素處理器,同時還包括一些不可編程的硬體單元(用於固定函數管線渲染)。所以對CPU進行編程只需要一個C程序,而對GPU進行編程則需要兩種程序:Vertex Program對頂點處理器進行編程,而Fragment Program對像素處理器進行編程。當然,對頂點處理和像素處理部分也可以選擇固定函數管線處理。Cg語言可以完美地實現Cg程序與固定函數管線的完美結合。
可編程渲染技術的發展,對遊戲引擎中渲染部分的開發也產生了深遠的影響。一般地,我們可以通過兩種途徑實現遊戲中的渲染效果。第一,渲染效果在關卡設計過程中由設計人員靈活實現。這主要是得益於.FX文件。這樣做的好處顯而易見,設計人員有了更大的自由度和發揮空間,而且所設計出來的場景與實際運行時的效果保持一致。採用這一途徑需要注意避免頻繁地切換渲染程序導致渲染幀率的降低。第二,從預先製作好的渲染效果庫中選取遊戲所需要的。這需要程序設計人員添加必要的C++代碼引用這些渲染程序模塊。一般情況下,程序員還需要將渲染程序中的相關參數編碼到模型(頂點)或紋理中去,以有效提高渲染速率。採用這種方式,程序設計人員就可以比較有針對性地避免渲染程序的頻繁切換,以確保遊戲運行時的幀率。當然,一旦引擎確定,可得到的渲染效果庫也就確定了。不同的遊戲類型,不同的遊戲,對兩種渲染途徑的要求也不同。這些都需要我們在設計遊戲引擎時進行分析和考慮的。
隨著相關產業對圖形處理要求的不斷提高,圖形處理器將朝著兩個方向發展:更快的運算速度和更加自由的可編程性。硬體速度的提高,也將不斷催生出一些新的渲染技術,同時也使得一些在目前的硬體平台上難以實現的渲染技術變為可能。光照計算所需要的運算量很大,在目前還只能通過各種間接的途徑模擬實現。可以預見,在下一代的實時渲染技術中,例如光線追蹤、真陰影等技術或許將變為可能。這些技術的實現,將使得圖形渲染效果變得更為真實。高度真實是實時渲染技術未來發展的一大特徵。硬體可編程度的提高,使得設計人員對硬體的控制將變得更為靈活和富有創造性。可編程將是未來渲染技術發展的又一大特徵。nVIDIA在力推其新一代圖形處理器及Cg語言的同時提出了一個Cinematic Render的概念,將實時渲染提到了一個全新的高度。
實時渲染技術從誕生的那一天起就不斷地推動著遊戲產業的發展,相信也將繼續影響下去。