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

實時陰影繪制技術研究

C++博客 首頁 新隨筆 聯系 聚合 管理
  48 Posts :: 20 Stories :: 57 Comments :: 0 Trackbacks
直到現在我才知道前邊講的所謂黑暗映射之類的是什么東西,其實說白了就是使用多重紋理的一種方式。
多重紋理從原則上講全部可以被多次渲染所替代,因為多重紋理實際上就是將多次渲染中的每遍中的紋理在一遍中進行操作。因此我們首先介紹一下多次渲染,然后概要介紹一下多重紋理的使用方法和實現的效果。

一種復雜的效果往往是無法通過單次渲染來完成的,因此多次渲染實際上非常普遍。在shadow volume算法中就要通過多次渲染來實現陰影混合。Hook在siggraph1998中提到Quake3使用了10次渲染:
1~4  累積凹凸貼圖(Accumulate bump map)
5     漫反射光照(Diffuse lighting)
6     基本紋理,具有鏡面反射成分
7     鏡面光照(Specular lighting)
8     放射性光照(Emissive lighting)
9     體積/大氣效果(volumetric/atmosphere effect)
10    屏幕顯示(screen flash)
這對硬件的性能要求非常高,即使再現在來講對于復雜場景來講也是不能忍受的。那么為了減少渲染次數,顯卡開始支持多重紋理。
我們來看一下多次渲染和多重紋理的代碼比較。
  • 多次渲染:
//texture #1
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
m_pd3dDevice->SetTexture(0,m_pWallTexture);
m_pd3dDevice->SetSteamSource(0,m_pCubeVB,0,sizeof(CUBEVERTEXT));
m_pd3dDevice->SetFVF(FVF_CUBEVERTEXT);
m_pd3dDevice->SetIndices(m_pCubeIB,0);
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,24,0,36/3);
//texture #2
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
m_pd3dDevice->SetTexture(0,m_pDetailTexture);
m_pd3dDevice->SetSteamSource(0,m_pCubeVB,0,sizeof(CUBEVERTEXT));
m_pd3dDevice->SetFVF(FVF_CUBEVERTEXT);
m_pd3dDevice->SetIndices(m_pCubeIB);
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,24,0,36/3);
  • 多重紋理
//texture #1
m_pd3dDevice->SetTexture(0,m_pWallTexture);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
//texture #2
m_pd3dDevice->SetTexture(1,m_pDetailTexture);
m_pd3dDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,0);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_CURRENT);
m_pd3dDevice->SetSteamSource(0,m_pCubeVB,0,sizeof(CUBEVERTEXT));
m_pd3dDevice->SetFVF(FVF_CUBEVERTEXT);
m_pd3dDevice->SetIndices(m_pCubeIB);
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,24,0,36/3);

通過對比可以看到多重紋理只對場景頂點進行了一次繪制,而多次渲染要進行對此繪制。
上邊代碼也基本展示了多重紋理的使用方法:設置每一個紋理階段的紋理操作參數和操作類型,然后調用頂點繪制即可。
在一個紋理階段有最多三個紋理參數,通過設置的某種操作將結果投入下一個階段。
http://blog.sina.com.cn/pic/40d00f170200013u
這樣進行多重紋理級聯以后的效果如下:
http://blog.sina.com.cn/pic/40d00f170200013v

具體來說,紋理的操作包括:
typedef enum _D3DTEXTUREOP {    
D3DTOP_DISABLE = 1,
D3DTOP_SELECTARG1 = 2,
D3DTOP_SELECTARG2 = 3,
D3DTOP_MODULATE = 4,
D3DTOP_MODULATE2X = 5,
D3DTOP_MODULATE4X = 6,
D3DTOP_ADD = 7,
D3DTOP_ADDSIGNED = 8,
D3DTOP_ADDSIGNED2X = 9,
D3DTOP_SUBTRACT = 10,
D3DTOP_ADDSMOOTH = 11,
D3DTOP_BLENDDIFFUSEALPHA = 12,
D3DTOP_BLENDTEXTUREALPHA = 13,
D3DTOP_BLENDFACTORALPHA = 14,
D3DTOP_BLENDTEXTUREALPHAPM = 15,
D3DTOP_BLENDCURRENTALPHA = 16,
D3DTOP_PREMODULATE = 17,
D3DTOP_MODULATEALPHA_ADDCOLOR = 18,
D3DTOP_MODULATECOLOR_ADDALPHA = 19,
D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
D3DTOP_BUMPENVMAP = 22,
D3DTOP_BUMPENVMAPLUMINANCE = 23,
D3DTOP_DOTPRODUCT3 = 24,
D3DTOP_MULTIPLYADD = 25,
D3DTOP_LERP = 26,
D3DTOP_FORCE_DWORD = 0x7fffffff
 } D3DTEXTUREOP;
這里邊也包括了alpha混合的操作,都是通過D3DTEXTUREOP來進行設置。
對于每個顏色的操作最多有三個參數,也是通過 SetTextureStageState()來設置的,該方法的第一個參數設置了紋理階段,第二個參數設置了參數序號: D3DTSS_COLORARG0,D3DTSS_COLORARG1,D3DTSS_COLORARG2。第三個參數是參數值:
D3DTA_CURRENT
D3DTA_DIFFUSE
D3DTA_SELECTMASK
D3DTA_SPECULAR
D3DTA_TEMP
D3DTA_TEXTURE
D3DTA_TFACTOR

分別表示了不同的顏色獲取途徑。
OK,下面我們來看一下幾種多重紋理的效果。
1,單色紋理貼圖
一些老的三維加速卡不支持使用目標像素的阿爾法值進行紋理混合,更多信息請參閱阿爾法紋理混合。一般來說這些加速卡也不支持多重紋理混合,如果應用程序在此類適配器上運行,那么可以用多趟紋理混合進行單色光照貼圖
要進行單色光照貼圖,應用程序應該把光照信息存放在光照貼圖的阿爾法數據中。應用程序使用
Microsoft? Direct3D?的紋理過濾功能把圖元的圖像中的每個像素映射到光照貼圖中的相應texel。應用程序應該把源混合因子設為相應texel的阿爾法值.
以下C++示例代碼描述了應用程序如何把一張紋理用作單色光照貼圖。
//本例假設d3dDevice為指向IDirect3DDevice9接口的有效指針,
//且lptexLightMap為指向包含單色光照貼圖數據的紋理的有效指針。

//把光照貼圖設置為當前紋理。
d3dDevice->SetTexture(0, lptexLightMap);
//設置顏色操作。
d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
//設置顏色操作的第一個參數。
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE);
因為不支持目標阿爾法混合的適配器一般來說也不支持多重紋理混合,這個示例把光照貼圖設為第一張紋理,而這在所有三維加速卡上都是可用的。示例代碼先設置紋理混合層的顏色操作,讓紋理數據與圖元已有的顏色進行混合,然后選擇第一張紋理和圖元已有的顏色作為輸入數據。
2,有色光照貼圖

如果應用程序使用有色光照貼圖,那么通常會渲染得到更具真實感的三維場景。一張有色光照貼圖使用RGB數據存放光照信息。
以下C++示例代碼顯示了如何用RGB顏色數據進行光照貼圖。
//本例假設d3dDevice為指向IDirect3DDevice9接口的有效指針,
//且lptexLightMap為指向包含單色光照貼圖數據的紋理的有效指針。
//把光照貼圖設為第一張紋理。
d3dDevice->SetTexture(0, lptexLightMap);
d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE );
d3dDevice->SetTextureStageState( 0,D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE );
這個示例先把光照貼圖設為第一張紋理,然后設置第一個混合層的狀態,對輸入數據進行調制(相乘),并把第一張紋理和圖元的當前顏色用作調制操作的參數。
3,鏡面反射貼圖

在對發亮的物體——那些使用了高反射度材質的物體——進行光照計算時會產生鏡面反射高光。在一些情況下,由光照模塊產生的鏡面反射高光不夠精確,為了產生更吸引人的鏡面反射高光,許多Microsoft? Direct3D?應用程序會給圖元使用鏡面反射光照貼圖。

要進行鏡面反射光照貼圖,只需把鏡面反射光照貼圖與圖元的紋理相加,然后再和RGB光照貼圖進行調制(與結果相乘)操作。


//以下C++示例代碼描述了這個過程。
//本例假設d3dDevice為指向IDirect3DDevice9接口的有效指針
//lptexBaseTexture為指向紋理的有效指針。
//lptexSpecLightMap為指向包含RGB鏡面反射光照貼圖數據的紋理的有效指針。
//lptexLightMap為指向包含RGB光照貼圖數據的紋理的有效指針。
//設置基本紋理。
d3dDevice->SetTexture(0, lptexBaseTexture );
//設置要對基本紋理執行的操作及參數。
d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
//設置鏡面反射光照貼圖。
d3dDevice->SetTexture(1, lptexSpecLightMap);
//設置要對鏡面反射光照貼圖執行的操作及參數。
d3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD );
d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT );
//設置RGB光照貼圖。
d3dDevice->SetTexture(2, lptexLightMap);
//設置要對RGB光照貼圖執行的操作及參數。
d3dDevice->SetTextureStageState(2,D3DTSS_COLOROP, D3DTOP_MODULATE);
d3dDevice->SetTextureStageState(2,D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(2,D3DTSS_COLORARG2, D3DTA_CURRENT );
4,漫反射光照貼圖

不光滑的表面在被光源照射時會顯示漫反射光。漫反射光的亮度取決于表面到光源的距離及表面法向與光源的方向向量間的夾角。通過光照計算(譯注:由光照模塊執行)模擬漫反射光只能得到一般的效果。
應用程序可以用光照貼圖模擬更為復雜的漫反射光照效果,只需在基本紋理的基礎上再加一張漫反射光照貼圖即可,如以下C++示例代碼所示。
//本例假設d3dDevice為指向IDirect3DDevice9接口的有效指針。
//lptexBaseTexture為指向紋理的有效指針。
//lptexLightMap為指向包含RGB光照貼圖數據的紋理的有效指針。
//設置基本紋理。
d3dDevice->SetTexture(0,lptexBaseTexture );
//設置要對基本紋理執行的操作及參數。
d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE );
d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE );
//設置漫反射光照貼圖。
d3dDevice->SetTexture(1,lptexDiffuseLightMap );
//設置混合層 。
d3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE );
d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT );
上邊介紹了四種基本貼圖,下邊介紹幾種特效貼圖。
1,黑暗映射(Dark mapping)
黑暗映射實際上是把一張灰度圖作用于當前的紋理中。采用調制的方式進行混合,適合于微弱光照的情況進行渲染。
2,黑暗貼圖動畫
就是通過控制顯示的次數和顯示亮度的關系,分別調用三種不同的調制操作類型來交替顯示,就可以達到黑暗貼圖動畫的效果。適合于閃爍的黑暗環境。
3,細節紋理(Detail mapping)
采用一張細節紋理,將基礎紋理和細節紋理做addsigned操作,可以模擬粗糙的表面細節。

上述效果都不是固定的應用,可以盡可能多的采用紋理類型和紋理混合形式,最終實現更好的效果。

 
順便說一下alpha調制。
原來我一直以為作為第四維alpha和RGB的處理方式是一樣的,直到昨天問了大牛才知道不是。現在的圖形硬件已經可以對RGB和alpha分別進行處理,因為alpha最開始是用來表示透明的,又可以用來在混合的時候表示混合因子,但是隨著圖形技術的發展alpha的應用也發生了變化,于是圖形硬件開始允許alpha進行單獨的操作。那么d3d里邊就可以對alpha操作進行單獨的設置。alpha操作的設置方法同顏色操作的設置方式基本相同,操作類型甚至都差不多。
 
最后是紋理管理。d3d有一個時間戳管理方法,通過最近最少使用算法來進行從內存到顯存的調度。當然也允許設置紋理的優先級來強制管理。

posted on 2006-01-10 11:12 苦行僧 閱讀(1205) 評論(0)  編輯 收藏 引用 所屬分類: directX
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲三级影院| 一区二区欧美在线观看| 久久精品一二三区| 欧美一区二区三区久久精品茉莉花| 亚洲国产精品成人va在线观看| 免费欧美在线| 欧美激情一区二区三区不卡| 免费影视亚洲| 亚洲高清毛片| 亚洲视频网在线直播| 亚洲视频第一页| 性欧美大战久久久久久久久| 香蕉久久夜色精品国产| 久久米奇亚洲| 欧美日本在线看| 国产精品欧美一区喷水| 国产综合久久| 99国产精品久久久久老师| 亚洲欧美精品在线| 麻豆av福利av久久av| 亚洲精品网址在线观看| 欧美一区免费视频| 欧美日韩午夜激情| 极品日韩久久| 在线综合欧美| 久久综合色播五月| 一二美女精品欧洲| 久久免费视频网| 国产精品久久久久久久久久久久久久 | 亚洲国产视频a| 亚洲一区在线观看视频| 理论片一区二区在线| 日韩五码在线| 性欧美超级视频| 欧美黄色一区二区| 亚洲欧美精品在线观看| 麻豆av一区二区三区| 欧美激情中文不卡| 国产伦精品免费视频 | 136国产福利精品导航网址应用 | 欧美一级视频| 欧美sm视频| 亚洲视频在线观看视频| 久久一区精品| 国产精品国产三级国产aⅴ入口| 国产精品家教| 亚洲高清在线| 欧美一区二区三区在线观看视频 | 欧美fxxxxxx另类| 日韩视频永久免费观看| 欧美一级夜夜爽| 欧美日韩高清在线| 禁断一区二区三区在线| 亚洲调教视频在线观看| 亚洲午夜在线观看| 久久国内精品视频| 久久久亚洲人| 亚洲自拍偷拍色片视频| 欧美日本韩国一区| 亚洲激情第一区| 蜜臀av在线播放一区二区三区| 亚洲精品偷拍| 麻豆国产精品777777在线| 国产精品高精视频免费| 亚洲精品国产精品久久清纯直播| 久久蜜臀精品av| 香蕉乱码成人久久天堂爱免费 | 欧美顶级少妇做爰| 黑人一区二区三区四区五区| 亚洲一区二区三区欧美 | 精品盗摄一区二区三区| 欧美一区二区三区四区在线观看地址| 91久久久久久| 免费观看成人| 亚洲国产欧美在线| 欧美激情视频一区二区三区免费 | 最新亚洲一区| 猛男gaygay欧美视频| 国产一区二区三区久久 | 国产精品久久久久毛片大屁完整版 | 久久精品人人爽| 国产欧美日韩亚州综合| 亚洲欧美日韩一区| 亚洲淫性视频| 亚洲大片免费看| 在线视频中文亚洲| 亚洲精品国精品久久99热| 嫩模写真一区二区三区三州| 精久久久久久| 欧美一区二区视频免费观看| 亚洲一线二线三线久久久| 国产欧美在线视频| 久久久亚洲综合| 久久夜色撩人精品| 亚洲免费观看| 一本高清dvd不卡在线观看| 欧美日韩亚洲一区二区| 亚洲欧美一区在线| 亚洲欧美视频一区| 国内精品视频一区| 欧美激情bt| 欧美日韩一区成人| 欧美一区二区三区男人的天堂 | 欧美1级日本1级| 欧美日本成人| 欧美在线视频日韩| 久久久久www| 亚洲毛片av| 亚洲视频一区| 伊人成人在线视频| 亚洲精品国产视频| 欧美大片免费观看| 亚洲日本精品国产第一区| 久久视频一区| 欧美激情网站在线观看| 亚洲欧美久久久久一区二区三区| 亚洲欧美第一页| 国产精品盗摄久久久| 久久久久免费视频| 欧美一区二区三区成人| 日韩午夜激情av| 免费精品99久久国产综合精品| 亚洲免费中文字幕| 可以免费看不卡的av网站| 亚洲午夜激情在线| 免费成人av资源网| 亚洲激情自拍| 欧美国产精品专区| 噜噜噜91成人网| 国产精品一区二区在线观看不卡 | 亚洲六月丁香色婷婷综合久久| 亚洲一区二区三区四区五区黄| 亚洲国产精品成人综合色在线婷婷| 一区二区高清视频| 91久久中文字幕| 久久精品盗摄| 夜夜嗨一区二区| 久久一区二区三区av| 老司机一区二区| 欧美日韩国产色站一区二区三区| 欧美成人精品在线观看| 午夜一区在线| 亚洲午夜视频在线| 欧美不卡在线| 久久久久网址| 国产性做久久久久久| 99视频精品全部免费在线| 在线观看的日韩av| 欧美一区视频在线| 欧美中文日韩| 国产目拍亚洲精品99久久精品| 日韩午夜精品视频| 国产一区二区三区免费在线观看| 亚洲国产高清在线| 国产欧美日韩综合精品二区| 亚洲国产日韩欧美一区二区三区| 欧美在线你懂的| 亚洲一区三区视频在线观看| 国产精品区免费视频| 中文国产亚洲喷潮| 午夜精品久久久久久久蜜桃app | 亚洲婷婷综合久久一本伊一区| 免费在线亚洲欧美| 亚洲国产1区| 日韩视频不卡| 欧美日韩和欧美的一区二区| 亚洲乱码视频| 午夜久久久久| 国模精品一区二区三区| a91a精品视频在线观看| 亚洲日韩视频| 免费日韩av电影| 欧美aⅴ99久久黑人专区| 136国产福利精品导航| 欧美 日韩 国产 一区| 亚洲欧洲日本mm| 亚洲在线电影| 国产一区二区三区观看| 久久一区免费| 日韩视频在线观看| 久久成人免费电影| 亚洲激情不卡| 国产精品视频精品视频| 欧美一区二区免费| 欧美激情aaaa| 亚洲国产婷婷| 国产人成精品一区二区三| 欧美在线短视频| 亚洲精品一级| 久久久久综合网| 国内精品久久久久久影视8| 牛人盗摄一区二区三区视频| 99视频在线精品国自产拍免费观看 | 久久精品国产在热久久| 亚洲大胆美女视频| 国产精品一区一区| 欧美福利电影网| 一区二区三区免费网站| 久久野战av| 亚洲欧美日韩区|