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

天行健 君子當自強而不息

D3D中的光照(1)

為了提高場景的真實性,我們可以為其加入燈光。燈光也能幫助表現物體的立體感以及物體的實體形狀。當使用燈光時,我們不再自己指定頂點的顏色;Direct3D中每個頂點都通過燈光引擎來計算頂點顏色,該計算是基于定義的燈光資源,材質以及燈光資源關心的表面方向。通過燈光模型計算頂點顏色會得到更真實的場景。

5.1燈光的組成

       在Direct3D燈光模型中,燈光是通過燈光資源的三個成員之一來照射的,即有三種燈光。

環境光(Ambient Light)——這種類型的燈光將被其他所有表面反射且被用在照亮整個場景。例如,物體的各部分都被照亮,對于一個角度,甚至穿過不在光源直接照射的地方他們都能被照亮。環境光的使用是粗略的,便宜的,它模仿反射光。

漫反射(Diffuse Reflection)——這種燈光按照特殊方向傳播。當它照射到一個表面,它將在所有方向上均勻的反射。因為漫射光在所有方向上都均勻的反射,被反射的光線將到達眼睛而與觀察點無關,因此我們不必為觀察者考慮。因而,漫射光僅僅需要考慮燈光方向和表面的朝向。這種燈光將成為你的資源中照射的普通燈光。

鏡面反射(Specular Reflection)——這種燈光按照特殊方向傳播。當它照射到一個表面時,它嚴格地按照一個方向反射。這將產生一個明亮的光澤,它能在某角度被看見。因為這種燈光在一個方向反射。明顯的觀察點,必須考慮燈光的方向和表面朝向,且必須按照鏡面燈光等式來考慮。鏡面燈光被用在物體上產生高光的地方,這種光澤只有在燈光照射在磨光的表面上才會產生。

鏡面光比其他燈光類型要求更多的計算;因此,Direct3D提供了一個開關選擇。實際上,它默認是被關閉的;要使用鏡面光你必須設置D3DRS_SPECULARENABLE渲染狀態。

Device->SetRenderState(D3DRS_SPECULARENABLE, true);

每一種燈光都是通過D3DCOLORVALUE結構或者描述燈光顏色的D3DXCOLOR來描繪的。這里有幾個燈光顏色的例子:

D3DXCOLOR redAmbient(1.0f, 0.0f, 0.0f, 1.0f);

D3DXCOLOR blueDiffuse(0.0f, 0.0f, 1.0f, 1.0f);

D3DXCOLOR whiteSpecular(1.0f, 1.0f, 1.0f, 1.0f);

注意:在D3DXCOLOR類中的alpha值用在描述燈光顏色時是被忽略的。

5.2材質

在現實世界中我們看到的物體顏色將由物體反射回來的燈光顏色來決定。比如,一個紅色的球是紅色的,因為它吸收所有的燈光顏色除了紅色光。紅色光是被球反射回來進入我們眼睛的,因此我們看到的球是紅色的。Direct3D通過我們定義的物體材質來模擬這些所有的現象。材質允許我們定義表面反射燈光的百分比。在代碼中通過D3DMATERIAL9結構描述一個材質。

typedef struct _D3DMATERIAL9 {

       D3DCOLORVALUE Diffuse, Ambient, Specular, Emissive;

       float Power;

} D3DMATERIAL9;

Diffuse——指定此表面反射的漫射光數量。

Ambient——指定此表面反射的環境光數量。

Specular——指定此表面反射的鏡面光數量

Emissive——這個是被用來給表面添加顏色,它使得物體看起來就象是它自己發出的光一樣。

Power——指定銳利的鏡面高光;它的值是高光的銳利值。

舉例,想得到一個紅色的球。我們將定義球的材質來只反射紅光吸收其他顏色的所有光:

D3DMATERIAL9 red;

::ZeroMemory(&red, sizeof(red));

red.Diffuse = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red

red.Ambient = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red

red.Specular = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red

red.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); // no emission

red.Power = 5.0f;

這里我們設置綠色和藍色的值為0,這表明材質反射0%此顏色的光。我們設置紅色為1,表示材質反射100%的紅光。注意,我們能夠控制每種燈光反射的顏色(環境、漫射和鏡面光)。

 

同樣假如我們定義一個只發出藍色光的光源,對球的光照將失敗因為藍色光將被全部吸收而沒有紅光被反射。當物體吸收了所有光以后,物體看起來就為黑色。同樣的,當物體反射100%的紅、綠和藍光,物體就將呈現為白色。

因為手工填充一個材質結構將是乏味的工作,我們添加下列有用的函數和全局材質常數到d3dUtility.h/cpp文件中:

// lights
D3DLIGHT9 init_directional_light(D3DXVECTOR3* direction, D3DXCOLOR* color);
D3DLIGHT9 init_point_light(D3DXVECTOR3
* position, D3DXCOLOR* color);
D3DLIGHT9 init_spot_light(D3DXVECTOR3
* position, D3DXVECTOR3* direction, D3DXCOLOR* color);

// materials
D3DMATERIAL9 init_material(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular, 
                           D3DXCOLOR emissive, 
float power);

const D3DMATERIAL9 WHITE_MATERIAL  = init_material(WHITE,  WHITE,  WHITE,  BLACK, 2.0f);
const D3DMATERIAL9 RED_MATERIAL       = init_material(RED,       RED,       RED,    BLACK, 2.0f);
const D3DMATERIAL9 GREEN_MATERIAL  = init_material(GREEN,  GREEN,  GREEN,  BLACK, 2.0f);
const D3DMATERIAL9 BLUE_MATERIAL   = init_material(BLUE,   BLUE,   BLUE,   BLACK, 2.0f);
const D3DMATERIAL9 YELLOW_MATERIAL = init_material(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);

D3DLIGHT9 init_directional_light(D3DXVECTOR3
* direction, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ZeroMemory(
&light, sizeof(light));

    light.Type        
= D3DLIGHT_DIRECTIONAL;
    light.Ambient    
= *color * 0.6f;
    light.Diffuse    
= *color;
    light.Specular    
= *color * 0.6f;
    light.Direction 
= *direction;

    
return light;
}

D3DLIGHT9 init_point_light(D3DXVECTOR3
* position, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ZeroMemory(
&light, sizeof(light));

    light.Type            
= D3DLIGHT_POINT;
    light.Ambient        
= *color * 0.6f;
    light.Diffuse        
= *color;
    light.Specular        
= *color * 0.6f;
    light.Position        
= *position;
    light.Range            
= 1000.0f;
    light.Falloff        
= 1.0f;
    light.Attenuation0    
= 1.0f;
    light.Attenuation1    
= 0.0f;
    light.Attenuation2    
= 0.0f;

    
return light;
}

D3DLIGHT9 init_spot_light(D3DXVECTOR3
* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ZeroMemory(
&light, sizeof(light));

    light.Type            
= D3DLIGHT_SPOT;
    light.Ambient        
= *color * 0.6f;
    light.Diffuse        
= *color;
    light.Specular        
= *color * 0.6f;
    light.Position        
= *position;
    light.Direction        
= *direction;
    light.Range            
= 1000.0f;
    light.Falloff        
= 1.0f;
    light.Attenuation0    
= 1.0f;
    light.Attenuation1    
= 0.0f;
    light.Attenuation2    
= 0.0f;
    light.Theta            
= 0.4f;
    light.Phi            
= 0.9f;

    
return light;
}

D3DMATERIAL9 init_material(D3DXCOLOR ambient, D3DXCOLOR diffuse, D3DXCOLOR specular, 
                           D3DXCOLOR emissive, 
float power)
{
    D3DMATERIAL9 material;

    material.Ambient  
= ambient;
    material.Diffuse  
= diffuse;
    material.Specular 
= specular;
    material.Emissive 
= emissive;
    material.Power      
= power;

    
return material;
}

 

頂點結構沒有材質屬性;一個通用的材質必須被設置。設置它我們使用IDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9*pMaterial)方法。

假設我們想渲染幾個不同材質的物體;我們將按照如下的寫法去做:

D3DMATERIAL9 blueMaterial, redMaterial;

 

// set up material structures

Device->SetMaterial(&blueMaterial);

drawSphere(); // blue sphere

 

Device->SetMaterial(&redMaterial);

drawSphere(); // red sphere

5.3頂點法線

       面法線(face normal)是描述多邊形表面方向的一個向量(如圖5.1)。

頂點法線(Vertex normals)也是基于同樣的概念,但是我們與其指定每個多邊形的法線,還不如為每個頂點指定(如圖5.2)。

Direct3D需要知道頂點法線以便它能夠確定燈光照射到物體表面的角度,并且一旦計算了每個頂點的燈光,Direct3D需要知道每個頂點的表面方向。注意頂點法線不一定和面法線相同。球體/環形物就是很好的實物例子,它們的頂點法線和三角形法線是不相同的(如圖5.3)。

為了描述頂點的頂點法線,我們必須更新原來的頂點結構::

class cLightVertex
{
public:
    
float m_x, m_y, m_z;
    
float m_nx, m_ny, m_nz; 

    cLightVertex() {}

    cLightVertex(
float x, float y, float z, float nx, float ny, float nz)
    {
        m_x  
= x;    m_y  = y;    m_z  = z;
        m_nx 
= nx;    m_ny = ny;    m_nz = nz;
    }
};

const DWORD LIGHT_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL;

 

作為一個簡單的物體比如立方體和球體,我們能夠通過觀察看見頂點法線。對于更多復雜的網格,我們需要一個更多的機械方法。假設一個由p0,p1,p2構成的三角形,我們需要計算每個頂點的法線n0,n1,n2。

簡單的步驟,我們列舉它是為了找到由三個點構成的三角形的面法線,同時使用面法線作為頂點法線。首先計算三角形上的兩個向量:

  • p1p0 = u

  • p2p0 = v

Then the face normal is:

  • n = u × v

Since each vertex normal is the same as the face normal:

  • n0 = n1 = n2 = n

下面是一個C函數,它通過三角形的三個頂點計算三角形的面法線。注意這個函數的三個頂點是按照順時針方向指定的。假如不是這樣,那么法線方向將是相反的。

void ComputeNormal(D3DXVECTOR3* p0, D3DXVECTOR3* p1, D3DXVECTOR3* p2, D3DXVECTOR3* out)

{

       D3DXVECTOR3 u = *p1 - *p0;

       D3DXVECTOR3 v = *p2 - *p0;

       D3DXVec3Cross(out, &u, &v);

       D3DXVec3Normalize(out, out);

}

當用三角形近似表示曲面時,使用面法線作為頂點法線不能表現一個平滑的結果。一個更好的方法是找到頂點法線的平均法線。為了找到頂點v的頂點法線vn,我們找到網格模型中所有三角形的面法線記為頂點v。vn是通過計算他們的平均面法線得到的。這里有一個例子,假設有3個三角形它們的面法線分別是n0,n1,n2,指定為頂點v。那么vn的平均法線就是:

vn = (1/3) . (n0 + n1 + n2)

變換過程中把頂點法線變為non-normal,這是有可能的。因此最好通過D3DRS_NORMALIZENORMALS設置渲染狀態,Direct3D重新單位化所有法線。

Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);


posted on 2008-03-16 13:39 lovedday 閱讀(1163) 評論(0)  編輯 收藏 引用


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


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩国产在线播放网站| 午夜视频在线观看一区二区| 欧美丰满少妇xxxbbb| 久久精品99国产精品日本| 欧美精品九九| 亚洲国产mv| 亚洲一区制服诱惑| 亚洲精品在线二区| 久久综合久久综合九色| 狠狠色狠狠色综合日日小说| 亚洲免费视频网站| 亚洲精品一区二区三区99| 鲁大师成人一区二区三区| 精品91久久久久| 免费观看成人www动漫视频| 国产曰批免费观看久久久| 久久国产精品久久久久久久久久| 亚洲一区二区三区久久| 国产农村妇女精品一二区| 国产手机视频精品| 久久久久网址| 国产精品国产三级国产| 久久亚洲精品网站| 欧美h视频在线| 香蕉成人久久| 欧美激情精品久久久| 久久精品青青大伊人av| 欧美日韩国产成人精品| 免费不卡在线视频| 国产亚洲精品久久飘花| 亚洲国产91精品在线观看| 欧美性一区二区| 欧美激情1区2区3区| 国产免费成人在线视频| 在线视频日韩精品| 亚洲精品久久久久| 久久亚洲高清| 美女91精品| 国产午夜精品美女毛片视频| 一区二区三区高清在线| 亚洲成人自拍视频| 欧美国产在线电影| 国产欧美日韩不卡| 欧美一区二区三区日韩| 久久午夜色播影院免费高清| 国产精品久线观看视频| 亚洲一级免费视频| 久久精品中文字幕一区| 国内精品视频666| 欧美激情中文字幕一区二区| 国产无一区二区| 香蕉av福利精品导航| 欧美一级大片在线免费观看| 国产丝袜美腿一区二区三区| 久久久不卡网国产精品一区| 欧美va天堂| 亚洲欧美激情视频在线观看一区二区三区 | 蜜桃av一区二区在线观看| 国产一区二区三区久久久| 久久精品免费看| 亚洲成人在线视频播放 | 亚洲第一精品福利| 女人天堂亚洲aⅴ在线观看| 艳妇臀荡乳欲伦亚洲一区| 久久久久久一区二区| 亚洲作爱视频| 亚洲电影在线| 国产美女精品视频| 欧美色大人视频| 欧美高清视频在线观看| 欧美在线视频a| 亚洲专区在线| 中文在线不卡视频| 亚洲日本久久| 免费短视频成人日韩| 久久女同精品一区二区| 欧美一区二区高清在线观看| 欧美日韩日本网| 欧美在线视频观看| 亚洲美女电影在线| 亚洲国产精品久久久久秋霞蜜臀| 国产精品你懂的在线欣赏| 国产精品99一区| 国产精品国产成人国产三级| 国产精品高潮粉嫩av| 国产精品制服诱惑| 国产欧美一区二区三区另类精品 | 久久中文在线| 久久精品国产久精国产爱| 香蕉久久一区二区不卡无毒影院 | 久久久久综合| 一区二区欧美日韩| 91久久精品国产91久久性色| 国产精品中文字幕在线观看| 国产精品福利在线| 激情久久综合| 99一区二区| 久久成人国产精品| 你懂的亚洲视频| 欧美激情视频网站| 亚洲系列中文字幕| 免费成人小视频| 国产精品一二| 亚洲免费福利视频| 欧美伊久线香蕉线新在线| 欧美大片91| 欧美一区二区高清| 欧美日韩一二三四五区| 国产一区二区三区在线观看免费视频| 在线成人激情黄色| 亚洲视频久久| 国产日韩专区| 亚洲一区二区毛片| 欧美高清视频一二三区| 99这里只有精品| 久久久久久久精| 国产精品sm| 国产精品一国产精品k频道56| 欧美日韩欧美一区二区| 激情五月综合色婷婷一区二区| 一区二区三区四区五区精品视频 | 午夜精品久久久久久久蜜桃app| 欧美gay视频| 亚洲人成网站999久久久综合| 久热精品视频| 久热这里只精品99re8久| 曰韩精品一区二区| 久久躁日日躁aaaaxxxx| 久久精品毛片| 亚洲精品美女在线| 99这里只有久久精品视频| 欧美日韩一区二区三区在线观看免| 亚洲第一中文字幕| 亚洲国产精品成人va在线观看| 久久aⅴ国产欧美74aaa| 一区二区三区在线免费播放| 免费看的黄色欧美网站| 欧美极品欧美精品欧美视频| 亚洲尤物影院| 久久免费的精品国产v∧| 欧美aⅴ99久久黑人专区| 在线成人中文字幕| 99视频精品全国免费| 国产一区欧美日韩| 亚洲人体偷拍| 国内精品美女av在线播放| 日韩午夜免费| 又紧又大又爽精品一区二区| 亚洲经典一区| 国产亚洲精品自拍| 亚洲免费观看视频| 亚洲免费综合| 99re亚洲国产精品| 欧美在线视频免费播放| 亚洲欧美视频在线观看| 久久伊人亚洲| 欧美一乱一性一交一视频| 欧美剧在线观看| 亚洲激情偷拍| 一本色道久久综合狠狠躁篇怎么玩 | 免费日韩成人| 中日韩高清电影网| 欧美亚洲一区| 亚洲免费在线观看| 国产精品成人午夜| 夜夜躁日日躁狠狠久久88av| 亚洲乱码国产乱码精品精| 欧美在线播放一区| 欧美一区二区视频观看视频| 国产精品激情电影| 亚洲午夜黄色| 久久久国产一区二区三区| 欧美日韩亚洲一区三区| 99在线热播精品免费| 99在线精品视频在线观看| 欧美日韩的一区二区| 亚洲国产精品电影| 亚洲久久视频| 国产精品www网站| 欧美伊久线香蕉线新在线| 久久最新视频| 亚洲视频久久| 国产资源精品在线观看| 美日韩免费视频| 亚洲午夜羞羞片| 欧美国产成人精品| 亚洲一区二区三区免费在线观看 | 宅男噜噜噜66国产日韩在线观看| 国产欧美日韩麻豆91| 欧美亚洲一区二区在线| 欧美大片免费观看在线观看网站推荐| 亚洲欧美日本国产专区一区| 午夜精品视频在线| 亚洲高清色综合| 国产欧美日韩| 国产精品高潮粉嫩av| 欧美ab在线视频| 久久久99精品免费观看不卡| 亚洲一区二区三区免费在线观看| 美女精品国产|