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

永遠也不完美的程序

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

常用鏈接

統計

積分與排名

好友鏈接

最新評論

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>
            国产精品yjizz| 蜜臀久久99精品久久久画质超高清| 亚洲少妇最新在线视频| 夜夜狂射影院欧美极品| 国产免费亚洲高清| 久久久欧美一区二区| 久久综合影音| 一本色道**综合亚洲精品蜜桃冫| 亚洲中无吗在线| 亚洲大片精品永久免费| 日韩视频三区| 黄色成人免费观看| 亚洲欧洲三级| 久久aⅴ乱码一区二区三区| 亚洲东热激情| 亚洲欧美精品在线| 欧美一级在线播放| 欧美国产日韩二区| 久久久久久久久蜜桃| 欧美日韩国产综合视频在线观看 | 欧美大尺度在线观看| 亚洲免费在线视频| 猛男gaygay欧美视频| 性娇小13――14欧美| 国产精品综合网站| 午夜日本精品| 亚洲欧美日韩中文播放| 国产精品免费网站| 日韩午夜在线播放| 亚洲一区欧美激情| 免费在线看一区| 久久国产直播| 国产精品第一页第二页第三页| 欧美激情一级片一区二区| 欧美sm视频| 久久成人免费电影| 欧美新色视频| 亚洲午夜极品| 洋洋av久久久久久久一区| 欧美激情按摩在线| 亚洲视频自拍偷拍| 久久久久久久一区二区| 亚洲国产成人在线播放| 欧美日韩国产成人高清视频| 午夜精品福利电影| 欧美一区综合| 国产精品日韩在线| 日韩香蕉视频| 欧美一区二区三区四区夜夜大片| 影音先锋亚洲电影| 久久久久九九九九| 欧美中文字幕在线播放| 在线看视频不卡| 欧美午夜影院| 免费成人av资源网| 午夜精品久久久久久99热软件| 欧美激情乱人伦| 欧美一区二区视频在线观看| 最新日韩中文字幕| 欧美肥婆在线| 亚洲欧美资源在线| 日韩网站免费观看| 麻豆成人av| 亚洲三级免费电影| 欧美日韩国内自拍| 久久天天狠狠| 亚洲人成艺术| 在线亚洲观看| 国产精品久久久久三级| 理论片一区二区在线| 亚洲欧美日韩精品综合在线观看| 一区二区毛片| 奶水喷射视频一区| 欧美一级午夜免费电影| 久久嫩草精品久久久精品一| 亚洲视频在线观看免费| 亚洲国产精品一区| 国产一区亚洲一区| 欧美福利电影网| 欧美在线视频网站| 亚洲欧美成人网| 一本色道久久综合亚洲精品高清| 午夜精品久久久久久久蜜桃app | 一本久道久久久| 一区视频在线播放| 欧美精品导航| 亚洲欧美日本视频在线观看| 亚洲精品美女久久7777777| 久久亚洲综合色一区二区三区| 亚洲国产欧美不卡在线观看| 欧美激情综合| 美日韩免费视频| 久久久精品一区二区三区| 亚洲激情女人| 欧美国产一区二区三区激情无套| 久久五月婷婷丁香社区| 久久精品国产一区二区电影| 午夜国产精品视频免费体验区| 亚洲午夜精品一区二区| 国产日韩欧美一区| 老司机午夜精品| 亚洲欧美在线看| 欧美aⅴ一区二区三区视频| 久久久91精品国产一区二区三区 | 狠狠88综合久久久久综合网| 国产欧美激情| 免费在线观看一区二区| 久热精品视频在线| 狼人社综合社区| 免费看的黄色欧美网站| 葵司免费一区二区三区四区五区| 美女露胸一区二区三区| 欧美激情精品久久久久久蜜臀| 欧美日韩成人| 国产精品免费观看在线| 国产热re99久久6国产精品| 国产人成精品一区二区三| 一区二区在线观看视频| 亚洲欧洲日本国产| 亚洲深夜激情| 久久精品一级爱片| 欧美成人乱码一区二区三区| 久久精品国产亚洲aⅴ| 久久夜色精品一区| 亚洲国产成人精品久久| 国内精品亚洲| 亚洲一区二区精品在线观看| 国产精品无码永久免费888| 亚洲一区视频| 亚洲图片在区色| 亚洲欧洲av一区二区| 久久国产精品久久久久久| 日韩一级不卡| 国产精品99久久久久久久vr | 国产精品家教| 国产亚洲欧美色| 国产精品一区在线播放| 国产亚洲成av人在线观看导航| 一区在线播放| 亚洲一区视频在线观看视频| 久久全国免费视频| 亚洲乱码国产乱码精品精可以看 | 亚洲激情欧美| 99精品视频免费| 最新国产精品拍自在线播放| 久久精品九九| 亚洲激情欧美| 久久精品一区中文字幕| 欧美欧美在线| 欧美日本不卡高清| 国产精品一区久久久| 亚洲精品日日夜夜| 先锋影音一区二区三区| 亚洲国产福利在线| 欧美一区二区三区在| 欧美日韩免费观看一区| 欧美体内谢she精2性欧美| 欧美日韩综合一区| 黄色成人精品网站| 亚洲一区二区视频在线| 欧美v亚洲v综合ⅴ国产v| 欧美激情片在线观看| 亚洲午夜在线观看视频在线| 久久综合狠狠| 国产美女精品视频| 日韩一区二区精品视频| 亚洲天堂偷拍| 欧美高清自拍一区| 性色av一区二区三区| 欧美视频中文字幕在线| 亚洲精品免费一二三区| 欧美日韩一二区| 女女同性精品视频| 久久天天躁狠狠躁夜夜av| 日韩特黄影片| 农夫在线精品视频免费观看| 韩国欧美一区| 久久国产欧美| 在线综合视频| 欧美精品一区二区在线播放| 亚洲国产成人精品视频| 久久男人av资源网站| 亚洲专区欧美专区| 国产精品久久久| 中文亚洲视频在线| 日韩亚洲视频在线| 欧美日本不卡高清| 日韩视频国产视频| 午夜精品久久久久久| 亚洲精品日韩久久| 欧美体内she精视频在线观看| 激情综合色丁香一区二区| 久久精品亚洲一区| 午夜老司机精品| 国产日韩欧美精品| 久久成人久久爱| 欧美一级久久| 激情综合网激情| 欧美成人国产va精品日本一级| 久久视频这里只有精品|