詞條解釋
導言:微軟最新發布的DirectX 10具有哪些新特性、新特點,它將給圖像處理帶來怎樣的變化?Microsoft發布的DirectX 10代表了自從可程式Shader出現以來在3D API方面的最巨大的進步。通過一番脫胎換骨般的重建,DirectX 10展現出一系列非常醒目的新特性,包括高度最佳化的運行時,強大的Geometry Shader,紋理數組等等,這些特性將引領PC實時三維圖形進入一個全新的世界。
DirectX 發展簡史
在過去的十年中,DirectX已經穩步成為了Microsoft Windows平台上進行遊戲開發的首選API。每一代的DirectX都帶來對新的圖形硬體特性的支持,因此每次都能幫助遊戲開發者們邁出驚人的一步。
微軟DirectX API(Application Programming interface :應用程式界面) 最早發布於1995年,其設計目標是為Windows平台軟體開發人員提供一個更簡便的針對多媒體和遊戲套用編程的標準接口。
在DirectX出台,開發者針對音頻、視頻等的操作必須基於硬體進行,——當然,基於OpenGL能夠在很大程式上減輕工作量,但OpenGL獲得的支持顯然遠遠不夠。——而顯示卡、音效卡等的產品種類眾多,要編寫一款能運行在所有平台上的遊戲簡直是一件噩夢般的工作。
通過提供一系列的針對多媒體套用的API,如圖形(包括2D與3D套用)、音頻或輸入設備等,DirectX提供了一整套的多媒體接口方案,這可以讓開發者根據API編寫相應的軟體程式,而不必考慮具體的硬體,硬體的差別性顯得無足輕重,編程人員得以更有效率的開發各種多媒體、遊戲軟體。
當然,DirectX的發展並不是一帆風順的,最初的版本遠談不上穩定。
版本 作業系統 發布日期
DirectX 1.0 Windows 95a 9/30/95DirectX 2.0/2.0a Windows 95OSR2/NT4.0 6/5/96
DirectX 3.0/3.0a Windows NT 4.0 SP3 9/15/96
DirectX 4.0未發布
DirectX 5.0 Windows NT 4.0/Beta for NT 5.0 7/16/97
DirectX 5.1 Windows 95/98/NT4.0 12/1/97
DirectX 5.2 Windows 95 5/5/98
DirectX 6.0 Windows 98/NT4.0 8/7/98
DirectX 6.1 Windows 95/98/98SE 2/3/99
DirectX 7.0 Windows 95/98/98SE/2000 9/22/99
DirectX 7.0a Windows 95/98/98SE/2000 9/99
DirectX 7.1 Windows 95/98/98SE/ME/2000 9/16/99
DirectX 8.0/8.0a Windows 95/98/98SE/ME/2000 9/30/2000
DirectX 8.1 Windows 95/98/98SE/ME/2000/XP 11/12/01
DirectX 9
Shader Model 2.0 Windows 95/98/98SE/ME/2000/XP 12/19/2002
DirectX 9
Shader Model 2.0b Windows 98/98SE/ME/2000/XP 8/13/2003
DirectX 9
Shader Model 3.0 Windows 98/98SE/ME/2000/XP 8/9/2004
DirectX 3D的發展
DirectX中套用在3D圖形方面的特定DirectX API即Direct3D,這也是DirectX中最重要的部分。不過,DirectX 3D得到廣泛套用是在DirectX 6.0之後:DirectX 6.0:加入了雙線性過濾、三線性過濾等最佳化3D圖像質量的技術,加入環境影射凹凸貼圖,使3D遊戲的畫面更具有真實感。
DirectX 7.0:最大的特色就是支持了T&L,中文名稱是“坐標轉換和光源”,3D遊戲中坐標和燈光的轉換工作從此由CPU轉交給了GPU,比DX6.1性能提升20%。這也成就了nVIDIA GeForce 256與ATi Radeon 256的輝煌,令3DFX徹底退出市場競爭。
DirectX 7.0a:增強了力反饋遊戲控制設備的性能和兼容性。
DirectX 7.1:與Windows Millennium一同發布。
DirectX 8.0/8.0a:支持Shader Model 1.0和1.1,從此在顯示卡中引入可程式像素著色器(Pixel Shaders)和頂點著色器(Vertex Shaders)的概念,同時套用在Xbox遊戲機中。同硬體T&L僅僅實現的固定光影轉換相比,VS和PS單元的靈活性更大,它使GPU真正成為了可程式的處理器。
DirectX 8.1: Pixel Shader升級到1.2、1.3、1.4版,可以支持最高每時鐘28指令執行,其中1.4版當時僅ATi Radeon 8500顯示卡支持。
DirectX 9.0 Shader Model 2.0: SM2.0的shader性能更強,支持最高96指令的pixel shader長度,同時DirectPlay和一些音頻方面也有大幅提升。
DirectX 9.0 Pixel Shader 2.0b: ATI Radeon X600/700/800系列顯示卡首先採納,開始支持更多指令(最高1536)和更多臨時暫存器(32相比之前為12),同時還加入新的貼面暫存器(facing register)和幾何實例(geometry instancing)的支持。
DirectX 9.0 Shader Model 3.0:支持更多指令,支持指令的流量控制和動態分支,從而使得編程人員可以在shaders中加入循環操作,使得編程更加容易,首次被Geforce 6800顯示卡採用。
從DirectX的發展史中我們可以看到,微軟的3D API和硬體一同發展,新硬體帶來新的DX特性,新的DX特性加速硬體的發展,在DirectX10上面,又是一個3D圖形發展的新境界。DirectX 10的架構優勢
DirectX之所以在廣大的開發者中流行,是得益於它的簡單易用和豐富的功能特性。然而,DirectX一直被一個主要的問題所困擾,那就是高CPU負載。
在圖形編程API出現之前,3D應用程式直接向圖形硬體傳送命令來完成圖形的繪製工作。雖然這樣開發工作比較繁重,但硬體效率則能在很大程度上得到保證。
而如DirectX和OpenGL這樣的圖形API則是通過在圖形硬體和應用程式之間架起了一個中間層,這樣,應用程式可以使用統一的圖形編程代碼來完成對底層硬體的操作,將程式設計師們從與大量的圖形硬體互動的惡夢中解救出來。但是,這也造成了每次DirectX從應用程式那裡接收到一條命令時,就必須先對這條命令進行分析和處理,再向圖形硬體傳送相對應的硬體命令。由於這個分析和處理的過程由CPU完成,造成了每一條3D繪圖命令都會帶來CPU的負載。
從技術角度,這種CPU負載給3D圖象帶來兩個負面影響:首先,限制了畫面中可以同時繪製的物體數量;其次,限制了可以在一個場景中使用的獨立的特效的數量。這就使得遊戲畫面中的細節數量受到了很大的限制,而圖像具有真實感的主要要求便是豐富的細節。
DirectX 10的主要優勢便是最大程度地降低了CPU負載,主要通過三個途徑來達到這個目的:第一,修改API核心,使得繪製物體和切換材質特效時的消耗降低,提高繪圖效率;第二,引入新的機制,降低圖形運算操作對CPU的依賴性,使更多的運算在GPU中完成;第三,使大量的物體可以通過調用單條DirectX繪製命令進行批量繪製。
下面我們就來仔細的看一下這三種方式:
提高繪圖效率
在DirectX 10中,對上代DirectX版本中三維數據和繪製命令的驗證過程進行了很大程度的修改。所謂三維數據和命令的驗證,是指在DirectX繪製圖形之前,對傳給它的圖形數據和繪製命令進行格式和數據完整性的檢查,以保證它們被送到圖形硬體時不會導致硬體出問題;這是很必要的一步操作,但是不幸的是這會帶來很大的性能開銷。
從上表我們可以很容易的看出,在DirectX 9中,每次繪製一幀畫面之前,都會對即將使用的相關數據進行一次驗證。而DirectX 10中,僅當這些數據被創建後驗證一次。這很明顯是可以大大提高遊戲進行中的效率的。
降低圖形運算對CPU的依賴
在降低圖形運算對CPU的依賴方面,DirectX 10 引入的三個重要機制就是:紋理陣列(texture arrays)、繪製預測 (predicated draw)和流式輸出(stream out)。不要被這三個晦澀的名詞嚇倒,實際上它們是三個不難理解的機制。
紋理陣列
傳統的DirectX在多張紋理中進行切換的操作是種很給CPU帶來很大壓力的操作,因為每切換一次,都要調用一次DirectX的API函式。而每繪製一個使用新紋理的物體,就要進行一次這樣的切換操作;有時為了實現特殊的材質特效,繪製一個物體時可能就要切換好幾次紋理,開銷很大。
所以,之前遊戲中經常會出現將大量的小紋理拼合到一張大的紋理中,通過給不同的三維物體分配這張大紋理的不同局部的方式,以期減少紋理切換,提高遊戲運行效率。這種方式實現起來相當複雜,而且DirectX 9中對紋理的尺寸的限制是4048×4048像素,也就是說,如果要容下更多的小紋理塊,可能就得載入很多張這樣的大紋理。
DirectX 10引入的新的紋理陣列機構,將允許在一個由顯示卡維護的陣列中容納512張單獨的紋理,而且,在shader程式中可以使用一條新的指令來獲取這個陣列中的任意一張紋理。而這種shader指令是運行在GPU中的;這樣,就把原來要消耗很多CPU時間的紋理切換工作輕鬆地轉給了GPU。由於紋理一般是直接放在顯存中的,因此以這樣的方式,將工作交與和顯存一同位於顯示卡上的GPU來完成更有效率。如今,在DirectX 10中,只要一開始設定好紋理陣列中的紋理,然後每次繪製一個物體時為它指定一個紋理的索引號,並同物體三維數據一起傳遞到shader中,就可以放心的讓GPU來給物體選紋理了。
繪製預測
在一般的三維場景里,很多物體都是完全被別的物體擋在後面的。這時候如果要顯示卡繪製這些物體就是白費力氣。儘管高級的GPU可以通過硬體算法將場景畫面中被擋住的像素(注意是像素)預先剔除,但是仍然會有很多不應進行的多餘運算。例如,一個完全被擋住的複雜的角色模型,它的身上可能有幾千個頂點,需要做複雜的骨骼皮膚動畫處理、頂點光照運算等等,然而,GPU是在處理完這些頂點之後,並要把這個角色模型一個像素一個像素地畫到畫面中時,才開始判斷每個像素是否需要畫,而當所有的像素都被剔除了時,之前做的頂點處理也就全白費了。在DirectX 10中的繪製預測便正是針對這種情況的解決,簡言之,繪製預測通過用一個可以代表某個複雜物體的簡單物體來判斷這個物體是否被全部擋住了,例如用一個可以罩住剛才那個角色的大盒子,當繪製這個盒子時,如果發現所有的像素都被禁止掉了,也即是說這個盒子肯定完全看不見,那么,裡面的角色繪製包括骨骼皮膚運算等之類的操作便完成不必進行。而一個盒子頂多有八個頂點,相比處理幾千個頂點,開銷小得多。
另外,以前這個步驟中有些真運算也需CPU完成的,在DirectX 10中,已經完全交由GPU來做,這也可以在一定程度上減輕CPU的壓力。
數據流式輸出
數據流式輸出也是DirectX 10的重要特性,它允許GPU上的Vertex shader或Geometry shader向顯存中添加數據,而這在以往的vertex shader中是不可能的。
在之前的DirectX版本中,vertex shader只能讀取顯存中已有的頂點數據;而DirectX 10中引入的新的Geometry shader,不但能讀取顯存中的頂點數據、幾何(點、線段、三角形)數據,還可以生成新的幾何數據放回顯存。
批量繪製
在DirectX 9中,對渲染狀態的管理一直是個十分信賴於CPU運算能力的操作。所謂渲染狀態,是指顯示卡進行一次繪製操作時所需要設定的各種數據和參數。例如,要繪製一個人物角色,就需要先設定他的幾何模型數據的數據格式、紋理過濾模式、半透明混合模式等等,每設定一項,都要調用一次DirectX API,占用大量CPU時間,極大的約束了渲染的性能。
為了使這些操作能夠批量的進行,DirectX 10中引入了兩個新的結構——狀態對象(state object)和常量緩衝(constant buffers)。
狀態對象就是將以前的零散狀態按照功能歸結為幾個整體,這樣,當要設定一系列相關狀態時,無需為每一個狀態來調用一次DirectX API,只需要調用一次將這些狀態統統設定到顯示卡中去。
而常量緩衝是另一個十分有意義的機制。在繪製模型前的準備工作中,渲染狀態的設定只是一小部分。還是拿繪製人物角色來說,能照亮這個人的光源的顏色、位置、類型、範圍等等,都要提前設給顯示卡;為了通過骨骼來帶動他的皮膚做出姿勢,還要設定骨骼的位置信息等等,而這些東西主要都是通過GPU中的常量暫存器(constant registers)來傳遞給它的。每個常量暫存器可以存儲一個4維的浮點型向量(即四個浮點數)。常量暫存器是遊戲程式向GPU輸入遊戲場景中數據的重要途徑。
在DirectX 9中,這種常量暫存器的數量是十分有限的,而且每次更新一個暫存器,都需要調用一次DirectX API函式。DirectX 10通過使用常量緩衝(constant buffer)這種結構,在每個constant buffer中都可以容納4096個常量,而且只需調用一次API就可以更新一大批常量。
比如說,在以前的DirectX版本中,如果程式想在場景里畫很多的樹木和雜草,可以採用一個類似於“克隆”的方法:先做好一棵或幾棵樹、草的三維模型,然後在畫一幀畫面時,不停的在不同的位置、方向,用不同的大小為參數,調用DirectX API的繪製函式來畫這些模型,就可以畫出很多草木來。但是每畫一棵,都要設定一大堆參數後調用一次API,這是很耗CPU時間的,所以在以前的遊戲中鮮有大規模且細節豐富的森林場景。
而在DirectX 10中,我們可以先把樹、草的幾個模型設給顯示卡,然後將所有要畫的樹木的位置、方向和大小一次性的寫入到constant buffer中,這樣,顯示卡便一下把所有的樹木和草都一起繪製出來了。
總之,DirectX 10通過提前數據驗證、紋理陣列、繪製預測、流式輸出、狀態對象、常量緩衝等機制,幫助遊戲的效果和效率上升到一個新的高度。這樣,也避免了之前DirectX版本因CPU負載過大而無法對圖形實施更多細節最佳化的問題。
Shader Model 4.0
DirectX 10另一個引人矚目的特性便是引入了Shader Model 4.0,那么,Shader Model 4.0能夠帶來怎樣的新特性,特別是將它與DirectX 9.0c中Shader Model 3.0相比時?
引入新Shader : Geometry shader
DirectX 10新引入的Geometry Shader,可以簡單地編程操縱幾何圖元,同時, vertex、geometry、pixel shader採用了統一的Sahder架構。
Geometry shaders是可程式圖形流水線的一大進步。它第一次允許由GPU來動態的生成和銷毀幾何圖元數據。通過和新的數據流輸出功能配合使用,許多以前無法實施的算法現在都可以在GPU中使用了。
統一的Shader架構
在DirectX 9中,Pixel shader總是在各個方面落後於vertex shaders,包括常量暫存器個數、可用的指令個數、shader長度等。程式設計師需要區分對待這兩種shader。
而在shader model 4中,無論 vertex、geometry和pixel shader,均有統一的指令集、同樣的臨時/常量暫存器個數,它們將平等的共享GPU中的所有可用資源。這樣,在編程時便不必再考慮每種shader自身的限制了。
百倍於DirectX 9的可用資源
對於shader中可用的資源,在Shader model 4.0中比原來有了驚人的擴充。就像早期的程式設計師們絞盡腦汁的省著用可憐的640k記憶體一樣,在使用以前的DirectX開發遊戲的過程中,程式設計師需要小心翼翼的分配珍貴的shader暫存器資源。暫存器的數量,直接影響著shader程式的複雜度。這和在640k記憶體的 機器上,怎么也不可能寫出Microsoft Office這樣的大規模軟體是同一個道理。
而在DirectX 10中,將臨時暫存器由原來的32個擴充到了4096個,將常量暫存器由原來的256個擴充到了65536個。
更多的渲染目標(Render Target)
所謂渲染目標,就是指GPU可以把畫面繪製到的目標,我們可以把它理解為GPU的畫布。一般來說,渲染目標被輸出到螢幕上,這樣我們就能看到畫好的畫面了。但是有時為了實現一些特效,某些渲染結果並不直接畫到螢幕上,而是再返給GPU做進一步的特效處理,而且渲染目標中也不一定是畫好的畫面的顏色信息。
根據圖形特效的需要,渲染目標可能是每個物體距離螢幕的遠近,或者物體表面上每個像素的方向,或者每個物體表面的溫度等等,之為了實現特效,可以按需要在其中繪製任何信息。為了提高這種情況下的效率,很多新的顯示卡都支持在同一遍Shader執行結束後,同時把不同的信息繪製到不同的渲染目標中。在DirectX 9中就已經支持這種機制了,但是它約束最多同時向四個渲染目標繪製。而DirectX 10將這個數量提升了一倍。
更多的紋理
在Shader Model 4.0中提供了對紋理陣列(Texture arrays)的支持。在前文中已經對紋理陣列有了比較詳細的介紹,在這裡只著重介紹一下與shader相關的部分。
在每個紋理陣列中,最多可以保存 512張同樣大小的紋理。而且每張貼圖的解析度被擴展到了8192×8192。更大的解析度意味著紋理中更豐富的細節。在一個shader中能夠同時訪問的紋理個數被增加到了128個,也就是說在每次執行同一個shader時,可以使用一個紋理陣列的512個紋理中的128個。所以說,在DirectX 10中,紋理的多樣性和細節程度將會有大幅的提升。
新的HDR顏色格式
要說這些年來在實時圖形界炒得最熱的概念,應該是HDR了。它通過採用浮點格式的顏色格式來為紋理、光照等計算提供極大的精度和顏色範圍(以前的紋理一般 都是採用整數型的顏色格式)。儘管最後顯示到螢幕上還是每個顏色通道8位的整數格式,但是以前由於在材質、光照計算中紋理也是用每通道8位的格式來參與計算,所以在顯示到畫面之前,很多細節就在低精度的運算中丟失了。
而採用每顏色通道16位浮點數的紋理,能夠保證在運算過程中幾乎沒有顏色細節信息的丟失。另外,採用16位浮點格式的顏色通道,可以表現更大的顏色範圍。這些就是HDR的優越性。
對用戶而言,當遊戲中的畫面罩上一層HDR效果後,立刻顯得和真正的照片一樣,有朦朧的光暈、細緻的高光和十分自然的色調。
然而,採用每個顏色通道16位浮點數的格式,比採用每通道8位的整數格式的紋理要多占據一倍的顯存;這給繪製的效率帶來了負面的影響。所以在 DirectX 10中引入了兩個新的HDR格式。第一種是R11G11B10,表示紅色和綠色通道用11位浮點數,而藍色通道採用10位浮點數表示。那么,為什麼不都用 11位呢?這是為了湊32這個整數。學過計算機的人都知道,當記憶體中一個數據單元的寬度是32位時,對它的操作效率最高;而且在紋理數據中一般要求每個像素的數據寬度是2的倍數,如2,8,16,32,64等等。又因為人眼對藍色的敏感度不如對紅色和綠色,所以它比其他兩個通道少用了一位。
另外一種格式是採用每通道9位尾數、所有通道共享5位指數的形式(眾所周知,在計算機中,浮點數是採用尾數附加指數的形式來表示的),加起來還是32位。 這些新的格式使得紋理能夠與原來占用同樣多的顯存空間,避免了大的空間和頻寬消耗。同時,為了適合需要精確的科學計算的場合,DirectX 10能夠支持每通道32位(4個通道加起來128位)精度的浮點數紋理。
DirectX 10中帶來的這些擴充和提高,使得創建前所未有的細節的實時遊戲場景真正成為可能。
幾何著色器與流式輸出
在DirectX 10發布之前,圖形硬體只有在GPU上操作已有數據的能力。頂點著色器(Vertex Shader)和像素著色器(Pixel Shader)都允許程式操作記憶體中已有的數據。這種開發模型非常成功,因為它在複雜格線蒙皮和對已有像素進行精確計算方面都表現的很出色。但是,這種開發模型不允許在圖像處理器上生成新數據。當一些物體在遊戲中被動態的創建時(比如新型武器的外形),就需要調用CPU。可惜現在大多數遊戲已經很給CPU帶來了很大的壓力,遊戲進行時動態創建龐大數量新數據的機會就變得微乎其微了。
Shader Model 4.0中引入的幾何著色器(Geometry Shader),第一次允許程式在圖像處理器中創建新數據。這一革命性的事件使得GPU在系統中的角色由只可處理已有數據的處理器變成了可以以極快速度既可處理又可生成數據的處理器。在以前圖形系統上無法實現的複雜算法現如今變成了現實。
幾何著色器被放在頂點著色器和光柵化階段(Rasterizer)中間。所謂光柵化,就是一行一行的掃描每個三角形,把它們一個像素一個像素的繪製到畫面 上。幾何著色器把經過頂點著色器處理過的頂點當作輸入,對於每個頂點,幾何著色器可以生成1024個頂點作為輸出。這種生成大量數據的能力叫做數據擴大 (Data Amplification)。同樣的,幾何著色器也可以通過輸出更少的頂點來刪除頂點,因此,就叫做數據縮小(Data Minimization)。這兩個新特性使GPU在改變數據流方面變得異常強大。
細分的虛擬位移貼圖(Displacement Mapping with tessellation)
幾何著色器讓虛擬位移貼圖可以在GPU上生成。虛擬位移貼圖是在離線渲染系統中非常流行的一項技術,它可以用一個簡單的模型和高度圖(Height Map)渲染出非常複雜的模型。高度圖是一張用來表示模型上各點高度的灰度圖。渲染時,低多邊形的模型會被細分成多邊形更多的模型,再根據高度圖上的信息,把多邊形擠出,來表現細節更豐富的模型。
而在DirectX 9中,GPU無法生成新的數據,低多邊形的模型無法被細分,所以只有小部分功能的虛擬位移貼圖可以實現出來。現在,使用DirectX 10的強大力量,數以千計的頂點可以憑空創造出來,也就實現了實時渲染中真正的細分的虛擬位移貼圖。
基於邊緣(Adjacency)的新算法
幾何著色器可以處理三種圖元:頂點、線和三角形。同樣的,它也可以輸出這三種圖元中的任何一種,雖然每個著色器只能輸出一種。在處理線和三角形時,幾何著 色器有取得邊緣信息的能力。使用線和三角形邊緣上的頂點,可以實現很多強大的算法。比如,邊緣信息可以用來計算卡通渲染和真實毛髮渲染的模型輪廓。
流式輸出(Stream Output)
在DirectX 10之前,幾何體必須在寫入記憶體之前被光柵化並送入像素著色器(pixel shader)。DirectX 10引入了一個叫做數據流式輸出(Stream Output)的新特性,它允許數據從頂點著色器或幾何著色器中直接被傳入幀緩衝記憶體(Frame Buffer Memory)。這種輸出可以被傳回渲染流水線重新處理。當幾何著色器與數據流輸出結合使用時,GPU不僅可以處理新的圖形算法,還可以提高一般運算和物理運算的效率。
在生成、刪除數據和數據流輸出這些技術的支持下,一個完整的粒子系統就可以獨立地在GPU上運行了。粒子在幾何著色器中生成,在數據擴大的過程中被擴大與派生。新的粒子被數據流輸出到記憶體,再被傳回到頂點著色器製作動畫。過了一段時間,它們開始逐漸消失,最後在幾何著色器中被銷毀。
高級渲染語言(HLSL 10)
DirectX 10 為以前的DirectX 9中的“高級著色語言”(High Level Shading Language )帶來了諸多功能強大的新元素。其中包括可以提升常量更新速度的“常量緩衝器”(Constant Buffers),提升渲染流程中運算元據的靈活性的“視圖”(view),為更廣泛的算法所準備的“整數與位指令”(Integer and Bitwise Instructions),添加了switch語句。
常量暫存器(Constant Buffers)
著色程式同普通的程式一樣需要使用常量來定義各種參數,例如光源的位置和顏色,攝像機的位置和投影矩陣以及一些材質的參數(例如反光度)。在整個渲染的過程中,這些常量往往需要頻繁的更新,而數以百計的常量的使用以及更新無疑會給CPU帶來極大的負載。DirectX 10中新加入的常量緩衝器可以根據他們的使用頻率將這些常量分配到指定的緩衝器中並協調的對其進行更新。
在一個著色程式中DirectX 10支持最多16個常量緩衝器,每一個緩衝器可以存放4096個常量。與其相比DirectX 9實在是少得可憐,因為它在每個著色程式中同時最多只能支持256個常量。
∠啾菵irectX 9,DirectX 10不僅提供了更多的常量,最主要的是它大幅的提升了常量更新的速度。對那些被分配到同一個緩衝器中的常量,我們只需進行一次操作就可以將它們全部更新完畢,而非單個單個的去更新。
由於不同的常量更新的時間間隔各異,所以跟據使用的頻率來對他們進行組織就可以獲得更高的效率。舉例來說:攝像機的視矩陣只在每一幀之間發生改變,而類似貼圖信息這樣的材質參數卻會在圖元切換時發生改變。於是這些常量緩衝器被分成了兩個部分:那些每幀更新的常量緩衝器專門存放那些需要在兩幀間更新的常數並在兩幀間一次把他們全部更新,另外的圖元切換更新的常量緩衝器也同理。這樣就會將更新常量過程中的一些不必要的工作消除,以便讓整個著色器腳本比在 DirectX 9中運行的更加順暢。
高級渲染語言(續)
視圖(Views)
在DirectX 9中,著色器(shader)中的數據的類型是被嚴格劃分開的。例如,頂點著色器用到的頂點緩衝器中的數據不能當作貼圖的數據來讓像素著色器使用。這樣就將特定的資源類型同其相對應的渲染流程中的特定步驟緊密地結合了起來,同時限制了資源資源在整個渲染流程中可以使用的範圍。
DirectX 10捨棄了“嚴格區分的數據類型”這一概念。當一段數據被創建,那么DirectX 10所做的僅僅是將其簡單的當作記憶體中的一段區域(bit field)來對待。如果要想使用這一段沒有定義類型的數據就必須通過使用一個“view”。 使用“view”,相同的一段數據就可以有各種各樣的方法來讀取。DirectX 10支持對同一段資源在同時使用兩個“view”。
通過這種多重“view”的手段,就可以在整個渲染流程的不同部分以不同目的使用同一段數據。例如:我們可以通過像素著色器將一段幾何數據渲染到一張紋理 上,之後頂點著色器通過一個“view”將這張紋理視為一個頂點緩衝器並將其中的數據作為幾何數據渲染。“view”通過在整個渲染流程中的不同步驟重複 使用同一段數據為“數據處理”帶來了更大的靈活性,幫助開發者實現更多更有創意更精彩的特效。
整數與位運算指令(Integer and Bitwise Instructions)
在新的高級著色器語言中添加了“整數與位指令”,這樣把“整數與位運算指令”的操作加入其基礎運算函式的好處在於幫助一些算法在GPU上的實現。開發者終於可以直接使用整數而非從浮點中強轉來計算出準確的答案。數組的索引號現在可以輕鬆的計算出來。GPU無整數運算的時代終於被終結了。這將為shader 程式的開發帶來很大的便利。
Switch 語句(Switch Statement)
在DirectX 10中, HLSL可以支持switch語句,這將大幅簡化那些有著大量判斷(分支)的著色器腳本的編碼。一種用法就是建立一個“航母級的著色器(shader) 程式”——包含了大量的小型著色器程式並且自身體形巨大的著色器程式。在這個“航母級的著色器程式”,我們可以通過設定一個材質ID在switch語句中 判斷來輕鬆的在渲染同一個圖元時切換不同的特效。也就是說,現在一個軍隊中的每個士兵身上都可以擁有各自不同的特效了。
DirectX 10的其他改進
alpha to coverage
在遊戲中,經常使用帶有半透明信息紋理的多邊形模型來模擬複雜的物體,例如,草、樹葉、鐵絲網等。如果使用真正的模型,一顆邊緣參差不齊的小草可能就要消耗掉幾百個多邊形;然而採用透明紋理,可以只用2~3個多邊形就解決了。
透明紋理示意
然而,當使用這種有半透明信息的紋理時候,它的不透明和透明部分的邊界線上,常常會出現難看的鋸齒。採用半透明混合技術可以解決這個問題,但是它需要把場景中所有這類物體按照由遠到近的順序來繪製,才能保證它們的遮擋關係是正確的,這會給CPU帶來很大的壓力,並不可取。在以前版本的DirectX中,Alpha測試和混合簡直就是圖形程式設計師的噩夢。
在DirectX 10中,使用了一種新的技術叫做Alpha to coverage。使用這種技術,在透明和不透明交界處的紋理像素會被進行多極取樣(Multi-sample),達到抗鋸齒的效果。這就在不引入大的性能開銷的情況下簡單並有效地解決了這個問題。室外場景的遊戲將大大受益於這種技術,樹葉、鐵絲網、草的邊緣將會更加柔和、圓滑。
Alpha to coverage效果
Shadow Map filtering
陰影圖(Shadow map)技術已經逐漸成為了渲染真實感陰影的流行技術。在包括《戰爭機器》、《分裂細胞:雙重特工》、《Ghost Recon》、《刺客信條》等的各大次世代遊戲中都能看到它的身影。然而,由於shadow map的尺寸限制,用它實現的陰影邊緣往往有明顯的鋸齒。在DirectX 10中,提供了對shadow map進行過濾的功能的正式支持。經過過濾後,陰影的邊緣將會變得更加柔和。