原帖地址:
http://school.ogdev.net/ArticleShow.asp?id=5552&categoryid=5編譯你的shaders現(xiàn)在我們已經(jīng)輸入了我們的頂點(diǎn)shader,對(duì)每一個(gè)shader開(kāi)發(fā)人員來(lái)說(shuō),接下來(lái)要做的事情就是編譯它以確定它是否正確。要編譯它,點(diǎn)擊主工具欄中的提交改變按鈕(圖標(biāo)為:

)。你也可以用快捷鍵(F7)來(lái)開(kāi)始編譯。這將編譯所有工作區(qū)中經(jīng)過(guò)修正的shaders,然后將編譯結(jié)果輸出到輸出窗口。
輸出窗口輸出窗口是一個(gè)可停靠的窗口,它通常位于主用戶(hù)界面底部(見(jiàn)圖18)。該窗口用于輸出shader的編譯結(jié)果和不同應(yīng)用程序的一些文本信息。輸出窗口與shader編輯器鏈接用于高亮顯示編譯錯(cuò)誤。

圖18 輸出窗口
一旦你點(diǎn)擊了提交改變按鈕,如果shader中有錯(cuò)誤,他們將被顯示在輸出窗口。點(diǎn)擊提交改變按鈕不僅編譯當(dāng)前的shader,它還將存儲(chǔ)shader代碼的改變。還有就是,提交改變將應(yīng)用到所有別改變的打開(kāi)的shaders。在輸出窗口中雙擊一個(gè)錯(cuò)誤將打開(kāi)一個(gè)糾正窗口并且高亮顯示有錯(cuò)誤的行(見(jiàn)圖19)。如果你改變了shader的文本然后沒(méi)有提交就想關(guān)閉窗口,RenderMonkey將詢(xún)問(wèn)在關(guān)閉窗口之前是否提交改變。

圖19 HLSL shader 中的編譯錯(cuò)誤
編輯匯編
盡管我們這個(gè)練習(xí)中沒(méi)有用到匯編sahders,還是讓我們認(rèn)識(shí)一下怎樣編輯匯編shaders。匯編shader編輯器窗口有兩個(gè)窗格扣組成——上面的窗格用于綁定RenderMonkey的變量節(jié)點(diǎn)到shader的常量寄存器中,下面的窗格用于編輯匯編shader文本。下面是匯編shader編輯器窗口的快照(如圖20)

圖12 匯編語(yǔ)言編輯器
常量?jī)?chǔ)存編輯器為一個(gè)三列的視圖列表。每行代表一個(gè)特定的寄存器的值。第一列(Constant)用于指定常量寄存器的索引。第二列(Name)顯示連接到寄存器的節(jié)點(diǎn)的名字或“…”(如果沒(méi)有變量鏈接到寄存器)。第三列顯示的是連接到寄存器的變量節(jié)點(diǎn)的初始值。
綁定一個(gè)RenderMonkey變量節(jié)點(diǎn)到一個(gè)常量?jī)?chǔ)存寄存器意味著軟件將直接將節(jié)點(diǎn)的內(nèi)部值綁定到寄存器值。在RenderMonkey中,向量和顏色節(jié)點(diǎn)表示為4個(gè)浮點(diǎn)值,標(biāo)量被映射為四個(gè)相同的浮點(diǎn)值,矩陣用16個(gè)浮點(diǎn)值表示。
要綁定一個(gè)節(jié)點(diǎn)到寄存器,在你想要綁定的常量行的“Name”列上單擊右鍵在彈出的菜單中選擇一個(gè)變量節(jié)點(diǎn)(見(jiàn)圖21)。該菜單包含了所有在被編輯的shader范圍內(nèi)的變量。一旦你選擇了一個(gè)節(jié)點(diǎn),他的名字將出現(xiàn)在“Name”列,它的初始值將顯示在“Initial Value”列。

圖21 映射一個(gè)節(jié)點(diǎn)到匯編shader常量寄存器
要清空一個(gè)常量寄存器,在上述的菜單中選擇 Clear。以前與節(jié)點(diǎn)連接的變量名將被“…”替代,它的初始值也將被清空。
注意,如果你綁定一個(gè)矩陣到一個(gè)特殊的常量,該常量將占四個(gè)常量行。
編輯器支持像素和頂點(diǎn)匯編代碼的自定義語(yǔ)法顏色。而且還能完全支持剪貼板操作。
像素shader編輯和設(shè)置
現(xiàn)在,我們應(yīng)經(jīng)對(duì)頂點(diǎn)shader有了一個(gè)完整的了解,接下來(lái)讓我們看看像素shader。要編輯像素shader,要在shader編輯器窗口中選中Pixel Shader標(biāo)簽頁(yè)。在開(kāi)始編輯文本之前,然我們先回顧一下光照公式以確定要用到那些參數(shù)。參照公式(2)—(4)我們能確定要用到以下參數(shù):
Ø Ka,Kd,Ks — 分別為環(huán)境,漫射和光照系數(shù)。
Ø Ia — 環(huán)境光強(qiáng)度。
Ø Id — 漫反射光照強(qiáng)度。
Ø Is — 鏡面反射光強(qiáng)度。
Ø Ns — 鏡面反射系數(shù)。
以上參數(shù)我們要將其作為常量添加到像素sahder中。Ka,Kd,Ks,ns將作為標(biāo)量添加到工作區(qū)中,Ia,Id和Is能被作為顏色節(jié)點(diǎn)添加。根據(jù)下表將變量節(jié)的添加到工作區(qū)節(jié)點(diǎn)中:
1. Ka:名字為Ka的標(biāo)量變量
2. Kd:名字為Kd的標(biāo)量變量
3. Ks:名字為Ks的標(biāo)量變量
4. ns:名字為Ns的標(biāo)量變量
5. Ia:名字為Ia的顏色變量
6. Id:名字為Id的顏色變量
7. Is:名字為Is的顏色變量
下圖為你定義完成后工作區(qū)樹(shù)視圖的快照:

好啦,讓我們將這些參數(shù)添加到像素shader的聲明塊中。用我們?cè)陧旤c(diǎn)shader一節(jié)中講解的方法將他們添加到像素shader的聲明中。如果你已經(jīng)添加完成了最后一個(gè)節(jié)點(diǎn),你應(yīng)該能看到下面的聲明塊:
Float Ka;
Float Kd;
Float Ks;
Float Ns;
Float4 Ia;
Float4 Id;
Float4 Is;
現(xiàn)在,我們已經(jīng)準(zhǔn)備好要開(kāi)始寫(xiě)我們的像素shader的代碼了。這里我們將真正感受到用高級(jí)著色語(yǔ)言編寫(xiě)sahders程序的簡(jiǎn)單和優(yōu)雅。如果你嘗試過(guò)用匯編語(yǔ)言寫(xiě)shader程序,那么你肯定會(huì)喜歡這種改變。本例中完整的像素shader程序如下(不包含聲明部分):
float4 main( float4 Diff : COLOR0,
float3 Normal : TEXCOORD0,
float3 View : TEXCOORD1,
float3 Light : TEXCOORD2 ) : COLOR
{
// Compute the reflection vector:
float3 vReflect = normalize( 2 * dot( Normal, Light) * Normal -Light );
// Compute ambient term:
float4 AmbientColor = Ia * Ka;
// Compute diffuse term:
float4 DiffuseColor = Id * Kd * max( 0, dot( Normal, Light ));
// Compute specular term:
float4 SpecularColor = Is * Ks * pow( max( 0, dot(vReflect, View)), Ns );
float4 FinalColor = AmbientColor + DiffuseColor + SpecularColor;
return FinalColor;
}
你只需要簡(jiǎn)單的將這些代碼寫(xiě)到像素shader的文本編輯器中然后點(diǎn)擊提交改變按鈕。記住,我們用了Pow指令,所以要將我們的目標(biāo)設(shè)置成ps_2_0或更高版本。
預(yù)覽窗口
現(xiàn)在,我們已經(jīng)完成了shaders的編輯工作,但是要想看到我們編輯的代碼的效果,還需要一個(gè)能用于查看結(jié)果的窗口。在RendeMinkey中,預(yù)覽窗口就是用來(lái)交互的預(yù)覽我們編輯的結(jié)果的窗口。所有shader中的變化或參數(shù)的更新都將適時(shí)地被渲染出來(lái),一次他是真正的交互式shader開(kāi)發(fā)。圖23顯示了一個(gè)海洋特效的預(yù)覽窗口。
圖23 預(yù)覽窗口
在RenderMondey的標(biāo)準(zhǔn)預(yù)覽模塊中提供了簡(jiǎn)單的導(dǎo)航系統(tǒng):
l 在窗口中平移用上下左右鍵,
l 向前或向后移動(dòng)攝像機(jī)用“Z”和“X”鍵,
l 用鼠標(biāo)旋轉(zhuǎn)屏幕
注意,預(yù)覽窗口中的模型將繞著Z軸旋轉(zhuǎn)。
點(diǎn)擊“P”鍵將根據(jù)渲染過(guò)程的個(gè)數(shù)顯示為一個(gè)視口陣列,用于預(yù)覽每一個(gè)渲染過(guò)程。(如圖24):

圖24 預(yù)覽窗口中的多重視口
你也能選擇一組預(yù)定義的視圖來(lái)觀看你的模型。在預(yù)覽窗口中單擊右鍵,再?gòu)棾龅牟藛沃羞x擇一個(gè)你想要的視圖。在該菜單中選擇“Properties”將允許你改變預(yù)覽窗口的屬性。再?gòu)棾龅膶?duì)話(huà)框中將允許你:
l 改變預(yù)覽窗口的背景色,
l 改變過(guò)程陣列視圖的背景色
l 改變視域
l 改變遠(yuǎn)近剪切面值
編輯變量
現(xiàn)在,我們的預(yù)覽窗口中將出現(xiàn)一個(gè)白色茶壺。茶壺的外表取決于變量的值。我們要將我們shaders中的所有參數(shù)都設(shè)定一個(gè)有意義的值。不過(guò),在這之前,先讓我們討論一下怎樣編輯變量。編輯變量有兩種方法,一種是雙擊該變量節(jié)點(diǎn),一種是右擊該節(jié)點(diǎn)再?gòu)棾龅牟藛沃羞x擇“Edit”。RenderMonkey將自動(dòng)選擇一個(gè)與被編輯變量相匹配的編輯框。
常量變量
每個(gè)標(biāo)量都可以通過(guò)下圖所示的標(biāo)量編輯模塊編輯。注意,你可以用任何方法改變標(biāo)量的值,如果你最后想反悔,可以單擊“Cancel”。不過(guò)論你最后怎樣,預(yù)覽窗口都會(huì)交互地顯示你的改變。

圖25 標(biāo)量編輯器
要編輯一個(gè)標(biāo)量,你可以直接指定一個(gè)值,也可以通過(guò)滑動(dòng)條交互的改變它的值。讓我們將我們工作區(qū)中的標(biāo)量設(shè)置成以下值:
1. Ka = 0.8
2. Kd = 0.8
3. Ks = 1.0
4. Ns = 100.0
正確的指定值后,你將在預(yù)覽窗口中看到一個(gè)白色的茶壺。我們已經(jīng)開(kāi)啟了光照!
向量變量每個(gè)向量能通過(guò)向量編輯模塊進(jìn)行編輯:

圖26 向量編輯器
每一個(gè)向量組件也向標(biāo)量一樣能直接指定值,也能通過(guò)滑動(dòng)條來(lái)改變。用戶(hù)也可以鉤選“Keep normalized”選項(xiàng)以保持向量始終是歸一化的。若果你對(duì)結(jié)果不滿(mǎn)意,也可以單擊Cancel按鈕。
好了,現(xiàn)在我們來(lái)設(shè)定光向量的值。雙擊lightDir變量然后輸入下列值:
X = -0.4; Y = 0.3; Z = 0.8; W = 0.0;
矩陣變量盡管在本例中我們沒(méi)有修改任何矩陣變量,也讓我們了解一下怎樣用怎樣用矩陣編輯模塊來(lái)編輯矩陣變量:

圖27 矩陣編輯器
通過(guò)以上兩例,相信讀者已經(jīng)知道怎樣編輯矩陣變量了。矩陣變量值是多了幾個(gè)值而已。這有一個(gè)選項(xiàng)用來(lái)將矩陣恢復(fù)為單位矩陣(Set to Identity Matrix)。
顏色變量每個(gè)顏色變量都能通過(guò)顏色編輯模塊編輯:

圖28 顏色編輯器
用戶(hù)能通過(guò)RGB和HSV兩種模式來(lái)編輯顏色。可以直接輸入顏色值,也可以通過(guò)顏色各個(gè)組建后的滑動(dòng)條,還可以在顏色盤(pán)上直接選擇一種顏色。窗口最右邊的滑動(dòng)條用來(lái)調(diào)節(jié)顏色的亮度。你調(diào)節(jié)的顏色時(shí)時(shí)地顯示在左上角的小方框中。Float Point 選項(xiàng)只對(duì)RGB模式有效,它將其各個(gè)組件值限制在-1.0和1.0范圍之內(nèi)。負(fù)的顏色值能用來(lái)減少顏色。同樣你也可以在不滿(mǎn)意時(shí)點(diǎn)擊Cancel按鈕。
如果我們將Ia值設(shè)置為R = 0, G = 112, B = 0, A = 255,我們將看到如圖29所示的茶壺。

圖29 Phong 光照特效
渲染狀態(tài)塊管理盡管我們已經(jīng)完成了我們的第一個(gè)視覺(jué)特效。我們還是要探索一下怎樣修改每一個(gè)繪制調(diào)用的渲染狀態(tài)。每個(gè)過(guò)程都可能有若干個(gè)渲染狀態(tài),它可能是從一個(gè)更高級(jí)的過(guò)程繼承而來(lái)也坑能就是他自己的。如果想創(chuàng)建一個(gè)渲染狀態(tài)節(jié)點(diǎn),在你想將其放置到的過(guò)程節(jié)點(diǎn)上單擊右鍵,再?gòu)棾龅牟藛沃羞x擇“Add Render State Block”如圖30:

圖30 在過(guò)程中增加渲染狀態(tài)塊
如果一個(gè)過(guò)程中沒(méi)有定義渲染狀態(tài)塊,應(yīng)用程序?qū)⑺阉髡麄€(gè)工作區(qū)樹(shù),然后將其找到的第一個(gè)渲染狀態(tài)塊節(jié)點(diǎn)作為該過(guò)程渲染狀態(tài)塊的父節(jié)點(diǎn)。當(dāng)你在一個(gè)過(guò)程中創(chuàng)建一個(gè)渲染狀態(tài)塊節(jié)點(diǎn)時(shí),它將繼承在工作區(qū)中找到的第一個(gè)高級(jí)別渲染狀態(tài)塊的值。如果以前沒(méi)有創(chuàng)建過(guò)渲染狀態(tài)塊,那么它將不繼承任何值。改變新創(chuàng)建的渲染狀態(tài)塊的值將覆蓋其繼承的值。注意,在搜索過(guò)程中應(yīng)用程序只查找當(dāng)前和默認(rèn)特效中的各個(gè)過(guò)程。也就是說(shuō)每個(gè)特效中渲染狀態(tài)塊的值不能被其他特效訪問(wèn)。要編輯渲染狀態(tài),雙擊渲染狀態(tài)節(jié)點(diǎn)或在該節(jié)點(diǎn)上單擊右鍵再?gòu)棾龅牟藛沃羞x擇“Edit”。渲染狀態(tài)編輯窗口如圖31所示:

圖31 渲染狀態(tài)編輯器
要編輯一個(gè)特定的渲染狀態(tài),在你要編輯的渲染狀態(tài)行的Value列單擊左鍵,如果該狀態(tài)由于定義的值,你可以在它們中選擇一個(gè),如果沒(méi)有你可以直接指定一個(gè)值。
讓我們將我們的茶壺改為線(xiàn)框顯示。要做到這點(diǎn)其實(shí)相當(dāng)容易。在渲染狀態(tài)編輯器中找到Fillmode渲染狀態(tài)將其值設(shè)為WIREFRAME。你將立即在預(yù)覽窗口中看到一個(gè)縣礦石的茶壺:

圖32 線(xiàn)框顯示
當(dāng)今的游戲中使用個(gè)工各樣的紋理貼圖來(lái)生成視覺(jué)特效。現(xiàn)在,就讓我們來(lái)學(xué)一學(xué)怎樣在RenderMonkey中使用紋理貼圖。就像你以前學(xué)習(xí)的一樣,RenderMonkey中有專(zhuān)門(mén)用于2D紋理,立方貼圖和體積紋理的變量類(lèi)型。那么現(xiàn)在就讓我們?cè)诠ぷ鲄^(qū)中增加一個(gè)2D紋理貼圖變量。在我們的特效工作區(qū)節(jié)點(diǎn)上單擊右鍵選擇Add Variable。選擇Texture類(lèi)型然后將其命名為baseMap。一個(gè)紋理變量將出現(xiàn)在你的工作區(qū)中(默認(rèn)的,紋理變量都被指定為藝術(shù)家可編輯的)。
接下來(lái),為了將紋理應(yīng)用到我們的特效中,需要在頂點(diǎn)shader中增加一個(gè)紋理坐標(biāo)流。雙擊名字為standard mapping的流映射節(jié)點(diǎn)燃后增加一個(gè)新的通道用于紋理坐標(biāo):Reg = v2, Usage = TexCoord, UsageIndex = 0, Type = Float2。這樣就在我們的頂點(diǎn)shader中增加了一個(gè)新的流通道。
下面的步驟是在我們的頂點(diǎn)shader程序中增加紋理坐標(biāo)。打開(kāi)頂點(diǎn)shader的文本編輯器然后輸入以下代碼(下面列出了代碼)。粗體顯示的行和被注釋的行是不同于上面例子的部分:
float4x4 view_matrix;
float4x4 view_proj_matrix;
float4 lightDir;
struct VS_OUTPUT
{
float4 Pos : POSITION;
float3 Norm : TEXCOORD0;
float3 View : TEXCOORD1;
float3 Light : TEXCOORD2;
float2 Tex : TEXCOORD3; // NEW
};
VS_OUTPUT main(
float4 inPos : POSITION,
float3 inNorm : NORMAL
float2 inTex : TEXCOORD0 ) // NEW
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
// Output transformed position:
Out.Pos = mul( view_proj_matrix, inPos );
// Output light vector:
Out.Light = -lightDir;
// Compute position in view space:
float3 Pview = mul( view_matrix, inPos );
// Transform the input normal to view space:
Out.Norm = normalize( mul( view_matrix, inNorm ) );
// Compute the view direction in view space:
Out.View = - normalize( Pview );
// Propagate texture coordinate to the pixel shader:
Out.Tex = inTex; // NEW
return Out;
}
新增的三行代碼將頂點(diǎn)shader從輸入的頂點(diǎn)流中獲取的紋理坐標(biāo)輸出給像素shader,但是,要想真正的在像素shader中對(duì)紋理進(jìn)行采樣,我們還需要將我們的紋理變量綁定到一個(gè)紋理對(duì)象中。
紋理對(duì)象
要使用紋理變量,你首先要?jiǎng)?chuàng)建一個(gè)紋理變量(在你的工作區(qū)中用增加變量對(duì)話(huà)框創(chuàng)建紋理變量)。一旦一個(gè)紋理變量被創(chuàng)建,你需要選擇一個(gè)從中加載紋理的文件。要在一個(gè)過(guò)程中實(shí)際的使用一個(gè)紋理,你要在該過(guò)程中增加一個(gè)紋理對(duì)象(在過(guò)程節(jié)點(diǎn)上單擊右鍵,選擇Add Texture Object,如圖33)。

圖33 在過(guò)程中增加紋理對(duì)象
這將創(chuàng)建一個(gè)空的紋理對(duì)象。一個(gè)紋理對(duì)象如果沒(méi)有一個(gè)有效的紋理引用,它的圖標(biāo)上將用一個(gè)紅色的叉線(xiàn):

。紋理對(duì)象映射到你shaders中的紋理階段,他們還用于存儲(chǔ)紋理和采樣器狀態(tài)。要使用一個(gè)紋理對(duì)象,還需要增加一個(gè)紋理引用。要增加一個(gè)引用,在紋理對(duì)象節(jié)點(diǎn)上單擊右鍵,在彈出的菜單中選擇Add Texture Reference菜單項(xiàng)(如圖34)。

圖34 為紋理對(duì)象增加一個(gè)引用
這將創(chuàng)建一個(gè)空的紋理引用。要實(shí)際綁定一個(gè)引用到一個(gè)紋理變量,用戶(hù)還需要指定要引用的變量的名字。如果一個(gè)有效的紋理變量被找到,紋理引用上的紅叉線(xiàn)將消失。如果紅線(xiàn)沒(méi)有消失,那就說(shuō)明紋理變量沒(méi)有被成功的引用。默認(rèn)情況下,如果工作區(qū)有一個(gè)baseMap紋理變量,RenderMonkey會(huì)將紋理引用綁定到該變量,所以我們不需要做任何事。
如果我們想為我們想為我們的紋理貼圖指定一些采樣狀態(tài),我們?yōu)橐粋€(gè)特定的紋理引用節(jié)點(diǎn)用紋理編輯器指定這些狀態(tài)值,雙擊紋理引用節(jié)點(diǎn)即可打開(kāi)紋理編輯器。(如圖35)

圖35 紋理編輯器
紋理編輯器為每個(gè)特效中的每個(gè)過(guò)程多分配了一個(gè)標(biāo)簽頁(yè)。紋理編輯器的頂部包含一個(gè)紋理應(yīng)用的列表。點(diǎn)擊紋理圖標(biāo),能選擇觀看該紋理或設(shè)置紋理狀態(tài)。要設(shè)置一個(gè)特定的狀態(tài),在狀態(tài)行和Value 列單擊,如果該狀態(tài)有預(yù)定值則選擇其中一個(gè),如果沒(méi)有直接指定一個(gè)值。注意,紋理編輯器為每個(gè)有有效文件關(guān)聯(lián)的紋理變量都增加顯示一個(gè)小的縮略圖,你將在該圖的左下角看到一個(gè)小圖標(biāo),這個(gè)小圖標(biāo)顯示了紋理的類(lèi)型。
注意,僅當(dāng)紋理對(duì)象又有效的紋理引用的時(shí)候會(huì)出現(xiàn)小圖標(biāo)

或顯示為一個(gè)縮略圖。如果紋理對(duì)象的紋理引用沒(méi)用被正確的連接,它將顯示為一個(gè)叉圖標(biāo)

。紋理編輯器為所有的紋理變量都創(chuàng)建縮略圖,可是,對(duì)立方貼圖或體積紋理它只顯示一個(gè)面或一個(gè)片斷。
在HLSL Shaders中使用紋理要在我們的像素shader中使用紋理貼圖,我們首先要增加一個(gè)采樣器。添加一個(gè)采樣器非常簡(jiǎn)單和添加一個(gè)常量的步驟一樣。你必須有一個(gè)有效的有引用的紋理對(duì)象用來(lái)添加一個(gè)采樣器。單擊Sampler標(biāo)簽后的箭頭(

)這將打開(kāi)一個(gè)能映射到HLSL 采樣器對(duì)象的紋理對(duì)象變量的列表。紋理引用的名字將被用于采樣器。用上述的方法你可以添加也可以刪除采樣器對(duì)象。
如果你想綁定一個(gè)參數(shù)到一個(gè)特定的寄存器,你要在寄存器組合框的下拉列表中選擇一個(gè)寄存器

。變量和采樣器映射的寄存器設(shè)置是各自獨(dú)立的。
然我們將我們的紋理對(duì)象映射到一個(gè)采樣器。點(diǎn)擊后面的小箭頭在下拉列表中選擇baseMap ,然后點(diǎn)擊Add。你將在生命窗口中看到如下代碼:
float4 Ia;
float Ka;
float4 Is;
float Kd;
float4 Id;
float Ns;
float Ks;
sampler baseMap;
在下面已經(jīng)更新了的像素shader的代碼(粗體顯示的行為相對(duì)以前更新的代碼):
float4 main( float4 Diff : COLOR0,
float3 Normal : TEXCOORD0,
float3 View : TEXCOORD1,
float3 Light : TEXCOORD2
float2 Tex : TEXCOORD3 ) : COLOR
{
// Compute the reflection vector:
float3 vReflect = normalize( 2 * dot( Normal, Light) * Normal - Light );
// Compute ambient term:
float4 AmbientColor = Ia * Ka;
// Compute diffuse term:
float4 DiffuseColor = Id * Kd * max( 0, dot( Normal, Light ));
// Compute specular term:
float4 SpecularColor = Is * Ks * pow( max( 0, dot(vReflect, View)), Ns );
float4 FinalColor =
(AmbientColor + DiffuseColor) * tex2D( baseMap, Tex ) + SpecularColor;
return FinalColor;
}
如果你現(xiàn)在編譯它,你將在預(yù)覽窗口中看到一個(gè)精細(xì)的帶紋理的茶壺:

圖25 帶紋理的茶壺特效
渲染到紋理讓我們將我們的特效變得稍微復(fù)雜一點(diǎn)。我們要將我們第一個(gè)過(guò)程的輸出(我們剛才創(chuàng)建的),作文我們第二個(gè)過(guò)程的輸入。這一技術(shù)叫渲染到紋理,使用它能創(chuàng)建各種各樣有趣的特效。
渲染過(guò)程要?jiǎng)?chuàng)建一個(gè)最簡(jiǎn)單的渲染到紋理特效,我們至少需要兩個(gè)過(guò)程。讓我們?cè)诠ぷ鲄^(qū)中增加一個(gè)新的過(guò)程。要增加一個(gè)新的過(guò)程,在特效節(jié)點(diǎn)上單擊右鍵在彈出的菜單中選擇Add Pass 。默認(rèn)的,每個(gè)新創(chuàng)建的過(guò)程都將包含頂點(diǎn)和像素shader節(jié)點(diǎn),一個(gè)模型節(jié)點(diǎn)和一個(gè)流映射參考節(jié)點(diǎn)(當(dāng)然,他們?cè)试S修改)。一旦你創(chuàng)建了一個(gè)新的過(guò)程,你將發(fā)現(xiàn)在預(yù)覽窗口中又出現(xiàn)了一個(gè)紅色的茶壺。這是因?yàn)椋粋€(gè)特效里的過(guò)程都是按順序別調(diào)用的。要向前或向后移動(dòng)一個(gè)過(guò)程,在該過(guò)程節(jié)點(diǎn)上單擊右鍵,然后選擇“Move Up”或“Move Down”(如圖36)。你也能用“Ctrl加Up”組合鍵來(lái)實(shí)現(xiàn)一個(gè)過(guò)程的上下移動(dòng)。現(xiàn)在我們有兩個(gè)過(guò)程,如果你將過(guò)程2移動(dòng)到過(guò)程1上,你將再次看到那個(gè)帶紋理的茶壺,然后你再把它移回來(lái),又將出現(xiàn)紅色的茶壺。

圖36 改變過(guò)程順序
為了方便調(diào)試shader程序,你也能將一個(gè)過(guò)程禁用。要禁用一個(gè)過(guò)程,在該過(guò)程節(jié)點(diǎn)上單擊右鍵選擇“Enable/Disable Pass”。一個(gè)禁用的過(guò)程的圖標(biāo)上將出現(xiàn)一個(gè)紅叉線(xiàn)

表示他已經(jīng)被禁用了。要激活一個(gè)過(guò)程,重復(fù)上述步驟即可。
工作區(qū)試圖中有一個(gè)禁用的過(guò)程的例子:

如果你已經(jīng)重新排列了過(guò)程的順序,在繼續(xù)學(xué)習(xí)之前,請(qǐng)將其恢復(fù)到原來(lái)的順序(過(guò)程1在過(guò)程2之前)。
可渲染的紋理支持RenderMonkey 支持將任何一個(gè)給定的過(guò)程渲染輸出成一個(gè)紋理供另一個(gè)后來(lái)的過(guò)程進(jìn)行采樣。要在你的工作區(qū)中增加該功能,下面給出了步驟:
1. 在工作區(qū)中的任何地方創(chuàng)建一個(gè)可渲染的紋理。注意,一次只能將一個(gè)過(guò)程的渲染輸出到該紋理。要增加一個(gè)可渲染的紋理,在任何你想將該紋理添加到的節(jié)點(diǎn)上擊右鍵選擇“Add Renderable Texture”:

圖37 增加可渲染的紋理
2. 你將看到一個(gè)新的節(jié)點(diǎn),其圖標(biāo)為:

。這就是可渲染紋理節(jié)點(diǎn),一會(huì)兒我們要將其連接到一個(gè)渲染目標(biāo)和一個(gè)紋理對(duì)象以便對(duì)其進(jìn)行采樣。
3. 接下來(lái),你要在你的過(guò)程中增加一個(gè)渲染目標(biāo)用來(lái)輸出可渲染的紋理。在過(guò)程節(jié)點(diǎn)上單擊右鍵選擇“Add Render Target”增加一個(gè)宣告染目標(biāo)(該節(jié)點(diǎn)的圖標(biāo)為

):

圖38 在過(guò)程中增加一個(gè)渲染目標(biāo)
4. 下面,你要將渲染目標(biāo)節(jié)點(diǎn)連接到你剛創(chuàng)建的可渲染的紋理。你可以通過(guò)直接將渲染目標(biāo)節(jié)點(diǎn)的名字改為可渲染紋理節(jié)點(diǎn)的名字來(lái)連接它,也可以右擊渲染目標(biāo)節(jié)點(diǎn)選擇一個(gè)參考節(jié)點(diǎn),如下圖:

圖39 連接渲染目標(biāo)節(jié)點(diǎn)到一個(gè)可渲染紋理變量
5. 現(xiàn)在,過(guò)程的輸出有了一個(gè)繪制可渲染紋理的渲染目標(biāo)節(jié)點(diǎn)。
6. 然后,我們要將該可渲染的紋理連接到一個(gè)過(guò)程以便對(duì)其進(jìn)行采樣。不過(guò)在這之前,你首先要在該過(guò)程中創(chuàng)建一個(gè)紋理對(duì)象和一個(gè)紋理參考。一旦你有了一個(gè)紋理參考,你必須將其連接到可渲染的紋理(或通過(guò)充命名的方式或單擊右鍵的方式,上面已經(jīng)介紹過(guò))。

圖40 連接紋理對(duì)象到一個(gè)可渲染的紋理變量
7. 現(xiàn)在,你就能像正常的紋理一樣使用該紋理對(duì)象了。
讓我們?cè)谖覀兊墓ぷ鲄^(qū)中增加一個(gè)可渲染的紋理。在特效工作區(qū)節(jié)點(diǎn)上單擊右鍵,選擇Add Renderable Texture。然后再過(guò)程1中增加一個(gè)渲染目標(biāo)(在過(guò)程1節(jié)點(diǎn)上單擊右鍵選擇Add Render Target)。連接渲染目標(biāo)到可渲染的紋理(方法不再累述)。現(xiàn)在,過(guò)程1的輸出已經(jīng)轉(zhuǎn)向了可渲染紋理變量。
下面,我們要在過(guò)程2中增加對(duì)可渲染紋理的采樣能力。首先,我么要保證定點(diǎn)shader正確的傳遞了紋理坐標(biāo)。將下面代碼下到定點(diǎn)shader中:
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 Tex: TEXCOORD0;
};
VS_OUTPUT main( float4 Pos: POSITION, float2 Tex: TEXCOORD0 )
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
Out.Pos = mul( view_proj_matrix, Pos );
Out.Tex = Tex;
return Out;
}
這將保證我們將插值的紋理傳遞給了像素shader。接下來(lái),我們?cè)谶^(guò)程2中增加一個(gè)有紋理引用的紋理對(duì)象(步驟上面都已經(jīng)講過(guò))。但這次我們不是將其連接到紋理變量,而是連接到可渲染的紋理變量。這將直接把過(guò)程1的輸出傳遞給過(guò)程2。打開(kāi)過(guò)程2的像素shader,增加一個(gè)采樣器。輸入以下代碼:
float4 main( float4 Diff : COLOR0,
float2 Tex : TEXCOORD0 ) : COLOR
{
return tex2D( renderTexture, Tex );
}
現(xiàn)在,預(yù)覽窗口中出現(xiàn)了一個(gè)帶紋理的茶壺,其紋理為我們?cè)谶^(guò)程1中渲染的茶壺(見(jiàn)圖41)。設(shè)置兩個(gè)過(guò)程的紋理對(duì)象的采樣器狀態(tài)來(lái)獲得更好的渲染效果:Minfilter = LINEAR Magfilter = LINEAR。

圖41 渲染到紋理特效
編輯可渲染的紋理要編輯一個(gè)可渲染紋理節(jié)點(diǎn),雙擊該節(jié)點(diǎn)將彈出可渲染紋理編輯框(見(jiàn)圖42)。

圖42 可渲染紋理編輯器
在編輯器中,你能改變可編輯紋理的尺寸。要改變寬度或高度直接在編輯框中輸入你想改變的大小,然后按回車(chē)確認(rèn)。選中“Use viewport dimensions”將會(huì)把紋理的大小邦定為視口的大小。要改變紋理的格式下拉列表中選擇一個(gè)與定義的格式。
編輯一個(gè)渲染目標(biāo)要編輯渲染目標(biāo)節(jié)點(diǎn),用戶(hù)要雙擊該節(jié)點(diǎn)打開(kāi)渲染目標(biāo)編輯器窗口:

圖43 渲染目標(biāo)編輯器
通過(guò)該編輯器,用戶(hù)能通過(guò)“Enable color clear”按鈕是否對(duì)一個(gè)可渲染的紋理使用一個(gè)透明色。如果用戶(hù)選擇用透明色,編輯器還提供了一個(gè)用于指定透明色的按鈕,點(diǎn)擊它然后回彈出顏色選擇對(duì)話(huà)框,在對(duì)話(huà)框中選擇一共顏色。用戶(hù)也能通過(guò)“Enable depth clear”復(fù)選框來(lái)制定是否使用深度清除。如果允許,用戶(hù)也能指定一個(gè)清除值。
藝術(shù)家編輯器shaders開(kāi)發(fā)者面臨的一個(gè)問(wèn)題是怎樣將其開(kāi)發(fā)的特效提交給藝術(shù)家,然后通過(guò)藝術(shù)家對(duì)其進(jìn)行加工來(lái)達(dá)到更好的效果。RenderMonkey 的解決方案是提供了一個(gè)藝術(shù)家編輯模塊。
Shader開(kāi)發(fā)人員能有選擇的指定一個(gè)變量是否為藝術(shù)家可編輯。在你想要指定的變量節(jié)點(diǎn)上單擊右鍵,再?gòu)棾龅牟藛沃羞x擇Artist Editable項(xiàng),該變量節(jié)點(diǎn)圖標(biāo)的左上角將出現(xiàn)一個(gè)黃色的小箭頭。然后你就能將你開(kāi)發(fā)的特效提供給與你一起工作的藝術(shù)家了。藝術(shù)家能通過(guò)藝術(shù)標(biāo)簽來(lái)對(duì)藝術(shù)家可編輯變量進(jìn)行編輯。當(dāng)前,支持的藝術(shù)家可編輯的變量類(lèi)型有向量,標(biāo)量和顏色,但是,任何變量都能被指定為藝術(shù)家可編輯然后通過(guò)藝術(shù)標(biāo)簽進(jìn)行訪問(wèn)。
要打開(kāi)藝術(shù)家編輯器,你能通過(guò)點(diǎn)擊應(yīng)用程序工具欄中的

圖標(biāo),也能在主菜單的視圖菜單中選擇“Artist Editor”項(xiàng)。

圖44藝術(shù)家編輯器界面
藝術(shù)家編輯器是一個(gè)可停靠窗口,它包含了特效工作區(qū),特效組,特效和過(guò)程標(biāo)簽頁(yè),只要他們中包含了藝術(shù)家可編輯的變量。如果節(jié)點(diǎn)中沒(méi)有包含藝術(shù)家可編輯變量,那么,該節(jié)點(diǎn)的標(biāo)簽頁(yè)將不會(huì)出現(xiàn)。
藝術(shù)家可編輯變量將按他們的類(lèi)型分組(顏色,向量和標(biāo)量)。每個(gè)組都能通過(guò)點(diǎn)擊

按鈕將其展開(kāi)或合并。

圖45 藝術(shù)家編輯器界面
在藝術(shù)家編輯模塊編輯變量
顏色
每個(gè)顏色變量有三個(gè)相關(guān)的控制項(xiàng)——顏色樣本按鈕用于打開(kāi)顏色拾取器,一個(gè)色調(diào)滑動(dòng)條和一個(gè)強(qiáng)度滑動(dòng)條:

圖46 顏色拾取器
向量
每個(gè)向量有五個(gè)可用的控制項(xiàng)——一個(gè)標(biāo)簽按鈕用于顯示向量編輯器的全貌,四個(gè)帶有滑動(dòng)條的組件編輯框,用于編輯向量的每一個(gè)組件:

圖47 藝術(shù)家編輯器中的向量編輯器

圖48 展開(kāi)的向量編輯框
標(biāo)量
每個(gè)標(biāo)量有兩個(gè)相關(guān)的控制想:一個(gè)由于展開(kāi)標(biāo)量編輯器的標(biāo)簽按鈕和一個(gè)用于編輯標(biāo)量值得編輯框。

圖49 標(biāo)量編輯框

圖50 展開(kāi)的標(biāo)量編輯器
posted on 2007-10-20 12:12
七星重劍 閱讀(3333)
評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi):
Game Graphics 、
HLSL&ShaderMonkey