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

天行健 君子當自強而不息

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>
            亚洲黄色成人久久久| 亚洲欧美日本国产有色| 亚洲成在人线av| 亚洲欧美日韩一区二区在线 | 激情五月***国产精品| 久久综合网hezyo| 欧美亚洲综合网| 亚洲电影在线播放| 欧美xxx在线观看| 亚洲国产精品综合| 亚洲国产成人精品女人久久久| 久久精品一区二区三区四区 | 一区二区三区精品在线| 狼狼综合久久久久综合网| 久久国产福利| 另类亚洲自拍| 日韩视频在线你懂得| 午夜欧美精品久久久久久久| 亚洲午夜性刺激影院| 亚洲第一精品在线| 欧美国产视频在线观看| 久久精品成人一区二区三区蜜臀| 欧美一区2区三区4区公司二百| 久久久久久九九九九| 欧美黄色免费| 亚洲国产精品123| 久久精品99无色码中文字幕| 亚洲国产视频直播| 老牛影视一区二区三区| 国产精品久久久久久久第一福利| 一区二区在线免费观看| 久久国产福利| 久久av红桃一区二区小说| 国产精品欧美一区喷水| 一区二区自拍| 久久久欧美精品| 久久精精品视频| 国产亚洲欧美一区二区三区| 午夜久久久久久久久久一区二区| 亚洲电影免费观看高清完整版| 午夜欧美大片免费观看| 国内精品久久久久久久影视蜜臀| 欧美尤物巨大精品爽| 欧美夜福利tv在线| 国内精品久久久久伊人av| 免费观看在线综合色| 欧美劲爆第一页| 在线视频欧美一区| 亚洲色在线视频| 国产精品一区二区你懂得 | 久久亚洲精品网站| 亚洲免费成人| 亚洲美女区一区| 国产精品亚洲综合天堂夜夜| 亚洲综合二区| 久久综合九色综合久99| 一区二区三区视频免费在线观看| 一区二区精品在线| 国产一区日韩欧美| 99热免费精品在线观看| 国产亚洲激情| 亚洲午夜精品国产| 亚洲精品国产系列| 久久国产乱子精品免费女 | 亚洲福利在线看| 亚洲无毛电影| 亚洲视频axxx| 欧美三级第一页| 亚洲精品久久久久久下一站| 国产亚洲精品福利| 亚洲欧美综合一区| 久久精品午夜| 永久久久久久| 久久先锋资源| 欧美国产在线视频| 亚洲国产精品va在线看黑人| 久久乐国产精品| 欧美激情一区二区久久久| 91久久精品日日躁夜夜躁国产| 欧美主播一区二区三区| 亚洲大胆人体视频| 久久久免费精品视频| 麻豆freexxxx性91精品| 亚洲精品少妇30p| 欧美精品一区在线播放| 亚洲最黄网站| 久久夜色精品国产噜噜av| 国产精品久久久久久久久久尿| 亚洲视频精品在线| 久久亚洲一区| 野花国产精品入口| 国产精品一区久久| 久久亚洲精品伦理| 99精品热视频只有精品10| 翔田千里一区二区| 狠狠色伊人亚洲综合成人| 免费观看成人鲁鲁鲁鲁鲁视频| 日韩午夜在线电影| 久久综合影音| 欧美在线免费播放| 亚洲在线视频网站| 亚洲电影一级黄| 久久躁狠狠躁夜夜爽| 亚洲欧美国产制服动漫| 亚洲大胆女人| 国内自拍亚洲| 国产日本亚洲高清| 欧美日韩的一区二区| 免费的成人av| 一区二区三区成人| 亚洲电影中文字幕| 久热精品在线视频| 欧美中文字幕久久| 一区二区三区国产| 91久久中文字幕| 欧美日韩国产成人在线91| 亚洲一区欧美| 这里只有精品在线播放| 亚洲欧美影音先锋| 99国产精品国产精品毛片| 韩国av一区二区三区在线观看| 国产精品第三页| 欧美视频在线免费| 美女主播一区| 日韩午夜精品视频| 欧美一区深夜视频| 日韩午夜在线播放| 亚洲日本中文字幕免费在线不卡| 美女视频黄a大片欧美| 久久一区二区三区四区| 农村妇女精品| 亚洲三级性片| 亚洲高清激情| 亚洲伦伦在线| 欧美在线亚洲| 先锋影音久久久| 久久久亚洲高清| 欧美高清视频一区二区| 亚洲欧美一区二区视频| 久久福利资源站| 欧美日本韩国一区| 国产一级久久| 亚洲一区尤物| 开元免费观看欧美电视剧网站| 亚洲激情中文1区| 香蕉免费一区二区三区在线观看 | 久久久久免费视频| 久久精品夜色噜噜亚洲aⅴ| 欧美mv日韩mv亚洲| 国产伦精品一区二区三区免费| 激情五月婷婷综合| 亚洲资源在线观看| 日韩亚洲欧美一区二区三区| 亚洲激情网站| 久久久久一区二区| 国产欧美一区二区精品性色| 日韩图片一区| 亚洲高清免费在线| 夜夜嗨av一区二区三区网站四季av | aa级大片欧美三级| 亚洲欧美成人在线| 久久久蜜桃一区二区人| 国产亚洲制服色| 久久福利影视| 久久国产日韩欧美| 欧美国产精品劲爆| 亚洲日本成人在线观看| 亚洲第一视频网站| 免费中文字幕日韩欧美| 狠狠色伊人亚洲综合成人| 亚洲国产一区二区a毛片| 看欧美日韩国产| 亚洲私人影院在线观看| 久久久久成人网| 亚洲青涩在线| 亚洲一区二区精品视频| 国产字幕视频一区二区| 免费日韩一区二区| 久久九九久精品国产免费直播| 亚洲激情影视| 国产精品扒开腿做爽爽爽视频 | 亚洲影院一区| 亚洲高清在线观看| 欧美三区在线视频| 久久精品一本| 久久综合国产精品| 亚洲欧美www| 欧美a级理论片| 亚洲高清久久久| 91久久线看在观草草青青| 亚洲国产日日夜夜| 伊人精品成人久久综合软件| 亚洲国产成人一区| 在线不卡a资源高清| 性做久久久久久久久| 亚洲视屏在线播放| 欧美成人免费视频| 欧美激情精品久久久久久蜜臀| 国产精品久久久久久亚洲调教| 亚洲欧洲三级|