青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

永遠也不完美的程序

不斷學習,不斷實踐,不斷的重構……

常用鏈接

統計

積分與排名

好友鏈接

最新評論

Shader示例

上一章里,我們詳細討論了HLSL著色語言的各方面。但并沒有實際展示如何編寫shader。雖然本書不是關于如何編寫shader的,但還是有必要編寫幾個簡單的shader,幫你深入了解HLSL。此外,在學習effect framework時,我們還會用到這些例子來闡述一些核心概念。

 

       記住,對創建一個完整的shader來說,不僅僅是編寫shader代碼,還包括用適當的語義符設置一系列渲染狀態和變量。當然,由于目前你還缺乏編寫完整shader的一些知識,所以,這里只討論前者:也就是頂點和像素著色程序代碼。本書的后面會對這些代碼進行擴展。

 

最簡單的Shader

 

       對于把物體渲染到屏幕上來說,有幾個基本的步驟是必須完成的。首先,需要接收輸入頂點的位置(頂點在世界坐標中的位置)并把它們轉變為屏幕坐標。通常使用world-view-projection矩陣來完成這個任務,它包含了把頂點從局部坐標映射為最終屏幕坐標的所有信息。現在開始,我們假設已經有這樣一個矩陣變量,并且名稱為view_proj_matrix

 

       先來定義一個把數據從頂點著色器傳遞給像素著色器的結構。我們把這個結構稱為VS_OUTPUT,當然,也可以是任何你喜歡的名字。目前,只需要把頂點位置數據添加到這個結構中。

 

struct VS_OUTPUT

{

     float4 Pos: POSITION;

};

 

       你應該注意到我們把POSITION語義連接到了Pos變量上,它將告訴effect系統如何把這個變量傳遞到像素著色器中。我會在下一章講解語義。現在只差頂點著色器代碼了。頂點著色器接收頂點位置,并使用view_proj_matrix矩陣對它進行變換,可以用內建的mul函數來完成這一步計算。我們把頂點著色器代碼放到一個名為vs_main的函數中:

 

VS_OUTPUT vs_main ( float4 inPos : POSITION)

{

     VS_OUTPUT Out;

     // output a transformed and projected vertex position

   Out.Pos = mul ( view_proj_matrix , inPos);

     return Out;

}

 

       這里同樣使用了POSITION語義修飾輸入參數inPos。它將告訴頂點著色器把幾何體數據流信息映射為這個參數的輸入值。接下來進入完成這個簡單shader的第二步。現在你知道了頂點在屏幕上的位置,可以定義頂點的顏色了。最簡單的方法就是把所有頂點的顏色都設置為一個常量。通常像素著色器將返回一個float4類型的值來表示當前像素在屏幕上的顏色值,float4分量分別表示紅色,綠色,藍色和alpha值。我們把像素著色器代碼放到一個名為ps_main的函數中:

 

float4 ps_main ( void ) : COLOR

{

     //Output constant color

     float4 Color;

     color[0] = color[3] = 1.0; // red and alpha on

     color[1] = color[2] = 0.0;// Green and Blue off

     return color;

}

 

       這幾乎是最簡單的代碼了,注意我們用COLOR語義修飾了函數的返回值,它將告訴編譯器把函數返回值作為當前像素的顏色值。

 

著色

 

       我們已經有渲染物體所需的最基本代碼了,如何把紋理映射到幾何體上,讓物體看起來更加真實呢?對于需要使用紋理的shader來說,需要有一個sampler類型的全局變量。在后面的章節中,我會教你如何使用語義和effect framework來設置紋理狀態。目前我們假設已經設置了好了紋理狀態:

 

       sampler Texture0;

 

       使用紋理之前,還需要知道知道對紋理的哪一部份進行采樣映射,因此,每個像素都必須有相應的紋理坐標。一般情況下,紋理坐標將作為幾何體信息的一部分輸入到頂點著色器中,經由頂點著色器計算處理之后,傳入到像素著色器中。通常使用TEXCOORDx語義來修飾作為參數傳遞的紋理坐標。這個語義將會告訴硬件如何在頂點和像素著色器之間交換數據。以下是修改之后的頂點著色器代碼:

 

struct VS_OUTPUT

{

        float4 Pos :     POSITION;

        float2 Txr1:    TEXCOORD0;

}

 

VS_OUTPUT vs_main(

        float4 inPos : POSITION;

        float2 Txr1 : TEXCOORD0)

{

        VS_OUTPUT Out;

        //Output our transformed and projected vertex position and texture coordinate

        Out.Pos = mul ( view_proj_matrix, inPos);

        Out.Txr1 = Txr1;

        returen Out;

}

 

       像素著色器也同樣簡單。在創建了sampler變量之后,可以使用HLSL的內建函數tex2D來對紋理進行采樣,代碼如下:

 

sampler Texture0;

float4 ps_main(

     float4 inDiffuse : COLOR0,

     float2 inTxr1 : TEXCOORD0) : COLOR0

{

     //Output the color taken from our texture

     return tex2D ( Texture0, inTxr1);

}

 

添加光照

 

       雖然添加了紋理的對象看起來不錯,但顯然還不夠真實。在增加場景真實度的過程中,很重要的一步就是為對象添加光照。真實世界中,從太陽到燈泡,充滿了各種光。沒有了光線,就什么都看不到了。

 

       雖然光照本身是一個相當復雜的主題,但在計算機圖形領域中,光通常被簡化為幾種基本類型:

 

l         環境光(Ambient lighting:場景中所有光源經過多次放射和折射之后,對場景總亮度貢獻的近似模擬。通常用它來減少場景中所需光源的數量,模擬出多光源下的照明效果。環境光通常是一個常量,對所有物體的作用效果都一樣。

l         漫反射光(Diffuse lighting):材質的微觀粗糙表面將導致在有所方向上均勻的反射入射光線。在任何角度接收到的反射光線強度都是相同的。

l         鏡面高光( Specular lighting):當材質表面相當光滑,粗糙度很低時,將以一種非均勻的方式反射光線。對鏡面高光來說,光線強度不但與入射光角度有關,和觀察者的角度也有關。

 

除了知道光線如何影響物體之外,你還需要如何對光源本身分類。雖然光總是由某個表面發出,比如太陽或燈泡表面,但你也可以把它們看作來自某個方向或某個點。

 

光照技術中,方向光是最簡單的類型。它們沒有位置信息,并且假設所有光線之間都是平行的,指向同一個方向。哪一種光源是這樣的呢?現實中并沒有這樣的光源。方向光是假設光源離物體無限遠時,照射到物體上的光線將近似于平行而得出的。

 

方向光最好的例子就是陽光。如果把太陽看作一個離地球上億千米的點光源,那么當陽光到達地球表面時已經近似于平行了,完全可以看作是方向光。

 

此外沒有位置信息表示方向光不隨距離而衰減。對方向光來說,要考慮的因素只有兩個:方向和光的顏色。看到這里你可能會問光線是如何影響物體表面的。如圖所示,光線照射到物體表面的強度只與入射光線和表面法線的角度有關。

       知道了這些基礎知識,就可以用入射光的方向矢量和表面法線的點積以及燈光的顏色因子計算出物體表面上任意一點的光照強度和顏色。這讓我們得出了以下代碼:

 

Color = Light_Color * saturate ( dot ( Light_Direction, inNormal ) );

 

       注意在上面的代碼中我們使用了saturate函數。它保證對于背對光線的面來說,獲得的光照強度不會為負值。當然,你也可以使用clamp函數,但是對于把值限制在01之間來說,saturate函數要更加高效。

 

       一般來說,場景中大多數的光都來自于燈泡,火炬或類似的光源。仔細觀察一下這類光源,它們通常由一個很小的有限點發出,并且位于場景中的某個特定位置。簡化一下,你可以把這些光源都看作場景中的一個點,這就是點光源。

 

       對這類光源來說,光線呈放射狀發出。這意味著只要物體和光源的距離相等,那么無論在哪個方向,所受到的影響都相同。由于表面的光照強度與光線和物體表面法線之間的關系有關,因此我們所要做的第一步就是計算出光線的方向。顯然,對于表面上的任意點來說,光線方向就等于從當前點的位置指向光源位置的矢量。對點光源來說,隨角度的衰減值如下:

 

//compute the normalized light direction vector and use it to determine the angular light attenuation

float3 Light_Direction = normal ( inPos – Light_Position);

float AngleAttn = saturate ( dot ( inNormal, Light_Direction) );

 

       此外對于點光源來說,還需要考慮它在距離上的衰減。自然,需要計算光源到當前點的距離,使用如下代碼:

 

float Distance = length ( inPos – Light_Position);

 

       通常情況下,點光源的衰減因子隨距離的平方成反比。但是為了獲得很多的可控性,可以調整公式,讓衰減和距離的二次多項式成反比,代碼如下:

 

//compute distance based attenuation. this is defined as

// attenuatin = 1 / ( a + b*distance + c * disctance * distance)

float DistAttn = saturate( 1 / ( LightAttenuation.x + LightAttenuation.y * Dist +

LightAttenuation.z * Dist));

 

現在把前面的代碼集成到頂點著色器中吧:

 

struct VS_OUTPUT

{

        float4 Pos:      POSITION;

        float2 TexCoord: TEXCOORD0;

        float2 Color:    COLOR0;

};

 

float4 Light_PointDiffuse( float3 VertPos, float3 VertNorm, float3 LightPos, float4 LightColor,

                                           float4 LightAttenuation)

{

        //determine the distance from the light o the vertex and the direction

        float3 LightDir = LightPos – VertPos;

        float Dist = length(LightDir);

        LightDir = LightDir / Dist; 

        //Compute distance based attenuation.

        float DistAttn = saturate( 1 / ( LightAttenuation.x + LightAttenuation.y * Dist +

               LightAttenuation.y * Dist*Dist));

        //comopute angle based attenuation

        float AngleAttn = saturate ( dot (VertNorm, LightDir));

        // Computer the final lighting

        return LightColor * DistAttn * AngleAttn;

}

 

VS_OUTPUT vs_main( float4 inPos: POSITION,

        float3 inNormal: NORMAL,

        float2 inTxr : TEXCOORD0)

{

        VS_OUTPUT Out;   

        Out.Pos = mul ( view_proj_matrix, inPos);

        Out.TexCoord = inTxr;

        float4 Color = Light_PointDiffuse ( inPos, inNormal, Light_Position, Light1_Color, Light_Attenuation)

        Out.Color = Color;

        return Our;

}

 

       我把計算點光源光照的代碼單獨放到了Light_PointDiffuse函數中,因此,當場景中有多個點光源時,你可以復用這段代碼。當然,我們在后面的章節會有這樣的例子。

posted on 2008-08-08 08:53 狂爛球 閱讀(1876) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美99久久| 亚洲精品日韩在线| 欧美mv日韩mv亚洲| 久久天天躁狠狠躁夜夜av| 久久精品国产77777蜜臀 | 亚洲人成在线影院| 欧美国产日本| 亚洲人精品午夜在线观看| 夜夜嗨av一区二区三区四季av| 亚洲人成网站精品片在线观看| 亚洲经典三级| 亚洲视频免费观看| 久久综合九色综合欧美就去吻| 欧美激情小视频| 国产精品网曝门| 在线欧美视频| 欧美在线free| 亚洲精品视频免费| 欧美一级在线播放| 欧美精品日韩精品| 国产在线麻豆精品观看| 亚洲三级电影在线观看| 先锋影音久久久| 欧美成人免费在线观看| 亚洲视频一起| 欧美福利电影网| 国产欧美日韩视频| 99精品久久免费看蜜臀剧情介绍| 午夜精品久久久久久久99水蜜桃 | 欧美丰满高潮xxxx喷水动漫| 亚洲精品久久在线| 久久久噜噜噜| 国产日韩欧美三区| 亚洲一区影院| 亚洲级视频在线观看免费1级| 久久xxxx精品视频| 国产精品日韩二区| 99这里只有精品| 欧美成人免费va影院高清| 午夜精品美女自拍福到在线| 欧美成人一区二免费视频软件| 国产伦精品一区二区三区免费| 99一区二区| 亚洲黄色有码视频| 欧美波霸影院| 亚洲欧美日韩人成在线播放| 老鸭窝亚洲一区二区三区| 日韩一区二区精品视频| 老鸭窝毛片一区二区三区| 国内成人精品一区| 午夜亚洲视频| 亚洲在线国产日韩欧美| 国产精品嫩草影院av蜜臀| 亚洲香蕉网站| 一区二区三区国产在线观看| 欧美日韩美女| 一区二区三区 在线观看视频| 亚洲高清视频一区| 欧美77777| 亚洲精品网址在线观看| 91久久线看在观草草青青| 你懂的国产精品| 亚洲高清av| 欧美激情导航| 欧美日韩第一页| 亚洲一区二区三区在线看 | 欧美视频在线不卡| 亚洲视频视频在线| 99亚洲一区二区| 国产精品一区二区三区乱码 | 99这里有精品| 99视频精品免费观看| 欧美视频官网| 欧美在线短视频| 久久欧美中文字幕| 亚洲黄色精品| 亚洲视频中文| 韩国欧美一区| 亚洲国产一二三| 国产精品美女久久福利网站| 久久国产精品久久久久久| 久久av在线看| 亚洲精品一区在线观看| 亚洲精品久久久久久久久久久| 欧美视频在线免费看| 久久精品免费播放| 久久综合精品一区| 亚洲欧美国产视频| 久久免费国产| 西瓜成人精品人成网站| 麻豆成人在线观看| 午夜精品99久久免费| 久久欧美中文字幕| 亚洲欧美在线磁力| 麻豆国产精品777777在线| 亚洲一区二区三区欧美| 久久久99爱| 亚洲欧美综合网| 免费不卡在线视频| 久久国产手机看片| 欧美色一级片| 亚洲激情网站| 在线观看日韩一区| 欧美极品一区| 日韩一级大片在线| 一本综合精品| 亚洲电影下载| 亚洲天堂免费观看| 亚洲人成在线播放| 欧美在线观看视频| 亚洲一区二区三区在线观看视频| 久久精品国产精品 | 一本色道婷婷久久欧美| 午夜国产精品视频| 一区二区三区免费在线观看| 久久久久久久999| 久久精品视频va| 国产精品va在线播放| 亚洲国产精品激情在线观看| 狠狠综合久久| 久久激情中文| 久久嫩草精品久久久精品一| 欧美日韩国产色综合一二三四| 欧美成人高清| 在线观看视频欧美| 久久久久国产一区二区| 久久精品中文字幕一区| 国产麻豆日韩欧美久久| 亚洲自拍16p| 欧美在线亚洲| 国产亚洲a∨片在线观看| 亚洲在线成人精品| 欧美一区二区三区男人的天堂| 国产精品久久久久9999吃药| 日韩午夜剧场| 亚洲欧美另类在线| 国产精品xxx在线观看www| 99国内精品久久| 亚洲一区999| 国产精品嫩草久久久久| 欧美亚洲色图校园春色| 欧美一区二区三区在线视频| 国产人成精品一区二区三| 亚洲欧美国产日韩中文字幕| 性高湖久久久久久久久| 国产一区二区黄| 久久久久久久综合日本| 欧美激情一区二区三区在线视频| 亚洲美女淫视频| 国产精品免费小视频| 欧美一区二区三区四区高清 | 久久久久国产成人精品亚洲午夜| 久久午夜精品一区二区| 韩国女主播一区| 女人天堂亚洲aⅴ在线观看| 亚洲欧洲精品天堂一级| 亚洲午夜免费视频| 国产亚洲一区二区三区| 欧美1区2区3区| 亚洲欧美日韩中文视频| 另类专区欧美制服同性| 亚洲精品日韩在线观看| 国产精品劲爆视频| 久久免费黄色| 一区二区三区精品在线| 久久青草欧美一区二区三区| 夜久久久久久| 久久精品亚洲一区二区| 欧美日韩国产影片| 欧美一区免费视频| 亚洲第一在线综合在线| 亚洲一区二区三区视频播放| 国产日韩欧美不卡在线| 欧美国产一区二区| 香蕉久久夜色精品国产| 亚洲黄色小视频| 久久精品99无色码中文字幕 | 亚洲久久一区| 国产毛片一区二区| 欧美激情精品久久久久| 午夜久久久久久| 亚洲毛片av在线| 免费成人高清在线视频| 亚洲字幕在线观看| 亚洲欧洲精品一区| 国产精品影视天天线| 欧美—级a级欧美特级ar全黄| 久久高清国产| 亚洲欧美一区二区三区在线| 最新亚洲视频| 欧美ab在线视频| 欧美一区二区三区精品| 亚洲无线视频| 日韩一级免费| 在线观看亚洲精品| 黄页网站一区| 国产在线观看精品一区二区三区| 欧美午夜久久久| 欧美日韩一区二区三区四区在线观看 | 一区二区三区高清不卡|