Shader Model 1.0-3.0的版本,Shader分為Vertex Shader和Pixel Shader兩種。沒(méi)有規(guī)定要同時(shí)使用這兩種Shader,可以只使用Vertex Shader,Pixel Shader的部分使用Fixed Function Pipeline,當(dāng)然反過(guò)來(lái)也可以。
Shader程序是被動(dòng)的,它們不會(huì)主動(dòng)加載,也不會(huì)主動(dòng)運(yùn)行,要有CPU來(lái)加載Shader用調(diào)用它們?nèi)ミ\(yùn)行。Direct3D中的SetVertexShader和SetPixelShader用來(lái)告訴GPU接下來(lái)運(yùn)行哪一組Shader。設(shè)置好Shader后,接下來(lái)調(diào)用DrawPrimitive和DrawIndexedPrimitive等函數(shù)來(lái)繪圖時(shí),就會(huì)使用這一組Shader來(lái)處理Vertex和Pixel。
GPU在運(yùn)行Vertex Shader處理頂點(diǎn)時(shí),會(huì)自動(dòng)把頂點(diǎn)數(shù)據(jù)區(qū)Vertex Buffer中屬于個(gè)別不同頂點(diǎn)的數(shù)據(jù)傳遞給Vertex Shader。Vertex Shader在運(yùn)行時(shí),只能看到單一頂點(diǎn)的數(shù)據(jù),也就是它被分配到得那個(gè)頂點(diǎn)。要讀取其他的頂點(diǎn)并不是不可行,但要通過(guò)一些技巧來(lái)傳遞數(shù)據(jù)。Vertex Shader無(wú)法隨機(jī)讀取Vertex Buffer,它不能把Vertex buffer 作為數(shù)組來(lái)使用。
除了從Vertex Buffer中獲得數(shù)據(jù)外,Vertex Shader還可以從常量寄存器Constant Registers 的空間中讀取數(shù)據(jù)。CPU要把數(shù)值放在常量寄存器中供Vertex Shader使用。常量寄存器中的數(shù)值對(duì)Vertex Shader來(lái)說(shuō)是只讀的數(shù)據(jù)。常量寄存器中的數(shù)值時(shí)全局的,每個(gè)頂點(diǎn)在運(yùn)行Vertex Shader時(shí)都會(huì)讀取到相同的內(nèi)容。越新版本的Shader支持越多的常量寄存器。
在Direct3D中使用Shader時(shí),F(xiàn)ixed Function Pipeline中設(shè)置光源、紋理和矩陣等的函數(shù)都會(huì)失效。這些數(shù)據(jù)都要通過(guò)CPU放進(jìn)常量寄存器,讓GPU使用。
Shader Model 3.0的Vertex Shader還支持讀取貼圖的功能,雖然Vertex Shader并不能直接填充Framebuffer畫(huà)面,但是讀取貼圖仍然有用處。2D貼圖可以視為一個(gè)可以被Vertex Shader自由讀取的二維數(shù)組,我們通常不會(huì)使用一張很漂亮的貼圖給Vertex Shader使用,Vertex Shader所使用的貼圖往往只是一堆非圖片數(shù)值數(shù)據(jù)。
Vertex Shader計(jì)算好的頂點(diǎn)數(shù)據(jù)通常并不會(huì)、也沒(méi)必要保存在內(nèi)存中。這些轉(zhuǎn)換后的三角形頂點(diǎn)數(shù)據(jù)會(huì)通過(guò)GPU的內(nèi)插器Interpolator,把內(nèi)插結(jié)果傳遞給下一步的Pixel Shader來(lái)填充三角形,畫(huà)好三角形后就把這些數(shù)據(jù)丟棄。
Vertex Shader處理好頂點(diǎn)后,GPU會(huì)使用Pixel Shader來(lái)填充轉(zhuǎn)換過(guò)后的三角形。GPU會(huì)通過(guò)轉(zhuǎn)換到屏幕坐標(biāo)系上的三角形的三個(gè)頂點(diǎn),來(lái)判斷畫(huà)面上有哪些像素會(huì)落在這個(gè)三角形內(nèi)部,然后對(duì)三角形內(nèi)部的每個(gè)像素進(jìn)行Pixel Shader來(lái)著色。
Pixel可以讀取的數(shù)據(jù)源主要是貼圖和常量寄存器。Vertex Shader和Pixel Shader所使用的常量寄存器是兩組不同的寄存器。Pixel Shader的常量寄存器同樣是全局的,在同一個(gè)繪圖指令中,每個(gè)像素運(yùn)行Pixel Shader時(shí)都會(huì)看到相同的常量寄存器內(nèi)容。除了貼圖和常量寄存器外,Pixel Shader還可以通過(guò)GPU的內(nèi)插器來(lái)獲得三角形3個(gè)頂點(diǎn)上通過(guò)Vertex Shader計(jì)算出來(lái)的數(shù)據(jù)。最常見(jiàn)的就是把不同頂點(diǎn)間的貼圖坐標(biāo)內(nèi)插,Pixel Shader再使用內(nèi)插過(guò)后的坐標(biāo)來(lái)讀取貼圖。
Geometry Shader是Shader Model 4.0新增的功能,它可以用來(lái)改變幾何圖形的輸出數(shù)量和排列方法。在Shader Model 1.0-3.0中,當(dāng)程序調(diào)用DrawPrimitive時(shí),就已經(jīng)決定要畫(huà)幾個(gè)圖形了。Geometry Shader是一個(gè)新的流程,它是在運(yùn)行完Vertex Shader后且還沒(méi)有使用Pixel Shader來(lái)著色之前運(yùn)行。它可以重新組合,過(guò)濾Vertex Shader所計(jì)算過(guò)后的頂點(diǎn)或自行生成頂點(diǎn)來(lái)穿件的幾何圖形。
Shader Model 4.0不再使用常量寄存器,而是使用常量緩存Constant Buffer。常量寄存器和常量緩存在使用上沒(méi)什么差別,比較大的差別是,如果Vertex Shader 和 Pixel Shader使用同一塊常量緩存,它們就可以讀取相同的數(shù)據(jù)。
有些Direct3D9 的函數(shù)是給Fixed Function Pipeline專(zhuān)用的,例如設(shè)置矩陣的SetTransform、設(shè)置紋理的SetMaterial,以及設(shè)置光源的SetLight。這幾個(gè)函數(shù)在使用Shader時(shí)都會(huì)無(wú)效,程序員要把這些數(shù)據(jù)改放在常量寄存器中讓Shader讀取。
----摘自《3D繪圖程序設(shè)計(jì)》
posted on 2010-02-26 18:33
郭小帥 閱讀(1952)
評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi):
Shader